cinnamon-settings-daemon-6.4.3/0000775000175000017500000000000014733247605015364 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/0000775000175000017500000000000014733247605017045 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/meson.build0000664000175000017500000000124714733247605021213 0ustar fabiofabiodesktop_conf = configuration_data() desktop_conf.set('libexecdir', join_paths(prefix, libexecdir)) ln_script = join_paths(meson.project_source_root(), 'install-scripts', 'meson_mk_symlink.py') # subdir('dummy') subdir('common') subdir('a11y-settings') subdir('automount') subdir('background') subdir('clipboard') subdir('datetime') subdir('housekeeping') subdir('keyboard') subdir('media-keys') subdir('power') subdir('screensaver-proxy') subdir('settings-remap') subdir('xsettings') if colord.found() subdir('color') endif if cups.found() subdir('print-notifications') endif if nss.found() subdir('smartcard') endif if wacom.found() subdir('wacom') endif cinnamon-settings-daemon-6.4.3/plugins/datetime/0000775000175000017500000000000014733247605020641 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-fedora.h0000664000175000017500000000300314733247605026551 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include #include gboolean _get_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp); gboolean _set_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean using_ntp); gboolean _update_etc_sysconfig_clock_fedora (GDBusMethodInvocation *invocation, const char *key, const char *value); cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism.h0000664000175000017500000000371514733247605025325 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef CSD_DATETIME_MECHANISM_H #define CSD_DATETIME_MECHANISM_H #include #include G_BEGIN_DECLS #define CSD_DATETIME_TYPE_MECHANISM (csd_datetime_mechanism_get_type ()) G_DECLARE_FINAL_TYPE (CsdDatetimeMechanism, csd_datetime_mechanism, CSD_DATETIME, MECHANISM, GObject) extern GMainLoop *loop; extern GDBusConnection *connection; typedef enum { CSD_DATETIME_MECHANISM_ERROR_GENERAL, CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, CSD_DATETIME_MECHANISM_NUM_ERRORS } CsdDatetimeMechanismError; #define CSD_DATETIME_MECHANISM_ERROR csd_datetime_mechanism_error_quark () GType csd_datetime_mechanism_error_get_type (void); #define CSD_DATETIME_MECHANISM_TYPE_ERROR (csd_datetime_mechanism_error_get_type ()) GQuark csd_datetime_mechanism_error_quark (void); GType csd_datetime_mechanism_get_type (void); CsdDatetimeMechanism *csd_datetime_mechanism_new (void); G_END_DECLS #endif /* CSD_DATETIME_MECHANISM_H */ cinnamon-settings-daemon-6.4.3/plugins/datetime/meson.build0000664000175000017500000000436014733247605023006 0ustar fabiofabio datetime_exported_iface = gnome.gdbus_codegen( 'csd-exported-datetime', 'csd-datetime-mechanism.xml', interface_prefix: 'org.cinnamon.SettingsDaemon.DateTimeMechanism.', namespace: 'Csd', annotations: ['org.cinnamon.SettingsDaemon.DateTimeMechanism', 'org.gtk.GDBus.C.Name', 'ExportedDateTime'] ) datetime_common_sources = [ 'system-timezone.c', 'system-timezone.h', ] datetime_sources = [ 'csd-datetime-mechanism.c', 'csd-datetime-mechanism.h', 'csd-datetime-mechanism-fedora.c', 'csd-datetime-mechanism-fedora.h', 'csd-datetime-mechanism-debian.c', 'csd-datetime-mechanism-debian.h', 'csd-datetime-mechanism-suse.c', 'csd-datetime-mechanism-suse.h', 'csd-datetime-mechanism-main.c', datetime_common_sources, datetime_exported_iface ] test_timezone_sources = [ 'test-system-timezone.c', datetime_common_sources, ] datetime_deps = [ common_dep, csd_dep, libnotify, polkit, gio, gio_unix ] if polkit.found() executable( 'csd-datetime-mechanism', datetime_sources, include_directories: [include_dirs, common_inc], dependencies: datetime_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-datetime-mechanism') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-datetime-mechanism') endif executable( 'test-datetime', test_timezone_sources, dependencies: datetime_deps, install: false, ) endif datetime_conf = configuration_data() datetime_conf.set('LIBEXECDIR', join_paths(prefix, libexecdir)) configure_file( input: 'org.cinnamon.SettingsDaemon.DateTimeMechanism.service.in', output: 'org.cinnamon.SettingsDaemon.DateTimeMechanism.service', configuration: datetime_conf, install_dir: dbusservicedir, ) install_data( 'org.cinnamon.settingsdaemon.datetimemechanism.policy', install_dir: polkitdir, ) install_data( 'org.cinnamon.SettingsDaemon.DateTimeMechanism.conf', install_dir: dbussystemdir, ) cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-fedora.c0000664000175000017500000001734014733247605026555 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "csd-datetime-mechanism-fedora.h" #include "csd-datetime-mechanism.h" /* Return the name of the installed NTP client, prefer chrony if both chrony * and ntp are installed */ static const char * get_ntp_client () { if (g_file_test ("/etc/chrony.conf", G_FILE_TEST_EXISTS)) return "chronyd"; else if (g_file_test ("/etc/ntp.conf", G_FILE_TEST_EXISTS)) return "ntpd"; return NULL; } gboolean _get_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp) { int exit_status; GError *error = NULL; const char *ntp_client; char *cmd; ntp_client = get_ntp_client (); if (ntp_client) { *can_use_ntp = TRUE; cmd = g_strconcat ("/sbin/service ", ntp_client, " status", NULL); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/service: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); if (exit_status == 0) *is_using_ntp = TRUE; else *is_using_ntp = FALSE; } else { *can_use_ntp = FALSE; *is_using_ntp = FALSE; } return TRUE; } gboolean _set_using_ntp_fedora (GDBusMethodInvocation *invocation, gboolean using_ntp) { GError *error; int exit_status; const char *ntp_client; char *cmd; error = NULL; ntp_client = get_ntp_client (); /* We omit --level 2345 so that systemd doesn't try to use the * SysV init scripts */ cmd = g_strconcat ("/sbin/chkconfig ", ntp_client, " ", using_ntp ? "on" : "off", NULL); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); cmd = g_strconcat ("/sbin/service ", ntp_client, " ", using_ntp ? "restart" : "stop", NULL);; if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); return TRUE; } gboolean _update_etc_sysconfig_clock_fedora (GDBusMethodInvocation *invocation, const char *key, const char *value) { char **lines; int n; gboolean replaced; char *data; gsize len; GError *error; /* On Red Hat / Fedora, the /etc/sysconfig/clock file needs to be kept in sync */ if (!g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", "No such file"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } error = NULL; if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } replaced = FALSE; lines = g_strsplit (data, "\n", 0); g_free (data); for (n = 0; lines[n] != NULL; n++) { if (g_str_has_prefix (lines[n], key)) { g_free (lines[n]); lines[n] = g_strdup_printf ("%s%s", key, value); replaced = TRUE; } } if (replaced) { GString *str; str = g_string_new (NULL); for (n = 0; lines[n] != NULL; n++) { g_string_append (str, lines[n]); if (lines[n + 1] != NULL) g_string_append_c (str, '\n'); } data = g_string_free (str, FALSE); len = strlen (data); if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error updating /etc/sysconfig/clock: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (data); return FALSE; } g_free (data); } g_strfreev (lines); return TRUE; } cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-debian.c0000664000175000017500000001623014733247605026534 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "csd-datetime-mechanism-debian.h" #include "csd-datetime-mechanism.h" static void _get_using_ntpdate (gboolean *can_use, gboolean *is_using, GError ** error) { if (!g_file_test ("/usr/sbin/ntpdate-debian", G_FILE_TEST_EXISTS)) return; *can_use = TRUE; if (g_file_test ("/etc/network/if-up.d/ntpdate", G_FILE_TEST_EXISTS)) *is_using = TRUE; } static void _get_using_ntpd (gboolean *can_use, gboolean *is_using, GError ** error) { int exit_status; GError *tmp_error = NULL; if (!g_file_test ("/usr/sbin/ntpd", G_FILE_TEST_EXISTS)) return; *can_use = TRUE; if (!g_spawn_command_line_sync ("/usr/sbin/service ntp status", NULL, NULL, &exit_status, &tmp_error)) { if (error != NULL && *error == NULL) { *error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /usr/sbin/service: %s", tmp_error->message); } g_error_free (tmp_error); return; } if (exit_status == 0) *is_using = TRUE; } gboolean _get_using_ntp_debian (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp) { GError *error = NULL; /* In Debian, ntpdate is used whenever the network comes up. So if either ntpdate or ntpd is installed and available, can_use is true. If either is active, is_using is true. */ _get_using_ntpdate (can_use_ntp, is_using_ntp, &error); _get_using_ntpd (can_use_ntp, is_using_ntp, &error); if (error == NULL) { return TRUE; } else { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } } static void _set_using_ntpdate (gboolean using_ntp, GError **error) { const gchar *cmd = NULL; GError *tmp_error = NULL; /* Debian uses an if-up.d script to sync network time when an interface comes up. This is a separate mechanism from ntpd altogether. */ #define NTPDATE_ENABLED "/etc/network/if-up.d/ntpdate" #define NTPDATE_DISABLED "/etc/network/if-up.d/ntpdate.disabled" if (using_ntp && g_file_test (NTPDATE_DISABLED, G_FILE_TEST_EXISTS)) cmd = "/bin/mv -f "NTPDATE_DISABLED" "NTPDATE_ENABLED; else if (!using_ntp && g_file_test (NTPDATE_ENABLED, G_FILE_TEST_EXISTS)) cmd = "/bin/mv -f "NTPDATE_ENABLED" "NTPDATE_DISABLED; else return; if (!g_spawn_command_line_sync (cmd, NULL, NULL, NULL, &tmp_error)) { if (error != NULL && *error == NULL) { *error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /bin/mv: %s", tmp_error->message); } g_error_free (tmp_error); return; } /* Kick start ntpdate to sync time immediately */ if (using_ntp && !g_spawn_command_line_sync ("/etc/network/if-up.d/ntpdate", NULL, NULL, NULL, &tmp_error)) { if (error != NULL && *error == NULL) { *error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /etc/network/if-up.d/ntpdate: %s", tmp_error->message); } g_error_free (tmp_error); return; } } static void _set_using_ntpd (gboolean using_ntp, GError **error) { GError *tmp_error = NULL; int exit_status; char *cmd; if (!g_file_test ("/usr/sbin/ntpd", G_FILE_TEST_EXISTS)) return; cmd = g_strconcat ("/usr/sbin/update-rc.d ntp ", using_ntp ? "enable" : "disable", NULL); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &tmp_error)) { if (error != NULL && *error == NULL) { *error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, tmp_error->message); } g_error_free (tmp_error); g_free (cmd); return; } g_free (cmd); cmd = g_strconcat ("/usr/sbin/service ntp ", using_ntp ? "restart" : "stop", NULL);; if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &tmp_error)) { if (error != NULL && *error == NULL) { *error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, tmp_error->message); } g_error_free (tmp_error); g_free (cmd); return; } g_free (cmd); } gboolean _set_using_ntp_debian (GDBusMethodInvocation *invocation, gboolean using_ntp) { GError *error = NULL; /* In Debian, ntpdate and ntpd may be installed separately, so don't assume both are valid. */ _set_using_ntpdate (using_ntp, &error); _set_using_ntpd (using_ntp, &error); if (error == NULL) { return TRUE; } else { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootcinnamon-settings-daemon-6.4.3/plugins/datetime/org.cinnamon.SettingsDaemon.DateTimeMechanism.service.incinnamon-settings-daemon-6.4.3/plugins/datetime/org.cinnamon.SettingsDaemon.DateTimeMechanism.servic0000664000175000017500000000016614733247605032714 0ustar fabiofabio[D-BUS Service] Name=org.cinnamon.SettingsDaemon.DateTimeMechanism Exec=@LIBEXECDIR@/csd-datetime-mechanism User=root cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism.c0000664000175000017500000007122514733247605025321 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "csd-exported-datetime.h" #include #include "system-timezone.h" #include "csd-datetime-mechanism.h" /* NTP helper functions for various distributions */ #include "csd-datetime-mechanism-fedora.h" #include "csd-datetime-mechanism-debian.h" #include "csd-datetime-mechanism-suse.h" struct _CsdDatetimeMechanism { GObject parent; CsdExportedDateTime *skeleton; PolkitAuthority *auth; }; G_DEFINE_TYPE (CsdDatetimeMechanism, csd_datetime_mechanism, G_TYPE_OBJECT) static gboolean _check_polkit_for_action (CsdDatetimeMechanism *mechanism, GDBusMethodInvocation *invocation); #define IFACE "org.cinnamon.SettingsDaemon.DateTimeMechanism" static const GDBusErrorEntry csd_datetime_mechanism_error_entries[] = { { CSD_DATETIME_MECHANISM_ERROR_GENERAL, IFACE ".GeneralError" }, { CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, IFACE ".NotPrivileged" }, { CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, IFACE ".InvalidTimezoneFile" } }; GQuark csd_datetime_mechanism_error_quark (void) { static volatile gsize quark_volatile = 0; g_dbus_error_register_error_domain ("csd_datetime_mechanism_error", &quark_volatile, csd_datetime_mechanism_error_entries, G_N_ELEMENTS (csd_datetime_mechanism_error_entries)); return quark_volatile; } static gboolean do_exit (gpointer user_data) { g_debug ("Exiting due to inactivity"); g_main_loop_quit (loop); return FALSE; } static void reset_killtimer (void) { static guint timer_id = 0; if (timer_id > 0) { g_source_remove (timer_id); timer_id = 0; } g_debug ("Setting killtimer to 30 seconds..."); timer_id = g_timeout_add_seconds (30, do_exit, NULL); } static gboolean check_can_do (CsdDatetimeMechanism *mechanism, const char *action, GDBusMethodInvocation *invocation, gint *canval) { const char *sender; PolkitSubject *subject; PolkitAuthorizationResult *result; GError *error; reset_killtimer (); /* Check that caller is privileged */ sender = g_dbus_method_invocation_get_sender (invocation); subject = polkit_system_bus_name_new (sender); error = NULL; result = polkit_authority_check_authorization_sync (mechanism->auth, subject, action, NULL, 0, NULL, &error); g_object_unref (subject); if (error) { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (polkit_authorization_result_get_is_authorized (result)) { *canval = 2; } else if (polkit_authorization_result_get_is_challenge (result)) { *canval = 1; } else { *canval = 0; } g_object_unref (result); return TRUE; } gboolean handle_can_set_timezone (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { gint canval = 0; reset_killtimer (); g_debug ("CanSetTimezone called"); if (!check_can_do (mechanism, "org.cinnamon.settingsdaemon.datetimemechanism.configure", invocation, &canval)) { return FALSE; } csd_exported_date_time_complete_can_set_timezone (object, invocation, canval); return TRUE; } static gboolean check_tz_name (const char *tz, GError **error) { GFile *file; char *tz_path, *actual_path; gboolean retval; retval = TRUE; tz_path = g_build_filename (SYSTEM_ZONEINFODIR, tz, NULL); /* Get the actual resolved path */ file = g_file_new_for_path (tz_path); actual_path = g_file_get_path (file); g_object_unref (file); /* The tz name passed had relative paths in it */ if (g_strcmp0 (tz_path, actual_path) != 0) { g_set_error (error, CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, "Timezone file '%s' was invalid.", tz); retval = FALSE; } g_free (tz_path); g_free (actual_path); return retval; } gboolean handle_set_timezone (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, const char *tz, CsdDatetimeMechanism *mechanism) { GError *error; reset_killtimer (); g_debug ("SetTimezone ('%s') called", tz); if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; error = NULL; if (!check_tz_name (tz, &error)) return FALSE; if (!system_timezone_set (tz, &error)) { GError *error2; int code; if (error->code == SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE) code = CSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE; else code = CSD_DATETIME_MECHANISM_ERROR_GENERAL; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, code, "%s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } csd_exported_date_time_complete_set_timezone (object, invocation); return TRUE; } gboolean handle_get_timezone (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { gchar *timezone; reset_killtimer (); g_debug ("GetTimezone called"); timezone = system_timezone_find (); csd_exported_date_time_complete_get_timezone (object, invocation, timezone); g_free (timezone); return TRUE; } static gboolean _sync_hwclock (GDBusMethodInvocation *invocation) { GError *error; error = NULL; if (g_file_test ("/sbin/hwclock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { int exit_status; if (!g_spawn_command_line_sync ("/sbin/hwclock --systohc", NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/hwclock: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } if (WEXITSTATUS (exit_status) != 0) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "/sbin/hwclock returned %d", exit_status); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } } return TRUE; } static gboolean _set_date (CsdDatetimeMechanism *mechanism, guint day, guint month, guint year, GDBusMethodInvocation *invocation) { GDateTime *time; char *date_str, *time_str; char *date_cmd; int exit_status; GError *error; if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; date_str = g_strdup_printf ("%02d/%02d/%d", month, day, year); error = NULL; time = g_date_time_new_now_local (); time_str = g_date_time_format (time, "%R:%S"); g_date_time_unref (time); date_cmd = g_strdup_printf ("/bin/date -s \"%s %s\" +\"%%D %%R:%%S\"", date_str, time_str); g_free (date_str); g_free (time_str); if (!g_spawn_command_line_sync (date_cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /bin/date: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (date_cmd); return FALSE; } g_free (date_cmd); if (WEXITSTATUS (exit_status) != 0) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "/bin/date returned %d", exit_status); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (!_sync_hwclock (invocation)) return FALSE; return TRUE; } gboolean handle_set_date (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, guint day, guint month, guint year, CsdDatetimeMechanism *mechanism) { reset_killtimer (); g_debug ("SetDate (%d, %d, %d) called", day, month, year); if (!_set_date (mechanism, day, month, year, invocation)) { return FALSE; } csd_exported_date_time_complete_set_date (object, invocation); return TRUE; } static gboolean _set_time (CsdDatetimeMechanism *mechanism, const struct timeval *tv, GDBusMethodInvocation *invocation) { GError *error; if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; if (settimeofday (tv, NULL) != 0) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error calling settimeofday({%ld,%ld}): %s", (gint64) tv->tv_sec, (gint64) tv->tv_usec, strerror (errno)); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (!_sync_hwclock (invocation)) return FALSE; return TRUE; } gboolean handle_set_time (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, gint64 seconds_since_epoch, CsdDatetimeMechanism *mechanism) { struct timeval tv; reset_killtimer (); g_debug ("SetTime (%" G_GINT64_FORMAT ") called", seconds_since_epoch); tv.tv_sec = (time_t) seconds_since_epoch; tv.tv_usec = 0; if (!_set_time (mechanism, &tv, invocation)) { return FALSE; } csd_exported_date_time_complete_set_time (object, invocation); return TRUE; } gboolean handle_can_set_time (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { gint canval = 0; g_debug ("CanSetTime called"); if (!check_can_do (mechanism, "org.cinnamon.settingsdaemon.datetimemechanism.configure", invocation, &canval)) { return FALSE; } csd_exported_date_time_complete_can_set_time (object, invocation, canval); return TRUE; } gboolean handle_adjust_time (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, gint64 seconds_to_add, CsdDatetimeMechanism *mechanism) { struct timeval tv; reset_killtimer (); g_debug ("AdjustTime (%" G_GINT64_FORMAT " ) called", seconds_to_add); if (gettimeofday (&tv, NULL) != 0) { GError *error; error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error calling gettimeofday(): %s", strerror (errno)); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } tv.tv_sec += (time_t) seconds_to_add; if (!_set_time (mechanism, &tv, invocation)) { return FALSE; } csd_exported_date_time_complete_adjust_time (object, invocation); return TRUE; } gboolean handle_get_hardware_clock_using_utc (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { char **lines; char *data; gsize len; GError *error; gboolean is_utc; reset_killtimer (); g_debug ("GetHardwareClockUsingUtc called"); error = NULL; if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/adjtime file: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } lines = g_strsplit (data, "\n", 0); g_free (data); if (g_strv_length (lines) < 3) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Cannot parse /etc/adjtime"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); g_strfreev (lines); return FALSE; } if (strcmp (lines[2], "UTC") == 0) { is_utc = TRUE; } else if (strcmp (lines[2], "LOCAL") == 0) { is_utc = FALSE; } else { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Expected UTC or LOCAL at line 3 of /etc/adjtime; found '%s'", lines[2]); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); g_strfreev (lines); return FALSE; } g_strfreev (lines); csd_exported_date_time_complete_get_hardware_clock_using_utc (object, invocation, is_utc); return TRUE; } gboolean handle_set_hardware_clock_using_utc (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, gboolean using_utc, CsdDatetimeMechanism *mechanism) { GError *error; error = NULL; reset_killtimer (); g_debug ("SetHardwareClockUsingUtc (%d) called", using_utc); if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; if (g_file_test ("/sbin/hwclock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { int exit_status; char *cmd; cmd = g_strdup_printf ("/sbin/hwclock %s --systohc", using_utc ? "--utc" : "--localtime"); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/hwclock: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); if (WEXITSTATUS (exit_status) != 0) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "/sbin/hwclock returned %d", exit_status); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) { /* Fedora */ if (!_update_etc_sysconfig_clock_fedora (invocation, "UTC=", using_utc ? "true" : "false")) return FALSE; } else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) { /* SUSE variant */ if (!_update_etc_sysconfig_clock_suse (invocation, "HWCLOCK=", using_utc ? "-u" : "--localtime")) return FALSE; } } csd_exported_date_time_complete_set_hardware_clock_using_utc (object, invocation); return TRUE; } gboolean handle_get_using_ntp (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { GError *error = NULL; gboolean ret; gboolean is_using_ntp = FALSE; gboolean can_use_ntp = FALSE; reset_killtimer (); g_debug ("GetUsingNtp called"); if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) /* Fedora */ ret = _get_using_ntp_fedora (invocation, &can_use_ntp, &is_using_ntp); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ ret = _get_using_ntp_debian (invocation, &can_use_ntp, &is_using_ntp); else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ ret = _get_using_ntp_suse (invocation, &can_use_ntp, &is_using_ntp); else { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error enabling NTP: OS variant not supported"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (ret) { csd_exported_date_time_complete_get_using_ntp (object, invocation, can_use_ntp, is_using_ntp); } return ret; } gboolean handle_set_using_ntp (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, gboolean using_ntp, CsdDatetimeMechanism *mechanism) { GError *error; gboolean ret; reset_killtimer (); g_debug ("SetUsingNtp (%d) called", using_ntp); error = NULL; if (!_check_polkit_for_action (mechanism, invocation)) return FALSE; if (g_file_test ("/etc/redhat-release", G_FILE_TEST_EXISTS)) /* Fedora */ ret = _set_using_ntp_fedora (invocation, using_ntp); else if (g_file_test ("/usr/sbin/update-rc.d", G_FILE_TEST_EXISTS)) /* Debian */ ret = _set_using_ntp_debian (invocation, using_ntp); else if (g_file_test ("/etc/SuSE-release", G_FILE_TEST_EXISTS)) /* SUSE variant */ ret = _set_using_ntp_suse (invocation, using_ntp); else { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error enabling NTP: OS variant not supported"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (ret) { csd_exported_date_time_complete_set_using_ntp (object, invocation); } return ret; } gboolean handle_can_set_using_ntp (CsdExportedDateTime *object, GDBusMethodInvocation *invocation, CsdDatetimeMechanism *mechanism) { gint canval = 0; g_debug ("CanSetUsingNtp called"); if (!check_can_do (mechanism, "org.cinnamon.settingsdaemon.datetimemechanism.configure", invocation, &canval)) { return FALSE; } csd_exported_date_time_complete_can_set_using_ntp (object, invocation, canval); return TRUE; } static void csd_datetime_mechanism_dispose (GObject *object) { CsdDatetimeMechanism *mechanism; g_return_if_fail (object != NULL); g_return_if_fail (CSD_DATETIME_IS_MECHANISM (object)); mechanism = CSD_DATETIME_MECHANISM (object); if (mechanism->skeleton != NULL) { g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (mechanism->skeleton)); g_clear_object (&mechanism->skeleton); } g_clear_object (&mechanism->auth); G_OBJECT_CLASS (csd_datetime_mechanism_parent_class)->dispose (object); } static void csd_datetime_mechanism_class_init (CsdDatetimeMechanismClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = csd_datetime_mechanism_dispose; } static void csd_datetime_mechanism_init (CsdDatetimeMechanism *mechanism) { } typedef struct { const gchar *signal_name; gpointer callback; } SkeletonSignal; static SkeletonSignal skeleton_signals[] = { // signal name callback { "handle-set-timezone", handle_set_timezone }, { "handle-get-timezone", handle_get_timezone }, { "handle-can-set-timezone", handle_can_set_timezone }, { "handle-set-date", handle_set_date }, { "handle-set-time", handle_set_time }, { "handle-can-set-time", handle_can_set_time }, { "handle-adjust-time", handle_adjust_time }, { "handle-get-hardware-clock-using-utc", handle_get_hardware_clock_using_utc }, { "handle-set-hardware-clock-using-utc", handle_set_hardware_clock_using_utc }, { "handle-get-using-ntp", handle_get_using_ntp }, { "handle-set-using-ntp", handle_set_using_ntp }, { "handle-can-set-using-ntp", handle_can_set_using_ntp } }; static gboolean register_mechanism (CsdDatetimeMechanism *mechanism) { GError *error = NULL; gint i; mechanism->auth = polkit_authority_get_sync (NULL, &error); if (mechanism->auth == NULL) { if (error != NULL) { g_critical ("error getting system bus: %s", error->message); g_error_free (error); } goto error; } mechanism->skeleton = csd_exported_date_time_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (mechanism->skeleton), connection, "/org/cinnamon/SettingsDaemon/DateTimeMechanism", &error); if (error != NULL) { g_critical ("error exporting datetime interface: %s", error->message); g_error_free (error); goto error; } for (i = 0; i < G_N_ELEMENTS (skeleton_signals); i++) { SkeletonSignal sig = skeleton_signals[i]; g_signal_connect (mechanism->skeleton, sig.signal_name, G_CALLBACK (sig.callback), mechanism); } reset_killtimer (); return TRUE; error: return FALSE; } CsdDatetimeMechanism * csd_datetime_mechanism_new (void) { GObject *object; gboolean res; object = g_object_new (CSD_DATETIME_TYPE_MECHANISM, NULL); res = register_mechanism (CSD_DATETIME_MECHANISM (object)); if (! res) { g_object_unref (object); return NULL; } return CSD_DATETIME_MECHANISM (object); } static gboolean _check_polkit_for_action (CsdDatetimeMechanism *mechanism, GDBusMethodInvocation *invocation) { const char *action = "org.cinnamon.settingsdaemon.datetimemechanism.configure"; const char *sender; GError *error; PolkitSubject *subject; PolkitAuthorizationResult *result; error = NULL; /* Check that caller is privileged */ sender = g_dbus_method_invocation_get_sender (invocation); subject = polkit_system_bus_name_new (sender); result = polkit_authority_check_authorization_sync (mechanism->auth, subject, action, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, NULL, &error); g_object_unref (subject); if (error) { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } if (!polkit_authorization_result_get_is_authorized (result)) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, "Not Authorized for action %s", action); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); g_object_unref (result); return FALSE; } g_object_unref (result); return TRUE; } cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-suse.h0000664000175000017500000000305014733247605026272 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * Copyright (C) 2011 Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include #include gboolean _get_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp); gboolean _set_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean using_ntp); gboolean _update_etc_sysconfig_clock_suse (GDBusMethodInvocation *invocation, const char *key, const char *value); cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-suse.c0000664000175000017500000001616214733247605026275 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * Copyright (C) 2011 Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include "csd-datetime-mechanism-suse.h" #include "csd-datetime-mechanism.h" gboolean _get_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp) { int exit_status; GError *error = NULL; if (g_file_test ("/etc/ntp.conf", G_FILE_TEST_EXISTS)) { *can_use_ntp = TRUE; if (!g_spawn_command_line_sync ("/sbin/service ntp status", NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning /sbin/service: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } if (exit_status == 0) *is_using_ntp = TRUE; else *is_using_ntp = FALSE; } else { *can_use_ntp = FALSE; *is_using_ntp = FALSE; } return TRUE; } gboolean _set_using_ntp_suse (GDBusMethodInvocation *invocation, gboolean using_ntp) { GError *error; int exit_status; char *cmd; error = NULL; /* We omit --level 2345 so that systemd doesn't try to use the * SysV init scripts */ cmd = g_strconcat ("/sbin/chkconfig ntp ", using_ntp ? "on" : "off", NULL); if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); cmd = g_strconcat ("/sbin/service ntp ", using_ntp ? "restart" : "stop", NULL);; if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error spawning '%s': %s", cmd, error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (cmd); return FALSE; } g_free (cmd); return TRUE; } gboolean _update_etc_sysconfig_clock_suse (GDBusMethodInvocation *invocation, const char *key, const char *value) { char **lines; int n; gboolean replaced; char *data; gsize len; GError *error; /* On SUSE variants, the /etc/sysconfig/clock file needs to be kept in sync */ if (!g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { error = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", "No such file"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return FALSE; } error = NULL; if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error reading /etc/sysconfig/clock file: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); return FALSE; } replaced = FALSE; lines = g_strsplit (data, "\n", 0); g_free (data); for (n = 0; lines[n] != NULL; n++) { if (g_str_has_prefix (lines[n], key)) { g_free (lines[n]); lines[n] = g_strdup_printf ("%s%s", key, value); replaced = TRUE; } } if (replaced) { GString *str; str = g_string_new (NULL); for (n = 0; lines[n] != NULL; n++) { g_string_append (str, lines[n]); if (lines[n + 1] != NULL) g_string_append_c (str, '\n'); } data = g_string_free (str, FALSE); len = strlen (data); if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { GError *error2; error2 = g_error_new (CSD_DATETIME_MECHANISM_ERROR, CSD_DATETIME_MECHANISM_ERROR_GENERAL, "Error updating /etc/sysconfig/clock: %s", error->message); g_error_free (error); g_dbus_method_invocation_return_gerror (invocation, error2); g_error_free (error2); g_free (data); return FALSE; } g_free (data); } g_strfreev (lines); return TRUE; } cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-main.c0000664000175000017500000000611314733247605026235 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "csd-datetime-mechanism.h" #define BUS_NAME "org.cinnamon.SettingsDaemon.DateTimeMechanism" GMainLoop *loop; GDBusConnection *connection; static CsdDatetimeMechanism *mechanism; static int ret; static void on_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { } static void on_name_lost (GDBusConnection *connection, const gchar *name, gpointer user_data) { if (mechanism == NULL) { g_critical ("Couldn't acquire bus name"); g_main_loop_quit (loop); return; } g_message ("Name lost or replaced - quitting"); g_main_loop_quit (loop); } int main (int argc, char **argv) { GError *error; guint owner_id; ret = 1; error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_critical ("Couldn't connect to system bus: %s", error->message); g_error_free (error); goto out; } mechanism = csd_datetime_mechanism_new (); if (mechanism == NULL) { goto out; } owner_id = g_bus_own_name_on_connection (connection, BUS_NAME, G_BUS_NAME_OWNER_FLAGS_REPLACE | G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, on_name_acquired, on_name_lost, NULL, NULL); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_object_unref (mechanism); g_bus_unown_name (owner_id); g_object_unref (connection); g_main_loop_unref (loop); ret = 0; out: return ret; } cinnamon-settings-daemon-6.4.3/plugins/datetime/org.cinnamon.SettingsDaemon.DateTimeMechanism.conf0000664000175000017500000000117114733247605032343 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism.xml0000664000175000017500000001236514733247605025677 0ustar fabiofabio Whether the caller can set the timezone The return value is not a boolean, but an integer with the following meaning: 0 the caller cannot set the timezone 1 the caller will be challenged before being able to set the timezone 2 the caller is authorized to set the timezone Whether the caller can set the time The return value is not a boolean, but an integer with the following meaning: 0 the caller cannot set the time 1 the caller will be challenged before being able to set the time 2 the caller is authorized to set the time Whether the caller can set the "use NTP" setting The return value is not a boolean, but an integer with the following meaning: 0 the caller cannot change the "use NTP" setting 1 the caller will be challenged before being able to change "use NTP" setting 2 the caller is authorized to change the "use NTP" setting cinnamon-settings-daemon-6.4.3/plugins/datetime/test-system-timezone.c0000664000175000017500000000445314733247605025144 0ustar fabiofabio/* Test for system timezone handling * * Copyright (C) 2008-2010 Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #include #include "system-timezone.h" static void timezone_print (void) { SystemTimezone *systz; systz = system_timezone_new (); g_print ("Current timezone: %s\n", system_timezone_get (systz)); g_object_unref (systz); } static int timezone_set (const char *new_tz) { GError *error; error = NULL; if (!system_timezone_set (new_tz, &error)) { g_printerr ("%s\n", error->message); g_error_free (error); return 1; } return 0; } int main (int argc, char **argv) { int retval; gboolean get = FALSE; char *tz_set = NULL; GError *error; GOptionContext *context; GOptionEntry options[] = { { "get", 'g', 0, G_OPTION_ARG_NONE, &get, "Get the current timezone", NULL }, { "set", 's', 0, G_OPTION_ARG_STRING, &tz_set, "Set the timezone to TIMEZONE", "TIMEZONE" }, { NULL, 0, 0, 0, NULL, NULL, NULL } }; retval = 0; context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); error = NULL; if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s\n", error->message); g_error_free (error); g_option_context_free (context); return 1; } g_option_context_free (context); if (get || (!tz_set)) timezone_print (); else if (tz_set) retval = timezone_set (tz_set); else g_assert_not_reached (); return retval; } cinnamon-settings-daemon-6.4.3/plugins/datetime/csd-datetime-mechanism-debian.h0000664000175000017500000000241714733247605026543 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 David Zeuthen * Copyright (C) 2011 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include #include gboolean _get_using_ntp_debian (GDBusMethodInvocation *invocation, gboolean *can_use_ntp, gboolean *is_using_ntp); gboolean _set_using_ntp_debian (GDBusMethodInvocation *invocation, gboolean using_ntp); cinnamon-settings-daemon-6.4.3/plugins/datetime/system-timezone.c0000664000175000017500000007141714733247605024173 0ustar fabiofabio/* System timezone handling * * Copyright (C) 2008 Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * Some code is based on previous code in clock-location.c and on code from * tz.c (shipped with version <= 2.22.0). Those files were under the same * license, with those authors and copyrights: * * clock-location.c: * ================ * No header, but most of the work was done (AFAIK) by * Federico Mena Quintero * Matthias Clasen * * tz.c: * ==== * Copyright (C) 2000-2001 Ximian, Inc. * Copyright (C) 2004 Sun Microsystems, Inc. * * Authors: Hans Petter Jansson * additional functions by Erwann Chenede * reworked by Vincent Untz * * Largely based on Michael Fulbright's work on Anaconda. */ /* FIXME: it'd be nice to filter out the timezones that we might get when * parsing config files that are not in zone.tab. Note that it's also wrong * in some cases: eg, in tzdata2008b, Asia/Calcutta got renamed to * Asia/Kolkata and the old name is not in zone.tab. */ #include #include #include #include #include #include "system-timezone.h" /* Files that we look at */ #define ETC_TIMEZONE "/etc/timezone" #define ETC_TIMEZONE_MAJ "/etc/TIMEZONE" #define ETC_RC_CONF "/etc/rc.conf" #define ETC_SYSCONFIG_CLOCK "/etc/sysconfig/clock" #define ETC_CONF_D_CLOCK "/etc/conf.d/clock" #define ETC_LOCALTIME "/etc/localtime" /* The first 4 characters in a timezone file, from tzfile.h */ #define TZ_MAGIC "TZif" static GObject *systz_singleton = NULL; G_DEFINE_TYPE (SystemTimezone, system_timezone, G_TYPE_OBJECT) typedef struct { char *tz; char *env_tz; } SystemTimezonePrivate; static GObject *system_timezone_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties); static void system_timezone_finalize (GObject *obj); #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezonePrivate)) SystemTimezone * system_timezone_new (void) { return g_object_new (SYSTEM_TIMEZONE_TYPE, NULL); } const char * system_timezone_get (SystemTimezone *systz) { SystemTimezonePrivate *priv; g_return_val_if_fail (IS_SYSTEM_TIMEZONE (systz), NULL); priv = PRIVATE (systz); return priv->tz; } const char * system_timezone_get_env (SystemTimezone *systz) { SystemTimezonePrivate *priv; g_return_val_if_fail (IS_SYSTEM_TIMEZONE (systz), NULL); priv = PRIVATE (systz); return priv->env_tz; } static void system_timezone_class_init (SystemTimezoneClass *class) { GObjectClass *g_obj_class = G_OBJECT_CLASS (class); g_obj_class->constructor = system_timezone_constructor; g_obj_class->finalize = system_timezone_finalize; g_type_class_add_private (class, sizeof (SystemTimezonePrivate)); } static void system_timezone_init (SystemTimezone *systz) { SystemTimezonePrivate *priv = PRIVATE (systz); priv->tz = NULL; priv->env_tz = NULL; } static GObject * system_timezone_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { GObject *obj; SystemTimezonePrivate *priv; /* This is a singleton, we don't need to have it per-applet */ if (systz_singleton) return g_object_ref (systz_singleton); obj = G_OBJECT_CLASS (system_timezone_parent_class)->constructor ( type, n_construct_properties, construct_properties); priv = PRIVATE (obj); priv->tz = system_timezone_find (); priv->env_tz = g_strdup (g_getenv ("TZ")); systz_singleton = obj; return systz_singleton; } static void system_timezone_finalize (GObject *obj) { SystemTimezonePrivate *priv = PRIVATE (obj); if (priv->tz) { g_free (priv->tz); priv->tz = NULL; } if (priv->env_tz) { g_free (priv->env_tz); priv->env_tz = NULL; } G_OBJECT_CLASS (system_timezone_parent_class)->finalize (obj); g_assert (obj == systz_singleton); systz_singleton = NULL; } /* * Code to deal with the system timezone on all distros. * There's no dependency on the SystemTimezone GObject here. * * Here's what we know: * * + /etc/localtime contains the binary data of the timezone. * It can be a symlink to the actual data file, a hard link to the data * file, or just a copy. So we can determine the timezone with this * (reading the symlink, comparing inodes, or comparing content). * * + However, most distributions also have the timezone setting * configured somewhere else. This might be better to read it from there. * * Debian/Ubuntu/Gentoo (new): content of /etc/timezone * Fedora/Mandriva: the ZONE key in /etc/sysconfig/clock * openSUSE: the TIMEZONE key in /etc/sysconfig/clock * Solaris/OpenSolaris: the TZ key in /etc/TIMEZONE * Arch Linux: the TIMEZONE key in /etc/rc.conf * Gentoo (old): the ZONE key in /etc/conf.d/clock * * FIXME: reading the system-tools-backends, it seems there's this too: * Solaris: the TZ key in /etc/default/init * /etc/TIMEZONE seems to be a link to /etc/default/init * * First, some functions to handle those system config files. * */ /* This works for Debian and derivatives (including Ubuntu), and new Gentoo */ static char * system_timezone_read_etc_timezone (void) { FILE *etc_timezone; GString *reading; int c; etc_timezone = g_fopen (ETC_TIMEZONE, "r"); if (!etc_timezone) return NULL; reading = g_string_new (""); c = fgetc (etc_timezone); /* only get the first line, we'll validate the value later */ while (c != EOF && !g_ascii_isspace (c)) { reading = g_string_append_c (reading, c); c = fgetc (etc_timezone); } fclose (etc_timezone); if (reading->str && reading->str[0] != '\0') return g_string_free (reading, FALSE); else g_string_free (reading, TRUE); return NULL; } static gboolean system_timezone_write_etc_timezone (const char *tz, GError **error) { char *content; GError *our_error; gboolean retval; if (!g_file_test (ETC_TIMEZONE, G_FILE_TEST_IS_REGULAR)) return TRUE; content = g_strdup_printf ("%s\n", tz); our_error = NULL; retval = g_file_set_contents (ETC_TIMEZONE, content, -1, &our_error); g_free (content); if (!retval) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_GENERAL, ETC_TIMEZONE" cannot be overwritten: %s", our_error->message); g_error_free (our_error); } return retval; } /* Read a file that looks like a key-file (but there's no need for groups) * and get the last value for a specific key */ static char * system_timezone_read_key_file (const char *filename, const char *key) { GIOChannel *channel; char *key_eq; char *line; char *retval; if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) return NULL; channel = g_io_channel_new_file (filename, "r", NULL); if (!channel) return NULL; key_eq = g_strdup_printf ("%s=", key); retval = NULL; while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { if (g_str_has_prefix (line, key_eq)) { char *value; int len; value = line + strlen (key_eq); g_strstrip (value); len = strlen (value); if (value[0] == '\"') { if (value[len - 1] == '\"') { if (retval) g_free (retval); retval = g_strndup (value + 1, len - 2); } } else { if (retval) g_free (retval); retval = g_strdup (line + strlen (key_eq)); } g_strstrip (retval); } g_free (line); } g_free (key_eq); g_io_channel_unref (channel); return retval; } static gboolean system_timezone_write_key_file (const char *filename, const char *key, const char *value, GError **error) { GError *our_error; char *content; gsize len; char *key_eq; char **lines; gboolean replaced; gboolean retval; int n; if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) return TRUE; our_error = NULL; if (!g_file_get_contents (filename, &content, &len, &our_error)) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_GENERAL, "%s cannot be read: %s", filename, our_error->message); g_error_free (our_error); return FALSE; } lines = g_strsplit (content, "\n", 0); g_free (content); key_eq = g_strdup_printf ("%s=", key); replaced = FALSE; for (n = 0; lines[n] != NULL; n++) { if (g_str_has_prefix (lines[n], key_eq)) { char *old_value; gboolean use_quotes; old_value = lines[n] + strlen (key_eq); g_strstrip (old_value); use_quotes = old_value[0] == '\"'; g_free (lines[n]); if (use_quotes) lines[n] = g_strdup_printf ("%s\"%s\"", key_eq, value); else lines[n] = g_strdup_printf ("%s%s", key_eq, value); replaced = TRUE; } } g_free (key_eq); if (!replaced) { g_strfreev (lines); return TRUE; } content = g_strjoinv ("\n", lines); g_strfreev (lines); retval = g_file_set_contents (filename, content, -1, &our_error); g_free (content); if (!retval) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_GENERAL, "%s cannot be overwritten: %s", filename, our_error->message); g_error_free (our_error); } return retval; } /* This works for Solaris/OpenSolaris */ static char * system_timezone_read_etc_TIMEZONE (void) { return system_timezone_read_key_file (ETC_TIMEZONE_MAJ, "TZ"); } static gboolean system_timezone_write_etc_TIMEZONE (const char *tz, GError **error) { return system_timezone_write_key_file (ETC_TIMEZONE_MAJ, "TZ", tz, error); } /* This works for Fedora and Mandriva */ static char * system_timezone_read_etc_sysconfig_clock (void) { return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK, "ZONE"); } static gboolean system_timezone_write_etc_sysconfig_clock (const char *tz, GError **error) { return system_timezone_write_key_file (ETC_SYSCONFIG_CLOCK, "ZONE", tz, error); } /* This works for openSUSE */ static char * system_timezone_read_etc_sysconfig_clock_alt (void) { return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK, "TIMEZONE"); } static gboolean system_timezone_write_etc_sysconfig_clock_alt (const char *tz, GError **error) { return system_timezone_write_key_file (ETC_SYSCONFIG_CLOCK, "TIMEZONE", tz, error); } /* This works for old Gentoo */ static char * system_timezone_read_etc_conf_d_clock (void) { return system_timezone_read_key_file (ETC_CONF_D_CLOCK, "TIMEZONE"); } static gboolean system_timezone_write_etc_conf_d_clock (const char *tz, GError **error) { return system_timezone_write_key_file (ETC_CONF_D_CLOCK, "TIMEZONE", tz, error); } /* This works for Arch Linux */ static char * system_timezone_read_etc_rc_conf (void) { return system_timezone_read_key_file (ETC_RC_CONF, "TIMEZONE"); } static gboolean system_timezone_write_etc_rc_conf (const char *tz, GError **error) { return system_timezone_write_key_file (ETC_RC_CONF, "TIMEZONE", tz, error); } /* * * First, getting the timezone. * */ static char * system_timezone_strip_path_if_valid (const char *filename) { int skip; if (!filename || !g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/")) return NULL; /* Timezone data files also live under posix/ and right/ for some * reason. * FIXME: make sure accepting those files is valid. I think "posix" is * okay, not sure about "right" */ if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/posix/")) skip = strlen (SYSTEM_ZONEINFODIR"/posix/"); else if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/right/")) skip = strlen (SYSTEM_ZONEINFODIR"/right/"); else skip = strlen (SYSTEM_ZONEINFODIR"/"); return g_strdup (filename + skip); } /* Read the soft symlink from /etc/localtime */ static char * system_timezone_read_etc_localtime_softlink (void) { char *file; char *tz; if (!g_file_test (ETC_LOCALTIME, G_FILE_TEST_IS_SYMLINK)) return NULL; file = g_file_read_link (ETC_LOCALTIME, NULL); tz = system_timezone_strip_path_if_valid (file); g_free (file); return tz; } typedef gboolean (*CompareFiles) (struct stat *a_stat, struct stat *b_stat, const char *a_content, gsize a_content_len, const char *b_filename); static char * recursive_compare (struct stat *localtime_stat, const char *localtime_content, gsize localtime_content_len, char *file, CompareFiles compare_func) { struct stat file_stat; if (g_stat (file, &file_stat) != 0) return NULL; if (S_ISREG (file_stat.st_mode)) { if (compare_func (localtime_stat, &file_stat, localtime_content, localtime_content_len, file)) return system_timezone_strip_path_if_valid (file); else return NULL; } else if (S_ISDIR (file_stat.st_mode)) { GDir *dir = NULL; char *ret = NULL; const char *subfile = NULL; char *subpath = NULL; dir = g_dir_open (file, 0, NULL); if (dir == NULL) return NULL; while ((subfile = g_dir_read_name (dir)) != NULL) { subpath = g_build_filename (file, subfile, NULL); ret = recursive_compare (localtime_stat, localtime_content, localtime_content_len, subpath, compare_func); g_free (subpath); if (ret != NULL) break; } g_dir_close (dir); return ret; } return NULL; } static gboolean files_are_identical_inode (struct stat *a_stat, struct stat *b_stat, const char *a_content, gsize a_content_len, const char *b_filename) { return (a_stat->st_ino == b_stat->st_ino); } /* Determine if /etc/localtime is a hard link to some file, by looking at * the inodes */ static char * system_timezone_read_etc_localtime_hardlink (void) { struct stat stat_localtime; if (g_stat (ETC_LOCALTIME, &stat_localtime) != 0) return NULL; if (!S_ISREG (stat_localtime.st_mode)) return NULL; return recursive_compare (&stat_localtime, NULL, 0, SYSTEM_ZONEINFODIR, files_are_identical_inode); } static gboolean files_are_identical_content (struct stat *a_stat, struct stat *b_stat, const char *a_content, gsize a_content_len, const char *b_filename) { char *b_content = NULL; gsize b_content_len = -1; int cmp; if (a_stat->st_size != b_stat->st_size) return FALSE; if (!g_file_get_contents (b_filename, &b_content, &b_content_len, NULL)) return FALSE; if (a_content_len != b_content_len) { g_free (b_content); return FALSE; } cmp = memcmp (a_content, b_content, a_content_len); g_free (b_content); return (cmp == 0); } /* Determine if /etc/localtime is a copy of a timezone file */ static char * system_timezone_read_etc_localtime_content (void) { struct stat stat_localtime; char *localtime_content = NULL; gsize localtime_content_len = -1; char *retval; if (g_stat (ETC_LOCALTIME, &stat_localtime) != 0) return NULL; if (!S_ISREG (stat_localtime.st_mode)) return NULL; if (!g_file_get_contents (ETC_LOCALTIME, &localtime_content, &localtime_content_len, NULL)) return NULL; retval = recursive_compare (&stat_localtime, localtime_content, localtime_content_len, SYSTEM_ZONEINFODIR, files_are_identical_content); g_free (localtime_content); return retval; } typedef char * (*GetSystemTimezone) (void); /* The order of the functions here define the priority of the methods used * to find the timezone. First method has higher priority. */ static GetSystemTimezone get_system_timezone_methods[] = { /* cheap and "more correct" than data from a config file */ system_timezone_read_etc_localtime_softlink, /* reading various config files */ system_timezone_read_etc_timezone, system_timezone_read_etc_sysconfig_clock, system_timezone_read_etc_sysconfig_clock_alt, system_timezone_read_etc_TIMEZONE, system_timezone_read_etc_rc_conf, /* reading deprecated config files */ system_timezone_read_etc_conf_d_clock, /* reading /etc/timezone directly. Expensive since we have to stat * many files */ system_timezone_read_etc_localtime_hardlink, system_timezone_read_etc_localtime_content, NULL }; static gboolean system_timezone_is_valid (const char *tz) { const char *c; if (!tz) return FALSE; for (c = tz; *c != '\0'; c++) { if (!(g_ascii_isalnum (*c) || *c == '/' || *c == '-' || *c == '_')) return FALSE; } return TRUE; } char * system_timezone_find (void) { char *tz; int i; for (i = 0; get_system_timezone_methods[i] != NULL; i++) { tz = get_system_timezone_methods[i] (); if (system_timezone_is_valid (tz)) return tz; g_free (tz); } return g_strdup ("UTC"); } /* * * Now, setting the timezone. * */ static gboolean system_timezone_is_zone_file_valid (const char *zone_file, GError **error) { GError *our_error; GIOChannel *channel; char buffer[strlen (TZ_MAGIC)]; gsize read; /* First, check the zone_file is properly rooted */ if (!g_str_has_prefix (zone_file, SYSTEM_ZONEINFODIR"/")) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, "Timezone file needs to be under "SYSTEM_ZONEINFODIR); return FALSE; } /* Second, check it's a regular file that exists */ if (!g_file_test (zone_file, G_FILE_TEST_IS_REGULAR)) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, "No such timezone file %s", zone_file); return FALSE; } /* Third, check that it's a tzfile (see tzfile(5)). The file has a 4 * bytes header which is TZ_MAGIC. * * TODO: is there glibc API for this? */ our_error = NULL; channel = g_io_channel_new_file (zone_file, "r", &our_error); if (!our_error) g_io_channel_read_chars (channel, buffer, strlen (TZ_MAGIC), &read, &our_error); if (channel) g_io_channel_unref (channel); if (our_error) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, "Timezone file %s cannot be read: %s", zone_file, our_error->message); g_error_free (our_error); return FALSE; } if (read != strlen (TZ_MAGIC) || strncmp (buffer, TZ_MAGIC, strlen (TZ_MAGIC)) != 0) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, "%s is not a timezone file", zone_file); return FALSE; } return TRUE; } static gboolean system_timezone_set_etc_timezone (const char *zone_file, GError **error) { GError *our_error; char *content; gsize len; if (!system_timezone_is_zone_file_valid (zone_file, error)) return FALSE; /* If /etc/localtime is a symlink, write a symlink */ if (g_file_test (ETC_LOCALTIME, G_FILE_TEST_IS_SYMLINK)) { if (g_unlink (ETC_LOCALTIME) == 0 && symlink (zone_file, ETC_LOCALTIME) == 0) return TRUE; /* If we couldn't symlink the file, we'll just fallback on * copying it */ } /* Else copy the file to /etc/localtime. We explicitly avoid doing * hard links since they break with different partitions */ our_error = NULL; if (!g_file_get_contents (zone_file, &content, &len, &our_error)) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_GENERAL, "Timezone file %s cannot be read: %s", zone_file, our_error->message); g_error_free (our_error); return FALSE; } if (!g_file_set_contents (ETC_LOCALTIME, content, len, &our_error)) { g_set_error (error, SYSTEM_TIMEZONE_ERROR, SYSTEM_TIMEZONE_ERROR_GENERAL, ETC_LOCALTIME" cannot be overwritten: %s", our_error->message); g_error_free (our_error); g_free (content); return FALSE; } g_free (content); return TRUE; } typedef gboolean (*SetSystemTimezone) (const char *tz, GError **error); /* The order here does not matter too much: we'll try to change all files * that already have a timezone configured. It matters in case of error, * since the process will be stopped and the last methods won't be called. * So we use the same order as in get_system_timezone_methods */ static SetSystemTimezone set_system_timezone_methods[] = { /* writing various config files if they exist and have the * setting already present */ system_timezone_write_etc_timezone, system_timezone_write_etc_sysconfig_clock, system_timezone_write_etc_sysconfig_clock_alt, system_timezone_write_etc_TIMEZONE, system_timezone_write_etc_rc_conf, /* writing deprecated config files if they exist and have the * setting already present */ system_timezone_write_etc_conf_d_clock, NULL }; static gboolean system_timezone_update_config (const char *tz, GError **error) { int i; for (i = 0; set_system_timezone_methods[i] != NULL; i++) { if (!set_system_timezone_methods[i] (tz, error)) return FALSE; /* FIXME: maybe continue to change all config files if * possible? */ } return TRUE; } gboolean system_timezone_set (const char *tz, GError **error) { char *zone_file; gboolean retval; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); zone_file = g_build_filename (SYSTEM_ZONEINFODIR, tz, NULL); /* FIXME: is it right to return FALSE even when /etc/localtime was * changed but not the config files? */ retval = system_timezone_set_etc_timezone (zone_file, error) && system_timezone_update_config (tz, error); g_free (zone_file); return retval; } GQuark system_timezone_error_quark (void) { static GQuark ret = 0; if (ret == 0) { ret = g_quark_from_static_string ("system-timezone-error"); } return ret; } cinnamon-settings-daemon-6.4.3/plugins/datetime/org.cinnamon.settingsdaemon.datetimemechanism.policy0000664000175000017500000000137614733247605033164 0ustar fabiofabio Cinnamon https://projects.linuxmint.com/cinnamon/ gnome-panel-clock Change system time and date settings To change time or date settings, you need to authenticate. no no auth_admin_keep cinnamon-settings-daemon-6.4.3/plugins/datetime/system-timezone.h0000664000175000017500000000504514733247605024172 0ustar fabiofabio/* System timezone handling * * Copyright (C) 2008 Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #ifndef __SYSTEM_TIMEZONE_H__ #define __SYSTEM_TIMEZONE_H__ #include #include G_BEGIN_DECLS #ifdef HAVE_SOLARIS #define SYSTEM_ZONEINFODIR "/usr/share/lib/zoneinfo/tab" #else #define SYSTEM_ZONEINFODIR "/usr/share/zoneinfo" #endif #define SYSTEM_TIMEZONE_TYPE (system_timezone_get_type ()) #define SYSTEM_TIMEZONE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezone)) #define SYSTEM_TIMEZONE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), SYSTEM_TIMEZONE_TYPE, SystemTimezoneClass)) #define IS_SYSTEM_TIMEZONE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SYSTEM_TIMEZONE_TYPE)) #define IS_SYSTEM_TIMEZONE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), SYSTEM_TIMEZONE_TYPE)) #define SYSTEM_TIMEZONE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezoneClass)) typedef struct { GObject g_object; } SystemTimezone; typedef struct { GObjectClass g_object_class; } SystemTimezoneClass; GType system_timezone_get_type (void); SystemTimezone *system_timezone_new (void); const char *system_timezone_get (SystemTimezone *systz); const char *system_timezone_get_env (SystemTimezone *systz); /* Functions to set the timezone. They won't be used by the applet, but * by a program with more privileges */ #define SYSTEM_TIMEZONE_ERROR system_timezone_error_quark () GQuark system_timezone_error_quark (void); typedef enum { SYSTEM_TIMEZONE_ERROR_GENERAL, SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, SYSTEM_TIMEZONE_NUM_ERRORS } SystemTimezoneError; char *system_timezone_find (void); gboolean system_timezone_set (const char *tz, GError **error); G_END_DECLS #endif /* __SYSTEM_TIMEZONE_H__ */ cinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/0000775000175000017500000000000014733247605022544 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/meson.build0000664000175000017500000000170014733247605024704 0ustar fabiofabioplugin_name = 'screensaver-proxy' screensaver_proxy_sources = [ 'csd-screensaver-proxy-manager.c', 'main.c', ] screensaver_proxy_deps = [ common_dep, csd_dep, libnotify, ] executable( 'csd-screensaver-proxy', screensaver_proxy_sources, include_directories: [include_dirs, common_inc], dependencies: screensaver_proxy_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-screensaver-proxy') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-screensaver-proxy') endif configure_file( input: 'cinnamon-settings-daemon-screensaver-proxy.desktop.in', output: 'cinnamon-settings-daemon-screensaver-proxy.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/csd-screensaver-proxy-manager.h0000664000175000017500000000517214733247605030600 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_SCREENSAVER_PROXY_MANAGER_H #define __CSD_SCREENSAVER_PROXY_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_SCREENSAVER_PROXY_MANAGER (csd_screensaver_proxy_manager_get_type ()) #define CSD_SCREENSAVER_PROXY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_SCREENSAVER_PROXY_MANAGER, CsdScreensaverProxyManager)) #define CSD_SCREENSAVER_PROXY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_SCREENSAVER_PROXY_MANAGER, CsdScreensaverProxyManagerClass)) #define CSD_IS_SCREENSAVER_PROXY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_SCREENSAVER_PROXY_MANAGER)) #define CSD_IS_SCREENSAVER_PROXY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_SCREENSAVER_PROXY_MANAGER)) #define CSD_SCREENSAVER_PROXY_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_SCREENSAVER_PROXY_MANAGER, CsdScreensaverProxyManagerClass)) typedef struct CsdScreensaverProxyManagerPrivate CsdScreensaverProxyManagerPrivate; typedef struct { GObject parent; CsdScreensaverProxyManagerPrivate *priv; } CsdScreensaverProxyManager; typedef struct { GObjectClass parent_class; } CsdScreensaverProxyManagerClass; GType csd_screensaver_proxy_manager_get_type (void); CsdScreensaverProxyManager *csd_screensaver_proxy_manager_new (void); gboolean csd_screensaver_proxy_manager_start (CsdScreensaverProxyManager *manager, GError **error); void csd_screensaver_proxy_manager_stop (CsdScreensaverProxyManager *manager); G_END_DECLS #endif /* __CSD_SCREENSAVER_PROXY_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/main.c0000664000175000017500000000110014733247605023624 0ustar fabiofabio#define NEW csd_screensaver_proxy_manager_new #define START csd_screensaver_proxy_manager_start #define STOP csd_screensaver_proxy_manager_stop #define MANAGER CsdScreensaverProxyManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-screensaver-proxy-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/csd-screensaver-proxy-manager.c0000664000175000017500000004704214733247605030575 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-session.h" #include "cinnamon-settings-profile.h" #include "csd-screensaver-proxy-manager.h" #define CSD_SCREENSAVER_PROXY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_SCREENSAVER_PROXY_MANAGER, CsdScreensaverProxyManagerPrivate)) /* As available in: * https://projects.kde.org/projects/kde/kde-workspace/repository/revisions/master/entry/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml * and documented in: * https://projects.kde.org/projects/kde/kde-workspace/repository/revisions/master/entry/ksmserver/screenlocker/interface.h */ static const gchar introspection_xml[] = "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""; static const gchar introspection_xml2[] = "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""; #define CSD_SCREENSAVER_PROXY_DBUS_SERVICE "org.freedesktop.ScreenSaver" #define CSD_SCREENSAVER_PROXY_DBUS_PATH "/org/freedesktop/ScreenSaver" #define CSD_SCREENSAVER_PROXY_DBUS_PATH2 "/ScreenSaver" #define CSD_SCREENSAVER_PROXY_DBUS_INTERFACE "org.freedesktop.ScreenSaver" #define GSM_INHIBITOR_FLAG_IDLE 1 << 3 struct CsdScreensaverProxyManagerPrivate { GDBusProxy *session; GDBusConnection *connection; GCancellable *bus_cancellable; GDBusNodeInfo *introspection_data; GDBusNodeInfo *introspection_data2; guint name_id; GHashTable *watch_ht; /* key = sender, value = name watch id */ GHashTable *cookie_ht; /* key = cookie, value = sender */ }; static void csd_screensaver_proxy_manager_finalize (GObject *object); G_DEFINE_TYPE (CsdScreensaverProxyManager, csd_screensaver_proxy_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_OBJECT "/org/gnome/SessionManager" #define GNOME_SESSION_DBUS_INTERFACE "org.gnome.SessionManager" static GDBusProxy * cinnamon_settings_session_get_session_proxy (void) { static GDBusProxy *session_proxy; GError *error = NULL; if (session_proxy != NULL) { g_object_ref (session_proxy); } else { session_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_OBJECT, GNOME_SESSION_DBUS_INTERFACE, NULL, &error); if (error) { g_warning ("Failed to connect to the session manager: %s", error->message); g_error_free (error); } else { g_object_add_weak_pointer (G_OBJECT (session_proxy), (gpointer*)&session_proxy); } } return session_proxy; } static void name_vanished_cb (GDBusConnection *connection, const gchar *name, CsdScreensaverProxyManager *manager) { GHashTableIter iter; gpointer cookie_ptr; const char *sender; /* Look for all the cookies under that name, * and call uninhibit for them */ g_hash_table_iter_init (&iter, manager->priv->cookie_ht); while (g_hash_table_iter_next (&iter, &cookie_ptr, (gpointer *) &sender)) { if (g_strcmp0 (sender, name) == 0) { guint cookie = GPOINTER_TO_UINT (cookie_ptr); g_dbus_proxy_call_sync (manager->priv->session, "Uninhibit", g_variant_new ("(u)", cookie), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); g_debug ("Removing cookie %u for sender %s", cookie, sender); g_hash_table_iter_remove (&iter); } } g_hash_table_remove (manager->priv->watch_ht, sender); } static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { CsdScreensaverProxyManager *manager = CSD_SCREENSAVER_PROXY_MANAGER (user_data); /* Check session pointer as a proxy for whether the manager is in the start or stop state */ if (manager->priv->session == NULL) { return; } g_debug ("Calling method '%s.%s' for ScreenSaver Proxy", interface_name, method_name); if (g_strcmp0 (method_name, "Inhibit") == 0) { GVariant *ret; const char *app_id; const char *reason; guint cookie; g_variant_get (parameters, "(ss)", &app_id, &reason); ret = g_dbus_proxy_call_sync (manager->priv->session, "Inhibit", g_variant_new ("(susu)", app_id, 0, reason, GSM_INHIBITOR_FLAG_IDLE), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); g_variant_get (ret, "(u)", &cookie); g_hash_table_insert (manager->priv->cookie_ht, GUINT_TO_POINTER (cookie), g_strdup (sender)); if (g_hash_table_lookup (manager->priv->watch_ht, sender) == NULL) { guint watch_id; watch_id = g_bus_watch_name_on_connection (manager->priv->connection, sender, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, (GBusNameVanishedCallback) name_vanished_cb, manager, NULL); g_hash_table_insert (manager->priv->watch_ht, g_strdup (sender), GUINT_TO_POINTER (watch_id)); } g_dbus_method_invocation_return_value (invocation, ret); } else if (g_strcmp0 (method_name, "UnInhibit") == 0) { guint cookie; g_variant_get (parameters, "(u)", &cookie); g_dbus_proxy_call_sync (manager->priv->session, "Uninhibit", parameters, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "Throttle") == 0) { g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "UnThrottle") == 0) { g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "Lock") == 0) { goto unimplemented; } else if (g_strcmp0 (method_name, "SimulateUserActivity") == 0) { goto unimplemented; } else if (g_strcmp0 (method_name, "GetActive") == 0) { goto unimplemented; } else if (g_strcmp0 (method_name, "GetActiveTime") == 0) { goto unimplemented; } else if (g_strcmp0 (method_name, "GetSessionIdleTime") == 0) { goto unimplemented; } else if (g_strcmp0 (method_name, "SetActive") == 0) { goto unimplemented; } return; unimplemented: g_dbus_method_invocation_return_dbus_error (invocation, "org.freedesktop.DBus.Error.NotSupported", "This method is not implemented"); } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, /* GetProperty */ NULL, /* SetProperty */ }; static void on_bus_gotten (GObject *source_object, GAsyncResult *res, CsdScreensaverProxyManager *manager) { GDBusConnection *connection; GDBusInterfaceInfo **infos; GError *error = NULL; if (manager->priv->bus_cancellable == NULL || g_cancellable_is_cancelled (manager->priv->bus_cancellable)) { g_warning ("Operation has been cancelled, so not retrieving session bus"); return; } connection = g_bus_get_finish (res, &error); if (connection == NULL) { g_warning ("Could not get session bus: %s", error->message); g_error_free (error); return; } manager->priv->connection = connection; infos = manager->priv->introspection_data->interfaces; g_dbus_connection_register_object (connection, CSD_SCREENSAVER_PROXY_DBUS_PATH, infos[0], &interface_vtable, manager, NULL, NULL); infos = manager->priv->introspection_data2->interfaces; g_dbus_connection_register_object (connection, CSD_SCREENSAVER_PROXY_DBUS_PATH2, infos[0], &interface_vtable, manager, NULL, NULL); manager->priv->name_id = g_bus_own_name_on_connection (manager->priv->connection, CSD_SCREENSAVER_PROXY_DBUS_SERVICE, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); } static void register_manager_dbus (CsdScreensaverProxyManager *manager) { manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); manager->priv->introspection_data2 = g_dbus_node_info_new_for_xml (introspection_xml2, NULL); manager->priv->bus_cancellable = g_cancellable_new (); g_assert (manager->priv->introspection_data != NULL); g_assert (manager->priv->introspection_data2 != NULL); g_bus_get (G_BUS_TYPE_SESSION, manager->priv->bus_cancellable, (GAsyncReadyCallback) on_bus_gotten, manager); } gboolean csd_screensaver_proxy_manager_start (CsdScreensaverProxyManager *manager, GError **error) { g_debug ("Starting screensaver-proxy manager"); cinnamon_settings_profile_start (NULL); manager->priv->session = cinnamon_settings_session_get_session_proxy (); manager->priv->watch_ht = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_bus_unwatch_name); manager->priv->cookie_ht = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_free); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_screensaver_proxy_manager_stop (CsdScreensaverProxyManager *manager) { g_debug ("Stopping screensaver_proxy manager"); if (manager->priv->session != NULL) { g_object_unref (manager->priv->session); manager->priv->session = NULL; } if (manager->priv->watch_ht != NULL) { g_hash_table_destroy (manager->priv->watch_ht); manager->priv->watch_ht = NULL; } if (manager->priv->cookie_ht != NULL) { g_hash_table_destroy (manager->priv->cookie_ht); manager->priv->cookie_ht = NULL; } } static void csd_screensaver_proxy_manager_class_init (CsdScreensaverProxyManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_screensaver_proxy_manager_finalize; g_type_class_add_private (klass, sizeof (CsdScreensaverProxyManagerPrivate)); } static void csd_screensaver_proxy_manager_init (CsdScreensaverProxyManager *manager) { manager->priv = CSD_SCREENSAVER_PROXY_MANAGER_GET_PRIVATE (manager); } static void csd_screensaver_proxy_manager_finalize (GObject *object) { CsdScreensaverProxyManager *manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_SCREENSAVER_PROXY_MANAGER (object)); manager = CSD_SCREENSAVER_PROXY_MANAGER (object); g_return_if_fail (manager->priv != NULL); if (manager->priv->name_id != 0) { g_bus_unown_name (manager->priv->name_id); manager->priv->name_id = 0; } if (manager->priv->connection != NULL) { g_object_unref (manager->priv->connection); manager->priv->connection = NULL; } if (manager->priv->bus_cancellable != NULL) { g_object_unref (manager->priv->bus_cancellable); manager->priv->bus_cancellable = NULL; } if (manager->priv->introspection_data != NULL) { g_dbus_node_info_unref (manager->priv->introspection_data); manager->priv->introspection_data = NULL; } if (manager->priv->introspection_data2 != NULL) { g_dbus_node_info_unref (manager->priv->introspection_data2); manager->priv->introspection_data2 = NULL; } G_OBJECT_CLASS (csd_screensaver_proxy_manager_parent_class)->finalize (object); } CsdScreensaverProxyManager * csd_screensaver_proxy_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_SCREENSAVER_PROXY_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); register_manager_dbus (manager_object); } return CSD_SCREENSAVER_PROXY_MANAGER (manager_object); } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootcinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/cinnamon-settings-daemon-screensaver-proxy.desktop.incinnamon-settings-daemon-6.4.3/plugins/screensaver-proxy/cinnamon-settings-daemon-screensaver-proxy.0000664000175000017500000000036214733247605033144 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - screensaver-proxy Exec=csd-screensaver-proxy OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/common/0000775000175000017500000000000014733247605020335 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/common/migrate-settings.c0000664000175000017500000000573614733247605024002 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2015 Red Hat * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author: Carlos Garnacho */ #include "config.h" #include #include "migrate-settings.h" void csd_settings_migrate_check (const gchar *origin_schema, const gchar *origin_path, const gchar *dest_schema, const gchar *dest_path, CsdSettingsMigrateEntry entries[], guint n_entries) { GSettings *origin_settings, *dest_settings; guint i; origin_settings = g_settings_new_with_path (origin_schema, origin_path); dest_settings = g_settings_new_with_path (dest_schema, dest_path); for (i = 0; i < n_entries; i++) { g_autoptr(GVariant) variant = NULL; variant = g_settings_get_user_value (origin_settings, entries[i].origin_key); if (!variant) continue; if (entries[i].dest_key) { if (entries[i].func) { g_autoptr(GVariant) old_default = NULL; g_autoptr(GVariant) new_default = NULL; GVariant *modified; old_default = g_settings_get_default_value (origin_settings, entries[i].origin_key); new_default = g_settings_get_default_value (dest_settings, entries[i].dest_key); modified = entries[i].func (variant, origin_settings, dest_settings, old_default, new_default); g_clear_pointer (&variant, g_variant_unref); if (modified) variant = g_variant_ref_sink (modified); } if (variant) g_settings_set_value (dest_settings, entries[i].dest_key, variant); } g_settings_reset (origin_settings, entries[i].origin_key); } g_object_unref (origin_settings); g_object_unref (dest_settings); } cinnamon-settings-daemon-6.4.3/plugins/common/csd-power-helper.h0000664000175000017500000000217414733247605023672 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef __CSD_POWER_HELPER_H #define __CSD_POWER_HELPER_H #include G_BEGIN_DECLS void csd_power_suspend (gboolean try_hybrid, gboolean suspend_then_hibernate); void csd_power_hibernate (void); void csd_power_poweroff (void); G_END_DECLS #endif /* __CSD_POWER_HELPER_H */ cinnamon-settings-daemon-6.4.3/plugins/common/csd-power-helper.c0000664000175000017500000002745414733247605023675 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include #include "config.h" #include "csd-power-helper.h" #define LOGIND_DBUS_NAME "org.freedesktop.login1" #define LOGIND_DBUS_PATH "/org/freedesktop/login1" #define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager" #define CONSOLEKIT_DBUS_NAME "org.freedesktop.ConsoleKit" #define CONSOLEKIT_DBUS_PATH_MANAGER "/org/freedesktop/ConsoleKit/Manager" #define CONSOLEKIT_DBUS_INTERFACE_MANAGER "org.freedesktop.ConsoleKit.Manager" #ifdef HAVE_LOGIND static gboolean use_logind (void) { static gboolean should_use_logind = FALSE; static gsize once_init_value = 0; if (g_once_init_enter (&once_init_value)) { should_use_logind = access("/run/systemd/seats/", F_OK) == 0; // sd_booted () g_once_init_leave (&once_init_value, 1); } return should_use_logind; } #else /* HAVE_LOGIND */ static gboolean use_logind (void) { return FALSE; } #endif /* HAVE_LOGIND */ static void logind_stop (void) { GDBusConnection *bus; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); g_dbus_connection_call (bus, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, "PowerOff", g_variant_new ("(b)", FALSE), NULL, 0, G_MAXINT, NULL, NULL, NULL); g_object_unref (bus); } static gboolean can_power_action (gchar *method_name) { GDBusConnection *bus; GVariant *res; gchar *rv; gboolean can_action; GError *error = NULL; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); res = g_dbus_connection_call_sync (bus, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, method_name, NULL, G_VARIANT_TYPE_TUPLE, 0, G_MAXINT, NULL, &error); g_object_unref (bus); if (error) { g_warning ("Calling %s failed: %s", method_name, error->message); g_clear_error (&error); return FALSE; } g_variant_get (res, "(s)", &rv); g_variant_unref (res); can_action = g_strcmp0 (rv, "yes") == 0 || g_strcmp0 (rv, "challenge") == 0; if (!can_action) { g_warning ("logind does not support method %s", method_name); } g_free (rv); return can_action; } static void logind_suspend (gboolean suspend_then_hibernate) { gchar *method_name = "Suspend"; if (suspend_then_hibernate && can_power_action("CanHibernate")) { method_name = "SuspendThenHibernate"; } GDBusConnection *bus; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); g_dbus_connection_call (bus, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, method_name, g_variant_new ("(b)", TRUE), NULL, 0, G_MAXINT, NULL, NULL, NULL); g_object_unref (bus); } static void logind_hybrid_suspend (void) { GDBusConnection *bus; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); g_dbus_connection_call (bus, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, "HybridSleep", g_variant_new ("(b)", TRUE), NULL, 0, G_MAXINT, NULL, NULL, NULL); g_object_unref (bus); } static void logind_hibernate (void) { GDBusConnection *bus; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); g_dbus_connection_call (bus, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, "Hibernate", g_variant_new ("(b)", TRUE), NULL, 0, G_MAXINT, NULL, NULL, NULL); g_object_unref (bus); } static void consolekit_stop_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *result; GError *error = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("couldn't stop using ConsoleKit: %s", error->message); g_error_free (error); } else { g_variant_unref (result); } } static void consolekit_stop (void) { GError *error = NULL; GDBusProxy *proxy; /* power down the machine in a safe way */ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_DBUS_NAME, CONSOLEKIT_DBUS_PATH_MANAGER, CONSOLEKIT_DBUS_INTERFACE_MANAGER, NULL, &error); if (proxy == NULL) { g_warning ("cannot connect to ConsoleKit: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, "Stop", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, consolekit_stop_cb, NULL); g_object_unref (proxy); } static void consolekit_sleep_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *result; GError *error = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("couldn't sleep using ConsoleKit: %s", error->message); g_error_free (error); } else { g_variant_unref (result); } } static void consolekit_suspend (gboolean suspend_then_hibernate) { GError *error = NULL; GDBusProxy *proxy; gchar *method_name = "Suspend"; if (suspend_then_hibernate && can_power_action("CanHibernate")) { method_name = "SuspendThenHibernate"; } proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_DBUS_NAME, CONSOLEKIT_DBUS_PATH_MANAGER, CONSOLEKIT_DBUS_INTERFACE_MANAGER, NULL, &error); if (proxy == NULL) { g_warning ("cannot connect to ConsoleKit: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, method_name, g_variant_new("(b)", TRUE), G_DBUS_CALL_FLAGS_NONE, -1, NULL, consolekit_sleep_cb, NULL); g_object_unref (proxy); } static void consolekit_hibernate (void) { GError *error = NULL; GDBusProxy *proxy; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_DBUS_NAME, CONSOLEKIT_DBUS_PATH_MANAGER, CONSOLEKIT_DBUS_INTERFACE_MANAGER, NULL, &error); if (proxy == NULL) { g_warning ("cannot connect to ConsoleKit: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, "Hibernate", g_variant_new("(b)", TRUE), G_DBUS_CALL_FLAGS_NONE, -1, NULL, consolekit_sleep_cb, NULL); g_object_unref (proxy); } static void consolekit_hybrid_suspend (void) { GError *error = NULL; GDBusProxy *proxy; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_DBUS_NAME, CONSOLEKIT_DBUS_PATH_MANAGER, CONSOLEKIT_DBUS_INTERFACE_MANAGER, NULL, &error); if (proxy == NULL) { g_warning ("cannot connect to ConsoleKit: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, "HybridSleep", g_variant_new("(b)", TRUE), G_DBUS_CALL_FLAGS_NONE, -1, NULL, consolekit_sleep_cb, NULL); g_object_unref (proxy); } void csd_power_suspend (gboolean try_hybrid, gboolean suspend_then_hibernate) { if (use_logind ()) { if (try_hybrid && can_power_action ("CanHybridSleep")) { logind_hybrid_suspend (); } else { logind_suspend (suspend_then_hibernate); } } else { if (try_hybrid && can_power_action ("CanHybridSleep")) { consolekit_hybrid_suspend (); } else { consolekit_suspend (suspend_then_hibernate); } } } void csd_power_poweroff (void) { if (use_logind ()) { logind_stop (); } else { consolekit_stop (); } } void csd_power_hibernate (void) { if (use_logind ()) { logind_hibernate (); } else { consolekit_hibernate (); } } cinnamon-settings-daemon-6.4.3/plugins/common/meson.build0000664000175000017500000000200514733247605022474 0ustar fabiofabiocommon_sources = [ 'csd-keygrab.c', 'csd-input-helper.c', 'csd-power-helper.c', 'migrate-settings.c' ] common_deps = [ config_h, gtk, x11, xi, ] common_inc = include_directories('.') common_lib = static_library( 'common_lib', common_sources, include_directories: [include_dirs, common_inc], dependencies: common_deps, ) common_dep = declare_dependency( include_directories: include_dirs, link_with: common_lib, dependencies: common_deps, ) helper_sources = [ 'test-input-helper.c', common_sources, ] executable( 'csd-input-helper', helper_sources, dependencies: common_dep, install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-input-helper') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-input-helper') endif install_data( 'input-device-example.sh', install_dir: join_paths(datadir, '@0@-@1@'.format(pkgname, api_version)), ) cinnamon-settings-daemon-6.4.3/plugins/common/csd-keygrab.h0000664000175000017500000000373414733247605022710 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2008 Jens Granseuer * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef __CSD_COMMON_KEYGRAB_H #define __CSD_COMMON_KEYGRAB_H G_BEGIN_DECLS #include #include #include typedef struct { guint keysym; guint state; guint *keycodes; } Key; typedef enum { CSD_KEYGRAB_NORMAL = 0, CSD_KEYGRAB_ALLOW_UNMODIFIED = 1 << 0, CSD_KEYGRAB_SYNCHRONOUS = 1 << 1 } CsdKeygrabFlags; void grab_key_unsafe (Key *key, CsdKeygrabFlags flags, GSList *screens); void ungrab_key_unsafe (Key *key, GSList *screens); gboolean match_xi2_key (Key *key, XIDeviceEvent *event); gboolean key_uses_keycode (const Key *key, guint keycode); Key * parse_key (const char *str); void free_key (Key *key); void grab_button (int deviceid, gboolean grab, GSList *screens); G_END_DECLS #endif /* __CSD_COMMON_KEYGRAB_H */ cinnamon-settings-daemon-6.4.3/plugins/common/daemon-skeleton.h0000664000175000017500000001746614733247605023611 0ustar fabiofabio/** * Create a test app for your plugin quickly. * * #define NEW csd_media_keys_manager_new * #define START csd_media_keys_manager_start * #define MANAGER CsdMediaKeysManager * #include "csd-media-keys-manager.h" * * #include "daemon-skeleton.h" */ #include "config.h" #include #include #include #include #include #ifndef PLUGIN_NAME #error Include PLUGIN_CFLAGS in the daemon s CFLAGS #endif /* !PLUGIN_NAME */ #ifndef INIT_LIBNOTIFY #define INIT_LIBNOTIFY FALSE #endif #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager" #define GNOME_SESSION_CLIENT_PRIVATE_NAME "org.gnome.SessionManager.ClientPrivate" static MANAGER *manager = NULL; static int timeout = -1; static gboolean verbose = FALSE; static GOptionEntry entries[] = { { "exit-time", 0, 0, G_OPTION_ARG_INT, &timeout, "Exit after n seconds time", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose", NULL }, {NULL} }; static void respond_to_end_session (GDBusProxy *proxy) { /* we must answer with "EndSessionResponse" */ g_dbus_proxy_call (proxy, "EndSessionResponse", g_variant_new ("(bs)", TRUE, ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } static void client_proxy_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { if (g_strcmp0 (signal_name, "QueryEndSession") == 0) { g_debug ("Got QueryEndSession signal"); respond_to_end_session (proxy); } else if (g_strcmp0 (signal_name, "EndSession") == 0) { g_debug ("Got EndSession signal"); respond_to_end_session (proxy); } else if (g_strcmp0 (signal_name, "Stop") == 0) { g_debug ("Got Stop signal"); g_main_loop_quit ((GMainLoop *) user_data); } } static void on_client_registered (GObject *source_object, GAsyncResult *res, GMainLoop *loop) { GVariant *variant; GDBusProxy *client_proxy; GError *error = NULL; gchar *object_path = NULL; variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (!variant) { if (error != NULL) { g_warning ("Unable to register client: %s", error->message); g_error_free (error); } return; } g_variant_get (variant, "(o)", &object_path); g_debug ("Registered client at path %s", object_path); client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, 0, NULL, GNOME_SESSION_DBUS_NAME, object_path, GNOME_SESSION_CLIENT_PRIVATE_NAME, NULL, &error); if (!client_proxy) { if (error != NULL) { g_warning ("Unable to get the session client proxy: %s", error->message); g_error_free (error); } return; } g_signal_connect (client_proxy, "g-signal", G_CALLBACK (client_proxy_signal_cb), loop); g_free (object_path); g_variant_unref (variant); } static void register_with_cinnamon_session (GMainLoop *loop) { const char *startup_id; GError *error = NULL; GDBusProxy *proxy; GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (!bus) { g_debug ("Could not connect to the dbus session bus"); return; } proxy = g_dbus_proxy_new_sync (bus, G_DBUS_PROXY_FLAGS_NONE, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_NAME, NULL, &error); g_object_unref (bus); if (proxy == NULL) { if (error != NULL) { g_debug ("Could not connect to the Session manager: %s", error->message); g_error_free (error); } return; } startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); g_dbus_proxy_call (proxy, "RegisterClient", g_variant_new ("(ss)", PLUGIN_NAME, startup_id ? startup_id : ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback) on_client_registered, loop); } static gboolean handle_signal (gpointer user_data) { GMainLoop *loop = (GMainLoop *) user_data; g_debug ("Got SIGTERM - shutting down"); if (g_main_loop_is_running (loop)) g_main_loop_quit (loop); return G_SOURCE_REMOVE; } static void message_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { /* Make this look like normal console output */ if (log_level & G_LOG_LEVEL_DEBUG) { g_autoptr(GDateTime) dt = g_date_time_new_now_local (); g_autofree gchar *iso8601 = g_date_time_format (dt, "%F:%T"); printf ("csd-%s:%s: %s\n", PLUGIN_NAME, iso8601, message); } else { printf ("%s: %s\n", g_get_prgname (), message); } } int main (int argc, char **argv) { GError *error; gboolean started; GOptionContext *context; GMainLoop *loop; bindtextdomain (GETTEXT_PACKAGE, CINNAMON_SETTINGS_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* Work around https://bugzilla.gnome.org/show_bug.cgi?id=674885 */ g_type_ensure (G_TYPE_DBUS_CONNECTION); g_type_ensure (G_TYPE_DBUS_PROXY); if (INIT_LIBNOTIFY) { notify_init ("cinnamon-settings-daemon"); } error = NULL; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { fprintf (stderr, "%s\n", error->message); g_error_free (error); exit (1); } g_option_context_free (context); loop = g_main_loop_new (NULL, FALSE); g_unix_signal_add (SIGTERM, (GSourceFunc) handle_signal, loop); if (verbose) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL); if (timeout > 0) { guint id; id = g_timeout_add_seconds (timeout, (GSourceFunc) g_main_loop_quit, loop); g_source_set_name_by_id (id, "[cinnamon-settings-daemon] g_main_loop_quit"); } manager = NEW (); error = NULL; if (REGISTER_BEFORE_STARTING) { register_with_cinnamon_session (loop); started = START (manager, &error); } else { started = START (manager, &error); register_with_cinnamon_session (loop); } if (!started) { if (error != NULL) { fprintf (stderr, "[cinnamon-settings-daemon-%s] Failed to start: %s\n", PLUGIN_NAME, error->message); g_error_free (error); } exit (1); } g_main_loop_run (loop); STOP (manager); g_object_unref (manager); return 0; } cinnamon-settings-daemon-6.4.3/plugins/common/csd-input-helper.c0000664000175000017500000004354514733247605023677 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include "csd-input-helper.h" #define INPUT_DEVICES_SCHEMA "org.cinnamon.settings-daemon.peripherals.input-devices" #define KEY_HOTPLUG_COMMAND "hotplug-command" typedef gboolean (* InfoIdentifyFunc) (XDeviceInfo *device_info); typedef gboolean (* DeviceIdentifyFunc) (XDevice *xdevice); gboolean device_set_property (XDevice *xdevice, const char *device_name, PropertyHelper *property) { int rc; unsigned long i; Atom prop; Atom realtype; int realformat; unsigned long nitems, bytes_after; unsigned char *data; prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), property->name, False); if (!prop) return FALSE; gdk_x11_display_error_trap_push (gdk_display_get_default ()); rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, 0, property->nitems, False, AnyPropertyType, &realtype, &realformat, &nitems, &bytes_after, &data); if (rc != Success || realtype != (Atom)property->type || realformat != property->format || nitems < (unsigned long)property->nitems) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); g_warning ("Error reading property \"%s\" for \"%s\"", property->name, device_name); return FALSE; } for (i = 0; i < nitems; i++) { switch (property->format) { case 8: data[i] = property->data.c[i]; break; case 32: ((long*)data)[i] = property->data.i[i]; break; default: g_warning("device_set_property: default case"); break; } } XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, realtype, realformat, PropModeReplace, data, nitems); XFree (data); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) { g_warning ("Error in setting \"%s\" for \"%s\"", property->name, device_name); return FALSE; } return TRUE; } static gboolean supports_xinput_devices_with_opcode (int *opcode) { gint op_code, event, error; gboolean retval; retval = XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "XInputExtension", &op_code, &event, &error); if (opcode) *opcode = op_code; return retval; } gboolean supports_xinput_devices (void) { return supports_xinput_devices_with_opcode (NULL); } gboolean supports_xtest (void) { gint op_code, event, error; gboolean retval; retval = XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "XTEST", &op_code, &event, &error); return retval; } gboolean supports_xinput2_devices (int *opcode) { int major, minor; if (supports_xinput_devices_with_opcode (opcode) == FALSE) return FALSE; gdk_x11_display_error_trap_push (gdk_display_get_default ()); major = 2; #ifdef XI_23 minor = 3; #else minor = 0; #endif if (XIQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor) != Success) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); #ifndef XI_23 /* try for 2.2, maybe gtk has already announced 2.2 support */ gdk_x11_display_error_trap_push (gdk_display_get_default ()); major = 2; minor = 2; if (XIQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor) != Success) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); return FALSE; } #else return FALSE; #endif } gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); if ((major * 1000 + minor) < (2000)) return FALSE; return TRUE; } gboolean device_is_touchpad (XDevice *xdevice) { Atom realtype, prop; int realformat; unsigned long nitems, bytes_after; unsigned char *data; const char *names[] = { "libinput Tapping Enabled", /* we don't check on the type being XI_TOUCHPAD here, * but having a "Synaptics Off" property should be enough */ "Synaptics Off", NULL, }; const char **name = names; do { prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), *name, True); if (prop) { gdk_x11_display_error_trap_push (gdk_display_get_default ()); if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); XFree (data); return TRUE; } gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); } name++; } while (*name); return FALSE; } gboolean device_info_is_touchpad (XDeviceInfo *device_info) { return (device_info->type == XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_TOUCHPAD, False)); } gboolean device_info_is_touchscreen (XDeviceInfo *device_info) { return (device_info->type == XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_TOUCHSCREEN, False)); } gboolean device_info_is_tablet (XDeviceInfo *device_info) { /* Note that this doesn't match Wacom tablets */ return (device_info->type == XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_TABLET, False)); } gboolean device_info_is_mouse (XDeviceInfo *device_info) { return (device_info->type == XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_MOUSE, False)); } gboolean device_info_is_trackball (XDeviceInfo *device_info) { gboolean retval; retval = (device_info->type == XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XI_TRACKBALL, False)); if (retval == FALSE && device_info->name != NULL) { char *lowercase; lowercase = g_ascii_strdown (device_info->name, -1); retval = strstr (lowercase, "trackball") != NULL; g_free (lowercase); } return retval; } static gboolean device_type_is_present (InfoIdentifyFunc info_func, DeviceIdentifyFunc device_func) { XDeviceInfo *device_info; gint n_devices,i; gboolean retval; if (supports_xinput_devices () == FALSE) return TRUE; retval = FALSE; device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices); if (device_info == NULL) return FALSE; for (i = 0; i < n_devices; i++) { XDevice *device; /* Check with the device info first */ retval = (info_func) (&device_info[i]); if (retval == FALSE) continue; /* If we only have an info func, we're done checking */ if (device_func == NULL) break; gdk_x11_display_error_trap_push (gdk_display_get_default ()); device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ()) || (device == NULL)) continue; retval = (device_func) (device); if (retval) { xdevice_close (device); break; } xdevice_close (device); } XFreeDeviceList (device_info); return retval; } gboolean touchscreen_is_present (void) { return device_type_is_present (device_info_is_touchscreen, NULL); } gboolean touchpad_is_present (void) { return device_type_is_present (device_info_is_touchpad, device_is_touchpad); } gboolean mouse_is_present (void) { return device_type_is_present (device_info_is_mouse, NULL); } gboolean trackball_is_present (void) { return device_type_is_present (device_info_is_trackball, NULL); } char * xdevice_get_device_node (int deviceid) { Atom prop; Atom act_type; int act_format; unsigned long nitems, bytes_after; unsigned char *data; char *ret; gdk_display_sync (gdk_display_get_default ()); prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Device Node", False); if (!prop) return NULL; gdk_x11_display_error_trap_push (gdk_display_get_default ()); if (!XIGetProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, prop, 0, 1000, False, AnyPropertyType, &act_type, &act_format, &nitems, &bytes_after, &data) == Success) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); return NULL; } if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) goto out; if (nitems == 0) goto out; if (act_type != XA_STRING) goto out; /* Unknown string format */ if (act_format != 8) goto out; ret = g_strdup ((char *) data); XFree (data); return ret; out: XFree (data); return NULL; } #define TOOL_ID_FORMAT_SIZE 32 static int get_id_for_index (guchar *data, guint idx) { guchar *ptr; int id; ptr = data; ptr += TOOL_ID_FORMAT_SIZE / 8 * idx; id = *((int32_t*)ptr); id = id & 0xfffff; return id; } #define STYLUS_DEVICE_ID 0x02 #define ERASER_DEVICE_ID 0x0A int xdevice_get_last_tool_id (int deviceid) { Atom prop; Atom act_type; int act_format; unsigned long nitems, bytes_after; unsigned char *data; int id; id = -1; gdk_display_sync (gdk_display_get_default ()); prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), WACOM_SERIAL_IDS_PROP, False); if (!prop) return -1; data = NULL; gdk_x11_display_error_trap_push (gdk_display_get_default ()); if (XIGetProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, prop, 0, 1000, False, AnyPropertyType, &act_type, &act_format, &nitems, &bytes_after, &data) != Success) { gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); goto out; } if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) goto out; if (nitems != 4 && nitems != 5) goto out; if (act_type != XA_INTEGER) goto out; if (act_format != TOOL_ID_FORMAT_SIZE) goto out; /* item 0 = tablet ID * item 1 = old device serial number (== last tool in proximity) * item 2 = old hardware serial number (including tool ID) * item 3 = current serial number (0 if no tool in proximity) * item 4 = current tool ID (since Feb 2012) * * Get the current tool ID first, if available, then the old one */ id = 0x0; if (nitems == 5) id = get_id_for_index (data, 4); if (id == 0x0) id = get_id_for_index (data, 2); /* That means that no tool was set down yet */ if (id == STYLUS_DEVICE_ID || id == ERASER_DEVICE_ID) id = 0x0; out: if (data != NULL) XFree (data); return id; } gboolean set_device_enabled (int device_id, gboolean enabled) { Atom prop; guchar value; prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "Device Enabled", False); if (!prop) return FALSE; gdk_x11_display_error_trap_push (gdk_display_get_default ()); value = enabled ? 1 : 0; XIChangeProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_id, prop, XA_INTEGER, 8, PropModeReplace, &value, 1); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) return FALSE; return TRUE; } static const char * custom_command_to_string (CustomCommand command) { switch (command) { case COMMAND_DEVICE_ADDED: return "added"; case COMMAND_DEVICE_REMOVED: return "removed"; case COMMAND_DEVICE_PRESENT: return "present"; default: g_assert_not_reached (); } } /* Run a custom command on device presence events. Parameters passed into * the custom command are: * command -t [added|removed|present] -i * Type 'added' and 'removed' signal 'device added' and 'device removed', * respectively. Type 'present' signals 'device present at * cinnamon-settings-daemon init'. * * The script is expected to run synchronously, and an exit value * of "1" means that no other settings will be applied to this * particular device. * * More options may be added in the future. * * This function returns TRUE if we should not apply any more settings * to the device. */ gboolean run_custom_command (GdkDevice *device, CustomCommand command) { GSettings *settings; char *cmd; char *argv[7]; int exit_status; gboolean rc; int id; settings = g_settings_new (INPUT_DEVICES_SCHEMA); cmd = g_settings_get_string (settings, KEY_HOTPLUG_COMMAND); g_object_unref (settings); if (!cmd || cmd[0] == '\0') { g_free (cmd); return FALSE; } /* Easter egg! */ g_object_get (device, "device-id", &id, NULL); argv[0] = cmd; argv[1] = (char *)"-t"; argv[2] = (char *) custom_command_to_string (command); argv[3] = (char *)"-i"; argv[4] = g_strdup_printf ("%d", id); argv[5] = g_strdup_printf ("%s", gdk_device_get_name (device)); argv[6] = NULL; rc = g_spawn_sync (g_get_home_dir (), argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &exit_status, NULL); if (rc == FALSE) g_warning ("Couldn't execute command '%s', verify that this is a valid command.", cmd); g_free (argv[0]); g_free (argv[4]); g_free (argv[5]); return (exit_status == 0); } GList * get_disabled_devices (GdkDeviceManager *manager) { XDeviceInfo *device_info; gint n_devices; gint i; GList *ret; ret = NULL; device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices); if (device_info == NULL) return ret; for (i = 0; i < n_devices; i++) { GdkDevice *device; /* Ignore core devices */ if (device_info[i].use == IsXKeyboard || device_info[i].use == IsXPointer) continue; /* Check whether the device is actually available */ device = gdk_x11_device_manager_lookup (manager, device_info[i].id); if (device != NULL) continue; ret = g_list_prepend (ret, GINT_TO_POINTER (device_info[i].id)); } XFreeDeviceList (device_info); return ret; } void xdevice_close (XDevice *xdevice) { gdk_x11_display_error_trap_push (gdk_display_get_default ()); XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice); gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default ()); } cinnamon-settings-daemon-6.4.3/plugins/common/input-device-example.sh0000664000175000017500000000301414733247605024714 0ustar fabiofabio#!/bin/sh # # This script is an example hotplug script for use with the various # input devices plugins. # # The script is called with the arguments: # -t [added|present|removed] # added ... device was just plugged in # present.. device was present at cinnamon-settings-daemon startup # removed.. device was just removed # -i # device ID being the XInput device ID # The name of the device # # The script should return 0 if the device is to be # ignored from future configuration. # # Set the script to be used with: # gsettings set org.cinnamon.settings-daemon.peripherals.input-devices hotplug-command /path/to/script/input-devices.sh # args=`getopt "t:i:" $*` set -- $args while [ $# -gt 0 ] do case $1 in -t) shift; type="$1" ;; -i) shift; id="$1" ;; --) shift; device="$@" break; ;; *) echo "Unknown option $1"; exit 1 ;; esac shift done retval=0 case $type in added) echo "Device '$device' (ID=$id) was added" ;; present) echo "Device '$device' (ID=$id) was already present at startup" ;; removed) echo "Device '$device' (ID=$id) was removed" ;; *) echo "Unknown operation" retval=1 ;; esac # All further processing will be disabled if $retval == 0 exit $retval cinnamon-settings-daemon-6.4.3/plugins/common/test-input-helper.c0000664000175000017500000000710314733247605024073 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include "csd-input-helper.h" static void print_disabled_devices (void) { GList *devices, *l; GdkDeviceManager *manager; manager = gdk_display_get_device_manager (gdk_display_get_default ()); devices = get_disabled_devices (manager); g_print ("Disabled devices:\t\t\t "); if (devices == NULL) { g_print ("no\n"); return; } for (l = devices; l != NULL; l = l->next) { g_print ("%d ", GPOINTER_TO_INT (l->data)); } g_list_free (devices); g_print ("\n"); } int main (int argc, char **argv) { gboolean supports_xinput; gboolean has_touchpad, has_touchscreen; XDeviceInfo *device_info; gint n_devices, opcode, i; gtk_init (&argc, &argv); supports_xinput = supports_xinput_devices (); if (supports_xinput) { g_print ("Supports XInput:\t\t\t yes\n"); } else { g_print ("Supports XInput:\t\t\t no\n"); return 0; } supports_xinput = supports_xinput2_devices (&opcode); if (supports_xinput) { g_print ("Supports XInput2:\t\t\t yes (opcode: %d)\n", opcode); } else { g_print ("Supports XInput2:\t\t\t no\n"); return 0; } has_touchpad = touchpad_is_present (); g_print ("Has touchpad:\t\t\t\t %s\n", has_touchpad ? "yes" : "no"); has_touchscreen = touchscreen_is_present (); g_print ("Has touchscreen:\t\t\t %s\n", has_touchscreen ? "yes" : "no"); device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices); if (device_info == NULL) { g_warning ("Has no input devices"); return 1; } print_disabled_devices (); for (i = 0; i < n_devices; i++) { XDevice *device; if (device_info_is_touchscreen (&device_info[i])) { g_print ("Device %d is touchscreen:\t\t %s\n", (int) device_info[i].id, "yes"); continue; } gdk_x11_display_error_trap_push (gdk_display_get_default ()); device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ()) || (device == NULL)) continue; if (device_is_touchpad (device)) g_print ("Device %d is touchpad:\t\t %s\n", (int) device_info[i].id, "yes"); else { int tool_id; tool_id = xdevice_get_last_tool_id (device_info[i].id); if (tool_id >= 0x0) g_print ("Device %d is touchpad/touchscreen:\t %s (tool ID: 0x%x)\n", (int) device_info[i].id, "no", tool_id); else g_print ("Device %d is touchpad/touchscreen:\t %s\n", (int) device_info[i].id, "no"); } xdevice_close (device); } XFreeDeviceList (device_info); return 0; } cinnamon-settings-daemon-6.4.3/plugins/common/csd-keygrab.c0000664000175000017500000003264714733247605022710 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2001-2003 Bastien Nocera * Copyright (C) 2006-2007 William Jon McCann * Copyright (C) 2008 Jens Granseuer * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include "csd-keygrab.h" /* these are the mods whose combinations are ignored by the keygrabbing code */ static GdkModifierType csd_ignored_mods = 0; /* these are the ones we actually use for global keys, we always only check * for these set */ static GdkModifierType csd_used_mods = 0; /* Taken from a comment in XF86keysym.h */ #define XF86KEYS_RANGE_MIN 0x10080001 #define XF86KEYS_RANGE_MAX 0x1008FFFF #define FKEYS_RANGE_MIN GDK_KEY_F1 #define FKEYS_RANGE_MAX GDK_KEY_R15 #define IN_RANGE(x, min, max) (x >= min && x <= max) static void setup_modifiers (void) { if (csd_used_mods == 0 || csd_ignored_mods == 0) { GdkModifierType dynmods; /* default modifiers */ csd_ignored_mods = \ 0x2000 /*Xkb modifier*/ | GDK_LOCK_MASK | GDK_HYPER_MASK; csd_used_mods = \ GDK_SHIFT_MASK | GDK_CONTROL_MASK |\ GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK |\ GDK_MOD5_MASK | GDK_SUPER_MASK | GDK_META_MASK; /* NumLock can be assigned to varying keys so we need to * resolve and ignore it specially */ dynmods = XkbKeysymToModifiers (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_KEY_Num_Lock); csd_ignored_mods |= dynmods; csd_used_mods &= ~dynmods; } } static void grab_key_real (guint keycode, GdkWindow *root, gboolean grab, gboolean synchronous, XIGrabModifiers *mods, int num_mods) { XIEventMask evmask; unsigned char mask[(XI_LASTEVENT + 7)/8]; memset (mask, 0, sizeof (mask)); XISetMask (mask, XI_KeyPress); XISetMask (mask, XI_KeyRelease); evmask.deviceid = XIAllMasterDevices; evmask.mask_len = sizeof (mask); evmask.mask = mask; if (grab) { XIGrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XIAllMasterDevices, keycode, GDK_WINDOW_XID (root), GrabModeAsync, synchronous ? GrabModeSync : GrabModeAsync, False, &evmask, num_mods, mods); } else { XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XIAllMasterDevices, keycode, GDK_WINDOW_XID (root), num_mods, mods); } } /* Grab the key. In order to ignore CSD_IGNORED_MODS we need to grab * all combinations of the ignored modifiers and those actually used * for the binding (if any). * * inspired by all_combinations from gnome-panel/gnome-panel/global-keys.c * * This may generate X errors. The correct way to use this is like: * * gdk_x11_display_error_trap_push (gdk_display_get_default ()); * * grab_key_unsafe (key, grab, screens); * * gdk_flush (); * if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) * g_warning ("Grab failed, another application may already have access to key '%u'", * key->keycode); * * This is not done in the function itself, to allow doing multiple grab_key * operations with one flush only. */ #define N_BITS 32 static void grab_key_internal (Key *key, gboolean grab, CsdKeygrabFlags flags, GSList *screens) { int indexes[N_BITS]; /* indexes of bits we need to flip */ int i; int bit; int bits_set_cnt; int uppervalue; guint mask, modifiers; GArray *all_mods; GSList *l; setup_modifiers (); mask = csd_ignored_mods & ~key->state & GDK_MODIFIER_MASK; /* XGrabKey requires real modifiers, not virtual ones */ modifiers = key->state; gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &modifiers); modifiers &= ~(GDK_META_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK); /* If key doesn't have a usable modifier, we don't want * to grab it, since the user might lose a useful key. * * The exception is the XFree86 keys and the Function keys * (which are useful to grab without a modifier). */ if (!(flags & CSD_KEYGRAB_ALLOW_UNMODIFIED) && (modifiers & csd_used_mods) == 0 && !IN_RANGE(key->keysym, XF86KEYS_RANGE_MIN, XF86KEYS_RANGE_MAX) && !IN_RANGE(key->keysym, FKEYS_RANGE_MIN, FKEYS_RANGE_MAX) && key->keysym != GDK_KEY_Pause && key->keysym != GDK_KEY_Print && key->keysym != GDK_KEY_Scroll_Lock && key->keysym != GDK_KEY_Break && key->keysym != GDK_KEY_Menu) { GString *keycodes; keycodes = g_string_new (""); if (key->keycodes != NULL) { guint *c; for (c = key->keycodes; *c; ++c) { g_string_printf (keycodes, " %u", *c); } } g_warning ("Key 0x%x (keycodes: %s) with state 0x%x (resolved to 0x%x) " " has no usable modifiers (usable modifiers are 0x%x)", key->keysym, keycodes->str, key->state, modifiers, csd_used_mods); g_string_free (keycodes, TRUE); return; } bit = 0; /* store the indexes of all set bits in mask in the array */ for (i = 0; mask; ++i, mask >>= 1) { if (mask & 0x1) { indexes[bit++] = i; } } bits_set_cnt = bit; all_mods = g_array_new (FALSE, TRUE, sizeof(XIGrabModifiers)); uppervalue = 1 << bits_set_cnt; /* store all possible modifier combinations for our mask into all_mods */ for (i = 0; i < uppervalue; ++i) { int j; int result = 0; XIGrabModifiers *mod; /* map bits in the counter to those in the mask */ for (j = 0; j < bits_set_cnt; ++j) { if (i & (1 << j)) { result |= (1 << indexes[j]); } } /* Grow the array by one, to fit our new XIGrabModifiers item */ g_array_set_size (all_mods, all_mods->len + 1); mod = &g_array_index (all_mods, XIGrabModifiers, all_mods->len - 1); mod->modifiers = result | modifiers; } /* Capture the actual keycodes with the modifier array */ for (l = screens; l; l = l->next) { GdkScreen *screen = l->data; guint *code; for (code = key->keycodes; *code; ++code) { grab_key_real (*code, gdk_screen_get_root_window (screen), grab, flags & CSD_KEYGRAB_SYNCHRONOUS, (XIGrabModifiers *) all_mods->data, all_mods->len); } } g_array_free (all_mods, TRUE); } void grab_key_unsafe (Key *key, CsdKeygrabFlags flags, GSList *screens) { grab_key_internal (key, TRUE, flags, screens); } void ungrab_key_unsafe (Key *key, GSList *screens) { grab_key_internal (key, FALSE, 0, screens); } static gboolean have_xkb (Display *dpy) { static int have_xkb = -1; if (have_xkb == -1) { int opcode, error_base, major, minor, xkb_event_base; have_xkb = XkbQueryExtension (dpy, &opcode, &xkb_event_base, &error_base, &major, &minor) && XkbUseExtension (dpy, &major, &minor); } return have_xkb; } gboolean key_uses_keycode (const Key *key, guint keycode) { if (key->keycodes != NULL) { guint *c; for (c = key->keycodes; *c; ++c) { if (*c == keycode) return TRUE; } } return FALSE; } /* Adapted from _gdk_x11_device_xi2_translate_state() * in gtk+/gdk/x11/gdkdevice-xi2.c */ static guint device_xi2_translate_state (XIModifierState *mods_state, XIGroupState *group_state) { guint state; gint group; state = (guint) mods_state->base | mods_state->latched | mods_state->locked; group = group_state->base | group_state->latched | group_state->locked; /* FIXME: do we need the XKB complications for this ? */ group = CLAMP(group, 0, 3); state |= group << 13; return state; } gboolean match_xi2_key (Key *key, XIDeviceEvent *event) { guint keyval; GdkModifierType consumed; gint group; guint keycode, state; if (key == NULL) return FALSE; setup_modifiers (); state = device_xi2_translate_state (&event->mods, &event->group); if (have_xkb (event->display)) group = XkbGroupForCoreState (state); else group = (state & GDK_KEY_Mode_switch) ? 1 : 0; keycode = event->detail; /* Check if we find a keysym that matches our current state */ if (gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), keycode, state, group, &keyval, NULL, NULL, &consumed)) { guint lower, upper; guint mask; /* HACK: we don't want to use SysRq as a keybinding, so we avoid * its translation from Alt+Print. */ if (keyval == GDK_KEY_Sys_Req && (state & GDK_MOD1_MASK) != 0) { consumed = 0; keyval = GDK_KEY_Print; } /* The Key structure contains virtual modifiers, whereas * the XEvent will be using the real modifier, so translate those */ mask = key->state; gdk_keymap_map_virtual_modifiers (gdk_keymap_get_default (), &mask); mask &= ~(GDK_META_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK); gdk_keyval_convert_case (keyval, &lower, &upper); /* If we are checking against the lower version of the * keysym, we might need the Shift state for matching, * so remove it from the consumed modifiers */ if (lower == key->keysym) consumed &= ~GDK_SHIFT_MASK; return ((lower == key->keysym || upper == key->keysym) && (state & ~consumed & csd_used_mods) == mask); } /* The key we passed doesn't have a keysym, so try with just the keycode */ return (key != NULL && key->state == (state & csd_used_mods) && key_uses_keycode (key, keycode)); } Key * parse_key (const char *str) { Key *key; if (str == NULL || *str == '\0' || g_str_equal (str, "disabled")) { return NULL; } key = g_new0 (Key, 1); gtk_accelerator_parse_with_keycode (str, &key->keysym, &key->keycodes, &key->state); if (key->keysym == 0 && key->keycodes == NULL && key->state == 0) { g_free (key); return NULL; } return key; } void free_key (Key *key) { if (key == NULL) return; g_free (key->keycodes); g_free (key); } static void grab_button_real (int deviceid, gboolean grab, GdkWindow *root) { XIGrabModifiers mods; mods.modifiers = XIAnyModifier; if (grab) { XIEventMask evmask; unsigned char mask[(XI_LASTEVENT + 7)/8]; memset (mask, 0, sizeof (mask)); XISetMask (mask, XI_ButtonRelease); XISetMask (mask, XI_ButtonPress); evmask.deviceid = deviceid; evmask.mask_len = sizeof (mask); evmask.mask = mask; XIGrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, XIAnyButton, GDK_WINDOW_XID (root), None, GrabModeAsync, GrabModeAsync, False, &evmask, 1, &mods); } else { XIUngrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, XIAnyButton, GDK_WINDOW_XID (root), 1, &mods); } } void grab_button (int deviceid, gboolean grab, GSList *screens) { GSList *l; for (l = screens; l; l = l->next) { GdkScreen *screen = l->data; grab_button_real (deviceid, grab, gdk_screen_get_root_window (screen)); } } cinnamon-settings-daemon-6.4.3/plugins/common/migrate-settings.h0000664000175000017500000000352214733247605023776 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2015 Red Hat * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author: Carlos Garnacho */ #ifndef __CSD_SETTINGS_MIGRATE_H__ #define __CSD_SETTINGS_MIGRATE_H__ typedef struct _CsdSettingsMigrateEntry CsdSettingsMigrateEntry; typedef GVariant * (* CsdSettingsMigrateFunc) (GVariant *variant, GSettings *old_schema, GSettings *new_schema, GVariant *old_default, GVariant *new_default); struct _CsdSettingsMigrateEntry { const gchar *origin_key; const gchar *dest_key; CsdSettingsMigrateFunc func; }; void csd_settings_migrate_check (const gchar *origin_schema, const gchar *origin_path, const gchar *dest_schema, const gchar *dest_path, CsdSettingsMigrateEntry entries[], guint n_entries); #endif /* __CSD_SETTINGS_MIGRATE_H__ */ cinnamon-settings-daemon-6.4.3/plugins/common/daemon-skeleton-gtk.h0000664000175000017500000001776114733247605024372 0ustar fabiofabio/** * Create a test app for your plugin quickly. * * #define NEW csd_media_keys_manager_new * #define START csd_media_keys_manager_start * #define MANAGER CsdMediaKeysManager * #include "csd-media-keys-manager.h" * * #include "daemon-skeleton.h" */ #include "config.h" #include #include #include #include #include #include #ifndef PLUGIN_NAME #error Include PLUGIN_CFLAGS in the daemon s CFLAGS #endif /* !PLUGIN_NAME */ #ifndef FORCE_X11_BACKEND #define FORCE_X11_BACKEND FALSE #endif #ifndef INIT_LIBNOTIFY #define INIT_LIBNOTIFY FALSE #endif #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager" #define GNOME_SESSION_CLIENT_PRIVATE_NAME "org.gnome.SessionManager.ClientPrivate" static MANAGER *manager = NULL; static int timeout = -1; static gboolean verbose = FALSE; static GOptionEntry entries[] = { { "exit-time", 0, 0, G_OPTION_ARG_INT, &timeout, "Exit after n seconds time", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose", NULL }, {NULL} }; static void respond_to_end_session (GDBusProxy *proxy) { /* we must answer with "EndSessionResponse" */ g_dbus_proxy_call (proxy, "EndSessionResponse", g_variant_new ("(bs)", TRUE, ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } static void client_proxy_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { if (g_strcmp0 (signal_name, "QueryEndSession") == 0) { g_debug ("Got QueryEndSession signal"); respond_to_end_session (proxy); } else if (g_strcmp0 (signal_name, "EndSession") == 0) { g_debug ("Got EndSession signal"); respond_to_end_session (proxy); } else if (g_strcmp0 (signal_name, "Stop") == 0) { g_debug ("Got Stop signal"); gtk_main_quit (); } } static void on_client_registered (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *variant; GDBusProxy *client_proxy; GError *error = NULL; gchar *object_path = NULL; variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (!variant) { if (error != NULL) { g_warning ("Unable to register client: %s", error->message); g_error_free (error); } return; } g_variant_get (variant, "(o)", &object_path); g_debug ("Registered client at path %s", object_path); client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, 0, NULL, GNOME_SESSION_DBUS_NAME, object_path, GNOME_SESSION_CLIENT_PRIVATE_NAME, NULL, &error); if (!client_proxy) { if (error != NULL) { g_warning ("Unable to get the session client proxy: %s", error->message); g_error_free (error); } return; } g_signal_connect (client_proxy, "g-signal", G_CALLBACK (client_proxy_signal_cb), NULL); g_free (object_path); g_variant_unref (variant); } static void register_with_cinnamon_session (void) { const char *startup_id; GError *error = NULL; GDBusProxy *proxy; GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (!bus) { g_debug ("Could not connect to the dbus session bus"); return; } proxy = g_dbus_proxy_new_sync (bus, G_DBUS_PROXY_FLAGS_NONE, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_NAME, NULL, &error); g_object_unref (bus); if (proxy == NULL) { if (error != NULL) { g_debug ("Could not connect to the Session manager: %s", error->message); g_error_free (error); } return; } startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); g_dbus_proxy_call (proxy, "RegisterClient", g_variant_new ("(ss)", PLUGIN_NAME, startup_id ? startup_id : ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback) on_client_registered, NULL); } static gboolean handle_signal (gpointer user_data) { g_debug ("Got SIGTERM - shutting down"); if (gtk_main_level () > 0) gtk_main_quit (); return G_SOURCE_REMOVE; } static void message_handler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { /* Make this look like normal console output */ if (log_level & G_LOG_LEVEL_DEBUG) { g_autoptr(GDateTime) dt = g_date_time_new_now_local (); g_autofree gchar *iso8601 = g_date_time_format (dt, "%F:%T"); printf ("csd-%s:%s: %s\n", PLUGIN_NAME, iso8601, message); } else { printf ("%s: %s\n", g_get_prgname (), message); } } int main (int argc, char **argv) { GError *error; gboolean started; bindtextdomain (GETTEXT_PACKAGE, CINNAMON_SETTINGS_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* Work around https://bugzilla.gnome.org/show_bug.cgi?id=674885 */ g_type_ensure (G_TYPE_DBUS_CONNECTION); g_type_ensure (G_TYPE_DBUS_PROXY); if (FORCE_X11_BACKEND) { const gchar *setup_display = getenv ("GNOME_SETUP_DISPLAY"); if (setup_display && *setup_display != '\0') g_setenv ("DISPLAY", setup_display, TRUE); gdk_set_allowed_backends ("x11"); } if (INIT_LIBNOTIFY) { notify_init ("cinnamon-settings-daemon"); } if (FORCE_GDK_SCALE) { g_setenv ("GDK_SCALE", "1", TRUE); } error = NULL; if (! gtk_init_with_args (&argc, &argv, PLUGIN_NAME, entries, NULL, &error)) { if (error != NULL) { fprintf (stderr, "%s\n", error->message); g_error_free (error); } exit (1); } if (FORCE_GDK_SCALE) { g_unsetenv ("GDK_SCALE"); } g_unix_signal_add (SIGTERM, (GSourceFunc) handle_signal, NULL); if (verbose) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL); if (timeout > 0) { guint id; id = g_timeout_add_seconds (timeout, (GSourceFunc) gtk_main_quit, NULL); g_source_set_name_by_id (id, "[cinnamon-settings-daemon] gtk_main_quit"); } manager = NEW (); error = NULL; if (REGISTER_BEFORE_STARTING) { register_with_cinnamon_session (); started = START (manager, &error); } else { started = START (manager, &error); register_with_cinnamon_session (); } if (!started) { if (error != NULL) { fprintf (stderr, "[cinnamon-settings-daemon-%s] Failed to start: %s\n", PLUGIN_NAME, error->message); g_error_free (error); } exit (1); } gtk_main (); STOP (manager); g_object_unref (manager); return 0; } cinnamon-settings-daemon-6.4.3/plugins/common/csd-input-helper.h0000664000175000017500000000652414733247605023700 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef __CSD_INPUT_HELPER_H #define __CSD_INPUT_HELPER_H G_BEGIN_DECLS #include #include #include #define WACOM_SERIAL_IDS_PROP "Wacom Serial IDs" typedef enum { COMMAND_DEVICE_ADDED, COMMAND_DEVICE_REMOVED, COMMAND_DEVICE_PRESENT } CustomCommand; /* Generic property setting code. Fill up the struct property with the property * data and pass it into device_set_property together with the device to be * changed. Note: doesn't cater for non-zero offsets yet, but we don't have * any settings that require that. */ typedef struct { const char *name; /* property name */ gint nitems; /* number of items in data */ gint format; /* CARD8 or CARD32 sized-items */ gint type; /* Atom representing data type */ union { const gchar *c; /* 8 bit data */ const gint *i; /* 32 bit data */ } data; } PropertyHelper; gboolean supports_xinput_devices (void); gboolean supports_xinput2_devices (int *opcode); gboolean supports_xtest (void); gboolean set_device_enabled (int device_id, gboolean enabled); gboolean device_is_touchpad (XDevice *xdevice); gboolean device_info_is_touchpad (XDeviceInfo *device_info); gboolean device_info_is_touchscreen (XDeviceInfo *device_info); gboolean device_info_is_tablet (XDeviceInfo *device_info); gboolean device_info_is_mouse (XDeviceInfo *device_info); gboolean device_info_is_trackball (XDeviceInfo *device_info); gboolean touchpad_is_present (void); gboolean touchscreen_is_present (void); gboolean mouse_is_present (void); gboolean trackball_is_present (void); gboolean device_set_property (XDevice *xdevice, const char *device_name, PropertyHelper *property); gboolean run_custom_command (GdkDevice *device, CustomCommand command); GList * get_disabled_devices (GdkDeviceManager *manager); char * xdevice_get_device_node (int deviceid); int xdevice_get_last_tool_id (int deviceid); void xdevice_close (XDevice *xdevice); G_END_DECLS #endif /* __CSD_INPUT_HELPER_H */ cinnamon-settings-daemon-6.4.3/plugins/automount/0000775000175000017500000000000014733247605021100 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/automount/cinnamon-settings-daemon-automount.desktop.in0000664000175000017500000000034214733247605032031 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - automount Exec=csd-automount OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/automount/meson.build0000664000175000017500000000245214733247605023245 0ustar fabiofabioplugin_name = 'automount' automount_sources = [ 'csd-automount-manager.c', 'csd-autorun.c', 'main.c', ] automount_deps = [ common_dep, csd_dep, libnotify, ] executable( 'csd-automount', automount_sources, include_directories: [include_dirs, common_inc], dependencies: automount_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install_rpath: join_paths(prefix, apilibdir), install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-automount') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-automount') endif test_automount_dialog_sources = [ 'test-automount-dialog.c', 'csd-autorun.c', ] executable( 'test-automount-dialog', test_automount_dialog_sources, dependencies: automount_deps, install: false, ) configure_file( input: 'cinnamon-settings-daemon-automount.desktop.in', output: 'cinnamon-settings-daemon-automount.desktop', configuration: desktop_conf, install_dir: autostartdir, ) configure_file( input: 'csd-automount.desktop.in', output: 'csd-automount.desktop', configuration: desktop_conf, install_dir: desktopdir, ) cinnamon-settings-daemon-6.4.3/plugins/automount/main.c0000664000175000017500000000103614733247605022170 0ustar fabiofabio#define NEW csd_automount_manager_new #define START csd_automount_manager_start #define STOP csd_automount_manager_stop #define MANAGER CsdAutomountManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE FALSE #include "csd-automount-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/automount/csd-automount.desktop.in0000664000175000017500000000104714733247605025704 0ustar fabiofabio[Desktop Entry] Type=Application Name=Files Name[am]=á‹á‹­áˆŽá‰½ Name[bg]=Файлове Name[ca]=Arxius Name[cs]=Soubory Name[da]=Filer Name[de]=Dateien Name[es]=Archivos Name[eu]=Fitxategiak Name[fr]=Fichiers Name[hr]=Nemo Name[hu]=Fájlok Name[ko]=íŒŒì¼ Name[lt]=Failai Name[nl]=Bestanden Name[pl]=Pliki Name[pt]=Ficheiros Name[pt_BR]=Arquivos Name[pt_PT]=Ficheiros Name[ru]=Файлы Name[sv]=Filer Name[tr]=Dosyalar Name[uk]=Файли Name[zh_CN]=文件 Name[zh_HK]=檔案 Icon=folder Exec=csd-automount OnlyShowIn=X-Cinnamon; NoDisplay=true cinnamon-settings-daemon-6.4.3/plugins/automount/csd-automount-manager.h0000664000175000017500000000461614733247605025472 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Red Hat, Inc. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA * * Author: Tomas Bzatek */ #ifndef __CSD_AUTOMOUNT_MANAGER_H #define __CSD_AUTOMOUNT_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_AUTOMOUNT_MANAGER (csd_automount_manager_get_type ()) #define CSD_AUTOMOUNT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_AUTOMOUNT_MANAGER, CsdAutomountManager)) #define CSD_AUTOMOUNT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_AUTOMOUNT_MANAGER, CsdAutomountManagerClass)) #define CSD_IS_AUTOMOUNT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_AUTOMOUNT_MANAGER)) #define CSD_IS_AUTOMOUNT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_AUTOMOUNT_MANAGER)) #define CSD_AUTOMOUNT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_AUTOMOUNT_MANAGER, CsdAutomountManagerClass)) typedef struct CsdAutomountManagerPrivate CsdAutomountManagerPrivate; typedef struct { GObject parent; CsdAutomountManagerPrivate *priv; } CsdAutomountManager; typedef struct { GObjectClass parent_class; } CsdAutomountManagerClass; GType csd_automount_manager_get_type (void); CsdAutomountManager * csd_automount_manager_new (void); gboolean csd_automount_manager_start (CsdAutomountManager *manager, GError **error); void csd_automount_manager_stop (CsdAutomountManager *manager); G_END_DECLS #endif /* __CSD_AUTOMOUNT_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/automount/csd-automount-manager.c0000664000175000017500000004270314733247605025464 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Red Hat, Inc. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA * * Author: Tomas Bzatek */ #include "config.h" #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "cinnamon-settings-session.h" #include "csd-automount-manager.h" #include "csd-autorun.h" #define CSD_AUTOMOUNT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_AUTOMOUNT_MANAGER, CsdAutomountManagerPrivate)) struct CsdAutomountManagerPrivate { GSettings *settings; GSettings *settings_screensaver; GVolumeMonitor *volume_monitor; unsigned int automount_idle_id; CinnamonSettingsSession *session; gboolean session_is_active; gboolean screensaver_active; guint ss_watch_id; GDBusProxy *ss_proxy; GList *volume_queue; }; G_DEFINE_TYPE (CsdAutomountManager, csd_automount_manager, G_TYPE_OBJECT) static GtkDialog * show_error_dialog (const char *primary_text, const char *secondary_text) { GtkWidget *dialog; dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", ""); g_object_set (dialog, "text", primary_text, "secondary-text", secondary_text, NULL); gtk_widget_show (GTK_WIDGET (dialog)); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); return GTK_DIALOG (dialog); } static void startup_volume_mount_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_volume_mount_finish (G_VOLUME (source_object), res, NULL); } static void automount_all_volumes (CsdAutomountManager *manager) { GList *volumes, *l; GMount *mount; GVolume *volume; if (g_settings_get_boolean (manager->priv->settings, "automount")) { /* automount all mountable volumes at start-up */ volumes = g_volume_monitor_get_volumes (manager->priv->volume_monitor); for (l = volumes; l != NULL; l = l->next) { volume = l->data; if (!g_volume_should_automount (volume) || !g_volume_can_mount (volume)) { continue; } mount = g_volume_get_mount (volume); if (mount != NULL) { g_object_unref (mount); continue; } /* pass NULL as GMountOperation to avoid user interaction */ g_volume_mount (volume, 0, NULL, NULL, startup_volume_mount_cb, NULL); } g_list_free_full (volumes, g_object_unref); } } static gboolean automount_all_volumes_idle_cb (gpointer data) { CsdAutomountManager *manager = CSD_AUTOMOUNT_MANAGER (data); automount_all_volumes (manager); manager->priv->automount_idle_id = 0; return FALSE; } static void volume_mount_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GMountOperation *mount_op = user_data; GError *error; char *primary; char *name; error = NULL; csd_allow_autorun_for_volume_finish (G_VOLUME (source_object)); if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) { if (error->code != G_IO_ERROR_FAILED_HANDLED && error->code != G_IO_ERROR_ALREADY_MOUNTED) { name = g_volume_get_name (G_VOLUME (source_object)); primary = g_strdup_printf (_("Unable to mount %s"), name); g_free (name); show_error_dialog (primary, error->message); g_free (primary); } g_error_free (error); } g_object_unref (mount_op); } static void do_mount_volume (GVolume *volume) { GMountOperation *mount_op; mount_op = gtk_mount_operation_new (NULL); g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION); csd_allow_autorun_for_volume (volume); g_volume_mount (volume, 0, mount_op, NULL, volume_mount_cb, mount_op); } static void check_volume_queue (CsdAutomountManager *manager) { GList *l; GVolume *volume; if (manager->priv->screensaver_active) return; l = manager->priv->volume_queue; while (l != NULL) { volume = l->data; do_mount_volume (volume); manager->priv->volume_queue = g_list_remove (manager->priv->volume_queue, volume); g_object_unref (volume); l = l->next; } manager->priv->volume_queue = NULL; } static void check_screen_lock_and_mount (CsdAutomountManager *manager, GVolume *volume) { if (!manager->priv->session_is_active) return; if (manager->priv->screensaver_active) { /* queue the volume, to mount it after the screensaver state changed */ g_debug ("Queuing volume %p", volume); manager->priv->volume_queue = g_list_prepend (manager->priv->volume_queue, g_object_ref (volume)); } else { /* mount it immediately */ do_mount_volume (volume); } } static void volume_removed_callback (GVolumeMonitor *monitor, GVolume *volume, CsdAutomountManager *manager) { g_debug ("Volume %p removed, removing from the queue", volume); /* clear it from the queue, if present */ manager->priv->volume_queue = g_list_remove (manager->priv->volume_queue, volume); } static void volume_added_callback (GVolumeMonitor *monitor, GVolume *volume, CsdAutomountManager *manager) { if (g_settings_get_boolean (manager->priv->settings, "automount") && g_volume_should_automount (volume) && g_volume_can_mount (volume)) { check_screen_lock_and_mount (manager, volume); } else { /* Allow csd_autorun() to run. When the mount is later * added programmatically (i.e. for a blank CD), * csd_autorun() will be called by mount_added_callback(). */ csd_allow_autorun_for_volume (volume); csd_allow_autorun_for_volume_finish (volume); } } static void autorun_show_window (GMount *mount, gpointer user_data) { GFile *location; char *uri; GError *error; char *primary; char *name; location = g_mount_get_root (mount); uri = g_file_get_uri (location); error = NULL; /* use default folder handler */ g_debug("Opening %s", uri); if (g_str_has_prefix (uri, "afc://")) { // AFC (Apple File Conduit, which runs on iPhone and other Apple devices) doesn't always work well // Observed on an iOS 4 device it would work the first time the device was connected, and then indefinitely hang after that // Even a simple 'ls /run/user/$USER/gvfs' would hang forever // It is unacceptable for CSD to hang, so we're treating AFC differently (asynchronously) g_debug("AFC protocol detected, opening asynchronously!"); char * command = g_strdup_printf("timeout 10s xdg-open %s", uri); g_debug("Executing command '%s'", command); system(command); g_debug("Command was executed, moving on.."); g_free(command); } else { if (! gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error)) { name = g_mount_get_name (mount); primary = g_strdup_printf (_("Unable to open a folder for %s"), name); g_free (name); show_error_dialog (primary, error->message); g_free (primary); g_error_free (error); } } g_free (uri); g_object_unref (location); } static void mount_added_callback (GVolumeMonitor *monitor, GMount *mount, CsdAutomountManager *manager) { /* don't autorun if the session is not active */ if (!manager->priv->session_is_active) { return; } csd_autorun (mount, manager->priv->settings, autorun_show_window, manager); } static void session_state_changed (CinnamonSettingsSession *session, GParamSpec *pspec, gpointer user_data) { CsdAutomountManager *manager = user_data; CsdAutomountManagerPrivate *p = manager->priv; if (cinnamon_settings_session_get_state (session) == CINNAMON_SETTINGS_SESSION_STATE_ACTIVE) { p->session_is_active = TRUE; } else { p->session_is_active = FALSE; } if (!p->session_is_active) { if (p->volume_queue != NULL) { g_list_free_full (p->volume_queue, g_object_unref); p->volume_queue = NULL; } } } static void do_initialize_session (CsdAutomountManager *manager) { manager->priv->session = cinnamon_settings_session_new (); g_signal_connect (manager->priv->session, "notify::state", G_CALLBACK (session_state_changed), manager); session_state_changed (manager->priv->session, NULL, manager); } #define SCREENSAVER_NAME "org.cinnamon.ScreenSaver" #define SCREENSAVER_PATH "/org/cinnamon/ScreenSaver" #define SCREENSAVER_INTERFACE "org.cinnamon.ScreenSaver" static void screensaver_signal_callback (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { CsdAutomountManager *manager = user_data; if (g_strcmp0 (signal_name, "ActiveChanged") == 0) { g_variant_get (parameters, "(b)", &manager->priv->screensaver_active); g_debug ("Screensaver active changed to %d", manager->priv->screensaver_active); check_volume_queue (manager); } } static void screensaver_get_active_ready_cb (GObject *source, GAsyncResult *res, gpointer user_data) { CsdAutomountManager *manager = user_data; GDBusProxy *proxy = manager->priv->ss_proxy; GVariant *result; GError *error = NULL; result = g_dbus_proxy_call_finish (proxy, res, &error); if (error != NULL) { g_warning ("Can't call GetActive() on the ScreenSaver object: %s", error->message); g_error_free (error); return; } g_variant_get (result, "(b)", &manager->priv->screensaver_active); g_variant_unref (result); g_debug ("Screensaver GetActive() returned %d", manager->priv->screensaver_active); } static void screensaver_proxy_ready_cb (GObject *source, GAsyncResult *res, gpointer user_data) { CsdAutomountManager *manager = user_data; GError *error = NULL; GDBusProxy *ss_proxy; ss_proxy = g_dbus_proxy_new_finish (res, &error); if (error != NULL) { g_warning ("Can't get proxy for the ScreenSaver object: %s", error->message); g_error_free (error); return; } g_debug ("ScreenSaver proxy ready"); manager->priv->ss_proxy = ss_proxy; g_signal_connect (ss_proxy, "g-signal", G_CALLBACK (screensaver_signal_callback), manager); g_dbus_proxy_call (ss_proxy, "GetActive", NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, screensaver_get_active_ready_cb, manager); } static void screensaver_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { CsdAutomountManager *manager = user_data; g_debug ("ScreenSaver name appeared"); manager->priv->screensaver_active = FALSE; g_dbus_proxy_new (connection, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, name, SCREENSAVER_PATH, SCREENSAVER_INTERFACE, NULL, screensaver_proxy_ready_cb, manager); } static void screensaver_vanished_callback (GDBusConnection *connection, const gchar *name, gpointer user_data) { CsdAutomountManager *manager = user_data; g_debug ("ScreenSaver name vanished"); manager->priv->screensaver_active = FALSE; if (manager->priv->ss_proxy != NULL) { g_object_unref (manager->priv->ss_proxy); manager->priv->ss_proxy = NULL; } /* in this case force a clear of the volume queue, without * mounting them. */ if (manager->priv->volume_queue != NULL) { g_list_free_full (manager->priv->volume_queue, g_object_unref); manager->priv->volume_queue = NULL; } } static void do_initialize_screensaver (CsdAutomountManager *manager) { CsdAutomountManagerPrivate *p = manager->priv; p->ss_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, SCREENSAVER_NAME, G_BUS_NAME_WATCHER_FLAGS_NONE, screensaver_appeared_callback, screensaver_vanished_callback, manager, NULL); } static void setup_automounter (CsdAutomountManager *manager) { do_initialize_session (manager); gchar *custom_saver = g_settings_get_string (manager->priv->settings_screensaver, "custom-screensaver-command"); /* if we fail to get the gsettings entry, or if the user did not select * a custom screen saver, default to cinnamon-screensaver */ if (NULL == custom_saver || g_strcmp0 (custom_saver, "") == 0) do_initialize_screensaver (manager); g_free (custom_saver); manager->priv->volume_monitor = g_volume_monitor_get (); g_signal_connect_object (manager->priv->volume_monitor, "mount-added", G_CALLBACK (mount_added_callback), manager, 0); g_signal_connect_object (manager->priv->volume_monitor, "volume-added", G_CALLBACK (volume_added_callback), manager, 0); g_signal_connect_object (manager->priv->volume_monitor, "volume-removed", G_CALLBACK (volume_removed_callback), manager, 0); manager->priv->automount_idle_id = g_idle_add_full (G_PRIORITY_LOW, automount_all_volumes_idle_cb, manager, NULL); } gboolean csd_automount_manager_start (CsdAutomountManager *manager, GError **error) { g_debug ("Starting automounting manager"); cinnamon_settings_profile_start (NULL); manager->priv->settings = g_settings_new ("org.cinnamon.desktop.media-handling"); manager->priv->settings_screensaver = g_settings_new ("org.cinnamon.desktop.screensaver"); setup_automounter (manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_automount_manager_stop (CsdAutomountManager *manager) { CsdAutomountManagerPrivate *p = manager->priv; g_debug ("Stopping automounting manager"); if (p->session != NULL) { g_object_unref (p->session); p->session = NULL; } if (p->volume_monitor != NULL) { g_object_unref (p->volume_monitor); p->volume_monitor = NULL; } if (p->settings != NULL) { g_object_unref (p->settings); p->settings = NULL; } if (p->settings_screensaver != NULL) { g_object_unref (p->settings_screensaver); p->settings_screensaver = NULL; } if (p->ss_proxy != NULL) { g_object_unref (p->ss_proxy); p->ss_proxy = NULL; } g_bus_unwatch_name (p->ss_watch_id); if (p->volume_queue != NULL) { g_list_free_full (p->volume_queue, g_object_unref); p->volume_queue = NULL; } if (p->automount_idle_id != 0) { g_source_remove (p->automount_idle_id); p->automount_idle_id = 0; } } static void csd_automount_manager_class_init (CsdAutomountManagerClass *klass) { g_type_class_add_private (klass, sizeof (CsdAutomountManagerPrivate)); } static void csd_automount_manager_init (CsdAutomountManager *manager) { manager->priv = CSD_AUTOMOUNT_MANAGER_GET_PRIVATE (manager); } CsdAutomountManager * csd_automount_manager_new (void) { return CSD_AUTOMOUNT_MANAGER (g_object_new (CSD_TYPE_AUTOMOUNT_MANAGER, NULL)); } cinnamon-settings-daemon-6.4.3/plugins/automount/csd-autorun.c0000664000175000017500000007175214733247605023524 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ /* * csd-automount.c: helpers for automounting hotplugged volumes * * Copyright (C) 2008, 2010 Red Hat, Inc. * * Nautilus 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA * * Authors: David Zeuthen * Cosimo Cecchi */ #include #include #include #include #include #include #include #include #include "csd-autorun.h" static gboolean should_autorun_mount (GMount *mount); #define CUSTOM_ITEM_ASK "csd-item-ask" #define CUSTOM_ITEM_DO_NOTHING "csd-item-do-nothing" #define CUSTOM_ITEM_OPEN_FOLDER "csd-item-open-folder" typedef struct { GtkWidget *dialog; GMount *mount; gboolean should_eject; gboolean selected_ignore; gboolean selected_open_folder; GAppInfo *selected_app; gboolean remember; char *x_content_type; CsdAutorunOpenWindow open_window_func; gpointer user_data; } AutorunDialogData; static int csd_autorun_g_strv_find (char **strv, const char *find_me) { guint index; g_return_val_if_fail (find_me != NULL, -1); for (index = 0; strv[index] != NULL; ++index) { if (strcmp (strv[index], find_me) == 0) { return index; } } return -1; } #define ICON_SIZE_STANDARD 48 static gint get_icon_size_for_stock_size (GtkIconSize size) { gint w, h; if (gtk_icon_size_lookup (size, &w, &h)) { return MAX (w, h); } return ICON_SIZE_STANDARD; } static GdkPixbuf * render_icon (GIcon *icon, gint icon_size) { GdkPixbuf *pixbuf; GtkIconInfo *info; pixbuf = NULL; if (G_IS_THEMED_ICON (icon)) { gchar const * const *names; info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), icon, icon_size, 0); if (info) { pixbuf = gtk_icon_info_load_icon (info, NULL); g_object_unref (info); } if (pixbuf == NULL) { names = g_themed_icon_get_names (G_THEMED_ICON (icon)); pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), *names, icon_size, 0, NULL); } } else if (G_IS_FILE_ICON (icon)) { GFile *icon_file; gchar *path; icon_file = g_file_icon_get_file (G_FILE_ICON (icon)); path = g_file_get_path (icon_file); pixbuf = gdk_pixbuf_new_from_file_at_size (path, icon_size, icon_size, NULL); g_free (path); g_object_unref (G_OBJECT (icon_file)); } return pixbuf; } static void csd_autorun_get_preferences (const char *x_content_type, gboolean *pref_start_app, gboolean *pref_ignore, gboolean *pref_open_folder) { GSettings *settings; char **x_content_start_app; char **x_content_ignore; char **x_content_open_folder; g_return_if_fail (pref_start_app != NULL); g_return_if_fail (pref_ignore != NULL); g_return_if_fail (pref_open_folder != NULL); settings = g_settings_new ("org.cinnamon.desktop.media-handling"); *pref_start_app = FALSE; *pref_ignore = FALSE; *pref_open_folder = FALSE; x_content_start_app = g_settings_get_strv (settings, "autorun-x-content-start-app"); x_content_ignore = g_settings_get_strv (settings, "autorun-x-content-ignore"); x_content_open_folder = g_settings_get_strv (settings, "autorun-x-content-open-folder"); if (x_content_start_app != NULL) { *pref_start_app = csd_autorun_g_strv_find (x_content_start_app, x_content_type) != -1; } if (x_content_ignore != NULL) { *pref_ignore = csd_autorun_g_strv_find (x_content_ignore, x_content_type) != -1; } if (x_content_open_folder != NULL) { *pref_open_folder = csd_autorun_g_strv_find (x_content_open_folder, x_content_type) != -1; } g_strfreev (x_content_ignore); g_strfreev (x_content_start_app); g_strfreev (x_content_open_folder); g_object_unref (settings); } static char ** remove_elem_from_str_array (char **v, const char *s) { GPtrArray *array; guint idx; array = g_ptr_array_new (); for (idx = 0; v[idx] != NULL; idx++) { if (g_strcmp0 (v[idx], s) == 0) { continue; } g_ptr_array_add (array, v[idx]); } g_ptr_array_add (array, NULL); g_free (v); return (char **) g_ptr_array_free (array, FALSE); } static char ** add_elem_to_str_array (char **v, const char *s) { GPtrArray *array; guint idx; array = g_ptr_array_new (); for (idx = 0; v[idx] != NULL; idx++) { g_ptr_array_add (array, v[idx]); } g_ptr_array_add (array, g_strdup (s)); g_ptr_array_add (array, NULL); g_free (v); return (char **) g_ptr_array_free (array, FALSE); } static void csd_autorun_set_preferences (const char *x_content_type, gboolean pref_start_app, gboolean pref_ignore, gboolean pref_open_folder) { GSettings *settings; char **x_content_start_app; char **x_content_ignore; char **x_content_open_folder; g_assert (x_content_type != NULL); settings = g_settings_new ("org.cinnamon.desktop.media-handling"); x_content_start_app = g_settings_get_strv (settings, "autorun-x-content-start-app"); x_content_ignore = g_settings_get_strv (settings, "autorun-x-content-ignore"); x_content_open_folder = g_settings_get_strv (settings, "autorun-x-content-open-folder"); x_content_start_app = remove_elem_from_str_array (x_content_start_app, x_content_type); if (pref_start_app) { x_content_start_app = add_elem_to_str_array (x_content_start_app, x_content_type); } g_settings_set_strv (settings, "autorun-x-content-start-app", (const gchar * const*) x_content_start_app); x_content_ignore = remove_elem_from_str_array (x_content_ignore, x_content_type); if (pref_ignore) { x_content_ignore = add_elem_to_str_array (x_content_ignore, x_content_type); } g_settings_set_strv (settings, "autorun-x-content-ignore", (const gchar * const*) x_content_ignore); x_content_open_folder = remove_elem_from_str_array (x_content_open_folder, x_content_type); if (pref_open_folder) { x_content_open_folder = add_elem_to_str_array (x_content_open_folder, x_content_type); } g_settings_set_strv (settings, "autorun-x-content-open-folder", (const gchar * const*) x_content_open_folder); g_strfreev (x_content_open_folder); g_strfreev (x_content_ignore); g_strfreev (x_content_start_app); g_object_unref (settings); } static void custom_item_activated_cb (GtkAppChooserButton *button, const gchar *item, gpointer user_data) { gchar *content_type; AutorunDialogData *data = user_data; content_type = gtk_app_chooser_get_content_type (GTK_APP_CHOOSER (button)); if (g_strcmp0 (item, CUSTOM_ITEM_ASK) == 0) { csd_autorun_set_preferences (content_type, FALSE, FALSE, FALSE); data->selected_open_folder = FALSE; data->selected_ignore = FALSE; } else if (g_strcmp0 (item, CUSTOM_ITEM_OPEN_FOLDER) == 0) { csd_autorun_set_preferences (content_type, FALSE, FALSE, TRUE); data->selected_open_folder = TRUE; data->selected_ignore = FALSE; } else if (g_strcmp0 (item, CUSTOM_ITEM_DO_NOTHING) == 0) { csd_autorun_set_preferences (content_type, FALSE, TRUE, FALSE); data->selected_open_folder = FALSE; data->selected_ignore = TRUE; } g_free (content_type); } static void combo_box_changed_cb (GtkComboBox *combo_box, gpointer user_data) { GAppInfo *info; AutorunDialogData *data = user_data; info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (combo_box)); if (info == NULL) return; if (data->selected_app != NULL) { g_object_unref (data->selected_app); data->selected_app = NULL; } data->selected_app = info; } static void prepare_combo_box (GtkWidget *combo_box, AutorunDialogData *data) { GtkAppChooserButton *app_chooser = GTK_APP_CHOOSER_BUTTON (combo_box); GIcon *icon; gboolean pref_ask; gboolean pref_start_app; gboolean pref_ignore; gboolean pref_open_folder; GAppInfo *info; gchar *content_type; content_type = gtk_app_chooser_get_content_type (GTK_APP_CHOOSER (app_chooser)); gtk_app_chooser_button_set_show_default_item (GTK_APP_CHOOSER_BUTTON (combo_box), TRUE); /* fetch preferences for this content type */ csd_autorun_get_preferences (content_type, &pref_start_app, &pref_ignore, &pref_open_folder); pref_ask = !pref_start_app && !pref_ignore && !pref_open_folder; info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (combo_box)); /* append the separator only if we have >= 1 apps in the chooser */ if (info != NULL) { gtk_app_chooser_button_append_separator (app_chooser); g_object_unref (info); } icon = g_themed_icon_new ("dialog-question"); gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_ASK, _("Ask what to do"), icon); g_object_unref (icon); icon = g_themed_icon_new ("window-close"); gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_DO_NOTHING, _("Do Nothing"), icon); g_object_unref (icon); icon = g_themed_icon_new ("folder-open"); gtk_app_chooser_button_append_custom_item (app_chooser, CUSTOM_ITEM_OPEN_FOLDER, _("Open Folder"), icon); g_object_unref (icon); gtk_app_chooser_button_set_show_dialog_item (app_chooser, TRUE); if (pref_ask) { gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_ASK); } else if (pref_ignore) { gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_DO_NOTHING); } else if (pref_open_folder) { gtk_app_chooser_button_set_active_custom_item (app_chooser, CUSTOM_ITEM_OPEN_FOLDER); } g_signal_connect (app_chooser, "changed", G_CALLBACK (combo_box_changed_cb), data); g_signal_connect (app_chooser, "custom-item-activated", G_CALLBACK (custom_item_activated_cb), data); g_free (content_type); } static gboolean is_shift_pressed (void) { gboolean ret; XkbStateRec state; Bool status; ret = FALSE; gdk_x11_display_error_trap_push (gdk_display_get_default ()); status = XkbGetState (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XkbUseCoreKbd, &state); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); if (status == Success) { ret = state.mods & ShiftMask; } return ret; } enum { AUTORUN_DIALOG_RESPONSE_EJECT = 0 }; static void csd_autorun_launch_for_mount (GMount *mount, GAppInfo *app_info) { GFile *root; GdkAppLaunchContext *launch_context; GError *error; gboolean result; GList *list; gchar *uri_scheme; gchar *uri; root = g_mount_get_root (mount); list = g_list_append (NULL, root); launch_context = gdk_app_launch_context_new (); error = NULL; result = g_app_info_launch (app_info, list, G_APP_LAUNCH_CONTEXT (launch_context), &error); g_object_unref (launch_context); if (!result) { if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_SUPPORTED) { uri = g_file_get_uri (root); uri_scheme = g_uri_parse_scheme (uri); /* FIXME: Present user a dialog to choose another app when the last one failed to handle a file */ g_warning ("Cannot open location: %s\n", error->message); g_free (uri_scheme); g_free (uri); } else { g_warning ("Cannot open app: %s\n", error->message); } g_error_free (error); } g_list_free (list); g_object_unref (root); } static void autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data); static void autorun_dialog_destroy (AutorunDialogData *data) { g_signal_handlers_disconnect_by_func (G_OBJECT (data->mount), G_CALLBACK (autorun_dialog_mount_unmounted), data); gtk_widget_destroy (GTK_WIDGET (data->dialog)); if (data->selected_app != NULL) { g_object_unref (data->selected_app); } g_object_unref (data->mount); g_free (data->x_content_type); g_free (data); } static void autorun_dialog_mount_unmounted (GMount *mount, AutorunDialogData *data) { /* remove the dialog if the media is unmounted */ autorun_dialog_destroy (data); } static void unmount_mount_callback (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error; char *primary; gboolean unmounted; gboolean should_eject; GtkWidget *dialog; should_eject = user_data != NULL; error = NULL; if (should_eject) { unmounted = g_mount_eject_with_operation_finish (G_MOUNT (source_object), res, &error); } else { unmounted = g_mount_unmount_with_operation_finish (G_MOUNT (source_object), res, &error); } if (! unmounted) { if (error->code != G_IO_ERROR_FAILED_HANDLED) { if (should_eject) { primary = g_strdup_printf (_("Unable to eject %p"), source_object); } else { primary = g_strdup_printf (_("Unable to unmount %p"), source_object); } dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", primary); gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", error->message); gtk_widget_show (GTK_WIDGET (dialog)); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); g_free (primary); } } if (error != NULL) { g_error_free (error); } } static void do_unmount (GMount *mount, gboolean should_eject, GtkWindow *window) { GMountOperation *mount_op; mount_op = gtk_mount_operation_new (window); if (should_eject) { g_mount_eject_with_operation (mount, 0, mount_op, NULL, unmount_mount_callback, (gpointer) 1); } else { g_mount_unmount_with_operation (mount, 0, mount_op, NULL, unmount_mount_callback, (gpointer) 0); } g_object_unref (mount_op); } static void autorun_dialog_response (GtkDialog *dialog, gint response, AutorunDialogData *data) { switch (response) { case AUTORUN_DIALOG_RESPONSE_EJECT: do_unmount (data->mount, data->should_eject, GTK_WINDOW (dialog)); break; case GTK_RESPONSE_NONE: /* window was closed */ break; case GTK_RESPONSE_CANCEL: break; case GTK_RESPONSE_OK: /* do the selected action */ if (data->remember) { /* make sure we don't ask again */ csd_autorun_set_preferences (data->x_content_type, TRUE, data->selected_ignore, data->selected_open_folder); if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) { g_app_info_set_as_default_for_type (data->selected_app, data->x_content_type, NULL); } } else { /* make sure we do ask again */ csd_autorun_set_preferences (data->x_content_type, FALSE, FALSE, FALSE); } if (!data->selected_ignore && !data->selected_open_folder && data->selected_app != NULL) { csd_autorun_launch_for_mount (data->mount, data->selected_app); } else if (!data->selected_ignore && data->selected_open_folder) { if (data->open_window_func != NULL) data->open_window_func (data->mount, data->user_data); } break; } autorun_dialog_destroy (data); } static void autorun_always_toggled (GtkToggleButton *togglebutton, AutorunDialogData *data) { data->remember = gtk_toggle_button_get_active (togglebutton); } static gboolean combo_box_enter_ok (GtkWidget *togglebutton, GdkEventKey *event, GtkDialog *dialog) { if (event->keyval == GDK_KEY_KP_Enter || event->keyval == GDK_KEY_Return) { gtk_dialog_response (dialog, GTK_RESPONSE_OK); return TRUE; } return FALSE; } /* returns TRUE if a folder window should be opened */ static gboolean do_autorun_for_content_type (GMount *mount, const char *x_content_type, CsdAutorunOpenWindow open_window_func, gpointer user_data) { AutorunDialogData *data; GtkWidget *dialog; GtkWidget *hbox; GtkWidget *vbox; GtkWidget *label; GtkWidget *combo_box; GtkWidget *always_check_button; GtkWidget *eject_button; GtkWidget *image; char *markup; char *content_description; char *mount_name; GIcon *icon; GdkPixbuf *pixbuf; int icon_size; gboolean user_forced_dialog; gboolean pref_ask; gboolean pref_start_app; gboolean pref_ignore; gboolean pref_open_folder; char *media_greeting; gboolean ret; ret = FALSE; mount_name = NULL; if (g_content_type_is_a (x_content_type, "x-content/win32-software")) { /* don't pop up the dialog anyway if the content type says * windows software. */ goto out; } user_forced_dialog = is_shift_pressed (); csd_autorun_get_preferences (x_content_type, &pref_start_app, &pref_ignore, &pref_open_folder); pref_ask = !pref_start_app && !pref_ignore && !pref_open_folder; if (user_forced_dialog) { goto show_dialog; } if (!pref_ask && !pref_ignore && !pref_open_folder) { GAppInfo *app_info; app_info = g_app_info_get_default_for_type (x_content_type, FALSE); if (app_info != NULL) { csd_autorun_launch_for_mount (mount, app_info); } goto out; } if (pref_open_folder) { ret = TRUE; goto out; } if (pref_ignore) { goto out; } show_dialog: mount_name = g_mount_get_name (mount); dialog = gtk_dialog_new (); gtk_window_set_default_size (GTK_WINDOW (dialog), 450, -1); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); icon = g_mount_get_icon (mount); icon_size = get_icon_size_for_stock_size (GTK_ICON_SIZE_DIALOG); image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG); pixbuf = render_icon (icon, icon_size); gtk_widget_set_halign (image, GTK_ALIGN_CENTER); gtk_widget_set_valign (image, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0); /* also use the icon on the dialog */ gtk_window_set_title (GTK_WINDOW (dialog), mount_name); gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); g_object_unref (icon); if (pixbuf) { g_object_unref (pixbuf); } vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); label = gtk_label_new (NULL); /* Customize greeting for well-known x-content types */ if (strcmp (x_content_type, "x-content/audio-cdda") == 0) { media_greeting = _("You have just inserted an Audio CD."); } else if (strcmp (x_content_type, "x-content/audio-dvd") == 0) { media_greeting = _("You have just inserted an Audio DVD."); } else if (strcmp (x_content_type, "x-content/video-dvd") == 0) { media_greeting = _("You have just inserted a Video DVD."); } else if (strcmp (x_content_type, "x-content/video-vcd") == 0) { media_greeting = _("You have just inserted a Video CD."); } else if (strcmp (x_content_type, "x-content/video-svcd") == 0) { media_greeting = _("You have just inserted a Super Video CD."); } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) { media_greeting = _("You have just inserted a blank CD."); } else if (strcmp (x_content_type, "x-content/blank-dvd") == 0) { media_greeting = _("You have just inserted a blank DVD."); } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) { media_greeting = _("You have just inserted a blank Blu-Ray disc."); } else if (strcmp (x_content_type, "x-content/blank-cd") == 0) { media_greeting = _("You have just inserted a blank HD DVD."); } else if (strcmp (x_content_type, "x-content/image-photocd") == 0) { media_greeting = _("You have just inserted a Photo CD."); } else if (strcmp (x_content_type, "x-content/image-picturecd") == 0) { media_greeting = _("You have just inserted a Picture CD."); } else if (strcmp (x_content_type, "x-content/image-dcf") == 0) { media_greeting = _("You have just inserted a medium with digital photos."); } else if (strcmp (x_content_type, "x-content/audio-player") == 0) { media_greeting = _("You have just inserted a digital audio player."); } else if (g_content_type_is_a (x_content_type, "x-content/software")) { media_greeting = _("You have just inserted a medium with software intended to be automatically started."); } else { /* fallback to generic greeting */ media_greeting = _("You have just inserted a medium."); } markup = g_strdup_printf ("%s %s", media_greeting, _("Choose what application to launch.")); gtk_label_set_markup (GTK_LABEL (label), markup); g_free (markup); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_xalign (GTK_LABEL (label), 0.0); gtk_label_set_yalign (GTK_LABEL (label), 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); label = gtk_label_new (NULL); content_description = g_content_type_get_description (x_content_type); markup = g_strdup_printf (_("Select how to open \"%s\" and whether to perform this action in the future for other media of type \"%s\"."), mount_name, content_description); g_free (content_description); gtk_label_set_markup (GTK_LABEL (label), markup); g_free (markup); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_xalign (GTK_LABEL (label), 0.0); gtk_label_set_yalign (GTK_LABEL (label), 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); data = g_new0 (AutorunDialogData, 1); data->dialog = dialog; data->mount = g_object_ref (mount); data->remember = !pref_ask; data->selected_ignore = pref_ignore; data->x_content_type = g_strdup (x_content_type); data->selected_app = g_app_info_get_default_for_type (x_content_type, FALSE); data->open_window_func = open_window_func; data->user_data = user_data; combo_box = gtk_app_chooser_button_new (x_content_type); prepare_combo_box (combo_box, data); g_signal_connect (G_OBJECT (combo_box), "key-press-event", G_CALLBACK (combo_box_enter_ok), dialog); gtk_box_pack_start (GTK_BOX (vbox), combo_box, TRUE, TRUE, 0); always_check_button = gtk_check_button_new_with_mnemonic (_("_Always perform this action")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (always_check_button), data->remember); g_signal_connect (G_OBJECT (always_check_button), "toggled", G_CALLBACK (autorun_always_toggled), data); gtk_box_pack_start (GTK_BOX (vbox), always_check_button, TRUE, TRUE, 0); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Ok"), GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); if (g_mount_can_eject (mount)) { eject_button = gtk_button_new_with_mnemonic (_("_Eject")); data->should_eject = TRUE; } else { eject_button = gtk_button_new_with_mnemonic (_("_Unmount")); data->should_eject = FALSE; } gtk_dialog_add_action_widget (GTK_DIALOG (dialog), eject_button, AUTORUN_DIALOG_RESPONSE_EJECT); gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), eject_button, TRUE); /* show the dialog */ gtk_widget_show_all (dialog); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (autorun_dialog_response), data); g_signal_connect (G_OBJECT (data->mount), "unmounted", G_CALLBACK (autorun_dialog_mount_unmounted), data); out: g_free (mount_name); return ret; } typedef struct { GMount *mount; CsdAutorunOpenWindow open_window_func; gpointer user_data; GSettings *settings; } AutorunData; static void autorun_guessed_content_type_callback (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error; char **guessed_content_type; AutorunData *data = user_data; gboolean open_folder; open_folder = FALSE; error = NULL; guessed_content_type = g_mount_guess_content_type_finish (G_MOUNT (source_object), res, &error); g_object_set_data_full (source_object, "csd-content-type-cache", g_strdupv (guessed_content_type), (GDestroyNotify)g_strfreev); if (error != NULL) { g_warning ("Unable to guess content type for mount: %s", error->message); g_error_free (error); } else { if (guessed_content_type != NULL && g_strv_length (guessed_content_type) > 0) { int n; for (n = 0; guessed_content_type[n] != NULL; n++) { if (do_autorun_for_content_type (data->mount, guessed_content_type[n], data->open_window_func, data->user_data)) { open_folder = TRUE; } } g_strfreev (guessed_content_type); } else { if (g_settings_get_boolean (data->settings, "automount-open")) { open_folder = TRUE; } } } /* only open the folder once.. */ if (open_folder && data->open_window_func != NULL) { data->open_window_func (data->mount, data->user_data); } g_object_unref (data->mount); g_object_unref (data->settings); g_free (data); } void csd_autorun (GMount *mount, GSettings *settings, CsdAutorunOpenWindow open_window_func, gpointer user_data) { AutorunData *data; if (!should_autorun_mount (mount) || g_settings_get_boolean (settings, "autorun-never")) { return; } data = g_new0 (AutorunData, 1); data->mount = g_object_ref (mount); data->open_window_func = open_window_func; data->user_data = user_data; data->settings = g_object_ref (settings); g_mount_guess_content_type (mount, FALSE, NULL, autorun_guessed_content_type_callback, data); } static gboolean remove_allow_volume (gpointer data) { GVolume *volume = data; g_object_set_data (G_OBJECT (volume), "csd-allow-autorun", NULL); return FALSE; } void csd_allow_autorun_for_volume (GVolume *volume) { g_object_set_data (G_OBJECT (volume), "csd-allow-autorun", GINT_TO_POINTER (1)); } #define INHIBIT_AUTORUN_SECONDS 10 void csd_allow_autorun_for_volume_finish (GVolume *volume) { if (g_object_get_data (G_OBJECT (volume), "csd-allow-autorun") != NULL) { g_timeout_add_seconds_full (0, INHIBIT_AUTORUN_SECONDS, remove_allow_volume, g_object_ref (volume), g_object_unref); } } static gboolean should_skip_native_mount_root (GFile *root) { char *path; gboolean should_skip; /* skip any mounts in hidden directory hierarchies */ path = g_file_get_path (root); should_skip = strstr (path, "/.") != NULL; g_free (path); return should_skip; } static gboolean should_autorun_mount (GMount *mount) { GFile *root; GVolume *enclosing_volume; gboolean ignore_autorun; ignore_autorun = TRUE; enclosing_volume = g_mount_get_volume (mount); if (enclosing_volume != NULL) { if (g_object_get_data (G_OBJECT (enclosing_volume), "csd-allow-autorun") != NULL) { ignore_autorun = FALSE; g_object_set_data (G_OBJECT (enclosing_volume), "csd-allow-autorun", NULL); } } if (ignore_autorun) { if (enclosing_volume != NULL) { g_object_unref (enclosing_volume); } return FALSE; } root = g_mount_get_root (mount); /* only do autorun on local files or files where g_volume_should_automount() returns TRUE */ ignore_autorun = TRUE; if ((g_file_is_native (root) && !should_skip_native_mount_root (root)) || (enclosing_volume != NULL && g_volume_should_automount (enclosing_volume))) { ignore_autorun = FALSE; } if (enclosing_volume != NULL) { g_object_unref (enclosing_volume); } g_object_unref (root); return !ignore_autorun; } void csd_autorun_for_content_type (GMount *mount, const gchar *content_type, CsdAutorunOpenWindow callback, gpointer user_data) { do_autorun_for_content_type (mount, content_type, callback, user_data); } cinnamon-settings-daemon-6.4.3/plugins/automount/test-automount-dialog.c0000664000175000017500000000415414733247605025515 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * save-session.c - Small program to talk to session manager. Copyright (C) 1998 Tom Tromey Copyright (C) 2008 Red Hat, Inc. 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 Street - Suite 500, Boston, MA 02110-1335, USA. */ #include #include #include #include #include #include #include #include "csd-autorun.h" static void autorun_show_window (GMount *mount, gpointer user_data) { gtk_main_quit (); } int main (int argc, char *argv[]) { GVolumeMonitor *monitor; GError *error; GList *mounts; error = NULL; if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { g_warning ("Unable to start: %s", error->message); g_error_free (error); exit (1); } if (argc != 2) { g_print ("Need one argument as content type\n"); exit (1); } monitor = g_volume_monitor_get (); mounts = g_volume_monitor_get_mounts (monitor); if (mounts) { GMount *mount = G_MOUNT (mounts->data); csd_autorun_for_content_type (mount, argv[1], (CsdAutorunOpenWindow) autorun_show_window, NULL); } gtk_main (); gtk_main_quit (); return 0; } cinnamon-settings-daemon-6.4.3/plugins/automount/csd-autorun.h0000664000175000017500000000360514733247605023521 0ustar fabiofabio/* * csd-automount.h:helpers for automounting hotplugged volumes * * Copyright (C) 2008 Red Hat, Inc. * * Nautilus 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA * * Authors: David Zeuthen * Cosimo Cecchi */ /* TODO: * * - unmount all the media we've automounted on shutdown * - finish x-content / * types * - finalize the semi-spec * - add probing/sniffing code * - implement missing features * - "Open Folder when mounted" * - Autorun spec (e.g. $ROOT/.autostart) * */ #ifndef __CSD_AUTORUN_H__ #define __CSD_AUTORUN_H__ #include #include typedef void (*CsdAutorunOpenWindow) (GMount *mount, gpointer user_data); void csd_autorun (GMount *mount, GSettings *settings, CsdAutorunOpenWindow open_window_func, gpointer user_data); void csd_autorun_for_content_type (GMount *mount, const gchar *content_type, CsdAutorunOpenWindow callback, gpointer user_data); void csd_allow_autorun_for_volume (GVolume *volume); void csd_allow_autorun_for_volume_finish (GVolume *volume); #endif /* __CSD_AUTORUN_H__ */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/0000775000175000017500000000000014733247605021075 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/xsettings/fontconfig-monitor.h0000664000175000017500000000254414733247605025074 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2008 Red Hat, Inc. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Behdad Esfahbod, Red Hat, Inc. */ #ifndef __FONTCONFIG_MONITOR_H #define __FONTCONFIG_MONITOR_H #include G_BEGIN_DECLS void fontconfig_cache_init (void); gboolean fontconfig_cache_update (void); typedef struct _fontconfig_monitor_handle fontconfig_monitor_handle_t; fontconfig_monitor_handle_t * fontconfig_monitor_start (GFunc notify_callback, gpointer notify_data); void fontconfig_monitor_stop (fontconfig_monitor_handle_t *handle); G_END_DECLS #endif /* __FONTCONFIG_MONITOR_H */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/csd-xsettings-manager.h0000664000175000017500000000514714733247605025464 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CINNAMON_XSETTINGS_MANAGER_H #define __CINNAMON_XSETTINGS_MANAGER_H #include G_BEGIN_DECLS #define CINNAMON_TYPE_XSETTINGS_MANAGER (cinnamon_xsettings_manager_get_type ()) #define CINNAMON_XSETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CINNAMON_TYPE_XSETTINGS_MANAGER, CinnamonSettingsXSettingsManager)) #define CINNAMON_XSETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CINNAMON_TYPE_XSETTINGS_MANAGER, CinnamonSettingsXSettingsManagerClass)) #define CINNAMON_IS_XSETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CINNAMON_TYPE_XSETTINGS_MANAGER)) #define CINNAMON_IS_XSETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CINNAMON_TYPE_XSETTINGS_MANAGER)) #define CINNAMON_XSETTINGS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CINNAMON_TYPE_XSETTINGS_MANAGER, CinnamonSettingsXSettingsManagerClass)) typedef struct CinnamonSettingsXSettingsManagerPrivate CinnamonSettingsXSettingsManagerPrivate; typedef struct { GObject parent; CinnamonSettingsXSettingsManagerPrivate *priv; } CinnamonSettingsXSettingsManager; typedef struct { GObjectClass parent_class; } CinnamonSettingsXSettingsManagerClass; GType cinnamon_xsettings_manager_get_type (void); CinnamonSettingsXSettingsManager * cinnamon_xsettings_manager_new (void); gboolean cinnamon_xsettings_manager_start (CinnamonSettingsXSettingsManager *manager, GError **error); void cinnamon_xsettings_manager_stop (CinnamonSettingsXSettingsManager *manager); G_END_DECLS #endif /* __CINNAMON_XSETTINGS_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/xsettings-common.c0000664000175000017500000000561414733247605024565 0ustar fabiofabio/* * Copyright © 2001 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Owen Taylor, Red Hat, Inc. */ #include #include "string.h" #include "stdlib.h" #include #include /* For CARD32 */ #include "xsettings-common.h" XSettingsSetting * xsettings_setting_new (const gchar *name) { XSettingsSetting *result; result = g_slice_new0 (XSettingsSetting); result->name = g_strdup (name); return result; } static gboolean xsettings_variant_equal0 (GVariant *a, GVariant *b) { if (a == b) return TRUE; if (!a || !b) return FALSE; return g_variant_equal (a, b); } GVariant * xsettings_setting_get (XSettingsSetting *setting) { gint i; for (i = G_N_ELEMENTS (setting->value) - 1; 0 <= i; i--) if (setting->value[i]) return setting->value[i]; return NULL; } void xsettings_setting_set (XSettingsSetting *setting, gint tier, GVariant *value, guint32 serial) { GVariant *old_value; old_value = xsettings_setting_get (setting); if (old_value) g_variant_ref (old_value); if (setting->value[tier]) g_variant_unref (setting->value[tier]); setting->value[tier] = value ? g_variant_ref_sink (value) : NULL; if (!xsettings_variant_equal0 (old_value, xsettings_setting_get (setting))) setting->last_change_serial = serial; if (old_value) g_variant_unref (old_value); } void xsettings_setting_free (XSettingsSetting *setting) { gint i; for (i = 0; i < G_N_ELEMENTS (setting->value); i++) if (setting->value[i]) g_variant_unref (setting->value[i]); g_free (setting->name); g_slice_free (XSettingsSetting, setting); } char xsettings_byte_order (void) { CARD32 myint = 0x01020304; return (*(char *)&myint == 1) ? MSBFirst : LSBFirst; } cinnamon-settings-daemon-6.4.3/plugins/xsettings/xsettings-common.h0000664000175000017500000000442714733247605024573 0ustar fabiofabio/* * Copyright © 2001 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Owen Taylor, Red Hat, Inc. */ #ifndef XSETTINGS_COMMON_H #define XSETTINGS_COMMON_H #include #define XSETTINGS_N_TIERS 2 typedef struct _XSettingsColor XSettingsColor; typedef struct _XSettingsSetting XSettingsSetting; /* Types of settings possible. Enum values correspond to * protocol values. */ typedef enum { XSETTINGS_TYPE_INT = 0, XSETTINGS_TYPE_STRING = 1, XSETTINGS_TYPE_COLOR = 2 } XSettingsType; struct _XSettingsColor { unsigned short red, green, blue, alpha; }; struct _XSettingsSetting { char *name; GVariant *value[XSETTINGS_N_TIERS]; unsigned long last_change_serial; }; XSettingsSetting *xsettings_setting_new (const gchar *name); GVariant * xsettings_setting_get (XSettingsSetting *setting); void xsettings_setting_set (XSettingsSetting *setting, gint tier, GVariant *value, guint32 serial); void xsettings_setting_free (XSettingsSetting *setting); char xsettings_byte_order (void); #endif /* XSETTINGS_COMMON_H */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/meson.build0000664000175000017500000000310214733247605023233 0ustar fabiofabioplugin_name = 'xsettings' xsettings_common_sources = [ 'csd-xsettings-gtk.c', ] xsettings_sources = [ 'csd-xsettings-manager.c', 'xsettings-common.c', 'xsettings-manager.c', 'fontconfig-monitor.c', 'main.c', xsettings_common_sources, ] test_xsettings_sources = [ 'test-gtk-modules.c', xsettings_common_sources, ] xsettings_deps = [ cinnamon_desktop, common_dep, csd_dep, fontconfig, libnotify, ] executable( 'csd-xsettings', xsettings_sources, include_directories: [include_dirs, common_inc, include_enums], dependencies: xsettings_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), '-DGTK_MODULES_DIRECTORY="@0@/@1@/cinnamon-settings-daemon-@2@/gtk-modules/"'.format(prefix, libdir, api_version), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-xsettings') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-xsettings') endif executable( 'test-gtk-modules', test_xsettings_sources, include_directories: [include_dirs, common_inc], dependencies: xsettings_deps, c_args: [ '-DGTK_MODULES_DIRECTORY="@0@/@1@/cinnamon-settings-daemon-@2@/gtk-modules/"'.format(prefix, libdir, api_version), ], ) configure_file( input: 'cinnamon-settings-daemon-xsettings.desktop.in', output: 'cinnamon-settings-daemon-xsettings.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/xsettings/cinnamon-settings-daemon-xsettings.desktop.in0000664000175000017500000000034214733247605032023 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - xsettings Exec=csd-xsettings OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/xsettings/csd-xsettings-manager.c0000664000175000017500000017603414733247605025463 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 Rodrigo Moya * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-enums.h" #include "csd-xsettings-manager.h" #include "csd-xsettings-gtk.h" #include "xsettings-manager.h" #include "fontconfig-monitor.h" #include "migrate-settings.h" #define GNOME_DESKTOP_USE_UNSTABLE_API #include #define CINNAMON_XSETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CINNAMON_TYPE_XSETTINGS_MANAGER, CinnamonSettingsXSettingsManagerPrivate)) #define MOUSE_SETTINGS_SCHEMA "org.cinnamon.desktop.peripherals.mouse" #define INTERFACE_SETTINGS_SCHEMA "org.cinnamon.desktop.interface" #define INTERFACE_WM_SETTINGS_SCHEMA "org.cinnamon.desktop.wm.preferences" #define SOUND_SETTINGS_SCHEMA "org.cinnamon.desktop.sound" #define PRIVACY_SETTINGS_SCHEMA "org.cinnamon.desktop.privacy" #define KEYBOARD_A11Y_SCHEMA "org.cinnamon.desktop.a11y.keyboard" #define XSETTINGS_PLUGIN_SCHEMA "org.cinnamon.settings-daemon.plugins.xsettings" #define XSETTINGS_OVERRIDE_KEY "overrides" #define GTK_MODULES_DISABLED_KEY "disabled-gtk-modules" #define GTK_MODULES_ENABLED_KEY "enabled-gtk-modules" #define TEXT_SCALING_FACTOR_KEY "text-scaling-factor" #define SCALING_FACTOR_KEY "scaling-factor" #define CURSOR_SIZE_KEY "cursor-size" #define ANIMATIONS_KEY "enable-animations" #define FONT_ANTIALIASING_KEY "antialiasing" #define FONT_HINTING_KEY "hinting" #define FONT_RGBA_ORDER_KEY "rgba-order" /* As we cannot rely on the X server giving us good DPI information, and * that we don't want multi-monitor screens to have different DPIs (thus * different text sizes), we'll hard-code the value of the DPI * * See also: * https://bugzilla.novell.com/show_bug.cgi?id=217790• * https://bugzilla.gnome.org/show_bug.cgi?id=643704 * * http://lists.fedoraproject.org/pipermail/devel/2011-October/157671.html * Why EDID is not trustworthy for DPI * Adam Jackson ajax at redhat.com * Tue Oct 4 17:54:57 UTC 2011 * * Previous message: GNOME 3 - font point sizes now scaled? * Next message: Why EDID is not trustworthy for DPI * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] * * On Tue, 2011-10-04 at 11:46 -0400, Kaleb S. KEITHLEY wrote: * * > Grovelling around in the F15 xorg-server sources and reviewing the Xorg * > log file on my F15 box, I see, with _modern hardware_ at least, that we * > do have the monitor geometry available from DDC or EDIC, and obviously * > it is trivial to compute the actual, correct DPI for each screen. * * I am clearly going to have to explain this one more time, forever. * Let's see if I can't write it authoritatively once and simply answer * with a URL from here out. (As always, use of the second person "you" * herein is plural, not singular.) * * EDID does not reliably give you the size of the display. * * Base EDID has at least two different places where you can give a * physical size (before considering extensions that aren't widely deployed * so whatever). The first is a global property, measured in centimeters, * of the physical size of the glass. The second is attached to your (zero * or more) detailed timing specifications, and reflects the size of the * mode, in millimeters. * * So, how does this screw you? * * a) Glass size is too coarse. On a large display that cm roundoff isn't * a big deal, but on subnotebooks it's a different game. The 11" MBA is * 25.68x14.44 cm, so that gives you a range of 52.54-54.64 dpcm horizontal * and 51.20-54.86 dpcm vertical (133.4-138.8 dpi h and 130.0-139.3 dpi v). * Which is optimistic, because that's doing the math forward from knowing * the actual size, and you as the EDID parser can't know which way the * manufacturer rounded. * * b) Glass size need not be non-zero. This is in fact the usual case for * projectors, which don't have a fixed display size since it's a function * of how far away the wall is from the lens. * * c) Glass size could be partially non-zero. Yes, really. EDID 1.4 * defines a method of using these two bytes to encode aspect ratio, where * if vertical size is 0 then the aspect ratio is computed as (horizontal * value + 99) / 100 in portrait mode (and the obvious reverse thing if * horizontal is zero). Admittedly, unlike every other item in this list, * I've never seen this in the wild. But it's legal. * * d) Glass size could be a direct encoding of the aspect ratio. Base EDID * doesn't condone this behaviour, but the CEA spec (to which all HDMI * monitors must conform) does allow-but-not-require it, which means your * 1920x1080 TV could claim to be 16 "cm" by 9 "cm". So of course that's * what TV manufacturers do because that way they don't have to modify the * EDID info when physical construction changes, and that's cheaper. * * e) You could use mode size to get size in millimeters, but you might not * have any detailed timings. * * f) You could use mode size, but mode size is explicitly _not_ glass * size. It's the size that the display chooses to present that mode. * Sometimes those are the same, and sometimes they're not. You could be * scaled or {letter,pillar}boxed, and that's not necessarily something you * can control from the host side. * * g) You could use mode size, but it could be an encoded aspect ratio, as * in case d above, because CEA says that's okay. * * h) You could use mode size, but it could be the aspect ratio from case d * multiplied by 10 in each direction (because, of course, you gave size in * centimeters and so your authoring tool just multiplied it up). * * i) Any or all of the above could be complete and utter garbage, because * - and I really, really need you to understand this - there is no * requirements program for any commercial OS or industry standard that * requires honesty here, as far as I'm aware. There is every incentive * for there to _never_ be one, because it would make the manufacturing * process more expensive. * * So from this point the suggestion is usually "well come up with some * heuristic to make a good guess assuming there's some correlation between * the various numbers you're given". I have in fact written heuristics * for this, and they're in your kernel and your X server, and they still * encounter a huge number of cases where we simply _cannot_ know from EDID * anything like a physical size, because - to pick only one example - the * consumer electronics industry are cheap bastards, because you the * consumer demanded that they be cheap. * * And then your only recourse is to an external database, and now you're * up the creek again because the identifying information here is a * vendor/model/serial tuple, and the vendor can and does change physical * construction without changing model number. Now you get to play the * guessing game of how big the serial number range is for each subvariant, * assuming they bothered to encode a serial number - and they didn't. Or, * if they bothered to encode week/year of manufacturer correctly - and * they didn't - which weeks meant which models. And then you still have * to go out and buy one of every TV at Fry's, and that covers you for one * market, for three months. * * If someone wants to write something better, please, by all means. If * it's kernel code, send it to dri-devel at lists.freedesktop.org and cc me * and I will happily review it. Likewise xorg-devel@ for X server * changes. * * I gently suggest that doing so is a waste of time. * * But if there's one thing free software has taught me, it's that you can * not tell people something is a bad idea and have any expectation they * will believe you. * * > Obviously in a multi-screen set-up using Xinerama this has the potential * > to be a Hard Problem if the monitors differ greatly in their DPI. * > * > If the major resistance is over what to do with older hardware that * > doesn't have this data available, then yes, punt; use a hard-coded * > default. Likewise, if the two monitors really differ greatly, then punt. * * I'm going to limit myself to observing that "greatly" is a matter of * opinion, and that in order to be really useful you'd need some way of * communicating "I punted" to the desktop. * * Beyond that, sure, pick a heuristic, accept that it's going to be * insufficient for someone, and then sit back and wait to get * second-guessed on it over and over. * * > And it wouldn't be so hard to to add something like -dpi:0, -dpi:1, * > -dpi:2 command line options to specify per-screen dpi. I kinda thought I * > did that a long, long time ago, but maybe I only thought about doing it * > and never actually got around to it. * * The RANDR extension as of version 1.2 does allow you to override * physical size on a per-output basis at runtime. We even try pretty hard * to set them as honestly as we can up front. The 96dpi thing people * complain about is from the per-screen info, which is simply a default * because of all the tl;dr above; because you have N outputs per screen * which means a single number is in general useless; and because there is * no way to refresh the per-screen info at runtime, as it's only ever sent * in the initial connection handshake. * * - ajax * */ #define DPI_FALLBACK 96 typedef struct _TranslationEntry TranslationEntry; typedef void (* TranslationFunc) (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value); struct _TranslationEntry { const char *gsettings_schema; const char *gsettings_key; const char *xsetting_name; TranslationFunc translate; }; struct CinnamonSettingsXSettingsManagerPrivate { guint start_idle_id; XSettingsManager **managers; GHashTable *settings; GSettings *plugin_settings; fontconfig_monitor_handle_t *fontconfig_handle; CsdXSettingsGtk *gtk; GDBusConnection *dbus_connection; guint cinnamon_properties_changed_id; guint cinnamon_name_watch_id; gboolean enable_animations; guint display_config_watch_id; guint monitors_changed_id; guint notify_idle_id; }; #define CSD_XSETTINGS_ERROR csd_xsettings_error_quark () enum { CSD_XSETTINGS_ERROR_INIT }; static void cinnamon_xsettings_manager_finalize (GObject *object); static void animations_enabled_changed (CinnamonSettingsXSettingsManager *manager); G_DEFINE_TYPE (CinnamonSettingsXSettingsManager, cinnamon_xsettings_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static GQuark csd_xsettings_error_quark (void) { return g_quark_from_static_string ("csd-xsettings-error-quark"); } static void set_session_bus_id (CinnamonSettingsXSettingsManager *manager) { const gchar *id; GDBusConnection *bus; GVariant *res; bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); res = g_dbus_connection_call_sync (bus, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); if (res) { g_variant_get (res, "(&s)", &id); int i; for (i = 0; manager->priv->managers[i]; i++) { xsettings_manager_set_string (manager->priv->managers[i], "Gtk/SessionBusId", id); } g_variant_unref (res); } g_object_unref (bus); } static void translate_bool_int (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { int i; for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_int (manager->priv->managers [i], trans->xsetting_name, g_variant_get_boolean (value)); } } static void translate_int_int (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { int i; for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_int (manager->priv->managers [i], trans->xsetting_name, g_variant_get_int32 (value)); } } static void translate_string_string (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { int i; for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_string (manager->priv->managers [i], trans->xsetting_name, g_variant_get_string (value, NULL)); } } static void translate_string_string_toolbar (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { int i; const char *tmp; /* This is kind of a workaround since GNOME expects the key value to be * "both_horiz" and gtk+ wants the XSetting to be "both-horiz". */ tmp = g_variant_get_string (value, NULL); if (tmp && strcmp (tmp, "both_horiz") == 0) { tmp = "both-horiz"; } for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_string (manager->priv->managers [i], trans->xsetting_name, tmp); } } static void translate_string_string_window_buttons (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { int i; const char *tmp; gchar *ptr, *final_str; /* This is kind of a workaround. "menu" is useless in metacity titlebars * it duplicates the same features as the right-click menu. * In CSD windows on the hand it is required to show unique features. */ tmp = g_variant_get_string (value, NULL); /* Check if menu is in the setting string already */ ptr = g_strstr_len (tmp, -1, "menu"); if (!ptr) { /* If it wasn't there already, we add it... */ /* Simple cases, :* - all items on right, just prepend menu on left side*/ if (g_str_has_prefix (tmp, ":")) { final_str = g_strdup_printf ("menu%s", tmp); } else /* All items on left... * (no :), append menu - we want actual window controls on the outside */ if (!g_strstr_len (tmp, -1, ":")) { final_str = g_strdup_printf ("%s,menu", tmp); } else { /* Items on both sides, split it, append menu to the lefthand, and re- * construct the string with the : separator */ gchar **split = g_strsplit (tmp, ":", 2); final_str = g_strdup_printf ("%s,menu:%s", split[0], split[1]); g_strfreev (split); } } else { /* If menu was already included, just copy the original string */ final_str = g_strdup (tmp); } for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_string (manager->priv->managers [i], trans->xsetting_name, final_str); } g_free (final_str); } static void translate_enable_animations (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { animations_enabled_changed (manager); } static TranslationEntry translations [] = { { "org.cinnamon.settings-daemon.plugins.xsettings", "menus-have-icons", "Gtk/MenuImages", translate_bool_int }, { "org.cinnamon.settings-daemon.plugins.xsettings", "buttons-have-icons", "Gtk/ButtonImages", translate_bool_int }, { "org.cinnamon.settings-daemon.plugins.xsettings", "show-input-method-menu", "Gtk/ShowInputMethodMenu", translate_bool_int }, { "org.cinnamon.settings-daemon.plugins.xsettings", "show-unicode-menu", "Gtk/ShowUnicodeMenu", translate_bool_int }, { "org.cinnamon.settings-daemon.plugins.xsettings", "automatic-mnemonics", "Gtk/AutoMnemonics", translate_bool_int }, { "org.cinnamon.settings-daemon.plugins.xsettings", "dialogs-use-header", "Gtk/DialogsUseHeader", translate_bool_int }, { "org.cinnamon.desktop.interface", "gtk-color-palette", "Gtk/ColorPalette", translate_string_string }, { "org.cinnamon.desktop.interface", "font-name", "Gtk/FontName", translate_string_string }, { "org.cinnamon.desktop.interface", "gtk-key-theme", "Gtk/KeyThemeName", translate_string_string }, { "org.cinnamon.desktop.interface", "toolbar-style", "Gtk/ToolbarStyle", translate_string_string_toolbar }, { "org.cinnamon.desktop.interface", "toolbar-icons-size", "Gtk/ToolbarIconSize", translate_string_string }, { "org.cinnamon.desktop.interface", "can-change-accels", "Gtk/CanChangeAccels", translate_bool_int }, { "org.cinnamon.desktop.interface", "cursor-blink-timeout", "Gtk/CursorBlinkTimeout", translate_int_int }, { "org.cinnamon.desktop.interface", "gtk-timeout-initial", "Gtk/TimeoutInitial", translate_int_int }, { "org.cinnamon.desktop.interface", "gtk-timeout-repeat", "Gtk/TimeoutRepeat", translate_int_int }, { "org.cinnamon.desktop.interface", "gtk-color-scheme", "Gtk/ColorScheme", translate_string_string }, { "org.cinnamon.desktop.interface", "gtk-im-preedit-style", "Gtk/IMPreeditStyle", translate_string_string }, { "org.cinnamon.desktop.interface", "gtk-im-status-style", "Gtk/IMStatusStyle", translate_string_string }, { "org.cinnamon.desktop.interface", "gtk-im-module", "Gtk/IMModule", translate_string_string }, { "org.cinnamon.desktop.interface", "menubar-accel", "Gtk/MenuBarAccel", translate_string_string }, { "org.cinnamon.desktop.interface", "enable-animations", "Gtk/EnableAnimations", translate_enable_animations }, { "org.cinnamon.desktop.interface", "cursor-theme", "Gtk/CursorThemeName", translate_string_string }, { "org.cinnamon.desktop.interface", "gtk-enable-primary-paste", "Gtk/EnablePrimaryPaste", translate_bool_int }, { "org.cinnamon.desktop.interface", "gtk-overlay-scrollbars", "Gtk/OverlayScrolling", translate_bool_int }, { "org.cinnamon.desktop.wm.preferences", "button-layout", "Gtk/DecorationLayout", translate_string_string_window_buttons }, { "org.cinnamon.desktop.wm.preferences", "action-double-click-titlebar", "Gtk/TitlebarDoubleClick", translate_string_string }, { "org.cinnamon.desktop.wm.preferences", "action-middle-click-titlebar", "Gtk/TitlebarMiddleClick", translate_string_string }, { "org.cinnamon.desktop.wm.preferences", "action-right-click-titlebar", "Gtk/TitlebarRightClick", translate_string_string }, { "org.cinnamon.desktop.privacy", "recent-files-max-age", "Gtk/RecentFilesMaxAge", translate_int_int }, { "org.cinnamon.desktop.privacy", "remember-recent-files", "Gtk/RecentFilesEnabled", translate_bool_int }, { "org.cinnamon.desktop.a11y.keyboard", "always-show-text-caret", "Gtk/KeynavUseCaret", translate_bool_int }, { "org.cinnamon.desktop.peripherals.mouse", "double-click", "Net/DoubleClickTime", translate_int_int }, { "org.cinnamon.desktop.peripherals.mouse", "drag-threshold", "Net/DndDragThreshold", translate_int_int }, { "org.cinnamon.desktop.interface", "cursor-blink", "Net/CursorBlink", translate_bool_int }, { "org.cinnamon.desktop.interface", "cursor-blink-time", "Net/CursorBlinkTime", translate_int_int }, { "org.cinnamon.desktop.interface", "gtk-theme", "Net/ThemeName", translate_string_string }, { "org.cinnamon.desktop.interface", "icon-theme", "Net/IconThemeName", translate_string_string }, { "org.cinnamon.desktop.sound", "theme-name", "Net/SoundThemeName", translate_string_string }, { "org.cinnamon.desktop.sound", "event-sounds", "Net/EnableEventSounds" , translate_bool_int }, { "org.cinnamon.desktop.sound", "input-feedback-sounds", "Net/EnableInputFeedbackSounds", translate_bool_int } }; static gboolean notify_idle (gpointer data) { CinnamonSettingsXSettingsManager *manager = data; gint i; for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_notify (manager->priv->managers[i]); } manager->priv->notify_idle_id = 0; return G_SOURCE_REMOVE; } static void queue_notify (CinnamonSettingsXSettingsManager *manager) { if (manager->priv->notify_idle_id != 0) return; manager->priv->notify_idle_id = g_idle_add (notify_idle, manager); } static double get_dpi_from_gsettings (CinnamonSettingsXSettingsManager *manager) { GSettings *interface_settings; double dpi; double factor; interface_settings = g_hash_table_lookup (manager->priv->settings, INTERFACE_SETTINGS_SCHEMA); factor = g_settings_get_double (interface_settings, TEXT_SCALING_FACTOR_KEY); dpi = DPI_FALLBACK; return dpi * factor; } static gboolean get_legacy_ui_scale (GVariantIter *properties, int *scale) { const char *key; GVariant *value; *scale = 0; while (g_variant_iter_loop (properties, "{&sv}", &key, &value)) { if (!g_str_equal (key, "legacy-ui-scaling-factor")) continue; *scale = g_variant_get_int32 (value); break; } if (*scale < 1) { g_warning ("Failed to get current UI legacy scaling factor"); *scale = 1; return FALSE; } return TRUE; } #define MODE_FORMAT "(siiddada{sv})" #define MODES_FORMAT "a" MODE_FORMAT #define MONITOR_SPEC_FORMAT "(ssss)" #define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})" #define MONITORS_FORMAT "a" MONITOR_FORMAT #define LOGICAL_MONITOR_FORMAT "(iiduba" MONITOR_SPEC_FORMAT "a{sv})" #define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT #define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "a{sv})" static int get_window_scale (CinnamonSettingsXSettingsManager *manager) { g_autoptr(GError) error = NULL; g_autoptr(GVariant) current_state = NULL; g_autoptr(GVariantIter) properties = NULL; int scale = 1; current_state = g_dbus_connection_call_sync (manager->priv->dbus_connection, "org.cinnamon.Muffin.DisplayConfig", "/org/cinnamon/Muffin/DisplayConfig", "org.cinnamon.Muffin.DisplayConfig", "GetCurrentState", NULL, NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error); if (!current_state) { g_debug ("Failed to get current display configuration state: %s", error->message); return 1; } g_variant_get (current_state, CURRENT_STATE_FORMAT, NULL, NULL, NULL, &properties); if (!get_legacy_ui_scale (properties, &scale)) g_warning ("Failed to get current UI legacy scaling factor"); return scale; } typedef struct { gboolean antialias; gboolean hinting; int scaled_dpi; int dpi; int window_scale; int cursor_size; const char *rgba; const char *hintstyle; } CinnamonSettingsXftSettings; /* Read GSettings and determine the appropriate Xft settings based on them. */ static void xft_settings_get (CinnamonSettingsXSettingsManager *manager, CinnamonSettingsXftSettings *settings) { GSettings *interface_settings; CsdFontAntialiasingMode antialiasing; CsdFontHinting hinting; CsdFontRgbaOrder order; gboolean use_rgba = FALSE; double dpi; int cursor_size; interface_settings = g_hash_table_lookup (manager->priv->settings, INTERFACE_SETTINGS_SCHEMA); antialiasing = g_settings_get_enum (manager->priv->plugin_settings, FONT_ANTIALIASING_KEY); hinting = g_settings_get_enum (manager->priv->plugin_settings, FONT_HINTING_KEY); order = g_settings_get_enum (manager->priv->plugin_settings, FONT_RGBA_ORDER_KEY); settings->antialias = (antialiasing != CSD_FONT_ANTIALIASING_MODE_NONE); settings->hinting = (hinting != CSD_FONT_HINTING_NONE); settings->window_scale = get_window_scale (manager); dpi = get_dpi_from_gsettings (manager); settings->dpi = dpi * 1024; /* Xft wants 1/1024ths of an inch */ settings->scaled_dpi = dpi * settings->window_scale * 1024; cursor_size = g_settings_get_int (interface_settings, CURSOR_SIZE_KEY); settings->cursor_size = cursor_size * settings->window_scale; settings->rgba = "rgb"; settings->hintstyle = "hintfull"; switch (hinting) { case CSD_FONT_HINTING_NONE: settings->hintstyle = "hintnone"; break; case CSD_FONT_HINTING_SLIGHT: settings->hintstyle = "hintslight"; break; case CSD_FONT_HINTING_MEDIUM: settings->hintstyle = "hintmedium"; break; case CSD_FONT_HINTING_FULL: settings->hintstyle = "hintfull"; break; } switch (order) { case CSD_FONT_RGBA_ORDER_RGBA: settings->rgba = "rgba"; break; case CSD_FONT_RGBA_ORDER_RGB: settings->rgba = "rgb"; break; case CSD_FONT_RGBA_ORDER_BGR: settings->rgba = "bgr"; break; case CSD_FONT_RGBA_ORDER_VRGB: settings->rgba = "vrgb"; break; case CSD_FONT_RGBA_ORDER_VBGR: settings->rgba = "vbgr"; break; } switch (antialiasing) { case CSD_FONT_ANTIALIASING_MODE_NONE: settings->antialias = 0; break; case CSD_FONT_ANTIALIASING_MODE_GRAYSCALE: settings->antialias = 1; break; case CSD_FONT_ANTIALIASING_MODE_RGBA: settings->antialias = 1; use_rgba = TRUE; } if (!use_rgba) { settings->rgba = "none"; } } static void xft_settings_set_xsettings (CinnamonSettingsXSettingsManager *manager, CinnamonSettingsXftSettings *settings) { int i; cinnamon_settings_profile_start (NULL); for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_int (manager->priv->managers [i], "Xft/Antialias", settings->antialias); xsettings_manager_set_int (manager->priv->managers [i], "Xft/Hinting", settings->hinting); xsettings_manager_set_string (manager->priv->managers [i], "Xft/HintStyle", settings->hintstyle); xsettings_manager_set_int (manager->priv->managers [i], "Gdk/WindowScalingFactor", settings->window_scale); xsettings_manager_set_int (manager->priv->managers [i], "Gdk/UnscaledDPI", settings->dpi); xsettings_manager_set_int (manager->priv->managers [i], "Xft/DPI", settings->scaled_dpi); xsettings_manager_set_string (manager->priv->managers [i], "Xft/RGBA", settings->rgba); xsettings_manager_set_int (manager->priv->managers [i], "Gtk/CursorThemeSize", settings->cursor_size); xsettings_manager_set_int (manager->priv->managers [i], "Gtk/EnableAnimations", manager->priv->enable_animations); } cinnamon_settings_profile_end (NULL); } static void update_property (GString *props, const gchar* key, const gchar* value) { gchar* needle; size_t needle_len; gchar* found = NULL; /* update an existing property */ needle = g_strconcat (key, ":", NULL); needle_len = strlen (needle); if (g_str_has_prefix (props->str, needle)) found = props->str; else found = strstr (props->str, needle); if (found) { size_t value_index; gchar* end; end = strchr (found, '\n'); value_index = (found - props->str) + needle_len + 1; g_string_erase (props, value_index, end ? (end - found - needle_len) : -1); g_string_insert (props, value_index, "\n"); g_string_insert (props, value_index, value); } else { g_string_append_printf (props, "%s:\t%s\n", key, value); } g_free (needle); } static void xft_settings_set_xresources (CinnamonSettingsXftSettings *settings) { GString *add_string; char dpibuf[G_ASCII_DTOSTR_BUF_SIZE]; Display *dpy; cinnamon_settings_profile_start (NULL); /* get existing properties */ dpy = XOpenDisplay (NULL); g_return_if_fail (dpy != NULL); add_string = g_string_new (XResourceManagerString (dpy)); g_debug("xft_settings_set_xresources: orig res '%s'", add_string->str); g_snprintf (dpibuf, sizeof (dpibuf), "%d", (int) (settings->scaled_dpi / 1024.0 + 0.5)); update_property (add_string, "Xft.dpi", dpibuf); update_property (add_string, "Xft.antialias", settings->antialias ? "1" : "0"); update_property (add_string, "Xft.hinting", settings->hinting ? "1" : "0"); update_property (add_string, "Xft.hintstyle", settings->hintstyle); update_property (add_string, "Xft.rgba", settings->rgba); g_debug("xft_settings_set_xresources: new res '%s'", add_string->str); /* Set the new X property */ XChangeProperty(dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, (const unsigned char *) add_string->str, add_string->len); XCloseDisplay (dpy); g_string_free (add_string, TRUE); cinnamon_settings_profile_end (NULL); } /* We mirror the Xft properties both through XSETTINGS and through * X resources */ static void update_xft_settings (CinnamonSettingsXSettingsManager *manager) { CinnamonSettingsXftSettings settings; cinnamon_settings_profile_start (NULL); xft_settings_get (manager, &settings); xft_settings_set_xsettings (manager, &settings); xft_settings_set_xresources (&settings); cinnamon_settings_profile_end (NULL); } static void xft_callback (GSettings *settings, const gchar *key, CinnamonSettingsXSettingsManager *manager) { update_xft_settings (manager); queue_notify (manager); } static void size_changed_callback (GdkScreen *screen, CinnamonSettingsXSettingsManager *manager) { update_xft_settings (manager); queue_notify (manager); } static void override_callback (GSettings *settings, const gchar *key, CinnamonSettingsXSettingsManager *manager) { GVariant *value; int i; value = g_settings_get_value (settings, XSETTINGS_OVERRIDE_KEY); for (i = 0; manager->priv->managers[i]; i++) { xsettings_manager_set_overrides (manager->priv->managers[i], value); } queue_notify (manager); g_variant_unref (value); } static void plugin_callback (GSettings *settings, const char *key, CinnamonSettingsXSettingsManager *manager) { if (g_str_equal (key, GTK_MODULES_DISABLED_KEY) || g_str_equal (key, GTK_MODULES_ENABLED_KEY)) { /* Do nothing, as CsdXsettingsGtk will handle it */ } else if (g_str_equal (key, XSETTINGS_OVERRIDE_KEY)) { override_callback (settings, key, manager); } else { xft_callback (settings, key, manager); } } static void gtk_modules_callback (CsdXSettingsGtk *gtk, GParamSpec *spec, CinnamonSettingsXSettingsManager *manager) { const char *modules = csd_xsettings_gtk_get_modules (manager->priv->gtk); int i; if (modules == NULL) { for (i = 0; manager->priv->managers [i]; ++i) { xsettings_manager_delete_setting (manager->priv->managers [i], "Gtk/Modules"); } } else { g_debug ("Setting GTK modules '%s'", modules); for (i = 0; manager->priv->managers [i]; ++i) { xsettings_manager_set_string (manager->priv->managers [i], "Gtk/Modules", modules); } } queue_notify (manager); } static void fontconfig_callback (fontconfig_monitor_handle_t *handle, CinnamonSettingsXSettingsManager *manager) { int i; int timestamp = time (NULL); cinnamon_settings_profile_start (NULL); for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_int (manager->priv->managers [i], "Fontconfig/Timestamp", timestamp); } queue_notify (manager); cinnamon_settings_profile_end (NULL); } static gboolean start_fontconfig_monitor_idle_cb (CinnamonSettingsXSettingsManager *manager) { cinnamon_settings_profile_start (NULL); manager->priv->fontconfig_handle = fontconfig_monitor_start ((GFunc) fontconfig_callback, manager); cinnamon_settings_profile_end (NULL); manager->priv->start_idle_id = 0; return FALSE; } static void start_fontconfig_monitor (CinnamonSettingsXSettingsManager *manager) { cinnamon_settings_profile_start (NULL); fontconfig_cache_init (); manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_fontconfig_monitor_idle_cb, manager); cinnamon_settings_profile_end (NULL); } static void stop_fontconfig_monitor (CinnamonSettingsXSettingsManager *manager) { if (manager->priv->fontconfig_handle) { fontconfig_monitor_stop (manager->priv->fontconfig_handle); manager->priv->fontconfig_handle = NULL; } } static void process_value (CinnamonSettingsXSettingsManager *manager, TranslationEntry *trans, GVariant *value) { (* trans->translate) (manager, trans, value); } static TranslationEntry * find_translation_entry (GSettings *settings, const char *key) { guint i; char *schema; g_object_get (settings, "schema-id", &schema, NULL); for (i = 0; i < G_N_ELEMENTS (translations); i++) { if (g_str_equal (schema, translations[i].gsettings_schema) && g_str_equal (key, translations[i].gsettings_key)) { g_free (schema); return &translations[i]; } } g_free (schema); return NULL; } static void xsettings_callback (GSettings *settings, const char *key, CinnamonSettingsXSettingsManager *manager) { TranslationEntry *trans; guint i; GVariant *value; if (g_str_equal (key, TEXT_SCALING_FACTOR_KEY) || g_str_equal (key, SCALING_FACTOR_KEY) || g_str_equal (key, CURSOR_SIZE_KEY)) { xft_callback (NULL, key, manager); return; } trans = find_translation_entry (settings, key); if (trans == NULL) { return; } value = g_settings_get_value (settings, key); process_value (manager, trans, value); g_variant_unref (value); for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_string (manager->priv->managers [i], "Net/FallbackIconTheme", "gnome"); } queue_notify (manager); } static void terminate_cb (void *data) { gboolean *terminated = data; if (*terminated) { return; } *terminated = TRUE; g_warning ("X Settings Manager is terminating"); gtk_main_quit (); } static gboolean setup_xsettings_managers (CinnamonSettingsXSettingsManager *manager) { GdkDisplay *display; int i; int n_screens; gboolean res; gboolean terminated; display = gdk_display_get_default (); n_screens = gdk_display_get_n_screens (display); res = xsettings_manager_check_running (gdk_x11_display_get_xdisplay (display), gdk_screen_get_number (gdk_screen_get_default ())); if (res) { g_warning ("You can only run one xsettings manager at a time; exiting"); return FALSE; } manager->priv->managers = g_new0 (XSettingsManager *, n_screens + 1); terminated = FALSE; for (i = 0; i < n_screens; i++) { GdkScreen *screen; screen = gdk_display_get_screen (display, i); manager->priv->managers [i] = xsettings_manager_new (gdk_x11_display_get_xdisplay (display), gdk_screen_get_number (screen), terminate_cb, &terminated); if (! manager->priv->managers [i]) { g_warning ("Could not create xsettings manager for screen %d!", i); return FALSE; } g_signal_connect (screen, "size-changed", G_CALLBACK (size_changed_callback), manager); } return TRUE; } static void monitors_changed (CinnamonSettingsXSettingsManager *manager) { update_xft_settings (manager); queue_notify (manager); } static void on_monitors_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer data) { CinnamonSettingsXSettingsManager *manager = data; monitors_changed (manager); } static void on_display_config_name_appeared_handler (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer data) { CinnamonSettingsXSettingsManager *manager = data; monitors_changed (manager); } static void animations_enabled_changed (CinnamonSettingsXSettingsManager *manager) { GSettings *settings; g_autoptr(GError) error = NULL; g_autoptr(GVariant) res = NULL; g_autoptr(GVariant) animations_enabled_variant = NULL; gboolean animations_enabled; gint i; // If the interface settings key is turned off, don't bother trying to check with cinnamon - // the user must have disabled it - this affects only Gtk programs. Otherwise, let Cinnamon // decide (based on current conditions and cinnamon-specific settings). settings = g_hash_table_lookup (manager->priv->settings, INTERFACE_SETTINGS_SCHEMA); animations_enabled = g_settings_get_boolean (settings, "enable-animations"); if (animations_enabled) { res = g_dbus_connection_call_sync (manager->priv->dbus_connection, "org.Cinnamon", "/org/Cinnamon", "org.freedesktop.DBus.Properties", "Get", g_variant_new ("(ss)", "org.Cinnamon", "AnimationsEnabled"), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (!res) { g_debug ("Failed to get AnimationsEnabled state from Cinnamon: %s", error->message); } else { g_variant_get (res, "(v)", &animations_enabled_variant); g_variant_get (animations_enabled_variant, "b", &animations_enabled); } } if (manager->priv->enable_animations == animations_enabled) return; manager->priv->enable_animations = animations_enabled; for (i = 0; manager->priv->managers [i]; ++i) { xsettings_manager_set_int (manager->priv->managers [i], "Gtk/EnableAnimations", manager->priv->enable_animations); } queue_notify (manager); } static void on_cinnamon_properties_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer data) { CinnamonSettingsXSettingsManager *manager = data; animations_enabled_changed (manager); } static void on_cinnamon_name_appeared_handler (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer data) { CinnamonSettingsXSettingsManager *manager = data; animations_enabled_changed (manager); } gboolean cinnamon_xsettings_manager_start (CinnamonSettingsXSettingsManager *manager, GError **error) { GVariant *overrides; guint i; GList *list, *l; g_debug ("Starting xsettings manager"); cinnamon_settings_profile_start (NULL); if (!setup_xsettings_managers (manager)) { g_set_error (error, CSD_XSETTINGS_ERROR, CSD_XSETTINGS_ERROR_INIT, "Could not initialize xsettings manager."); return FALSE; } manager->priv->monitors_changed_id = g_dbus_connection_signal_subscribe (manager->priv->dbus_connection, "org.cinnamon.Muffin.DisplayConfig", "org.cinnamon.Muffin.DisplayConfig", "MonitorsChanged", "/org/cinnamon/Muffin/DisplayConfig", NULL, G_DBUS_SIGNAL_FLAGS_NONE, on_monitors_changed, manager, NULL); manager->priv->display_config_watch_id = g_bus_watch_name_on_connection (manager->priv->dbus_connection, "org.cinnamon.Muffin.DisplayConfig", G_BUS_NAME_WATCHER_FLAGS_NONE, on_display_config_name_appeared_handler, NULL, manager, NULL); manager->priv->cinnamon_properties_changed_id = g_dbus_connection_signal_subscribe (manager->priv->dbus_connection, "org.Cinnamon", "org.freedesktop.DBus.Properties", "PropertiesChanged", "/org/Cinnamon", NULL, G_DBUS_SIGNAL_FLAGS_NONE, on_cinnamon_properties_changed, manager, NULL); manager->priv->cinnamon_name_watch_id = g_bus_watch_name_on_connection (manager->priv->dbus_connection, "org.Cinnamon", G_BUS_NAME_WATCHER_FLAGS_NONE, on_cinnamon_name_appeared_handler, NULL, manager, NULL); manager->priv->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); g_hash_table_insert (manager->priv->settings, MOUSE_SETTINGS_SCHEMA, g_settings_new (MOUSE_SETTINGS_SCHEMA)); g_hash_table_insert (manager->priv->settings, INTERFACE_SETTINGS_SCHEMA, g_settings_new (INTERFACE_SETTINGS_SCHEMA)); g_hash_table_insert (manager->priv->settings, INTERFACE_WM_SETTINGS_SCHEMA, g_settings_new (INTERFACE_WM_SETTINGS_SCHEMA)); g_hash_table_insert (manager->priv->settings, SOUND_SETTINGS_SCHEMA, g_settings_new (SOUND_SETTINGS_SCHEMA)); g_hash_table_insert (manager->priv->settings, XSETTINGS_PLUGIN_SCHEMA, g_settings_new (XSETTINGS_PLUGIN_SCHEMA)); g_hash_table_insert (manager->priv->settings, PRIVACY_SETTINGS_SCHEMA, g_settings_new (PRIVACY_SETTINGS_SCHEMA)); g_hash_table_insert (manager->priv->settings, KEYBOARD_A11Y_SCHEMA, g_settings_new (KEYBOARD_A11Y_SCHEMA)); for (i = 0; i < G_N_ELEMENTS (translations); i++) { GVariant *val; GSettings *settings; settings = g_hash_table_lookup (manager->priv->settings, translations[i].gsettings_schema); if (settings == NULL) { g_warning ("Schemas '%s' has not been setup", translations[i].gsettings_schema); continue; } val = g_settings_get_value (settings, translations[i].gsettings_key); process_value (manager, &translations[i], val); g_variant_unref (val); } list = g_hash_table_get_values (manager->priv->settings); for (l = list; l != NULL; l = l->next) { g_signal_connect_object (G_OBJECT (l->data), "changed", G_CALLBACK (xsettings_callback), manager, 0); } g_list_free (list); /* Plugin settings (GTK modules and Xft) */ manager->priv->plugin_settings = g_settings_new (XSETTINGS_PLUGIN_SCHEMA); g_signal_connect_object (manager->priv->plugin_settings, "changed", G_CALLBACK (plugin_callback), manager, 0); manager->priv->gtk = csd_xsettings_gtk_new (); g_signal_connect (G_OBJECT (manager->priv->gtk), "notify::gtk-modules", G_CALLBACK (gtk_modules_callback), manager); gtk_modules_callback (manager->priv->gtk, NULL, manager); /* Xft settings */ update_xft_settings (manager); set_session_bus_id (manager); start_fontconfig_monitor (manager); overrides = g_settings_get_value (manager->priv->plugin_settings, XSETTINGS_OVERRIDE_KEY); for (i = 0; manager->priv->managers [i]; i++) { xsettings_manager_set_string (manager->priv->managers [i], "Net/FallbackIconTheme", "gnome"); xsettings_manager_set_overrides (manager->priv->managers [i], overrides); xsettings_manager_set_int (manager->priv->managers [i], "Gtk/ShellShowsAppMenu", FALSE); xsettings_manager_set_int (manager->priv->managers [i], "Gtk/ShellShowsMenubar", FALSE); } queue_notify (manager); g_variant_unref (overrides); cinnamon_settings_profile_end (NULL); return TRUE; } void cinnamon_xsettings_manager_stop (CinnamonSettingsXSettingsManager *manager) { CinnamonSettingsXSettingsManagerPrivate *p = manager->priv; int i; g_debug ("Stopping xsettings manager"); if (manager->priv->cinnamon_properties_changed_id) { g_dbus_connection_signal_unsubscribe (manager->priv->dbus_connection, manager->priv->cinnamon_properties_changed_id); manager->priv->cinnamon_properties_changed_id = 0; } if (manager->priv->cinnamon_name_watch_id) { g_bus_unwatch_name (manager->priv->cinnamon_name_watch_id); manager->priv->cinnamon_name_watch_id = 0; } if (manager->priv->monitors_changed_id) { g_dbus_connection_signal_unsubscribe (manager->priv->dbus_connection, manager->priv->monitors_changed_id); manager->priv->monitors_changed_id = 0; } if (manager->priv->display_config_watch_id) { g_bus_unwatch_name (manager->priv->display_config_watch_id); manager->priv->display_config_watch_id = 0; } if (p->managers != NULL) { for (i = 0; p->managers [i]; ++i) xsettings_manager_destroy (p->managers [i]); g_free (p->managers); p->managers = NULL; } if (p->plugin_settings != NULL) { g_object_unref (p->plugin_settings); p->plugin_settings = NULL; } stop_fontconfig_monitor (manager); if (p->settings != NULL) { g_hash_table_destroy (p->settings); p->settings = NULL; } if (p->gtk != NULL) { g_object_unref (p->gtk); p->gtk = NULL; } } static GObject * cinnamon_xsettings_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CinnamonSettingsXSettingsManager *xsettings_manager; xsettings_manager = CINNAMON_XSETTINGS_MANAGER (G_OBJECT_CLASS (cinnamon_xsettings_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (xsettings_manager); } static void cinnamon_xsettings_manager_class_init (CinnamonSettingsXSettingsManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = cinnamon_xsettings_manager_constructor; object_class->finalize = cinnamon_xsettings_manager_finalize; g_type_class_add_private (klass, sizeof (CinnamonSettingsXSettingsManagerPrivate)); } static void cinnamon_xsettings_manager_init (CinnamonSettingsXSettingsManager *manager) { GError *error; manager->priv = CINNAMON_XSETTINGS_MANAGER_GET_PRIVATE (manager); error = NULL; manager->priv->dbus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (!manager->priv->dbus_connection) { g_error ("Failed to get session bus: %s", error->message); } } static void cinnamon_xsettings_manager_finalize (GObject *object) { CinnamonSettingsXSettingsManager *xsettings_manager; g_return_if_fail (object != NULL); g_return_if_fail (CINNAMON_IS_XSETTINGS_MANAGER (object)); xsettings_manager = CINNAMON_XSETTINGS_MANAGER (object); g_return_if_fail (xsettings_manager->priv != NULL); if (xsettings_manager->priv->start_idle_id != 0) { g_source_remove (xsettings_manager->priv->start_idle_id); xsettings_manager->priv->start_idle_id = 0; } g_clear_object (&xsettings_manager->priv->dbus_connection); G_OBJECT_CLASS (cinnamon_xsettings_manager_parent_class)->finalize (object); } static GVariant * map_speed (GVariant *variant, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { gdouble value; value = g_variant_get_double (variant); /* Remap from [0..10] to [-1..1] */ value = (value / 5) - 1; return g_variant_new_double (value); } static GVariant * map_send_events (GVariant *variant, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { gboolean enabled; enabled = g_settings_get_boolean (origin_settings, "touchpad-enabled"); if (enabled) { if (g_settings_get_boolean (origin_settings, "disable-with-external-mouse")) { g_settings_set_enum (dest_settings, "send-events", C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE); } else { g_settings_set_enum (dest_settings, "send-events", C_DESKTOP_DEVICE_SEND_EVENTS_ENABLED); } } else { g_settings_set_enum (dest_settings, "send-events", C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED); } return NULL; } static GVariant * map_scroll_method (GVariant *variant, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { gint old; old = g_settings_get_int (origin_settings, "scrolling-method"); switch (old) { case 0: // disabled g_settings_set_boolean (dest_settings, "edge-scrolling-enabled", FALSE); g_settings_set_boolean (dest_settings, "two-finger-scrolling-enabled", FALSE); break; case 2: // edge g_settings_set_boolean (dest_settings, "edge-scrolling-enabled", TRUE); g_settings_set_boolean (dest_settings, "two-finger-scrolling-enabled", FALSE); break; case 1: // two-finger case 3: // auto, also the new default default: g_settings_set_boolean (dest_settings, "edge-scrolling-enabled", FALSE); g_settings_set_boolean (dest_settings, "two-finger-scrolling-enabled", TRUE); break; } return NULL; } static GVariant * map_click_method (GVariant *variant, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { gint old; old = g_settings_get_int (origin_settings, "clickpad-click"); switch (old) { case 0: // disabled g_settings_set_enum (dest_settings, "click-method", C_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE); break; case 1: // corners g_settings_set_enum (dest_settings, "click-method", C_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS); break; case 2: // fingers g_settings_set_enum (dest_settings, "click-method", C_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS); break; case 3: // automatic g_settings_set_enum (dest_settings, "click-method", C_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT); break; } return NULL; } static void migrate_mouse_settings (void) { CsdSettingsMigrateEntry trackball_entries[] = { { "scroll-wheel-emulation-button", "scroll-wheel-emulation-button", NULL } }; CsdSettingsMigrateEntry mouse_entries[] = { { "locate-pointer", "locate-pointer", NULL }, { "left-handed", "left-handed", NULL }, { "natural-scroll", "natural-scroll", NULL }, { "custom-acceleration", NULL, NULL }, { "motion-acceleration", "speed", map_speed }, { "custom-threshold", NULL, NULL }, { "motion-threshold", NULL, NULL }, { "double-click", "double-click", NULL }, { "drag-threshold", "drag-threshold", NULL }, { "middle-button-enabled", "middle-click-emulation", NULL }, }; CsdSettingsMigrateEntry touchpad_entries[] = { { "disable-while-typing", "disable-while-typing", NULL }, { "scrolling-method", "edge-scrolling-enabled", map_scroll_method }, { "tap-to-click", "tap-to-click", NULL }, { "clickpad-click", "click-method", map_click_method }, { "touchpad-enabled", "send-events", map_send_events }, { "disable-with-external-mouse", "send-events", map_send_events }, { "left-handed", "left-handed", NULL }, { "custom-acceleration", NULL, NULL }, { "motion-acceleration", "speed", map_speed }, { "motion-threshold", NULL, NULL }, { "natural-scroll", "natural-scroll", NULL } }; csd_settings_migrate_check ("org.cinnamon.settings-daemon.peripherals.trackball.deprecated", "/org/cinnamon/settings-daemon/peripherals/trackball/", "org.cinnamon.desktop.peripherals.trackball", "/org/cinnamon/desktop/peripherals/trackball/", trackball_entries, G_N_ELEMENTS (trackball_entries)); csd_settings_migrate_check ("org.cinnamon.settings-daemon.peripherals.mouse.deprecated", "/org/cinnamon/settings-daemon/peripherals/mouse/", "org.cinnamon.desktop.peripherals.mouse", "/org/cinnamon/desktop/peripherals/mouse/", mouse_entries, G_N_ELEMENTS (mouse_entries)); csd_settings_migrate_check ("org.cinnamon.settings-daemon.peripherals.touchpad.deprecated", "/org/cinnamon/settings-daemon/peripherals/touchpad/", "org.cinnamon.desktop.peripherals.touchpad", "/org/cinnamon/desktop/peripherals/touchpad/", touchpad_entries, G_N_ELEMENTS (touchpad_entries)); } CinnamonSettingsXSettingsManager * cinnamon_xsettings_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { migrate_mouse_settings (); manager_object = g_object_new (CINNAMON_TYPE_XSETTINGS_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CINNAMON_XSETTINGS_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/xsettings/main.c0000664000175000017500000000120514733247605022163 0ustar fabiofabio#define NEW cinnamon_xsettings_manager_new #define START cinnamon_xsettings_manager_start #define STOP cinnamon_xsettings_manager_stop #define MANAGER CinnamonSettingsXSettingsManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING FALSE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-xsettings-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/xsettings/xsettings-manager.h0000664000175000017500000000524014733247605024707 0ustar fabiofabio/* * Copyright © 2001 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Owen Taylor, Red Hat, Inc. */ #ifndef XSETTINGS_MANAGER_H #define XSETTINGS_MANAGER_H #include #include "xsettings-common.h" typedef struct _XSettingsManager XSettingsManager; typedef void (*XSettingsTerminateFunc) (void *cb_data); Bool xsettings_manager_check_running (Display *display, int screen); XSettingsManager *xsettings_manager_new (Display *display, int screen, XSettingsTerminateFunc terminate, void *cb_data); void xsettings_manager_destroy (XSettingsManager *manager); void xsettings_manager_delete_setting (XSettingsManager *manager, const char *name); void xsettings_manager_set_int (XSettingsManager *manager, const char *name, int value); void xsettings_manager_set_string (XSettingsManager *manager, const char *name, const char *value); void xsettings_manager_set_color (XSettingsManager *manager, const char *name, XSettingsColor *value); void xsettings_manager_notify (XSettingsManager *manager); void xsettings_manager_set_overrides (XSettingsManager *manager, GVariant *overrides); #endif /* XSETTINGS_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/README.xsettings0000664000175000017500000000260014733247605024002 0ustar fabiofabioThis is very simple documentation for the 'override' GSettings key for cinnamon-setting-daemon's xsettings plugin. The override is given as a dictionary of overrides to be applied on top of the usual values that are exported to the X server as XSETTINGS. The intent of this is to allow users to override values of programmatically determined settings (such as 'Gtk/ShellShowsAppMenu') and to allow developers to introduce new XSETTINGS for testing (without having to kill the cinnamon-settings-daemon running in the session and run their own patched version). The type of the overrides is 'a{sv}'. The key gives the full XSETTINGS setting name to override (for example, 'Gtk/ShellShowsAppMenu'). The value is one of the following: - a string ('s') for the case of a string XSETTING - an int32 ('i') for the case of an integer XSETTING - a 4-tuple of uint16s ('(qqqq)') for the case of a color XSETTING Dictionary items with a value that is not one of the above types will be ignored. Specifically note that XSETTINGS does not have a concept of booleans -- you must use an integer that is either 0 or 1. An example setting for this key (as expressed in GVariant text format) might be: { 'Gtk/ShellShowsAppMenu': < 0 >, 'Xft/DPI', < 98304 > } Noting that variants must be specified in the usual way (wrapped in <>). Note also that DPI in the above example is expressed in 1024ths of an inch. cinnamon-settings-daemon-6.4.3/plugins/xsettings/test-gtk-modules.c0000664000175000017500000000127514733247605024456 0ustar fabiofabio #include "csd-xsettings-gtk.h" static void gtk_modules_callback (CsdXSettingsGtk *gtk, GParamSpec *spec, gpointer user_data) { const char *modules; modules = csd_xsettings_gtk_get_modules (gtk); g_message ("GTK+ modules list changed to: %s", modules ? modules : "(empty)"); } int main (int argc, char **argv) { GMainLoop *loop; CsdXSettingsGtk *gtk; gtk = csd_xsettings_gtk_new (); g_signal_connect (G_OBJECT (gtk), "notify::gtk-modules", G_CALLBACK (gtk_modules_callback), NULL); gtk_modules_callback (gtk, NULL, NULL); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); g_main_loop_unref (loop); return 0; } cinnamon-settings-daemon-6.4.3/plugins/xsettings/csd-xsettings-gtk.h0000664000175000017500000000414414733247605024633 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Bastien Nocera * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_XSETTINGS_GTK_H__ #define __CSD_XSETTINGS_GTK_H__ #include #include #include G_BEGIN_DECLS #define CSD_TYPE_XSETTINGS_GTK (csd_xsettings_gtk_get_type ()) #define CSD_XSETTINGS_GTK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_XSETTINGS_GTK, CsdXSettingsGtk)) #define CSD_XSETTINGS_GTK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_XSETTINGS_GTK, CsdXSettingsGtkClass)) #define CSD_IS_XSETTINGS_GTK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_XSETTINGS_GTK)) #define CSD_IS_XSETTINGS_GTK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_XSETTINGS_GTK)) #define CSD_XSETTINGS_GTK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_XSETTINGS_GTK, CsdXSettingsGtkClass)) typedef struct CsdXSettingsGtkPrivate CsdXSettingsGtkPrivate; typedef struct { GObject parent; CsdXSettingsGtkPrivate *priv; } CsdXSettingsGtk; typedef struct { GObjectClass parent_class; } CsdXSettingsGtkClass; GType csd_xsettings_gtk_get_type (void) G_GNUC_CONST; CsdXSettingsGtk *csd_xsettings_gtk_new (void); const char * csd_xsettings_gtk_get_modules (CsdXSettingsGtk *gtk); G_END_DECLS #endif /* __CSD_XSETTINGS_GTK_H__ */ cinnamon-settings-daemon-6.4.3/plugins/xsettings/fontconfig-monitor.c0000664000175000017500000001142314733247605025063 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2008 Red Hat, Inc. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Behdad Esfahbod, Red Hat, Inc. */ #include "fontconfig-monitor.h" #include #include #define TIMEOUT_SECONDS 2 static void stuff_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer handle); void fontconfig_cache_init (void) { FcInit (); } gboolean fontconfig_cache_update (void) { return !FcConfigUptoDate (NULL) && FcInitReinitialize (); } static void monitor_files (GPtrArray *monitors, FcStrList *list, gpointer data) { const char *str; while ((str = (const char *) FcStrListNext (list))) { GFile *file; GFileMonitor *monitor; file = g_file_new_for_path (str); monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); g_object_unref (file); if (!monitor) continue; g_signal_connect (monitor, "changed", G_CALLBACK (stuff_changed), data); g_ptr_array_add (monitors, monitor); } FcStrListDone (list); } struct _fontconfig_monitor_handle { GPtrArray *monitors; guint timeout; GFunc notify_callback; gpointer notify_data; }; static GPtrArray * monitors_create (gpointer data) { GPtrArray *monitors = g_ptr_array_new (); monitor_files (monitors, FcConfigGetConfigFiles (NULL), data); monitor_files (monitors, FcConfigGetFontDirs (NULL) , data); return monitors; } static void monitors_free (GPtrArray *monitors) { if (!monitors) return; g_ptr_array_foreach (monitors, (GFunc) g_object_unref, NULL); g_ptr_array_free (monitors, TRUE); } static gboolean update (gpointer data) { fontconfig_monitor_handle_t *handle = data; gboolean notify = FALSE; handle->timeout = 0; if (fontconfig_cache_update ()) { notify = TRUE; monitors_free (handle->monitors); handle->monitors = monitors_create (data); } /* we finish modifying handle before calling the notify callback, * allowing the callback to free the monitor if it decides to. */ if (notify && handle->notify_callback) handle->notify_callback (data, handle->notify_data); return FALSE; } static void stuff_changed (GFileMonitor *monitor G_GNUC_UNUSED, GFile *file G_GNUC_UNUSED, GFile *other_file G_GNUC_UNUSED, GFileMonitorEvent event_type G_GNUC_UNUSED, gpointer data) { fontconfig_monitor_handle_t *handle = data; /* wait for quiescence */ if (handle->timeout) { g_source_remove (handle->timeout); handle->timeout = 0; } handle->timeout = g_timeout_add_seconds (TIMEOUT_SECONDS, update, data); } fontconfig_monitor_handle_t * fontconfig_monitor_start (GFunc notify_callback, gpointer notify_data) { fontconfig_monitor_handle_t *handle = g_slice_new0 (fontconfig_monitor_handle_t); handle->notify_callback = notify_callback; handle->notify_data = notify_data; handle->monitors = monitors_create (handle); return handle; } void fontconfig_monitor_stop (fontconfig_monitor_handle_t *handle) { if (handle->timeout) { g_source_remove (handle->timeout); handle->timeout = 0; } monitors_free (handle->monitors); handle->monitors = NULL; } #ifdef FONTCONFIG_MONITOR_TEST static void yay (void) { g_message ("yay"); } int main (void) { GMainLoop *loop; fontconfig_monitor_start ((GFunc) yay, NULL); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); g_main_loop_unref (loop); return 0; } #endif cinnamon-settings-daemon-6.4.3/plugins/xsettings/csd-xsettings-gtk.c0000664000175000017500000003021214733247605024621 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include "csd-xsettings-gtk.h" #define XSETTINGS_PLUGIN_SCHEMA "org.cinnamon.settings-daemon.plugins.xsettings" #define GTK_MODULES_DISABLED_KEY "disabled-gtk-modules" #define GTK_MODULES_ENABLED_KEY "enabled-gtk-modules" enum { PROP_0, PROP_GTK_MODULES }; struct CsdXSettingsGtkPrivate { char *modules; GHashTable *dir_modules; GSettings *settings; guint64 dir_mtime; GFileMonitor *monitor; GList *cond_settings; }; #define CSD_XSETTINGS_GTK_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), CSD_TYPE_XSETTINGS_GTK, CsdXSettingsGtkPrivate)) G_DEFINE_TYPE(CsdXSettingsGtk, csd_xsettings_gtk, G_TYPE_OBJECT) static void update_gtk_modules (CsdXSettingsGtk *gtk); static void empty_cond_settings_list (CsdXSettingsGtk *gtk) { if (gtk->priv->cond_settings == NULL) return; /* Empty the list of settings */ g_list_foreach (gtk->priv->cond_settings, (GFunc) g_object_unref, NULL); g_list_free (gtk->priv->cond_settings); gtk->priv->cond_settings = NULL; } static void cond_setting_changed (GSettings *settings, const char *key, CsdXSettingsGtk *gtk) { gboolean enabled; const char *module_name; module_name = g_object_get_data (G_OBJECT (settings), "module-name"); enabled = g_settings_get_boolean (settings, key); if (enabled != FALSE) { if (gtk->priv->dir_modules == NULL) gtk->priv->dir_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_insert (gtk->priv->dir_modules, g_strdup (module_name), NULL); } else if (gtk->priv->dir_modules != NULL) { g_hash_table_remove (gtk->priv->dir_modules, module_name); } update_gtk_modules (gtk); } static char * process_desktop_file (const char *path, CsdXSettingsGtk *gtk) { GKeyFile *keyfile; char *retval; char *module_name; retval = NULL; if (g_str_has_suffix (path, ".desktop") == FALSE && g_str_has_suffix (path, ".gtk-module") == FALSE) return retval; keyfile = g_key_file_new (); if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL) == FALSE) goto bail; if (g_key_file_has_group (keyfile, "GTK Module") == FALSE) goto bail; module_name = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Name", NULL); if (module_name == NULL) goto bail; if (g_key_file_has_key (keyfile, "GTK Module", "X-GTK-Module-Enabled-Schema", NULL) != FALSE) { char *schema; char *key; gboolean enabled; GSettings *settings; char *signal; schema = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Enabled-Schema", NULL); key = g_key_file_get_string (keyfile, "GTK Module", "X-GTK-Module-Enabled-Key", NULL); settings = g_settings_new (schema); enabled = g_settings_get_boolean (settings, key); gtk->priv->cond_settings = g_list_prepend (gtk->priv->cond_settings, settings); g_object_set_data_full (G_OBJECT (settings), "module-name", g_strdup (module_name), (GDestroyNotify) g_free); signal = g_strdup_printf ("changed::%s", key); g_signal_connect_object (G_OBJECT (settings), signal, G_CALLBACK (cond_setting_changed), gtk, 0); g_free (signal); g_free (schema); g_free (key); if (enabled != FALSE) retval = g_strdup (module_name); } else { retval = g_strdup (module_name); } g_free (module_name); bail: g_key_file_free (keyfile); return retval; } static void get_gtk_modules_from_dir (CsdXSettingsGtk *gtk) { GFile *file; GFileInfo *info; GHashTable *ht; file = g_file_new_for_path (GTK_MODULES_DIRECTORY); info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (info != NULL) { guint64 dir_mtime; dir_mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); if (gtk->priv->dir_mtime == 0 || dir_mtime > gtk->priv->dir_mtime) { GDir *dir; const char *name; empty_cond_settings_list (gtk); gtk->priv->dir_mtime = dir_mtime; if (gtk->priv->dir_modules != NULL) { g_hash_table_destroy (gtk->priv->dir_modules); gtk->priv->dir_modules = NULL; } dir = g_dir_open (GTK_MODULES_DIRECTORY, 0, NULL); if (dir == NULL) goto bail; ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); while ((name = g_dir_read_name (dir)) != NULL) { char *path; char *module; path = g_build_filename (GTK_MODULES_DIRECTORY, name, NULL); module = process_desktop_file (path, gtk); if (module != NULL) g_hash_table_insert (ht, module, NULL); g_free (path); } g_dir_close (dir); gtk->priv->dir_modules = ht; } } else { empty_cond_settings_list (gtk); } bail: if (info != NULL) g_object_unref (info); g_object_unref (file); } static void stringify_gtk_modules (gpointer key, gpointer value, GString *str) { if (str->len != 0) g_string_append_c (str, ':'); g_string_append (str, key); } static void update_gtk_modules (CsdXSettingsGtk *gtk) { char **enabled, **disabled; GHashTable *ht; guint i; GString *str; char *modules; enabled = g_settings_get_strv (gtk->priv->settings, GTK_MODULES_ENABLED_KEY); disabled = g_settings_get_strv (gtk->priv->settings, GTK_MODULES_DISABLED_KEY); ht = g_hash_table_new (g_str_hash, g_str_equal); if (gtk->priv->dir_modules != NULL) { GList *list, *l; list = g_hash_table_get_keys (gtk->priv->dir_modules); for (l = list; l != NULL; l = l->next) { g_hash_table_insert (ht, l->data, NULL); } g_list_free (list); } for (i = 0; enabled[i] != NULL; i++) g_hash_table_insert (ht, enabled[i], NULL); for (i = 0; disabled[i] != NULL; i++) g_hash_table_remove (ht, disabled[i]); str = g_string_new (NULL); g_hash_table_foreach (ht, (GHFunc) stringify_gtk_modules, str); g_hash_table_destroy (ht); modules = g_string_free (str, FALSE); if (modules == NULL || gtk->priv->modules == NULL || g_str_equal (modules, gtk->priv->modules) == FALSE) { g_free (gtk->priv->modules); gtk->priv->modules = modules; g_object_notify (G_OBJECT (gtk), "gtk-modules"); } else { g_free (modules); } g_strfreev (enabled); g_strfreev (disabled); } static void gtk_modules_dir_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, CsdXSettingsGtk *gtk) { get_gtk_modules_from_dir (gtk); update_gtk_modules (gtk); } static void csd_xsettings_gtk_init (CsdXSettingsGtk *gtk) { GFile *file; gtk->priv = CSD_XSETTINGS_GTK_GET_PRIVATE (gtk); g_debug ("CsdXSettingsGtk initializing"); gtk->priv->settings = g_settings_new (XSETTINGS_PLUGIN_SCHEMA); get_gtk_modules_from_dir (gtk); file = g_file_new_for_path (GTK_MODULES_DIRECTORY); gtk->priv->monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); g_signal_connect (G_OBJECT (gtk->priv->monitor), "changed", G_CALLBACK (gtk_modules_dir_changed_cb), gtk); g_object_unref (file); update_gtk_modules (gtk); } static void csd_xsettings_gtk_finalize (GObject *object) { CsdXSettingsGtk *gtk; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_XSETTINGS_GTK (object)); g_debug ("CsdXSettingsGtk finalizing"); gtk = CSD_XSETTINGS_GTK (object); g_return_if_fail (gtk->priv != NULL); g_free (gtk->priv->modules); gtk->priv->modules = NULL; if (gtk->priv->dir_modules != NULL) { g_hash_table_destroy (gtk->priv->dir_modules); gtk->priv->dir_modules = NULL; } g_object_unref (gtk->priv->settings); if (gtk->priv->monitor != NULL) g_object_unref (gtk->priv->monitor); empty_cond_settings_list (gtk); G_OBJECT_CLASS (csd_xsettings_gtk_parent_class)->finalize (object); } static void csd_xsettings_gtk_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdXSettingsGtk *self; self = CSD_XSETTINGS_GTK (object); switch (prop_id) { case PROP_GTK_MODULES: g_value_set_string (value, self->priv->modules); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_xsettings_gtk_class_init (CsdXSettingsGtkClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = csd_xsettings_gtk_get_property; object_class->finalize = csd_xsettings_gtk_finalize; g_object_class_install_property (object_class, PROP_GTK_MODULES, g_param_spec_string ("gtk-modules", NULL, NULL, NULL, G_PARAM_READABLE)); g_type_class_add_private (klass, sizeof (CsdXSettingsGtkPrivate)); } CsdXSettingsGtk * csd_xsettings_gtk_new (void) { return CSD_XSETTINGS_GTK (g_object_new (CSD_TYPE_XSETTINGS_GTK, NULL)); } const char * csd_xsettings_gtk_get_modules (CsdXSettingsGtk *gtk) { return gtk->priv->modules; } cinnamon-settings-daemon-6.4.3/plugins/xsettings/xsettings-manager.c0000664000175000017500000002560714733247605024713 0ustar fabiofabio/* * Copyright © 2001 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Owen Taylor, Red Hat, Inc. */ #include #include #include #include #include /* For CARD16 */ #include "xsettings-manager.h" #define XSETTINGS_VARIANT_TYPE_COLOR (G_VARIANT_TYPE ("(qqqq)")) struct _XSettingsManager { Display *display; int screen; Window window; Atom manager_atom; Atom selection_atom; Atom xsettings_atom; XSettingsTerminateFunc terminate; void *cb_data; GHashTable *settings; unsigned long serial; GVariant *overrides; }; typedef struct { Window window; Atom timestamp_prop_atom; } TimeStampInfo; static Bool timestamp_predicate (Display *display, XEvent *xevent, XPointer arg) { TimeStampInfo *info = (TimeStampInfo *)arg; if (xevent->type == PropertyNotify && xevent->xproperty.window == info->window && xevent->xproperty.atom == info->timestamp_prop_atom) return True; return False; } /** * get_server_time: * @display: display from which to get the time * @window: a #Window, used for communication with the server. * The window must have PropertyChangeMask in its * events mask or a hang will result. * * Routine to get the current X server time stamp. * * Return value: the time stamp. **/ static Time get_server_time (Display *display, Window window) { unsigned char c = 'a'; XEvent xevent; TimeStampInfo info; info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); info.window = window; XChangeProperty (display, window, info.timestamp_prop_atom, info.timestamp_prop_atom, 8, PropModeReplace, &c, 1); XIfEvent (display, &xevent, timestamp_predicate, (XPointer)&info); return xevent.xproperty.time; } Bool xsettings_manager_check_running (Display *display, int screen) { char buffer[256]; Atom selection_atom; sprintf(buffer, "_XSETTINGS_S%d", screen); selection_atom = XInternAtom (display, buffer, False); if (XGetSelectionOwner (display, selection_atom)) return True; else return False; } XSettingsManager * xsettings_manager_new (Display *display, int screen, XSettingsTerminateFunc terminate, void *cb_data) { XSettingsManager *manager; Time timestamp; XClientMessageEvent xev; char buffer[256]; manager = g_slice_new (XSettingsManager); manager->display = display; manager->screen = screen; sprintf(buffer, "_XSETTINGS_S%d", screen); manager->selection_atom = XInternAtom (display, buffer, False); manager->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False); manager->manager_atom = XInternAtom (display, "MANAGER", False); manager->terminate = terminate; manager->cb_data = cb_data; manager->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) xsettings_setting_free); manager->serial = 0; manager->overrides = NULL; manager->window = XCreateSimpleWindow (display, RootWindow (display, screen), 0, 0, 10, 10, 0, WhitePixel (display, screen), WhitePixel (display, screen)); XSelectInput (display, manager->window, PropertyChangeMask); timestamp = get_server_time (display, manager->window); XSetSelectionOwner (display, manager->selection_atom, manager->window, timestamp); /* Check to see if we managed to claim the selection. If not, * we treat it as if we got it then immediately lost it */ if (XGetSelectionOwner (display, manager->selection_atom) == manager->window) { xev.type = ClientMessage; xev.window = RootWindow (display, screen); xev.message_type = manager->manager_atom; xev.format = 32; xev.data.l[0] = timestamp; xev.data.l[1] = manager->selection_atom; xev.data.l[2] = manager->window; xev.data.l[3] = 0; /* manager specific data */ xev.data.l[4] = 0; /* manager specific data */ XSendEvent (display, RootWindow (display, screen), False, StructureNotifyMask, (XEvent *)&xev); } else { manager->terminate (manager->cb_data); } return manager; } void xsettings_manager_destroy (XSettingsManager *manager) { XDestroyWindow (manager->display, manager->window); g_hash_table_unref (manager->settings); g_slice_free (XSettingsManager, manager); } static void xsettings_manager_set_setting (XSettingsManager *manager, const gchar *name, gint tier, GVariant *value) { XSettingsSetting *setting; setting = g_hash_table_lookup (manager->settings, name); if (setting == NULL) { setting = xsettings_setting_new (name); setting->last_change_serial = manager->serial; g_hash_table_insert (manager->settings, setting->name, setting); } xsettings_setting_set (setting, tier, value, manager->serial); if (xsettings_setting_get (setting) == NULL) g_hash_table_remove (manager->settings, name); } void xsettings_manager_set_int (XSettingsManager *manager, const char *name, int value) { xsettings_manager_set_setting (manager, name, 0, g_variant_new_int32 (value)); } void xsettings_manager_set_string (XSettingsManager *manager, const char *name, const char *value) { xsettings_manager_set_setting (manager, name, 0, g_variant_new_string (value)); } void xsettings_manager_set_color (XSettingsManager *manager, const char *name, XSettingsColor *value) { GVariant *tmp; tmp = g_variant_new ("(qqqq)", value->red, value->green, value->blue, value->alpha); g_assert (g_variant_is_of_type (tmp, XSETTINGS_VARIANT_TYPE_COLOR)); /* paranoia... */ xsettings_manager_set_setting (manager, name, 0, tmp); } void xsettings_manager_delete_setting (XSettingsManager *manager, const char *name) { xsettings_manager_set_setting (manager, name, 0, NULL); } static gchar xsettings_get_typecode (GVariant *value) { switch (g_variant_classify (value)) { case G_VARIANT_CLASS_INT32: return XSETTINGS_TYPE_INT; case G_VARIANT_CLASS_STRING: return XSETTINGS_TYPE_STRING; case G_VARIANT_CLASS_TUPLE: return XSETTINGS_TYPE_COLOR; default: g_assert_not_reached (); } } static void align_string (GString *string, gint alignment) { /* Adds nul-bytes to the string until its length is an even multiple * of the specified alignment requirement. */ while ((string->len % alignment) != 0) g_string_append_c (string, '\0'); } static void setting_store (XSettingsSetting *setting, GString *buffer) { XSettingsType type; GVariant *value; guint16 len16; value = xsettings_setting_get (setting); type = xsettings_get_typecode (value); g_string_append_c (buffer, type); g_string_append_c (buffer, 0); len16 = strlen (setting->name); g_string_append_len (buffer, (gchar *) &len16, 2); g_string_append (buffer, setting->name); align_string (buffer, 4); g_string_append_len (buffer, (gchar *) &setting->last_change_serial, 4); if (type == XSETTINGS_TYPE_STRING) { const gchar *string; gsize stringlen; guint32 len32; string = g_variant_get_string (value, &stringlen); len32 = stringlen; g_string_append_len (buffer, (gchar *) &len32, 4); g_string_append (buffer, string); align_string (buffer, 4); } else /* GVariant format is the same as XSETTINGS format for the non-string types */ g_string_append_len (buffer, g_variant_get_data (value), g_variant_get_size (value)); } void xsettings_manager_notify (XSettingsManager *manager) { GString *buffer; GHashTableIter iter; int n_settings; gpointer value; n_settings = g_hash_table_size (manager->settings); buffer = g_string_new (NULL); g_string_append_c (buffer, xsettings_byte_order ()); g_string_append_c (buffer, '\0'); g_string_append_c (buffer, '\0'); g_string_append_c (buffer, '\0'); g_string_append_len (buffer, (gchar *) &manager->serial, 4); g_string_append_len (buffer, (gchar *) &n_settings, 4); g_hash_table_iter_init (&iter, manager->settings); while (g_hash_table_iter_next (&iter, NULL, &value)) setting_store (value, buffer); XChangeProperty (manager->display, manager->window, manager->xsettings_atom, manager->xsettings_atom, 8, PropModeReplace, (guchar *) buffer->str, buffer->len); g_string_free (buffer, TRUE); manager->serial++; } void xsettings_manager_set_overrides (XSettingsManager *manager, GVariant *overrides) { GVariantIter iter; const gchar *key; GVariant *value; g_return_if_fail (overrides != NULL && g_variant_is_of_type (overrides, G_VARIANT_TYPE_VARDICT)); if (manager->overrides) { /* unset the existing overrides */ g_variant_iter_init (&iter, manager->overrides); while (g_variant_iter_next (&iter, "{&sv}", &key, NULL)) /* only unset it at this point if it's not in the new list */ if (!g_variant_lookup (overrides, key, "*", NULL)) xsettings_manager_set_setting (manager, key, 1, NULL); g_variant_unref (manager->overrides); } /* save this so we can do the unsets next time */ manager->overrides = g_variant_ref_sink (overrides); /* set the new values */ g_variant_iter_init (&iter, overrides); while (g_variant_iter_loop (&iter, "{&sv}", &key, &value)) { /* only accept recognised types... */ if (!g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) && !g_variant_is_of_type (value, G_VARIANT_TYPE_INT32) && !g_variant_is_of_type (value, XSETTINGS_VARIANT_TYPE_COLOR)) continue; xsettings_manager_set_setting (manager, key, 1, value); } } cinnamon-settings-daemon-6.4.3/plugins/wacom/0000775000175000017500000000000014733247605020153 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/wacom/meson.build0000664000175000017500000000262314733247605022320 0ustar fabiofabioplugin_name = 'wacom' sources = files( 'csd-wacom-manager.c', 'csd-wacom-oled.c', 'main.c' ) deps = [ gtk, common_dep, libnotify, librsvg, math, pango, wacom ] cflags = [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ] executable( 'csd-' + plugin_name, sources, include_directories: [include_dirs, include_enums, common_inc], dependencies: deps, c_args: cflags, install: true, install_rpath: join_paths(prefix, apilibdir), install_dir: libexecdir ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-wacom') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-wacom') endif led_deps = [ gudev, math ] programs = [ 'csd-wacom-led-helper', 'csd-wacom-oled-helper', ] foreach program: programs executable( program, program + '.c', include_directories: include_dirs, dependencies: led_deps, install: true, install_dir: libexecdir ) endforeach configure_file( input: 'cinnamon-settings-daemon-wacom.desktop.in', output: 'cinnamon-settings-daemon-wacom.desktop', configuration: desktop_conf, install_dir: autostartdir, ) configure_file( input: 'org.cinnamon.settings-daemon.plugins.wacom.policy.in', output: 'org.cinnamon.settings-daemon.plugins.wacom.policy', configuration: desktop_conf, install_dir: polkitdir, ) cinnamon-settings-daemon-6.4.3/plugins/wacom/cinnamon-settings-daemon-wacom.desktop.in0000664000175000017500000000033214733247605030156 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - wacom Exec=csd-wacom OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-manager.c0000664000175000017500000004436314733247605023616 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2010 Red Hat, Inc. * * 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 . * */ #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef GDK_WINDOWING_WAYLAND #include #endif #ifdef GDK_WINDOWING_X11 #include #endif #if HAVE_WACOM #include #endif #include "csd-enums.h" #include "cinnamon-settings-profile.h" #include "csd-wacom-manager.h" #include "csd-wacom-oled.h" #include "migrate-settings.h" #include "csd-input-helper.h" #define CSD_DBUS_NAME "org.cinnamon.SettingsDaemon" #define CSD_DBUS_PATH "/org/cinnamon/SettingsDaemon" #define CSD_DBUS_BASE_INTERFACE "org.cinnamon.SettingsDaemon" #define CSD_WACOM_DBUS_PATH CSD_DBUS_PATH "/Wacom" #define CSD_WACOM_DBUS_NAME CSD_DBUS_NAME ".Wacom" #define LEFT_HANDED_KEY "left-handed" static const gchar introspection_xml[] = "" " " " " " " " " " " " " " " " " " " " " " " ""; struct _CsdWacomManager { GObject parent; guint start_idle_id; GdkSeat *seat; guint device_added_id; gchar *machine_id; #if HAVE_WACOM WacomDeviceDatabase *wacom_db; #endif /* DBus */ GDBusNodeInfo *introspection_data; GDBusConnection *dbus_connection; GCancellable *dbus_cancellable; guint dbus_register_object_id; guint name_id; }; static void csd_wacom_manager_class_init (CsdWacomManagerClass *klass); static void csd_wacom_manager_init (CsdWacomManager *wacom_manager); static void csd_wacom_manager_finalize (GObject *object); static gboolean set_led (const gchar *device_path, guint group, guint index, GError **error); static gboolean is_opaque_tablet (CsdWacomManager *manager, GdkDevice *device); G_DEFINE_TYPE (CsdWacomManager, csd_wacom_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static GVariant * map_tablet_mapping (GVariant *value, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { const gchar *mapping; mapping = g_variant_get_boolean (value) ? "absolute" : "relative"; return g_variant_new_string (mapping); } static GVariant * map_tablet_left_handed (GVariant *value, GSettings *origin_settings, GSettings *dest_settings, GVariant *old_default, GVariant *new_default) { const gchar *rotation = g_variant_get_string (value, NULL); return g_variant_new_boolean (g_strcmp0 (rotation, "half") == 0 || g_strcmp0 (rotation, "ccw") == 0); } static void migrate_tablet_settings (CsdWacomManager *manager, GdkDevice *device) { CsdSettingsMigrateEntry tablet_settings[] = { { "is-absolute", "mapping", map_tablet_mapping }, { "keep-aspect", "keep-aspect", NULL }, { "rotation", "left-handed", map_tablet_left_handed }, }; gchar *old_path, *new_path; const gchar *vendor, *product; vendor = gdk_device_get_vendor_id (device); product = gdk_device_get_product_id (device); old_path = g_strdup_printf ("/org/cinnamon/settings-daemon/peripherals/wacom/%s-usb:%s:%s/", manager->machine_id, vendor, product); new_path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/tablets/%s:%s/", vendor, product); csd_settings_migrate_check ("org.cinnamon.settings-daemon.peripherals.wacom.deprecated", old_path, "org.cinnamon.desktop.peripherals.tablet", new_path, tablet_settings, G_N_ELEMENTS (tablet_settings)); /* Opaque tablets' mapping may be modified by users, so only these * need migration of settings. */ if (is_opaque_tablet (manager, device)) { CsdSettingsMigrateEntry display_setting[] = { { "display", "output", NULL }, }; csd_settings_migrate_check ("org.cinnamon.desktop.peripherals.tablet.deprecated", new_path, "org.cinnamon.desktop.peripherals.tablet", new_path, display_setting, G_N_ELEMENTS (display_setting)); } g_free (old_path); g_free (new_path); } static void csd_wacom_manager_class_init (CsdWacomManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_wacom_manager_finalize; } static gchar * get_device_path (GdkDevice *device) { return xdevice_get_device_node (gdk_x11_device_get_id (device)); } static gboolean is_opaque_tablet (CsdWacomManager *manager, GdkDevice *device) { gboolean is_opaque = FALSE; #if HAVE_WACOM WacomDevice *wacom_device; gchar *devpath; devpath = get_device_path (device); wacom_device = libwacom_new_from_path (manager->wacom_db, devpath, WFALLBACK_GENERIC, NULL); if (wacom_device) { WacomIntegrationFlags integration_flags; integration_flags = libwacom_get_integration_flags (wacom_device); is_opaque = (integration_flags & (WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM)) == 0; libwacom_destroy (wacom_device); } #endif return is_opaque; } static GdkDevice * lookup_device_by_path (CsdWacomManager *manager, const gchar *path) { GList *devices, *l; devices = gdk_seat_get_slaves (manager->seat, GDK_SEAT_CAPABILITY_ALL); for (l = devices; l; l = l->next) { GdkDevice *device = l->data; gchar *dev_path = get_device_path (device); if (g_strcmp0 (dev_path, path) == 0) { g_free (dev_path); return device; } g_free (dev_path); } g_list_free (devices); return NULL; } static GSettings * device_get_settings (GdkDevice *device) { GSettings *settings; gchar *path; path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/tablets/%s:%s/", gdk_device_get_vendor_id (device), gdk_device_get_product_id (device)); settings = g_settings_new_with_path ("org.cinnamon.desktop.peripherals.tablet", path); g_free (path); return settings; } static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer data) { CsdWacomManager *self = CSD_WACOM_MANAGER (data); GError *error = NULL; GdkDevice *device; if (g_strcmp0 (method_name, "SetGroupModeLED") == 0) { gchar *device_path; guint group, mode; g_variant_get (parameters, "(suu)", &device_path, &group, &mode); device = lookup_device_by_path (self, device_path); if (!device) { g_dbus_method_invocation_return_value (invocation, NULL); return; } if (set_led (device_path, group, mode, &error)) g_dbus_method_invocation_return_value (invocation, NULL); else g_dbus_method_invocation_return_gerror (invocation, error); } else if (g_strcmp0 (method_name, "SetOLEDLabels") == 0) { gchar *device_path, *label; gboolean left_handed; GSettings *settings; GVariantIter *iter; gint i = 0; g_variant_get (parameters, "(sas)", &device_path, &iter); device = lookup_device_by_path (self, device_path); if (!device) { g_dbus_method_invocation_return_value (invocation, NULL); return; } settings = device_get_settings (device); left_handed = g_settings_get_boolean (settings, LEFT_HANDED_KEY); g_object_unref (settings); while (g_variant_iter_loop (iter, "s", &label)) { if (!set_oled (device_path, left_handed, i, label, &error)) { g_free (label); break; } i++; } g_variant_iter_free (iter); if (error) g_dbus_method_invocation_return_gerror (invocation, error); else g_dbus_method_invocation_return_value (invocation, NULL); } } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, /* Get Property */ NULL, /* Set Property */ }; static gboolean set_led (const gchar *device_path, guint group, guint index, GError **error) { char *command; gboolean ret; #ifndef HAVE_GUDEV /* Not implemented on non-Linux systems */ return TRUE; #endif g_debug ("Switching group ID %d to index %d for device %s", group, index, device_path); command = g_strdup_printf ("pkexec " LIBEXECDIR "/csd-wacom-led-helper --path %s --group %d --led %d", device_path, group, index); ret = g_spawn_command_line_sync (command, NULL, NULL, NULL, error); g_free (command); return ret; } static void device_added_cb (GdkSeat *seat, GdkDevice *device, CsdWacomManager *manager) { if (gdk_device_get_source (device) == GDK_SOURCE_PEN && gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_SLAVE) { migrate_tablet_settings (manager, device); } } static void add_devices (CsdWacomManager *manager, GdkSeatCapabilities capabilities) { GList *devices, *l; devices = gdk_seat_get_slaves (manager->seat, capabilities); for (l = devices; l ; l = l->next) device_added_cb (manager->seat, l->data, manager); g_list_free (devices); } static void set_devicepresence_handler (CsdWacomManager *manager) { GdkSeat *seat; seat = gdk_display_get_default_seat (gdk_display_get_default ()); manager->device_added_id = g_signal_connect (seat, "device-added", G_CALLBACK (device_added_cb), manager); manager->seat = seat; } static void csd_wacom_manager_init (CsdWacomManager *manager) { #if HAVE_WACOM manager->wacom_db = libwacom_database_new (); #endif } static gboolean csd_wacom_manager_idle_cb (CsdWacomManager *manager) { cinnamon_settings_profile_start (NULL); set_devicepresence_handler (manager); add_devices (manager, GDK_SEAT_CAPABILITY_TABLET_STYLUS); cinnamon_settings_profile_end (NULL); manager->start_idle_id = 0; return FALSE; } static void on_bus_gotten (GObject *source_object, GAsyncResult *res, CsdWacomManager *manager) { GDBusConnection *connection; GError *error = NULL; connection = g_bus_get_finish (res, &error); if (connection == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Couldn't get session bus: %s", error->message); g_error_free (error); return; } manager->dbus_connection = connection; manager->dbus_register_object_id = g_dbus_connection_register_object (connection, CSD_WACOM_DBUS_PATH, manager->introspection_data->interfaces[0], &interface_vtable, manager, NULL, &error); if (manager->dbus_register_object_id == 0) { g_warning ("Error registering object: %s", error->message); g_error_free (error); return; } manager->name_id = g_bus_own_name_on_connection (connection, CSD_WACOM_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); } static void register_manager (CsdWacomManager *manager) { manager->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); manager->dbus_cancellable = g_cancellable_new (); g_assert (manager->introspection_data != NULL); g_bus_get (G_BUS_TYPE_SESSION, manager->dbus_cancellable, (GAsyncReadyCallback) on_bus_gotten, manager); } static gchar * get_machine_id (void) { gchar *no_per_machine_file, *machine_id = NULL; gboolean per_machine; gsize len; no_per_machine_file = g_build_filename (g_get_user_config_dir (), "cinnamon-settings-daemon", "no-per-machine-config", NULL); per_machine = !g_file_test (no_per_machine_file, G_FILE_TEST_EXISTS); g_free (no_per_machine_file); if (!per_machine || (!g_file_get_contents ("/etc/machine-id", &machine_id, &len, NULL) && !g_file_get_contents ("/var/lib/dbus/machine-id", &machine_id, &len, NULL))) { return g_strdup ("00000000000000000000000000000000"); } machine_id[len - 1] = '\0'; return machine_id; } gboolean csd_wacom_manager_start (CsdWacomManager *manager, GError **error) { cinnamon_settings_profile_start (NULL); register_manager (manager_object); manager->machine_id = get_machine_id (); manager->start_idle_id = g_idle_add ((GSourceFunc) csd_wacom_manager_idle_cb, manager); g_source_set_name_by_id (manager->start_idle_id, "[cinnamon-settings-daemon] csd_wacom_manager_idle_cb"); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_wacom_manager_stop (CsdWacomManager *manager) { g_debug ("Stopping wacom manager"); g_clear_pointer (&manager->machine_id, g_free); if (manager->name_id != 0) { g_bus_unown_name (manager->name_id); manager->name_id = 0; } if (manager->dbus_register_object_id) { g_dbus_connection_unregister_object (manager->dbus_connection, manager->dbus_register_object_id); manager->dbus_register_object_id = 0; } if (manager->seat != NULL) { g_signal_handler_disconnect (manager->seat, manager->device_added_id); manager->seat = NULL; } } static void csd_wacom_manager_finalize (GObject *object) { CsdWacomManager *wacom_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_WACOM_MANAGER (object)); wacom_manager = CSD_WACOM_MANAGER (object); g_return_if_fail (wacom_manager != NULL); csd_wacom_manager_stop (wacom_manager); if (wacom_manager->start_idle_id != 0) g_source_remove (wacom_manager->start_idle_id); #if HAVE_WACOM libwacom_database_destroy (wacom_manager->wacom_db); #endif G_OBJECT_CLASS (csd_wacom_manager_parent_class)->finalize (object); } CsdWacomManager * csd_wacom_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_WACOM_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_WACOM_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/wacom/main.c0000664000175000017500000000101114733247605021234 0ustar fabiofabio#define NEW csd_wacom_manager_new #define START csd_wacom_manager_start #define STOP csd_wacom_manager_stop #define MANAGER CsdWacomManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-wacom-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-oled-constants.h0000664000175000017500000000303314733247605025133 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2013 Przemo Firszt * * 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 . * */ #ifndef __CSD_WACOM_OLED_CONSTANTS_H #define __CSD_WACOM_OLED_CONSTANTS_H G_BEGIN_DECLS typedef enum { CSD_WACOM_OLED_TYPE_USB, CSD_WACOM_OLED_TYPE_BLUETOOTH, CSD_WACOM_OLED_TYPE_RAW_BLUETOOTH } CsdWacomOledType; /* OLED parameters */ #define OLED_WIDTH 64 /*Width of OLED icon - hardware dependent*/ #define OLED_HEIGHT 32 /*Height of OLED icon - hardware dependent*/ #define LABEL_SIZE 30 /*Maximum length of text for OLED icon*/ #define MAX_TOKEN (LABEL_SIZE >> 1) /*Maximum number of tokens equals half of maximum number of characters*/ #define MAX_IMAGE_SIZE 1024 /*Size of buffer for storing OLED image*/ #define MAX_1ST_LINE_LEN 10 /*Maximum number of characters in 1st line of OLED icon*/ G_END_DECLS #endif /* __CSD_WACOM_OLED_CONSTANTS_H */ cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-oled.h0000664000175000017500000000220114733247605023115 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2013 Przemo Firszt * * 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 . * */ #include "csd-wacom-oled-constants.h" #include #ifndef __CSD_WACOM_OLED_H #define __CSD_WACOM_OLED_H G_BEGIN_DECLS gboolean set_oled (const gchar *device_path, gboolean left_handed, guint button, char *label, GError **error); char *csd_wacom_oled_gdkpixbuf_to_base64 (GdkPixbuf *pixbuf); G_END_DECLS #endif /* __CSD_WACOM_OLED_H */ cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-led-helper.c0000664000175000017500000001451114733247605024215 0ustar fabiofabio/* * Copyright (C) 2010-2011 Richard Hughes * Copyright (C) 2012 Bastien Nocera * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include #include #define LED_BRIGHTNESS 127 /* maximum brightness accepted by led on wacom Intuos4 connected over Bluetooth */ static int csd_wacom_led_helper_write (const gchar *filename, gint value, GError **error) { gchar *text = NULL; gint retval; gint length; gint fd = -1; int ret = 1; fd = open (filename, O_WRONLY); if (fd < 0) { g_set_error (error, 1, 0, "failed to open filename: %s", filename); goto out; } /* convert to text */ text = g_strdup_printf ("%i", value); length = strlen (text); /* write to device file */ retval = write (fd, text, length); if (retval != length) { g_set_error (error, 1, 0, "writing '%s' to %s failed", text, filename); goto out; } else ret = 0; out: if (fd >= 0) close (fd); g_free (text); return ret; } static char * get_led_sys_path (GUdevClient *client, GUdevDevice *device, int group_num, int led_num, gboolean usb, int *write_value) { GUdevDevice *parent; char *status = NULL; char *filename = NULL; GUdevDevice *hid_dev; const char *dev_uniq; GList *hid_list; GList *element; const char *dev_hid_uniq; /* check for new unified hid implementation first */ parent = g_udev_device_get_parent_with_subsystem (device, "hid", NULL); if (parent) { status = g_strdup_printf ("status_led%d_select", group_num); filename = g_build_filename (g_udev_device_get_sysfs_path (parent), "wacom_led", status, NULL); g_free (status); g_object_unref (parent); if(g_file_test (filename, G_FILE_TEST_EXISTS)) { *write_value = led_num; return filename; } g_clear_pointer (&filename, g_free); } /* old kernel */ if (usb) { parent = g_udev_device_get_parent_with_subsystem (device, "usb", "usb_interface"); if (!parent) goto no_parent; status = g_strdup_printf ("status_led%d_select", group_num); filename = g_build_filename (g_udev_device_get_sysfs_path (parent), "wacom_led", status, NULL); g_free (status); *write_value = led_num; } else { parent = g_udev_device_get_parent_with_subsystem (device, "input", NULL); if (!parent) goto no_parent; dev_uniq = g_udev_device_get_property (parent, "UNIQ"); hid_list = g_udev_client_query_by_subsystem (client, "hid"); element = g_list_first(hid_list); while (element) { hid_dev = (GUdevDevice*)element->data; dev_hid_uniq = g_udev_device_get_property (hid_dev, "HID_UNIQ"); if (g_strrstr (dev_uniq, dev_hid_uniq)){ status = g_strdup_printf ("/leds/%s:selector:%i/brightness", g_udev_device_get_name (hid_dev), led_num); filename = g_build_filename (g_udev_device_get_sysfs_path (hid_dev), status, NULL); g_free (status); break; } element = g_list_next(element); } g_list_free_full(hid_list, g_object_unref); *write_value = LED_BRIGHTNESS; } g_object_unref (parent); return filename; no_parent: g_debug ("Could not find proper parent device for '%s'", g_udev_device_get_device_file (device)); return NULL; } int main (int argc, char **argv) { GOptionContext *context; GUdevClient *client; GUdevDevice *device; int uid, euid; char *filename; gboolean usb; int value; GError *error = NULL; const char * const subsystems[] = { "hid", "input", NULL }; int ret = 1; char *path = NULL; int group_num = -1; int led_num = -1; const GOptionEntry options[] = { { "path", '\0', 0, G_OPTION_ARG_FILENAME, &path, "Device path for the Wacom device", NULL }, { "group", '\0', 0, G_OPTION_ARG_INT, &group_num, "Which LED group to set", NULL }, { "led", '\0', 0, G_OPTION_ARG_INT, &led_num, "Which LED to set", NULL }, { NULL} }; /* get calling process */ uid = getuid (); euid = geteuid (); if (uid != 0 || euid != 0) { g_print ("This program can only be used by the root user\n"); return 1; } context = g_option_context_new (NULL); g_option_context_set_summary (context, "GNOME Settings Daemon Wacom LED Helper"); g_option_context_add_main_entries (context, options, NULL); g_option_context_parse (context, &argc, &argv, NULL); if (path == NULL || group_num < 0 || led_num < 0) { char *txt; txt = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", txt); g_free (txt); g_option_context_free (context); return 1; } g_option_context_free (context); client = g_udev_client_new (subsystems); device = g_udev_client_query_by_device_file (client, path); if (device == NULL) { g_debug ("Could not find device '%s' in udev database", path); goto out; } if (g_udev_device_get_property_as_boolean (device, "ID_INPUT_TABLET") == FALSE && g_udev_device_get_property_as_boolean (device, "ID_INPUT_TOUCHPAD") == FALSE) { g_debug ("Device '%s' is not a Wacom tablet", path); goto out; } if (g_strcmp0 (g_udev_device_get_property (device, "ID_BUS"), "usb") != 0) usb = FALSE; else usb = TRUE; filename = get_led_sys_path (client, device, group_num, led_num, usb, &value); if (!filename) goto out; if (csd_wacom_led_helper_write (filename, value, &error)) { g_debug ("Could not set LED status for '%s': %s", path, error->message); g_error_free (error); g_free (filename); goto out; } g_free (filename); g_debug ("Successfully set LED status for '%s', group %d to %d", path, group_num, led_num); ret = 0; out: g_free (path); g_clear_object (&device); g_clear_object (&client); return ret; } cinnamon-settings-daemon-6.4.3/plugins/wacom/org.cinnamon.settings-daemon.plugins.wacom.policy.in0000664000175000017500000000341414733247605032260 0ustar fabiofabio CINNAMON Settings Daemon http://git.gnome.org/browse/gnome-settings-daemon input-tablet Modify the lit LED for a Wacom tablet Authentication is required to modify the lit LED for a Wacom tablet no no yes @libexecdir@/csd-wacom-led-helper Modify the OLED image for a Wacom tablet Authentication is required to modify the OLED image for a Wacom tablet no no yes @libexecdir@/csd-wacom-oled-helper cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-manager.h0000664000175000017500000000270414733247605023614 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2010 Red Hat, Inc. * * 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 . * */ #ifndef __CSD_WACOM_MANAGER_H #define __CSD_WACOM_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_WACOM_MANAGER (csd_wacom_manager_get_type ()) G_DECLARE_FINAL_TYPE (CsdWacomManager, csd_wacom_manager, CSD, WACOM_MANAGER, GObject) CsdWacomManager * csd_wacom_manager_new (void); gboolean csd_wacom_manager_start (CsdWacomManager *manager, GError **error); void csd_wacom_manager_stop (CsdWacomManager *manager); G_END_DECLS #endif /* __CSD_WACOM_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-oled.c0000664000175000017500000001457414733247605023130 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2013 Przemo Firszt * * 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 . * */ #include "config.h" #include #include #include #include #include #include #include #include "csd-wacom-oled.h" #define MAGIC_BASE64 "base64:" /*Label starting with base64: is treated as already encoded*/ #define MAGIC_BASE64_LEN strlen(MAGIC_BASE64) static void oled_surface_to_image (guchar *image, cairo_surface_t *surface) { unsigned char *csurf; int i, x, y; unsigned char lo, hi; cairo_surface_flush (surface); csurf = cairo_image_surface_get_data (surface); i = 0; for (y = 0; y < OLED_HEIGHT; y++) { for (x = 0; x < (OLED_WIDTH / 2); x++) { hi = 0xf0 & csurf[4 * OLED_WIDTH * y + 8 * x + 1]; lo = 0x0f & (csurf[4 * OLED_WIDTH * y + 8 * x + 5] >> 4); image[i] = hi | lo; i++; } } } static void oled_split_text (char *label, char *line1, char *line2) { char delimiters[5] = "+-_ "; char **token; int token_len[MAX_TOKEN]; gsize length; int i; if (g_utf8_strlen (label, LABEL_SIZE) <= MAX_1ST_LINE_LEN) { g_utf8_strncpy (line1, label, MAX_1ST_LINE_LEN); return; } token = g_strsplit_set (label, delimiters, -1); if (g_utf8_strlen (token[0], LABEL_SIZE) > MAX_1ST_LINE_LEN) { g_utf8_strncpy (line1, label, MAX_1ST_LINE_LEN); g_utf8_strncpy (line2, label + MAX_1ST_LINE_LEN, LABEL_SIZE - MAX_1ST_LINE_LEN); return; } for (i = 0; token[i] != NULL; i++) token_len[i] = g_utf8_strlen (token[i], LABEL_SIZE); length = token_len[0]; i = 0; while ((length + token_len[i + 1] + 1) <= MAX_1ST_LINE_LEN) { i++; length = length + token_len[i] + 1; } g_utf8_strncpy (line1, label, length); g_utf8_strncpy (line2, label + length + 1, LABEL_SIZE - length); return; } static void oled_render_text (char *label, guchar *image, gboolean left_handed) { cairo_t *cr; cairo_surface_t *surface; PangoFontDescription *desc; PangoLayout *layout; int width, height; double dx, dy; char line1[LABEL_SIZE + 1] = ""; char line2[LABEL_SIZE + 1] = ""; char *buf; oled_split_text (label ,line1, line2); buf = g_strdup_printf ("%s\n%s", line1, line2); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, OLED_WIDTH, OLED_HEIGHT); cr = cairo_create (surface); /* Rotate text so it's seen correctly on the device, or at * least from top to bottom for LTR text in vertical modes. */ if (left_handed) { cairo_translate (cr, OLED_WIDTH, OLED_HEIGHT); cairo_scale (cr, -1, -1); } cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.99); cairo_paint (cr); layout = pango_cairo_create_layout (cr); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_text (layout, buf, - 1); g_free (buf); desc = pango_font_description_new (); pango_font_description_set_family (desc, "Terminal"); pango_font_description_set_absolute_size (desc, PANGO_SCALE * 11); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_get_size (layout, &width, &height); width = width/PANGO_SCALE; cairo_new_path (cr); dx = trunc (((double)OLED_WIDTH - width) / 2); if (*line2 == '\0') dy = 10; else dy = 4; cairo_move_to (cr, dx, dy); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); pango_cairo_update_layout (cr, layout); pango_cairo_layout_path (cr, layout); cairo_fill (cr); oled_surface_to_image (image, surface); g_object_unref (layout); cairo_destroy (cr); cairo_surface_destroy (surface); } char * csd_wacom_oled_gdkpixbuf_to_base64 (GdkPixbuf *pixbuf) { int i, x, y, ch, rs; guchar *pix, *p; guchar *image; guchar lo, hi; char *base_string, *base64; if (OLED_WIDTH != gdk_pixbuf_get_width (pixbuf)) return NULL; if (OLED_HEIGHT != gdk_pixbuf_get_height (pixbuf)) return NULL; ch = gdk_pixbuf_get_n_channels (pixbuf); rs = gdk_pixbuf_get_rowstride (pixbuf); pix = gdk_pixbuf_get_pixels (pixbuf); image = g_malloc (MAX_IMAGE_SIZE); i = 0; for (y = 0; y < OLED_HEIGHT; y++) { for (x = 0; x < (OLED_WIDTH / 2); x++) { p = pix + y * rs + 2 * x * ch; hi = 0xf0 & ((p[0] + p[1] + p[2])/ 3 * p[3] / 0xff); p = pix + y * rs + ((2 * x) + 1) * ch; lo = 0x0f & (((p[0] + p[1] + p[2])/ 3 * p[3] / 0xff) >> 4); image[i] = hi | lo; i++; } } base_string = g_base64_encode (image, MAX_IMAGE_SIZE); base64 = g_strconcat (MAGIC_BASE64, base_string, NULL); g_free (base_string); g_free (image); return base64; } static char * oled_encode_image (char *label, gboolean left_handed) { unsigned char *image; image = g_malloc (MAX_IMAGE_SIZE); /* convert label to image */ oled_render_text (label, image, left_handed); return (g_base64_encode (image, MAX_IMAGE_SIZE)); } gboolean set_oled (const gchar *device_path, gboolean left_handed, guint button, char *label, GError **error) { char *command; gboolean ret; char *buffer; gint status; #ifndef HAVE_GUDEV /* Not implemented on non-Linux systems */ return TRUE; #endif if (g_str_has_prefix (label, MAGIC_BASE64)) { buffer = g_strdup (label + MAGIC_BASE64_LEN); } else { buffer = oled_encode_image (label, left_handed); } g_debug ("Setting OLED label '%s' on button %d (device %s)", label, button, device_path); command = g_strdup_printf ("pkexec " LIBEXECDIR "/csd-wacom-oled-helper --path %s --button %d --buffer %s", device_path, button, buffer); ret = g_spawn_command_line_sync (command, NULL, NULL, &status, error); if (ret == TRUE && status != 0) ret = FALSE; g_free (command); return ret; } cinnamon-settings-daemon-6.4.3/plugins/wacom/csd-wacom-oled-helper.c0000664000175000017500000002522414733247605024377 0ustar fabiofabio/* * Copyright (C) 2012 Przemo Firszt * * The code is derived from csd-wacom-led-helper.c * written by: * Copyright (C) 2010-2011 Richard Hughes * Copyright (C) 2012 Bastien Nocera * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "config.h" #include #include #include #include #include #include #include "csd-wacom-oled-constants.h" #define USB_PIXELS_PER_BYTE 2 #define BT_PIXELS_PER_BYTE 8 #define USB_BUF_LEN OLED_HEIGHT * OLED_WIDTH / USB_PIXELS_PER_BYTE #define BT_BUF_LEN OLED_WIDTH * OLED_HEIGHT / BT_PIXELS_PER_BYTE static void oled_scramble_icon (guchar *image) { guchar buf[USB_BUF_LEN]; int x, y, i; guchar l1, l2, h1, h2; for (i = 0; i < USB_BUF_LEN; i++) buf[i] = image[i]; for (y = 0; y < (OLED_HEIGHT / 2); y++) { for (x = 0; x < (OLED_WIDTH / 2); x++) { l1 = (0x0F & (buf[OLED_HEIGHT - 1 - x + OLED_WIDTH * y])); l2 = (0x0F & (buf[OLED_HEIGHT - 1 - x + OLED_WIDTH * y] >> 4)); h1 = (0xF0 & (buf[OLED_WIDTH - 1 - x + OLED_WIDTH * y] << 4)); h2 = (0xF0 & (buf[OLED_WIDTH - 1 - x + OLED_WIDTH * y])); image[2 * x + OLED_WIDTH * y] = h1 | l1; image[2 * x + 1 + OLED_WIDTH * y] = h2 | l2; } } } static void oled_bt_scramble_icon (guchar *input_image) { unsigned char image[BT_BUF_LEN]; unsigned mask; unsigned s1; unsigned s2; unsigned r1 ; unsigned r2 ; unsigned r; unsigned char buf[256]; int i, w, x, y, z; for (i = 0; i < BT_BUF_LEN; i++) image[i] = input_image[i]; for (x = 0; x < 32; x++) { for (y = 0; y < 8; y++) buf[(8 * x) + (7 - y)] = image[(8 * x) + y]; } /* Change 76543210 into GECA6420 as required by Intuos4 WL * HGFEDCBA HFDB7531 */ for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++) { for (z = 0; z < 8; z++) { mask = 0x0001; r1 = 0; r2 = 0; i = (x << 6) + (y << 4) + z; s1 = buf[i]; s2 = buf[i+8]; for (w = 0; w < 8; w++) { r1 |= (s1 & mask); r2 |= (s2 & mask); s1 <<= 1; s2 <<= 1; mask <<= 2; } r = r1 | (r2 << 1); i = (x << 6) + (y << 4) + (z << 1); image[i] = 0xFF & r; image[i+1] = (0xFF00 & r) >> 8; } } } for (i = 0; i < BT_BUF_LEN; i++) input_image[i] = image[i]; } static void csd_wacom_oled_convert_1_bit (guchar *image) { guchar buf[BT_BUF_LEN]; guchar b0, b1, b2, b3, b4, b5, b6, b7; int i; for (i = 0; i < BT_BUF_LEN; i++) { b0 = 0b10000000 & (image[(4 * i) + 0] >> 0); b1 = 0b01000000 & (image[(4 * i) + 0] << 3); b2 = 0b00100000 & (image[(4 * i) + 1] >> 2); b3 = 0b00010000 & (image[(4 * i) + 1] << 1); b4 = 0b00001000 & (image[(4 * i) + 2] >> 4); b5 = 0b00000100 & (image[(4 * i) + 2] >> 1); b6 = 0b00000010 & (image[(4 * i) + 3] >> 6); b7 = 0b00000001 & (image[(4 * i) + 3] >> 3); buf[i] = b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7; } for (i = 0; i < BT_BUF_LEN; i++) image[i] = buf[i]; } static int csd_wacom_oled_prepare_buf (guchar *image, CsdWacomOledType type) { int len = 0; switch (type) { case CSD_WACOM_OLED_TYPE_USB: /* Image has to be scrambled for devices connected over USB ... */ oled_scramble_icon (image); len = USB_BUF_LEN; break; case CSD_WACOM_OLED_TYPE_BLUETOOTH: /* ... but for bluetooth it has to be converted to 1 bit colour instead of scrambling */ csd_wacom_oled_convert_1_bit (image); len = BT_BUF_LEN; break; case CSD_WACOM_OLED_TYPE_RAW_BLUETOOTH: /* Image has also to be scrambled for devices connected over BT using the raw API ... */ csd_wacom_oled_convert_1_bit (image); len = BT_BUF_LEN; oled_bt_scramble_icon (image); break; default: g_assert_not_reached (); } return len; } static gboolean csd_wacom_oled_helper_write (const gchar *filename, gchar *buffer, CsdWacomOledType type, GError **error) { guchar *image; gint retval; gsize length; gint fd = -1; gboolean ret = TRUE; fd = open (filename, O_WRONLY); if (fd < 0) { ret = FALSE; g_set_error (error, 1, 0, "Failed to open filename: %s", filename); goto out; } image = g_base64_decode (buffer, &length); if (length != USB_BUF_LEN) { ret = FALSE; g_set_error (error, 1, 0, "Base64 buffer has length of %" G_GSIZE_FORMAT " (expected %i)", length, USB_BUF_LEN); goto out; } if (!image) { ret = FALSE; g_set_error (error, 1, 0, "Decoding base64 buffer failed"); goto out; } length = csd_wacom_oled_prepare_buf (image, type); if (!length) { ret = FALSE; g_set_error (error, 1, 0, "Invalid image buffer length"); goto out; } retval = write (fd, image, length); if (retval != length) { ret = FALSE; g_set_error (error, 1, 0, "Writing to %s failed", filename); } g_free (image); out: if (fd >= 0) close (fd); return ret; } static char * get_oled_sysfs_path (GUdevDevice *device, int button_num) { char *status; char *filename; status = g_strdup_printf ("button%d_rawimg", button_num); filename = g_build_filename (g_udev_device_get_sysfs_path (device), "wacom_led", status, NULL); g_free (status); return filename; } static char * get_bt_oled_sysfs_path (GUdevDevice *device, int button_num) { char *status; char *filename; status = g_strdup_printf ("/oled%i_img", button_num); filename = g_build_filename (g_udev_device_get_sysfs_path (device), status, NULL); g_free (status); return filename; } static char * get_bt_oled_filename (GUdevClient *client, GUdevDevice *device, int button_num) { GUdevDevice *hid_dev; const char *dev_uniq; GList *hid_list; GList *element; const char *dev_hid_uniq; char *filename = NULL; dev_uniq = g_udev_device_get_property (device, "UNIQ"); hid_list = g_udev_client_query_by_subsystem (client, "hid"); element = g_list_first(hid_list); while (element) { hid_dev = (GUdevDevice*)element->data; dev_hid_uniq = g_udev_device_get_property (hid_dev, "HID_UNIQ"); if (g_strrstr (dev_uniq, dev_hid_uniq)){ filename = get_bt_oled_sysfs_path (hid_dev, button_num); g_object_unref (hid_dev); break; } g_object_unref (hid_dev); element = g_list_next(element); } g_list_free(hid_list); return filename; } static char * get_oled_sys_path (GUdevClient *client, GUdevDevice *device, int button_num, gboolean usb, CsdWacomOledType *type) { GUdevDevice *parent; char *filename = NULL; /* check for new unified hid implementation first */ parent = g_udev_device_get_parent_with_subsystem (device, "hid", NULL); if (parent) { filename = get_oled_sysfs_path (parent, button_num); g_object_unref (parent); if(g_file_test (filename, G_FILE_TEST_EXISTS)) { *type = usb ? CSD_WACOM_OLED_TYPE_USB : CSD_WACOM_OLED_TYPE_RAW_BLUETOOTH; return filename; } g_clear_pointer (&filename, g_free); } /* old kernel */ if (usb) { parent = g_udev_device_get_parent_with_subsystem (device, "usb", "usb_interface"); if (!parent) goto no_parent; filename = get_oled_sysfs_path (parent, button_num); *type = CSD_WACOM_OLED_TYPE_USB; } else if (g_strrstr (g_udev_device_get_property (device, "DEVPATH"), "bluetooth")) { parent = g_udev_device_get_parent_with_subsystem (device, "input", NULL); if (!parent) goto no_parent; filename = get_bt_oled_filename (client, parent, button_num); *type = CSD_WACOM_OLED_TYPE_BLUETOOTH; } else { g_critical ("Not an expected device: '%s'", g_udev_device_get_device_file (device)); goto out_err; } g_object_unref (parent); return filename; no_parent: g_debug ("Could not find proper parent device for '%s'", g_udev_device_get_device_file (device)); out_err: return NULL; } int main (int argc, char **argv) { GOptionContext *context; GUdevClient *client; GUdevDevice *device; int uid, euid; char *filename; GError *error = NULL; const char * const subsystems[] = { "input", NULL }; int ret = 1; gboolean usb; CsdWacomOledType type; char *path = NULL; char *buffer = NULL; int button_num = -1; const GOptionEntry options[] = { { "path", '\0', 0, G_OPTION_ARG_FILENAME, &path, "Device path for the Wacom device", NULL }, { "buffer", '\0', 0, G_OPTION_ARG_STRING, &buffer, "Image to set base64 encoded", NULL }, { "button", '\0', 0, G_OPTION_ARG_INT, &button_num, "Which button icon to set", NULL }, { NULL} }; /* get calling process */ uid = getuid (); euid = geteuid (); if (uid != 0 || euid != 0) { g_print ("This program can only be used by the root user\n"); return 1; } context = g_option_context_new (NULL); g_option_context_set_summary (context, "GNOME Settings Daemon Wacom OLED Icon Helper"); g_option_context_add_main_entries (context, options, NULL); g_option_context_parse (context, &argc, &argv, NULL); if (path == NULL || button_num < 0 || buffer == NULL) { char *txt; txt = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", txt); g_free (txt); g_option_context_free (context); return 1; } g_option_context_free (context); client = g_udev_client_new (subsystems); device = g_udev_client_query_by_device_file (client, path); if (device == NULL) { g_critical ("Could not find device '%s' in udev database", path); goto out; } if (g_udev_device_get_property_as_boolean (device, "ID_INPUT_TABLET") == FALSE && g_udev_device_get_property_as_boolean (device, "ID_INPUT_TOUCHPAD") == FALSE) { g_critical ("Device '%s' is not a Wacom tablet", path); goto out; } if (g_strcmp0 (g_udev_device_get_property (device, "ID_BUS"), "usb") != 0) usb = FALSE; else usb = TRUE; filename = get_oled_sys_path (client, device, button_num, usb, &type); if (!filename) goto out; if (csd_wacom_oled_helper_write (filename, buffer, type, &error) == FALSE) { g_critical ("Could not set OLED icon for '%s': %s", path, error->message); g_error_free (error); g_free (filename); goto out; } g_free (filename); g_debug ("Successfully set OLED icon for '%s', button %d", path, button_num); ret = 0; out: g_free (path); g_free (buffer); g_clear_object (&device); g_clear_object (&client); return ret; } cinnamon-settings-daemon-6.4.3/plugins/power/0000775000175000017500000000000014733247605020201 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/power/meson.build0000664000175000017500000000522214733247605022344 0ustar fabiofabioplugin_name = 'power' power_proxy = gnome.gdbus_codegen( 'csd-power-proxy', 'org.cinnamon.SettingsDaemon.Power.xml', namespace: 'Csd', annotations: [ ['org.cinnamon.SettingsDaemon.Power', 'org.gtk.GDBus.C.Name', 'Power'] ], ) power_screen_proxy = gnome.gdbus_codegen( 'csd-power-screen-proxy', 'org.cinnamon.SettingsDaemon.Power.Screen.xml', namespace: 'Csd', annotations: [ ['org.cinnamon.SettingsDaemon.Power.Screen', 'org.gtk.GDBus.C.Name', 'Screen'] ], ) power_keyboard_proxy = gnome.gdbus_codegen( 'csd-power-keyboard-proxy', 'org.cinnamon.SettingsDaemon.Power.Keyboard.xml', namespace: 'Csd', annotations: [ ['org.cinnamon.SettingsDaemon.Power.Keyboard', 'org.gtk.GDBus.C.Name', 'Keyboard'] ], ) power_sources = [ 'csd-power-manager.c', 'gpm-common.c', 'gpm-phone.c', 'gpm-idletime.c', 'main.c', power_proxy, power_screen_proxy, power_keyboard_proxy, ] backlight_sources = [ 'csd-backlight-helper.c', ] power_deps = [ canberra, cinnamon_desktop, common_dep, csd_dep, gio_unix, libnotify, math, upower_glib, xext, ] executable( 'csd-power', power_sources, include_directories: [include_dirs, common_inc, include_enums], dependencies: power_deps, c_args: [ '-DPLUGIN_NAME="@0@"'.format(plugin_name), '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), ], install_rpath: join_paths(prefix, apilibdir), install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-power') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-power') endif if gudev.found() executable( 'csd-backlight-helper', backlight_sources, include_directories: [include_dirs, common_inc], dependencies: [power_deps, gudev], c_args: [ # '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-backlight-helper') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-backlight-helper') endif endif configure_file( input: 'cinnamon-settings-daemon-power.desktop.in', output: 'cinnamon-settings-daemon-power.desktop', configuration: desktop_conf, install_dir: autostartdir, ) configure_file( input: 'org.cinnamon.settings-daemon.plugins.power.policy.in', output: 'org.cinnamon.settings-daemon.plugins.power.policy', configuration: desktop_conf, install_dir: polkitdir, ) cinnamon-settings-daemon-6.4.3/plugins/power/gpm-phone.h0000664000175000017500000000627314733247605022254 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __GPMPHONE_H #define __GPMPHONE_H #include G_BEGIN_DECLS #define GPM_TYPE_PHONE (gpm_phone_get_type ()) #define GPM_PHONE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_PHONE, GpmPhone)) #define GPM_PHONE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_PHONE, GpmPhoneClass)) #define GPM_IS_PHONE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_PHONE)) #define GPM_IS_PHONE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_PHONE)) #define GPM_PHONE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_PHONE, GpmPhoneClass)) #define CINNAMON_PHONE_MANAGER_DBUS_SERVICE "org.cinnamon.phone" #define CINNAMON_PHONE_MANAGER_DBUS_PATH "/org/cinnamon/phone/Manager" #define CINNAMON_PHONE_MANAGER_DBUS_INTERFACE "org.cinnamon.phone.Manager" typedef struct GpmPhonePrivate GpmPhonePrivate; typedef struct { GObject parent; GpmPhonePrivate *priv; } GpmPhone; typedef struct { GObjectClass parent_class; void (* device_added) (GpmPhone *phone, guint idx); void (* device_removed) (GpmPhone *phone, guint idx); void (* device_refresh) (GpmPhone *phone, guint idx); } GpmPhoneClass; GType gpm_phone_get_type (void); GpmPhone *gpm_phone_new (void); gboolean gpm_phone_get_present (GpmPhone *phone, guint idx); guint gpm_phone_get_percentage (GpmPhone *phone, guint idx); gboolean gpm_phone_get_on_ac (GpmPhone *phone, guint idx); guint gpm_phone_get_num_batteries (GpmPhone *phone); gboolean gpm_phone_coldplug (GpmPhone *phone); G_END_DECLS #endif /* __GPMPHONE_H */ cinnamon-settings-daemon-6.4.3/plugins/power/gpm-common.h0000664000175000017500000000371714733247605022433 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __GPMCOMMON_H #define __GPMCOMMON_H #include #include G_BEGIN_DECLS gchar *gpm_get_timestring (guint time); const gchar *gpm_device_to_localised_string (UpDevice *device); const gchar *gpm_device_kind_to_localised_string (UpDeviceKind kind, guint number); const gchar *gpm_device_kind_to_icon (UpDeviceKind kind); const gchar *gpm_device_technology_to_localised_string (UpDeviceTechnology technology_enum); const gchar *gpm_device_state_to_localised_string (UpDeviceState state); GIcon *gpm_upower_get_device_icon (UpDevice *device, gboolean use_symbolic); gchar *gpm_upower_get_device_summary (UpDevice *device); gchar *gpm_upower_get_device_description (UpDevice *device); G_END_DECLS #endif /* __GPMCOMMON_H */ cinnamon-settings-daemon-6.4.3/plugins/power/org.cinnamon.SettingsDaemon.Power.Keyboard.xml0000664000175000017500000000173314733247605031074 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/plugins/power/csd-backlight-helper.c0000664000175000017500000001623114733247605024324 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2010-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #define CSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS 0 #define CSD_BACKLIGHT_HELPER_EXIT_CODE_FAILED 1 #define CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID 3 #define CSD_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER 4 #define CSD_BACKLIGHT_HELPER_EXIT_CODE_NO_DEVICES 5 #define CSD_POWER_SETTINGS_SCHEMA "org.cinnamon.settings-daemon.plugins.power" static gchar * csd_backlight_helper_get_type (GList *devices, const gchar *type) { const gchar *type_tmp; GList *d; for (d = devices; d != NULL; d = d->next) { type_tmp = g_udev_device_get_sysfs_attr (d->data, "type"); if (g_strcmp0 (type_tmp, type) == 0) return g_strdup (g_udev_device_get_sysfs_path (d->data)); } return NULL; } static gchar * csd_backlight_helper_get_best_backlight (gchar** preference_list) { gchar *path = NULL; GList *devices; GUdevClient *client; client = g_udev_client_new (NULL); devices = g_udev_client_query_by_subsystem (client, "backlight"); if (devices == NULL) goto out; /* setup our gsettings interface */ if (preference_list == NULL || preference_list[0] == NULL) { g_print("%s\n%s\n", "Warning: no backlight sources have been configured.", "Check " CSD_POWER_SETTINGS_SCHEMA " to configure some."); goto out; } int i = 0; for (i=0; preference_list[i] != NULL; i++) { path = csd_backlight_helper_get_type (devices, preference_list[i]); if (path != NULL) goto out; } out: g_object_unref (client); g_list_foreach (devices, (GFunc) g_object_unref, NULL); g_list_free (devices); return path; } static gboolean csd_backlight_helper_write (const gchar *filename, gint value, GError **error) { gchar *text = NULL; gint retval; gint length; gint fd = -1; gboolean ret = TRUE; fd = open (filename, O_WRONLY); if (fd < 0) { ret = FALSE; g_set_error (error, 1, 0, "failed to open filename: %s", filename); goto out; } /* convert to text */ text = g_strdup_printf ("%i", value); length = strlen (text); /* write to device file */ retval = write (fd, text, length); if (retval != length) { ret = FALSE; g_set_error (error, 1, 0, "writing '%s' to %s failed", text, filename); goto out; } out: if (fd >= 0) close (fd); g_free (text); return ret; } int main (int argc, char *argv[]) { GOptionContext *context; gint uid; gint euid; guint retval = 0; GError *error = NULL; gboolean ret = FALSE; gint set_brightness = -1; gboolean get_brightness = FALSE; gboolean get_max_brightness = FALSE; gchar *filename = NULL; gchar *filename_file = NULL; gchar *contents = NULL; gchar** backlight_preference_order = NULL; const GOptionEntry options[] = { { "set-brightness", '\0', 0, G_OPTION_ARG_INT, &set_brightness, /* command line argument */ "Set the current brightness", NULL }, { "get-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_brightness, /* command line argument */ "Get the current brightness", NULL }, { "get-max-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_max_brightness, /* command line argument */ "Get the number of brightness levels supported", NULL }, { "backlight-preference", 'b', 0, G_OPTION_ARG_STRING_ARRAY, &backlight_preference_order, /* command line argument */ "Set a backlight control search preference", NULL }, { NULL} }; context = g_option_context_new (NULL); g_option_context_set_summary (context, "Cinnamon Settings Daemon Backlight Helper"); g_option_context_add_main_entries (context, options, NULL); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); #ifndef __linux__ /* the g-s-d plugin should only call this helper on linux */ g_critical ("Attempting to call gsb-backlight-helper on non-Linux"); g_assert_not_reached (); #endif /* no input */ if (set_brightness == -1 && !get_brightness && !get_max_brightness) { g_print ("%s\n", "No valid option was specified"); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; goto out; } /* find device */ filename = csd_backlight_helper_get_best_backlight (backlight_preference_order); if (filename == NULL) { retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_NO_DEVICES; g_print ("%s: %s\n", "Could not get or set the value of the backlight", "No backlight devices present"); goto out; } /* GetBrightness */ if (get_brightness) { filename_file = g_build_filename (filename, "brightness", NULL); ret = g_file_get_contents (filename_file, &contents, NULL, &error); if (!ret) { g_print ("%s: %s\n", "Could not get the value of the backlight", error->message); g_error_free (error); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; goto out; } /* just print the contents to stdout */ g_print ("%s", contents); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS; goto out; } /* GetSteps */ if (get_max_brightness) { filename_file = g_build_filename (filename, "max_brightness", NULL); ret = g_file_get_contents (filename_file, &contents, NULL, &error); if (!ret) { g_print ("%s: %s\n", "Could not get the maximum value of the backlight", error->message); g_error_free (error); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; goto out; } /* just print the contents to stdout */ g_print ("%s", contents); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS; goto out; } /* check calling UID */ uid = getuid (); euid = geteuid (); if (uid != 0 || euid != 0) { g_print ("%s\n", "This program can only be used by the root user"); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; goto out; } /* SetBrightness */ if (set_brightness != -1) { filename_file = g_build_filename (filename, "brightness", NULL); ret = csd_backlight_helper_write (filename_file, set_brightness, &error); if (!ret) { g_print ("%s: %s\n", "Could not set the value of the backlight", error->message); g_error_free (error); retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID; goto out; } } /* success */ retval = CSD_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS; out: g_free (filename); g_free (filename_file); g_free (contents); return retval; } cinnamon-settings-daemon-6.4.3/plugins/power/gpm-common.c0000664000175000017500000012353114733247605022423 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "gpm-common.h" #define GPM_UP_TIME_PRECISION 5*60 #define GPM_UP_TEXT_MIN_TIME 120 /** * Return value: The time string, e.g. "2 hours 3 minutes" **/ gchar * gpm_get_timestring (guint time_secs) { char* timestring = NULL; gint hours; gint minutes; /* Add 0.5 to do rounding */ minutes = (int) ( ( time_secs / 60.0 ) + 0.5 ); if (minutes == 0) { timestring = g_strdup (_("Unknown time")); return timestring; } if (minutes < 60) { timestring = g_strdup_printf (ngettext ("%i minute", "%i minutes", minutes), minutes); return timestring; } hours = minutes / 60; minutes = minutes % 60; if (minutes == 0) timestring = g_strdup_printf (ngettext ( "%i hour", "%i hours", hours), hours); else /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" * Swap order with "%2$s %2$i %1$s %1$i if needed */ timestring = g_strdup_printf (_("%i %s %i %s"), hours, ngettext ("hour", "hours", hours), minutes, ngettext ("minute", "minutes", minutes)); return timestring; } static const gchar * gpm_upower_get_device_icon_index (UpDevice *device) { gdouble percentage; /* get device properties */ g_object_get (device, "percentage", &percentage, NULL); if (percentage < 10) return "000"; else if (percentage < 30) return "020"; else if (percentage < 50) return "040"; else if (percentage < 70) return "060"; else if (percentage < 90) return "080"; return "100"; } static const gchar * gpm_upower_get_device_icon_suffix (UpDevice *device) { gdouble percentage; /* get device properties */ g_object_get (device, "percentage", &percentage, NULL); if (percentage < 10) return "caution"; else if (percentage < 30) return "low"; else if (percentage < 60) return "good"; return "full"; } static const gchar * gpm_upower_get_precise_icon_index (UpDevice *device) { gdouble percentage; /* get device properties */ g_object_get (device, "percentage", &percentage, NULL); if (percentage < 10) return "0"; else if (percentage < 20) return "10"; else if (percentage < 30) return "20"; else if (percentage < 40) return "30"; else if (percentage < 50) return "40"; else if (percentage < 60) return "50"; else if (percentage < 70) return "60"; else if (percentage < 80) return "70"; else if (percentage < 90) return "80"; else if (percentage < 99) return "90"; return "100"; } GIcon * gpm_upower_get_device_icon (UpDevice *device, gboolean use_symbolic) { GString *filename; gchar **iconnames; const gchar *kind_str; const gchar *suffix_str; const gchar *index_str; const gchar *precise_str; UpDeviceKind kind; UpDeviceState state; gboolean is_present; gdouble percentage; GIcon *icon = NULL; g_return_val_if_fail (device != NULL, NULL); /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, "percentage", &percentage, "is-present", &is_present, NULL); /* get correct icon prefix */ filename = g_string_new (NULL); /* get the icon from some simple rules */ if (kind == UP_DEVICE_KIND_LINE_POWER) { if (use_symbolic) g_string_append (filename, "ac-adapter-symbolic;"); g_string_append (filename, "ac-adapter;"); } else if (kind == UP_DEVICE_KIND_MONITOR) { if (use_symbolic) g_string_append (filename, "gpm-monitor-symbolic;"); g_string_append (filename, "gpm-monitor;"); } else { kind_str = up_device_kind_to_string (kind); if (!is_present) { if (use_symbolic) g_string_append (filename, "battery-missing-symbolic;"); g_string_append_printf (filename, "gpm-%s-missing;", kind_str); g_string_append_printf (filename, "gpm-%s-000;", kind_str); g_string_append (filename, "battery-missing;"); } else { switch (state) { case UP_DEVICE_STATE_EMPTY: if (use_symbolic) g_string_append (filename, "battery-empty-symbolic;"); g_string_append_printf (filename, "gpm-%s-empty;", kind_str); g_string_append_printf (filename, "gpm-%s-000;", kind_str); g_string_append (filename, "battery-empty;"); break; case UP_DEVICE_STATE_FULLY_CHARGED: if (use_symbolic) { g_string_append (filename, "battery-level-100-charged-symbolic;"); g_string_append (filename, "battery-full-charged-symbolic;"); g_string_append (filename, "battery-full-charging-symbolic;"); } g_string_append_printf (filename, "gpm-%s-full;", kind_str); g_string_append_printf (filename, "gpm-%s-100;", kind_str); g_string_append (filename, "battery-full-charged;"); g_string_append (filename, "battery-full-charging;"); break; case UP_DEVICE_STATE_CHARGING: case UP_DEVICE_STATE_PENDING_CHARGE: suffix_str = gpm_upower_get_device_icon_suffix (device); index_str = gpm_upower_get_device_icon_index (device); precise_str = gpm_upower_get_precise_icon_index (device); if (use_symbolic) { g_string_append_printf (filename, "battery-level-%s-charging-symbolic;", precise_str); g_string_append_printf (filename, "battery-%s-charging-symbolic;", suffix_str); } g_string_append_printf (filename, "gpm-%s-%s-charging;", kind_str, index_str); g_string_append_printf (filename, "battery-%s-charging;", suffix_str); break; case UP_DEVICE_STATE_DISCHARGING: case UP_DEVICE_STATE_PENDING_DISCHARGE: suffix_str = gpm_upower_get_device_icon_suffix (device); index_str = gpm_upower_get_device_icon_index (device); precise_str = gpm_upower_get_precise_icon_index (device); if (use_symbolic) { g_string_append_printf (filename, "battery-level-%s-symbolic;", precise_str); g_string_append_printf (filename, "battery-%s-symbolic;", suffix_str); } g_string_append_printf (filename, "gpm-%s-%s;", kind_str, index_str); g_string_append_printf (filename, "battery-%s;", suffix_str); break; case UP_DEVICE_STATE_UNKNOWN: case UP_DEVICE_STATE_LAST: default: if (use_symbolic) g_string_append (filename, "battery-missing-symbolic;"); g_string_append (filename, "gpm-battery-missing;"); g_string_append (filename, "battery-missing;"); } } } /* nothing matched */ if (filename->len == 0) { g_warning ("nothing matched, falling back to default icon"); g_string_append (filename, "dialog-warning;"); } g_debug ("got filename: %s", filename->str); iconnames = g_strsplit (filename->str, ";", -1); icon = g_themed_icon_new_from_names (iconnames, -1); g_strfreev (iconnames); g_string_free (filename, TRUE); return icon; } /** * gpm_precision_round_down: * @value: The input value * @smallest: The smallest increment allowed * * 101, 10 100 * 95, 10 90 * 0, 10 0 * 112, 10 110 * 100, 10 100 **/ static gint gpm_precision_round_down (gfloat value, gint smallest) { gfloat division; if (fabs (value) < 0.01) return 0; if (smallest == 0) { g_warning ("divisor zero"); return 0; } division = (gfloat) value / (gfloat) smallest; division = floorf (division); division *= smallest; return (gint) division; } gchar * gpm_upower_get_device_summary (UpDevice *device) { const gchar *kind_desc = NULL; const gchar *device_desc = NULL; GString *description; guint time_to_full_round; guint time_to_empty_round; gchar *time_to_full_str = NULL; gchar *time_to_empty_str = NULL; UpDeviceKind kind; UpDeviceState state; gdouble percentage; gboolean is_present; gint64 time_to_full; gint64 time_to_empty; /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, "percentage", &percentage, "is-present", &is_present, "time-to-full", &time_to_full, "time-to-empty", &time_to_empty, NULL); description = g_string_new (NULL); kind_desc = gpm_device_kind_to_localised_string (kind, 1); device_desc = gpm_device_to_localised_string (device); /* not installed */ if (!is_present) { g_string_append (description, device_desc); goto out; } /* don't display all the extra stuff for keyboards and mice */ if (kind == UP_DEVICE_KIND_MOUSE || kind == UP_DEVICE_KIND_KEYBOARD || kind == UP_DEVICE_KIND_PDA) { g_string_append (description, kind_desc); g_string_append_printf (description, " (%.0f%%)", percentage); goto out; } /* we care if we are on AC */ if (kind == UP_DEVICE_KIND_PHONE) { if (state == UP_DEVICE_STATE_CHARGING || !(state == UP_DEVICE_STATE_DISCHARGING)) { g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); goto out; } g_string_append (description, kind_desc); g_string_append_printf (description, " (%.0f%%)", percentage); goto out; } /* precalculate so we don't get Unknown time remaining */ time_to_full_round = gpm_precision_round_down (time_to_full, GPM_UP_TIME_PRECISION); time_to_empty_round = gpm_precision_round_down (time_to_empty, GPM_UP_TIME_PRECISION); /* we always display "Laptop battery 16 minutes remaining" as we need to clarify what device we are referring to */ if (state == UP_DEVICE_STATE_FULLY_CHARGED) { g_string_append (description, device_desc); if (kind == UP_DEVICE_KIND_BATTERY && time_to_empty_round > GPM_UP_TEXT_MIN_TIME) { time_to_empty_str = gpm_get_timestring (time_to_empty_round); g_string_append (description, " - "); /* TRANSLATORS: The laptop battery is charged, and we know a time. * The parameter is the time, e.g. 7 hours 6 minutes */ g_string_append_printf (description, _("provides %s laptop runtime"), time_to_empty_str); } goto out; } if (state == UP_DEVICE_STATE_DISCHARGING) { if (time_to_empty_round > GPM_UP_TEXT_MIN_TIME) { time_to_empty_str = gpm_get_timestring (time_to_empty_round); /* TRANSLATORS: the device is discharging, and we have a time remaining * The first parameter is the device type, e.g. "Laptop battery" and * the second is the time, e.g. 7 hours 6 minutes */ g_string_append_printf (description, _("%s %s remaining"), kind_desc, time_to_empty_str); g_string_append_printf (description, " (%.0f%%)", percentage); } else { g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); } goto out; } if (state == UP_DEVICE_STATE_CHARGING) { if (time_to_full_round > GPM_UP_TEXT_MIN_TIME && time_to_empty_round > GPM_UP_TEXT_MIN_TIME) { /* display both discharge and charge time */ time_to_full_str = gpm_get_timestring (time_to_full_round); time_to_empty_str = gpm_get_timestring (time_to_empty_round); /* TRANSLATORS: device is charging, and we have a time to full and a percentage * The first parameter is the device type, e.g. "Laptop battery" and * the second is the time, e.g. "7 hours 6 minutes" */ g_string_append_printf (description, _("%s %s until charged"), kind_desc, time_to_full_str); g_string_append_printf (description, " (%.0f%%)", percentage); g_string_append (description, " - "); /* TRANSLATORS: the device is charging, and we have a time to full and empty. * The parameter is a time string, e.g. "7 hours 6 minutes" */ g_string_append_printf (description, _("provides %s battery runtime"), time_to_empty_str); } else if (time_to_full_round > GPM_UP_TEXT_MIN_TIME) { /* display only charge time */ time_to_full_str = gpm_get_timestring (time_to_full_round); /* TRANSLATORS: device is charging, and we have a time to full and a percentage. * The first parameter is the device type, e.g. "Laptop battery" and * the second is the time, e.g. "7 hours 6 minutes" */ g_string_append_printf (description, _("%s %s until charged"), kind_desc, time_to_full_str); g_string_append_printf (description, " (%.0f%%)", percentage); } else { g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); } goto out; } if (state == UP_DEVICE_STATE_PENDING_DISCHARGE) { g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); goto out; } if (state == UP_DEVICE_STATE_PENDING_CHARGE) { g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); goto out; } if (state == UP_DEVICE_STATE_EMPTY) { g_string_append (description, device_desc); goto out; } /* fallback */ g_warning ("in an undefined state we are not charging or " "discharging and the batteries are also not charged"); g_string_append (description, device_desc); g_string_append_printf (description, " (%.0f%%)", percentage); out: g_free (time_to_full_str); g_free (time_to_empty_str); return g_string_free (description, FALSE); } gchar * gpm_upower_get_device_description (UpDevice *device) { GString *details; const gchar *text; gchar *time_str; UpDeviceKind kind; UpDeviceState state; UpDeviceTechnology technology; gdouble percentage; gdouble capacity; gdouble energy; gdouble energy_full; gdouble energy_full_design; gdouble energy_rate; gboolean is_present; gint64 time_to_full; gint64 time_to_empty; gchar *vendor = NULL; gchar *serial = NULL; gchar *model = NULL; g_return_val_if_fail (device != NULL, NULL); /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, "percentage", &percentage, "is-present", &is_present, "time-to-full", &time_to_full, "time-to-empty", &time_to_empty, "technology", &technology, "capacity", &capacity, "energy", &energy, "energy-full", &energy_full, "energy-full-design", &energy_full_design, "energy-rate", &energy_rate, "vendor", &vendor, "serial", &serial, "model", &model, NULL); details = g_string_new (""); text = gpm_device_kind_to_localised_string (kind, 1); /* TRANSLATORS: the type of data, e.g. Laptop battery */ g_string_append_printf (details, "%s %s\n", _("Product:"), text); if (!is_present) { /* TRANSLATORS: device is missing */ g_string_append_printf (details, "%s %s\n", _("Status:"), _("Missing")); } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: device is charged */ g_string_append_printf (details, "%s %s\n", _("Status:"), _("Charged")); } else if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: device is charging */ g_string_append_printf (details, "%s %s\n", _("Status:"), _("Charging")); } else if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: device is discharging */ g_string_append_printf (details, "%s %s\n", _("Status:"), _("Discharging")); } if (percentage >= 0) { /* TRANSLATORS: percentage */ g_string_append_printf (details, "%s %.1f%%\n", _("Percentage charge:"), percentage); } if (vendor) { /* TRANSLATORS: manufacturer */ g_string_append_printf (details, "%s %s\n", _("Vendor:"), vendor); } if (technology != UP_DEVICE_TECHNOLOGY_UNKNOWN) { text = gpm_device_technology_to_localised_string (technology); /* TRANSLATORS: how the battery is made, e.g. Lithium Ion */ g_string_append_printf (details, "%s %s\n", _("Technology:"), text); } if (serial) { /* TRANSLATORS: serial number of the battery */ g_string_append_printf (details, "%s %s\n", _("Serial number:"), serial); } if (model) { /* TRANSLATORS: model number of the battery */ g_string_append_printf (details, "%s %s\n", _("Model:"), model); } if (time_to_full > 0) { time_str = gpm_get_timestring (time_to_full); /* TRANSLATORS: time to fully charged */ g_string_append_printf (details, "%s %s\n", _("Charge time:"), time_str); g_free (time_str); } if (time_to_empty > 0) { time_str = gpm_get_timestring (time_to_empty); /* TRANSLATORS: time to empty */ g_string_append_printf (details, "%s %s\n", _("Discharge time:"), time_str); g_free (time_str); } if (capacity > 0) { const gchar *condition; if (capacity > 99) { /* TRANSLATORS: Excellent, Good, Fair and Poor are all related to battery Capacity */ condition = _("Excellent"); } else if (capacity > 90) { condition = _("Good"); } else if (capacity > 70) { condition = _("Fair"); } else { condition = _("Poor"); } /* TRANSLATORS: %.1f is a percentage and %s the condition (Excellent, Good, ...) */ g_string_append_printf (details, "%s %.1f%% (%s)\n", _("Capacity:"), capacity, condition); } if (kind == UP_DEVICE_KIND_BATTERY) { if (energy > 0) { /* TRANSLATORS: current charge */ g_string_append_printf (details, "%s %.1f Wh\n", _("Current charge:"), energy); } if (energy_full > 0 && energy_full_design != energy_full) { /* TRANSLATORS: last full is the charge the battery was seen to charge to */ g_string_append_printf (details, "%s %.1f Wh\n", _("Last full charge:"), energy_full); } if (energy_full_design > 0) { /* Translators: */ /* TRANSLATORS: Design charge is the amount of charge the battery is designed to have when brand new */ g_string_append_printf (details, "%s %.1f Wh\n", _("Design charge:"), energy_full_design); } if (energy_rate > 0) { /* TRANSLATORS: the charge or discharge rate */ g_string_append_printf (details, "%s %.1f W\n", _("Charge rate:"), energy_rate); } } if (kind == UP_DEVICE_KIND_MOUSE || kind == UP_DEVICE_KIND_KEYBOARD) { if (energy > 0) { /* TRANSLATORS: the current charge for CSR devices */ g_string_append_printf (details, "%s %.0f/7\n", _("Current charge:"), energy); } if (energy_full_design > 0) { /* TRANSLATORS: the design charge for CSR devices */ g_string_append_printf (details, "%s %.0f/7\n", _("Design charge:"), energy_full_design); } } /* remove the last \n */ g_string_truncate (details, details->len-1); g_free (vendor); g_free (serial); g_free (model); return g_string_free (details, FALSE); } const gchar * gpm_device_kind_to_localised_string (UpDeviceKind kind, guint number) { const gchar *text = NULL; switch (kind) { case UP_DEVICE_KIND_LINE_POWER: /* TRANSLATORS: system power cord */ text = ngettext ("AC adapter", "AC adapters", number); break; case UP_DEVICE_KIND_BATTERY: /* TRANSLATORS: laptop primary battery */ text = ngettext ("Laptop battery", "Laptop batteries", number); break; case UP_DEVICE_KIND_UPS: /* TRANSLATORS: battery-backed AC power source */ text = ngettext ("UPS", "UPSs", number); break; case UP_DEVICE_KIND_MONITOR: /* TRANSLATORS: a monitor is a device to measure voltage and current */ text = ngettext ("Monitor", "Monitors", number); break; case UP_DEVICE_KIND_MOUSE: /* TRANSLATORS: wireless mice with internal batteries */ text = ngettext ("Mouse", "Mice", number); break; case UP_DEVICE_KIND_KEYBOARD: /* TRANSLATORS: wireless keyboard with internal battery */ text = ngettext ("Keyboard", "Keyboards", number); break; case UP_DEVICE_KIND_PDA: /* TRANSLATORS: portable device */ text = ngettext ("PDA", "PDAs", number); break; case UP_DEVICE_KIND_PHONE: /* TRANSLATORS: cell phone (mobile...) */ text = ngettext ("Cell phone", "Cell phones", number); break; case UP_DEVICE_KIND_MEDIA_PLAYER: /* TRANSLATORS: media player, mp3 etc */ text = ngettext ("Media player", "Media players", number); break; case UP_DEVICE_KIND_TABLET: /* TRANSLATORS: tablet device */ text = ngettext ("Tablet", "Tablets", number); break; case UP_DEVICE_KIND_COMPUTER: /* TRANSLATORS: tablet device */ text = ngettext ("Computer", "Computers", number); break; #if UP_CHECK_VERSION(0,99,6) case UP_DEVICE_KIND_GAMING_INPUT: /* TRANSLATORS: gaming peripherals */ text = ngettext ("Game controller", "Game controllers", number); break; #endif case UP_DEVICE_KIND_UNKNOWN: text = ngettext ("Unknown device", "Unknown devices", number); break; case UP_DEVICE_KIND_LAST: default: g_warning ("enum unrecognised: %i", kind); text = up_device_kind_to_string (kind); } return text; } const gchar * gpm_device_kind_to_icon (UpDeviceKind kind) { const gchar *icon = NULL; switch (kind) { case UP_DEVICE_KIND_LINE_POWER: icon = "ac-adapter"; break; case UP_DEVICE_KIND_BATTERY: icon = "battery"; break; case UP_DEVICE_KIND_UPS: icon = "network-wired"; break; case UP_DEVICE_KIND_MONITOR: icon = "application-certificate"; break; case UP_DEVICE_KIND_MOUSE: icon = "input-mouse"; break; case UP_DEVICE_KIND_KEYBOARD: icon = "input-keyboard"; break; case UP_DEVICE_KIND_PDA: icon = "pda"; break; case UP_DEVICE_KIND_PHONE: icon = "phone"; break; case UP_DEVICE_KIND_MEDIA_PLAYER: icon = "multimedia-player"; break; case UP_DEVICE_KIND_TABLET: icon = "input-tablet"; break; case UP_DEVICE_KIND_COMPUTER: icon = "computer-apple-ipad"; break; #if UP_CHECK_VERSION(0,99,6) case UP_DEVICE_KIND_GAMING_INPUT: icon = "input-gaming"; break; #endif case UP_DEVICE_KIND_UNKNOWN: icon = "gtk-help"; break; case UP_DEVICE_KIND_LAST: default: g_warning ("enum unrecognised: %i", kind); icon = "gtk-help"; } return icon; } const gchar * gpm_device_technology_to_localised_string (UpDeviceTechnology technology_enum) { const gchar *technology = NULL; switch (technology_enum) { case UP_DEVICE_TECHNOLOGY_LITHIUM_ION: /* TRANSLATORS: battery technology */ technology = _("Lithium Ion"); break; case UP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER: /* TRANSLATORS: battery technology */ technology = _("Lithium Polymer"); break; case UP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE: /* TRANSLATORS: battery technology */ technology = _("Lithium Iron Phosphate"); break; case UP_DEVICE_TECHNOLOGY_LEAD_ACID: /* TRANSLATORS: battery technology */ technology = _("Lead acid"); break; case UP_DEVICE_TECHNOLOGY_NICKEL_CADMIUM: /* TRANSLATORS: battery technology */ technology = _("Nickel Cadmium"); break; case UP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE: /* TRANSLATORS: battery technology */ technology = _("Nickel metal hydride"); break; case UP_DEVICE_TECHNOLOGY_UNKNOWN: /* TRANSLATORS: battery technology */ technology = _("Unknown technology"); break; case UP_DEVICE_TECHNOLOGY_LAST: default: g_assert_not_reached (); break; } return technology; } const gchar * gpm_device_state_to_localised_string (UpDeviceState state) { const gchar *state_string = NULL; switch (state) { case UP_DEVICE_STATE_CHARGING: /* TRANSLATORS: battery state */ state_string = _("Charging"); break; case UP_DEVICE_STATE_DISCHARGING: /* TRANSLATORS: battery state */ state_string = _("Discharging"); break; case UP_DEVICE_STATE_EMPTY: /* TRANSLATORS: battery state */ state_string = _("Empty"); break; case UP_DEVICE_STATE_FULLY_CHARGED: /* TRANSLATORS: battery state */ state_string = _("Charged"); break; case UP_DEVICE_STATE_PENDING_CHARGE: /* TRANSLATORS: battery state */ state_string = _("Waiting to charge"); break; case UP_DEVICE_STATE_PENDING_DISCHARGE: /* TRANSLATORS: battery state */ state_string = _("Waiting to discharge"); break; case UP_DEVICE_STATE_UNKNOWN: /* TRANSLATORS: battery state */ state_string = _("Unknown"); break; case UP_DEVICE_STATE_LAST: default: g_assert_not_reached (); break; } return state_string; } const gchar * gpm_device_to_localised_string (UpDevice *device) { UpDeviceState state; UpDeviceKind kind; gboolean present; /* get device parameters */ g_object_get (device, "is-present", &present, "kind", &kind, "state", &state, NULL); /* laptop battery */ if (kind == UP_DEVICE_KIND_BATTERY) { if (!present) { /* TRANSLATORS: device not present */ return _("Laptop battery not present"); } if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Laptop battery is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Laptop battery is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Laptop battery is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Laptop battery is charged"); } if (state == UP_DEVICE_STATE_PENDING_CHARGE) { /* TRANSLATORS: battery state */ return _("Laptop battery is waiting to charge"); } if (state == UP_DEVICE_STATE_PENDING_DISCHARGE) { /* TRANSLATORS: battery state */ return _("Laptop battery is waiting to discharge"); } } /* UPS */ if (kind == UP_DEVICE_KIND_UPS) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("UPS is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("UPS is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("UPS is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("UPS is charged"); } } /* mouse */ if (kind == UP_DEVICE_KIND_MOUSE) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Mouse is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Mouse is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Mouse is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Mouse is charged"); } } /* keyboard */ if (kind == UP_DEVICE_KIND_KEYBOARD) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Keyboard is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Keyboard is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Keyboard is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Keyboard is charged"); } } /* PDA */ if (kind == UP_DEVICE_KIND_PDA) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("PDA is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("PDA is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("PDA is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("PDA is charged"); } } /* phone */ if (kind == UP_DEVICE_KIND_PHONE) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Cell phone is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Cell phone is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Cell phone is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Cell phone is charged"); } } /* media player */ if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Media player is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Media player is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Media player is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Media player is charged"); } } /* tablet */ if (kind == UP_DEVICE_KIND_TABLET) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Tablet is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Tablet is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Tablet is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Tablet is charged"); } } /* computer */ if (kind == UP_DEVICE_KIND_COMPUTER) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Computer is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Computer is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Computer is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Computer is charged"); } } #if UP_CHECK_VERSION(0,99,6) /* computer */ if (kind == UP_DEVICE_KIND_GAMING_INPUT) { if (state == UP_DEVICE_STATE_CHARGING) { /* TRANSLATORS: battery state */ return _("Game controller is charging"); } if (state == UP_DEVICE_STATE_DISCHARGING) { /* TRANSLATORS: battery state */ return _("Game controller is discharging"); } if (state == UP_DEVICE_STATE_EMPTY) { /* TRANSLATORS: battery state */ return _("Game controller is empty"); } if (state == UP_DEVICE_STATE_FULLY_CHARGED) { /* TRANSLATORS: battery state */ return _("Game controller is charged"); } } #endif return gpm_device_kind_to_localised_string (kind, 1); } cinnamon-settings-daemon-6.4.3/plugins/power/main.c0000664000175000017500000000123314733247605021270 0ustar fabiofabio#define NEW csd_power_manager_new #define START csd_power_manager_start #define STOP csd_power_manager_stop #define MANAGER CsdPowerManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-power-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/power/org.cinnamon.SettingsDaemon.Power.xml0000664000175000017500000000116714733247605027336 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/plugins/power/gpm-idletime.h0000664000175000017500000000544014733247605022732 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __GPM_IDLETIME_H #define __GPM_IDLETIME_H #include G_BEGIN_DECLS #define GPM_IDLETIME_TYPE (gpm_idletime_get_type ()) #define GPM_IDLETIME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_IDLETIME_TYPE, GpmIdletime)) #define GPM_IDLETIME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_IDLETIME_TYPE, GpmIdletimeClass)) #define GPM_IS_IDLETIME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_IDLETIME_TYPE)) #define GPM_IS_IDLETIME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_IDLETIME_TYPE)) #define GPM_IDLETIME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_IDLETIME_TYPE, GpmIdletimeClass)) typedef struct GpmIdletimePrivate GpmIdletimePrivate; typedef struct { GObject parent; GpmIdletimePrivate *priv; } GpmIdletime; typedef struct { GObjectClass parent_class; void (* alarm_expired) (GpmIdletime *idletime, guint timer_id); void (* reset) (GpmIdletime *idletime); } GpmIdletimeClass; GType gpm_idletime_get_type (void); GpmIdletime *gpm_idletime_new (void); void gpm_idletime_alarm_reset_all (GpmIdletime *idletime); gboolean gpm_idletime_alarm_set (GpmIdletime *idletime, guint alarm_id, guint timeout); gboolean gpm_idletime_alarm_remove (GpmIdletime *idletime, guint alarm_id); gint64 gpm_idletime_get_time (GpmIdletime *idletime); G_END_DECLS #endif /* __GPM_IDLETIME_H */ cinnamon-settings-daemon-6.4.3/plugins/power/gpm-idletime.c0000664000175000017500000003746314733247605022737 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "gpm-idletime.h" static void gpm_idletime_finalize (GObject *object); #define GPM_IDLETIME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_IDLETIME_TYPE, GpmIdletimePrivate)) struct GpmIdletimePrivate { gint sync_event; gboolean reset_set; XSyncCounter idle_counter; GPtrArray *array; Display *dpy; }; typedef struct { guint id; XSyncValue timeout; XSyncAlarm xalarm; GpmIdletime *idletime; } GpmIdletimeAlarm; enum { SIGNAL_ALARM_EXPIRED, SIGNAL_RESET, LAST_SIGNAL }; typedef enum { GPM_IDLETIME_ALARM_TYPE_POSITIVE, GPM_IDLETIME_ALARM_TYPE_NEGATIVE, GPM_IDLETIME_ALARM_TYPE_DISABLED } GpmIdletimeAlarmType; static guint signals [LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (GpmIdletime, gpm_idletime, G_TYPE_OBJECT) static gint64 gpm_idletime_xsyncvalue_to_int64 (XSyncValue value) { return ((guint64) XSyncValueHigh32 (value)) << 32 | (guint64) XSyncValueLow32 (value); } /* gets the IDLETIME counter value, or 0 for invalid */ gint64 gpm_idletime_get_time (GpmIdletime *idletime) { XSyncValue value; /* we don't have IDLETIME support */ if (!idletime->priv->idle_counter) return 0; /* NX explodes if you query the counter */ gdk_x11_display_error_trap_push (gdk_display_get_default ()); XSyncQueryCounter (idletime->priv->dpy, idletime->priv->idle_counter, &value); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ())) return 0; return gpm_idletime_xsyncvalue_to_int64 (value); } static void gpm_idletime_xsync_alarm_set (GpmIdletime *idletime, GpmIdletimeAlarm *alarm_item, GpmIdletimeAlarmType alarm_type) { XSyncAlarmAttributes attr; XSyncValue delta; unsigned int flags; XSyncTestType test; /* just remove it */ if (alarm_type == GPM_IDLETIME_ALARM_TYPE_DISABLED) { if (alarm_item->xalarm) { XSyncDestroyAlarm (idletime->priv->dpy, alarm_item->xalarm); alarm_item->xalarm = None; } return; } /* which way do we do the test? */ if (alarm_type == GPM_IDLETIME_ALARM_TYPE_POSITIVE) test = XSyncPositiveTransition; else test = XSyncNegativeTransition; XSyncIntToValue (&delta, 0); attr.trigger.counter = idletime->priv->idle_counter; attr.trigger.value_type = XSyncAbsolute; attr.trigger.test_type = test; attr.trigger.wait_value = alarm_item->timeout; attr.delta = delta; flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCAValue | XSyncCADelta; if (alarm_item->xalarm) { XSyncChangeAlarm (idletime->priv->dpy, alarm_item->xalarm, flags, &attr); } else { alarm_item->xalarm = XSyncCreateAlarm (idletime->priv->dpy, flags, &attr); } } void gpm_idletime_alarm_reset_all (GpmIdletime *idletime) { guint i; GpmIdletimeAlarm *alarm_item; g_return_if_fail (GPM_IS_IDLETIME (idletime)); if (!idletime->priv->reset_set) return; /* reset all the alarms (except the reset alarm) to their timeouts */ for (i=1; i < idletime->priv->array->len; i++) { alarm_item = g_ptr_array_index (idletime->priv->array, i); gpm_idletime_xsync_alarm_set (idletime, alarm_item, GPM_IDLETIME_ALARM_TYPE_POSITIVE); } /* set the reset alarm to be disabled */ alarm_item = g_ptr_array_index (idletime->priv->array, 0); gpm_idletime_xsync_alarm_set (idletime, alarm_item, GPM_IDLETIME_ALARM_TYPE_DISABLED); /* emit signal so say we've reset all timers */ g_signal_emit (idletime, signals [SIGNAL_RESET], 0); /* we need to be reset again on the next event */ idletime->priv->reset_set = FALSE; } static GpmIdletimeAlarm * gpm_idletime_alarm_find_id (GpmIdletime *idletime, guint id) { guint i; GpmIdletimeAlarm *alarm_item; for (i = 0; i < idletime->priv->array->len; i++) { alarm_item = g_ptr_array_index (idletime->priv->array, i); if (alarm_item->id == id) return alarm_item; } return NULL; } static void gpm_idletime_set_reset_alarm (GpmIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event) { GpmIdletimeAlarm *alarm_item; int overflow; XSyncValue add; gint64 current, reset_threshold; alarm_item = gpm_idletime_alarm_find_id (idletime, 0); if (!idletime->priv->reset_set) { /* don't match on the current value because * XSyncNegativeComparison means less or equal. */ XSyncIntToValue (&add, -1); XSyncValueAdd (&alarm_item->timeout, alarm_event->counter_value, add, &overflow); /* set the reset alarm to fire the next time * idletime->priv->idle_counter < the current counter value */ gpm_idletime_xsync_alarm_set (idletime, alarm_item, GPM_IDLETIME_ALARM_TYPE_NEGATIVE); /* don't try to set this again if multiple timers are * going off in sequence */ idletime->priv->reset_set = TRUE; current = gpm_idletime_get_time (idletime); reset_threshold = gpm_idletime_xsyncvalue_to_int64 (alarm_item->timeout); if (current < reset_threshold) { /* We've missed the alarm already */ gpm_idletime_alarm_reset_all (idletime); } } } static GpmIdletimeAlarm * gpm_idletime_alarm_find_event (GpmIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event) { guint i; GpmIdletimeAlarm *alarm_item; for (i = 0; i < idletime->priv->array->len; i++) { alarm_item = g_ptr_array_index (idletime->priv->array, i); if (alarm_event->alarm == alarm_item->xalarm) return alarm_item; } return NULL; } static GdkFilterReturn gpm_idletime_event_filter_cb (GdkXEvent *gdkxevent, GdkEvent *event, gpointer data) { GpmIdletimeAlarm *alarm_item; XEvent *xevent = (XEvent *) gdkxevent; GpmIdletime *idletime = (GpmIdletime *) data; XSyncAlarmNotifyEvent *alarm_event; /* no point continuing */ if (xevent->type != idletime->priv->sync_event + XSyncAlarmNotify) return GDK_FILTER_CONTINUE; alarm_event = (XSyncAlarmNotifyEvent *) xevent; /* did we match one of our alarms? */ alarm_item = gpm_idletime_alarm_find_event (idletime, alarm_event); if (alarm_item == NULL) return GDK_FILTER_CONTINUE; /* are we the reset alarm? */ if (alarm_item->id == 0) { gpm_idletime_alarm_reset_all (idletime); goto out; } /* emit */ g_signal_emit (alarm_item->idletime, signals[SIGNAL_ALARM_EXPIRED], 0, alarm_item->id); /* we need the first alarm to go off to set the reset alarm */ gpm_idletime_set_reset_alarm (idletime, alarm_event); out: /* don't propagate */ return GDK_FILTER_REMOVE; } static GpmIdletimeAlarm * gpm_idletime_alarm_new (GpmIdletime *idletime, guint id) { GpmIdletimeAlarm *alarm_item; /* create a new alarm */ alarm_item = g_new0 (GpmIdletimeAlarm, 1); /* set the default values */ alarm_item->id = id; alarm_item->xalarm = None; alarm_item->idletime = g_object_ref (idletime); return alarm_item; } gboolean gpm_idletime_alarm_set (GpmIdletime *idletime, guint id, guint timeout) { GpmIdletimeAlarm *alarm_item; g_return_val_if_fail (GPM_IS_IDLETIME (idletime), FALSE); g_return_val_if_fail (id != 0, FALSE); if (timeout == 0) { gpm_idletime_alarm_remove (idletime, id); return FALSE; } /* see if we already created an alarm with this ID */ alarm_item = gpm_idletime_alarm_find_id (idletime, id); if (alarm_item == NULL) { /* create a new alarm */ alarm_item = gpm_idletime_alarm_new (idletime, id); g_ptr_array_add (idletime->priv->array, alarm_item); } /* set the timeout */ XSyncIntToValue (&alarm_item->timeout, (gint)timeout); /* set, and start the timer */ gpm_idletime_xsync_alarm_set (idletime, alarm_item, GPM_IDLETIME_ALARM_TYPE_POSITIVE); return TRUE; } static gboolean gpm_idletime_alarm_free (GpmIdletime *idletime, GpmIdletimeAlarm *alarm_item) { g_return_val_if_fail (GPM_IS_IDLETIME (idletime), FALSE); g_return_val_if_fail (alarm_item != NULL, FALSE); if (alarm_item->xalarm) { XSyncDestroyAlarm (idletime->priv->dpy, alarm_item->xalarm); } g_object_unref (alarm_item->idletime); g_ptr_array_remove (idletime->priv->array, alarm_item); g_free (alarm_item); return TRUE; } gboolean gpm_idletime_alarm_remove (GpmIdletime *idletime, guint id) { GpmIdletimeAlarm *alarm_item; g_return_val_if_fail (GPM_IS_IDLETIME (idletime), FALSE); alarm_item = gpm_idletime_alarm_find_id (idletime, id); if (alarm_item == NULL) return FALSE; gpm_idletime_alarm_free (idletime, alarm_item); return TRUE; } static void gpm_idletime_class_init (GpmIdletimeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gpm_idletime_finalize; g_type_class_add_private (klass, sizeof (GpmIdletimePrivate)); signals [SIGNAL_ALARM_EXPIRED] = g_signal_new ("alarm-expired", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpmIdletimeClass, alarm_expired), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); signals [SIGNAL_RESET] = g_signal_new ("reset", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpmIdletimeClass, reset), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void gpm_idletime_init (GpmIdletime *idletime) { int sync_error; int ncounters; XSyncSystemCounter *counters; GpmIdletimeAlarm *alarm_item; gint major, minor; guint i; idletime->priv = GPM_IDLETIME_GET_PRIVATE (idletime); idletime->priv->array = g_ptr_array_new (); idletime->priv->reset_set = FALSE; idletime->priv->idle_counter = None; idletime->priv->sync_event = 0; idletime->priv->dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default()); /* get the sync event */ if (!XSyncQueryExtension (idletime->priv->dpy, &idletime->priv->sync_event, &sync_error)) { g_warning ("No Sync extension."); return; } /* check XSync is compatible with the server version */ if (!XSyncInitialize (idletime->priv->dpy, &major, &minor)) { g_warning ("Sync extension not compatible."); return; } counters = XSyncListSystemCounters (idletime->priv->dpy, &ncounters); for (i = 0; i < ncounters && !idletime->priv->idle_counter; i++) { if (strcmp(counters[i].name, "IDLETIME") == 0) idletime->priv->idle_counter = counters[i].counter; } XSyncFreeSystemCounterList (counters); /* arh. we don't have IDLETIME support */ if (!idletime->priv->idle_counter) { g_warning ("No idle counter"); return; } /* catch the timer alarm */ gdk_window_add_filter (NULL, gpm_idletime_event_filter_cb, idletime); /* create a reset alarm */ alarm_item = gpm_idletime_alarm_new (idletime, 0); g_ptr_array_add (idletime->priv->array, alarm_item); } static void gpm_idletime_finalize (GObject *object) { guint i; GpmIdletime *idletime; GpmIdletimeAlarm *alarm_item; g_return_if_fail (object != NULL); g_return_if_fail (GPM_IS_IDLETIME (object)); idletime = GPM_IDLETIME (object); idletime->priv = GPM_IDLETIME_GET_PRIVATE (idletime); /* remove filter */ gdk_window_remove_filter (NULL, gpm_idletime_event_filter_cb, idletime); /* free all counters, including reset counter */ for (i = 0; i < idletime->priv->array->len; i++) { alarm_item = g_ptr_array_index (idletime->priv->array, i); gpm_idletime_alarm_free (idletime, alarm_item); } g_ptr_array_free (idletime->priv->array, TRUE); G_OBJECT_CLASS (gpm_idletime_parent_class)->finalize (object); } GpmIdletime * gpm_idletime_new (void) { return g_object_new (GPM_IDLETIME_TYPE, NULL); } cinnamon-settings-daemon-6.4.3/plugins/power/gpm-phone.c0000664000175000017500000002633214733247605022245 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "gpm-phone.h" static void gpm_phone_finalize (GObject *object); #define GPM_PHONE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_PHONE, GpmPhonePrivate)) struct GpmPhonePrivate { GDBusProxy *proxy; GDBusConnection *connection; guint watch_id; gboolean present; guint percentage; gboolean onac; }; enum { DEVICE_ADDED, DEVICE_REMOVED, DEVICE_REFRESH, LAST_SIGNAL }; static guint signals [LAST_SIGNAL] = { 0 }; static gpointer gpm_phone_object = NULL; G_DEFINE_TYPE (GpmPhone, gpm_phone, G_TYPE_OBJECT) gboolean gpm_phone_coldplug (GpmPhone *phone) { GError *error = NULL; GVariant *reply; gboolean ret; g_return_val_if_fail (phone != NULL, FALSE); g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE); if (phone->priv->proxy == NULL) return FALSE; reply = g_dbus_proxy_call_sync (phone->priv->proxy, "Coldplug", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_warning ("DEBUG: ERROR: %s", error->message); g_error_free (error); } if (reply != NULL) { ret = TRUE; g_variant_unref (reply); } else ret = FALSE; return ret; } gboolean gpm_phone_get_present (GpmPhone *phone, guint idx) { g_return_val_if_fail (phone != NULL, FALSE); g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE); return phone->priv->present; } guint gpm_phone_get_percentage (GpmPhone *phone, guint idx) { g_return_val_if_fail (phone != NULL, 0); g_return_val_if_fail (GPM_IS_PHONE (phone), 0); return phone->priv->percentage; } gboolean gpm_phone_get_on_ac (GpmPhone *phone, guint idx) { g_return_val_if_fail (phone != NULL, FALSE); g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE); return phone->priv->onac; } guint gpm_phone_get_num_batteries (GpmPhone *phone) { g_return_val_if_fail (phone != NULL, 0); g_return_val_if_fail (GPM_IS_PHONE (phone), 0); if (phone->priv->present) return 1; return 0; } static void gpm_phone_battery_state_changed (GDBusProxy *proxy, guint idx, guint percentage, gboolean on_ac, GpmPhone *phone) { g_return_if_fail (GPM_IS_PHONE (phone)); g_debug ("got BatteryStateChanged %i = %i (%i)", idx, percentage, on_ac); phone->priv->percentage = percentage; phone->priv->onac = on_ac; phone->priv->present = TRUE; g_debug ("emitting device-refresh : (%i)", idx); g_signal_emit (phone, signals [DEVICE_REFRESH], 0, idx); } static void gpm_phone_num_batteries_changed (GDBusProxy *proxy, guint number, GpmPhone *phone) { g_return_if_fail (GPM_IS_PHONE (phone)); g_debug ("got NumberBatteriesChanged %i", number); if (number > 1) { g_warning ("number not 0 or 1, not valid!"); return; } /* are we removed? */ if (number == 0) { phone->priv->present = FALSE; phone->priv->percentage = 0; phone->priv->onac = FALSE; g_debug ("emitting device-removed : (%i)", 0); g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0); return; } if (phone->priv->present) { g_warning ("duplicate NumberBatteriesChanged with no change"); return; } /* reset to defaults until we get BatteryStateChanged */ phone->priv->present = TRUE; phone->priv->percentage = 0; phone->priv->onac = FALSE; g_debug ("emitting device-added : (%i)", 0); g_signal_emit (phone, signals [DEVICE_ADDED], 0, 0); } static void gpm_phone_generic_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { GpmPhone *self = GPM_PHONE (user_data); if (!g_strcmp0 (signal_name, "BatteryStateChanged")) { guint idx, percentage; gboolean on_ac; g_variant_get (parameters, "(uub)", &idx, &percentage, &on_ac); gpm_phone_battery_state_changed (proxy, idx, percentage, on_ac, self); return; } if (!g_strcmp0 (signal_name, "NumberBatteriesChanged")) { guint number; g_variant_get (parameters, "(u)", &number); gpm_phone_num_batteries_changed (proxy, number, self); return; } /* not a signal we're interested in */ } static void gpm_phone_class_init (GpmPhoneClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gpm_phone_finalize; g_type_class_add_private (klass, sizeof (GpmPhonePrivate)); signals [DEVICE_ADDED] = g_signal_new ("device-added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpmPhoneClass, device_added), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); signals [DEVICE_REMOVED] = g_signal_new ("device-removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpmPhoneClass, device_removed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); signals [DEVICE_REFRESH] = g_signal_new ("device-refresh", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpmPhoneClass, device_refresh), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); } static void gpm_phone_service_appeared_cb (GDBusConnection *connection, const gchar *name, const gchar *name_owner, GpmPhone *phone) { GError *error = NULL; g_return_if_fail (GPM_IS_PHONE (phone)); if (phone->priv->connection == NULL) { g_debug ("get connection"); g_clear_error (&error); phone->priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (phone->priv->connection == NULL) { g_warning ("Could not connect to DBUS daemon: %s", error->message); g_error_free (error); phone->priv->connection = NULL; return; } } if (phone->priv->proxy == NULL) { g_debug ("get proxy"); g_clear_error (&error); phone->priv->proxy = g_dbus_proxy_new_sync (phone->priv->connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CINNAMON_PHONE_MANAGER_DBUS_SERVICE, CINNAMON_PHONE_MANAGER_DBUS_PATH, CINNAMON_PHONE_MANAGER_DBUS_INTERFACE, NULL, &error); if (phone->priv->proxy == NULL) { g_warning ("Cannot connect, maybe the daemon is not running: %s", error->message); g_error_free (error); phone->priv->proxy = NULL; return; } g_signal_connect (phone->priv->proxy, "g-signal", G_CALLBACK(gpm_phone_generic_signal_cb), phone); } } static void gpm_phone_service_vanished_cb (GDBusConnection *connection, const gchar *name, GpmPhone *phone) { g_return_if_fail (GPM_IS_PHONE (phone)); if (phone->priv->proxy == NULL) return; g_debug ("removing proxy"); g_object_unref (phone->priv->proxy); phone->priv->proxy = NULL; if (phone->priv->present) { phone->priv->present = FALSE; phone->priv->percentage = 0; g_debug ("emitting device-removed : (%i)", 0); g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0); } } static void gpm_phone_init (GpmPhone *phone) { phone->priv = GPM_PHONE_GET_PRIVATE (phone); phone->priv->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, CINNAMON_PHONE_MANAGER_DBUS_SERVICE, G_BUS_NAME_WATCHER_FLAGS_NONE, (GBusNameAppearedCallback) gpm_phone_service_appeared_cb, (GBusNameVanishedCallback) gpm_phone_service_vanished_cb, phone, NULL); } static void gpm_phone_finalize (GObject *object) { GpmPhone *phone; g_return_if_fail (GPM_IS_PHONE (object)); phone = GPM_PHONE (object); phone->priv = GPM_PHONE_GET_PRIVATE (phone); if (phone->priv->proxy != NULL) g_object_unref (phone->priv->proxy); g_bus_unwatch_name (phone->priv->watch_id); G_OBJECT_CLASS (gpm_phone_parent_class)->finalize (object); } GpmPhone * gpm_phone_new (void) { if (gpm_phone_object != NULL) { g_object_ref (gpm_phone_object); } else { gpm_phone_object = g_object_new (GPM_TYPE_PHONE, NULL); g_object_add_weak_pointer (gpm_phone_object, &gpm_phone_object); } return GPM_PHONE (gpm_phone_object); } cinnamon-settings-daemon-6.4.3/plugins/power/cinnamon-settings-daemon-power.desktop.in0000664000175000017500000000033214733247605030232 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - power Exec=csd-power OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/power/csd-power-manager.c0000664000175000017500000060227014733247605023667 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011 Richard Hughes * Copyright (C) 2011 Ritesh Khadgaray * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define GNOME_DESKTOP_USE_UNSTABLE_API #include #include "gpm-common.h" #include "gpm-phone.h" #include "gpm-idletime.h" #include "cinnamon-settings-profile.h" #include "cinnamon-settings-session.h" #include "csd-enums.h" #include "csd-power-manager.h" #include "csd-power-helper.h" #include "csd-power-proxy.h" #include "csd-power-screen-proxy.h" #include "csd-power-keyboard-proxy.h" #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager" #define GNOME_SESSION_DBUS_PATH_PRESENCE "/org/gnome/SessionManager/Presence" #define GNOME_SESSION_DBUS_INTERFACE "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_INTERFACE_PRESENCE "org.gnome.SessionManager.Presence" #define UPOWER_DBUS_NAME "org.freedesktop.UPower" #define UPOWER_DBUS_PATH_KBDBACKLIGHT "/org/freedesktop/UPower/KbdBacklight" #define UPOWER_DBUS_INTERFACE_KBDBACKLIGHT "org.freedesktop.UPower.KbdBacklight" #define CSD_POWER_SETTINGS_SCHEMA "org.cinnamon.settings-daemon.plugins.power" #define CSD_XRANDR_SETTINGS_SCHEMA "org.cinnamon.settings-daemon.plugins.xrandr" #define CSD_SAVER_SETTINGS_SCHEMA "org.cinnamon.desktop.screensaver" #define CSD_SESSION_SETTINGS_SCHEMA "org.cinnamon.desktop.session" #define CSD_CINNAMON_SESSION_SCHEMA "org.cinnamon.SessionManager" #define CSD_POWER_DBUS_PATH "/org/cinnamon/SettingsDaemon/Power" #define CSD_POWER_DBUS_INTERFACE "org.cinnamon.SettingsDaemon.Power" #define CSD_POWER_DBUS_INTERFACE_SCREEN "org.cinnamon.SettingsDaemon.Power.Screen" #define CSD_POWER_DBUS_INTERFACE_KEYBOARD "org.cinnamon.SettingsDaemon.Power.Keyboard" #define GS_DBUS_NAME "org.cinnamon.ScreenSaver" #define GS_DBUS_PATH "/org/cinnamon/ScreenSaver" #define GS_DBUS_INTERFACE "org.cinnamon.ScreenSaver" #define CSD_POWER_MANAGER_NOTIFY_TIMEOUT_NEVER 0 /* ms */ #define CSD_POWER_MANAGER_NOTIFY_TIMEOUT_SHORT 10 * 1000 /* ms */ #define CSD_POWER_MANAGER_NOTIFY_TIMEOUT_LONG 30 * 1000 /* ms */ #define CSD_POWER_MANAGER_CRITICAL_ALERT_TIMEOUT 5 /* seconds */ #define CSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT 30 /* seconds */ #define LOGIND_DBUS_NAME "org.freedesktop.login1" #define LOGIND_DBUS_PATH "/org/freedesktop/login1" #define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager" /* Keep this in sync with gnome-shell */ #define SCREENSAVER_FADE_TIME 10 /* seconds */ #define XSCREENSAVER_WATCHDOG_TIMEOUT 120 /* seconds */ enum { CSD_POWER_IDLETIME_NULL_ID, CSD_POWER_IDLETIME_DIM_ID, CSD_POWER_IDLETIME_LOCK_ID, CSD_POWER_IDLETIME_BLANK_ID, CSD_POWER_IDLETIME_SLEEP_ID }; /* on ACPI machines we have 4-16 levels, on others it's ~150 */ #define BRIGHTNESS_STEP_AMOUNT(max) ((max) < 20 ? 1 : (max) / 20) /* take a discrete value with offset and convert to percentage */ static int abs_to_percentage (int min, int max, int value) { g_return_val_if_fail (max > min, -1); g_return_val_if_fail (value >= min, -1); g_return_val_if_fail (value <= max, -1); return (CLAMP(((value - min) * 100) / (max - min), 0, 100)); } #define ABS_TO_PERCENTAGE(min, max, value) abs_to_percentage(min, max, value) #define PERCENTAGE_TO_ABS(min, max, value) (min + (((max - min) * value) / 100)) #define CSD_POWER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_POWER_MANAGER, CsdPowerManagerPrivate)) typedef enum { CSD_POWER_IDLE_MODE_NORMAL, CSD_POWER_IDLE_MODE_DIM, CSD_POWER_IDLE_MODE_BLANK, CSD_POWER_IDLE_MODE_SLEEP } CsdPowerIdleMode; struct CsdPowerManagerPrivate { CinnamonSettingsSession *session; guint p_name_id; guint s_name_id; guint k_name_id; CsdPower *power_iface; CsdScreen *screen_iface; CsdKeyboard *keyboard_iface; gboolean lid_is_closed; gboolean on_battery; GSettings *settings; GSettings *settings_screensaver; GSettings *settings_xrandr; GSettings *settings_desktop_session; GSettings *settings_cinnamon_session; UpClient *up_client; GDBusConnection *connection; GCancellable *bus_cancellable; GDBusProxy *upower_kbd_proxy; gboolean skip_unsupported_xrandr; gboolean backlight_helper_force; gchar* backlight_helper_preference_args; gint kbd_brightness_now; gint kbd_brightness_max; gint kbd_brightness_old; gint kbd_brightness_pre_dim; GnomeRRScreen *x11_screen; gboolean use_time_primary; gchar *previous_summary; GIcon *previous_icon; GpmPhone *phone; GPtrArray *devices_array; guint action_percentage; guint action_time; guint critical_percentage; guint critical_time; guint low_percentage; guint low_time; gboolean notify_keyboard; gboolean notify_mouse; gboolean notify_other_devices; gint pre_dim_brightness; /* level, not percentage */ UpDevice *device_composite; NotifyNotification *notification_discharging; NotifyNotification *notification_low; ca_context *canberra_context; ca_proplist *critical_alert_loop_props; guint32 critical_alert_timeout_id; GDBusProxy *screensaver_proxy; GDBusProxy *session_proxy; GDBusProxy *session_presence_proxy; GpmIdletime *idletime; CsdPowerIdleMode current_idle_mode; guint lid_close_safety_timer_id; guint xscreensaver_watchdog_timer_id; gboolean is_virtual_machine; gint fd_close_loop_end; /* logind stuff */ GDBusProxy *logind_proxy; gboolean inhibit_lid_switch_enabled; gint inhibit_lid_switch_fd; gboolean inhibit_lid_switch_taken; gint inhibit_suspend_fd; gboolean inhibit_suspend_taken; guint inhibit_lid_switch_timer_id; }; enum { PROP_0, }; static void csd_power_manager_finalize (GObject *object); static UpDevice *engine_get_composite_device (CsdPowerManager *manager, UpDevice *original_device); static UpDevice *engine_update_composite_device (CsdPowerManager *manager, UpDevice *original_device); static GIcon *engine_get_icon (CsdPowerManager *manager); static gchar *engine_get_summary (CsdPowerManager *manager); static UpDevice *engine_get_primary_device (CsdPowerManager *manager); static void engine_charge_low (CsdPowerManager *manager, UpDevice *device); static void engine_charge_critical (CsdPowerManager *manager, UpDevice *device); static void engine_charge_action (CsdPowerManager *manager, UpDevice *device); static gboolean external_monitor_is_connected (GnomeRRScreen *screen); static void do_power_action_type (CsdPowerManager *manager, CsdPowerActionType action_type); static void do_lid_closed_action (CsdPowerManager *manager); static void inhibit_lid_switch (CsdPowerManager *manager); static void uninhibit_lid_switch (CsdPowerManager *manager); static void setup_locker_process (gpointer user_data); static void lock_screen_with_custom_saver (CsdPowerManager *manager, gchar *custom_saver, gboolean idle_lock); static void activate_screensaver (CsdPowerManager *manager, gboolean force_lock); static void kill_lid_close_safety_timer (CsdPowerManager *manager); static void backlight_get_output_id (CsdPowerManager *manager, gint *xout, gint *yout); #if UP_CHECK_VERSION(0,99,0) static void device_properties_changed_cb (UpDevice *device, GParamSpec *pspec, CsdPowerManager *manager); #endif static void connect_power_iface (CsdPowerManager *manager); static void connect_screen_iface (CsdPowerManager *manager); static void connect_keyboard_iface (CsdPowerManager *manager); G_DEFINE_TYPE (CsdPowerManager, csd_power_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; GQuark csd_power_manager_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("csd_power_manager_error"); return quark; } static gboolean system_on_battery (CsdPowerManager *manager) { UpDevice *primary; // this will only return a device if it's the battery, it's present, // and discharging. primary = engine_get_primary_device (manager); return primary != NULL; } static gboolean play_loop_timeout_cb (CsdPowerManager *manager) { ca_context *context; context = ca_gtk_context_get_for_screen (gdk_screen_get_default ()); ca_context_play_full (context, 0, manager->priv->critical_alert_loop_props, NULL, NULL); return TRUE; } static gboolean play_loop_stop (CsdPowerManager *manager) { if (manager->priv->critical_alert_timeout_id == 0) { g_warning ("no sound loop present to stop"); return FALSE; } if (manager->priv->critical_alert_timeout_id) { g_source_remove (manager->priv->critical_alert_timeout_id); manager->priv->critical_alert_timeout_id = 0; } ca_proplist_destroy (manager->priv->critical_alert_loop_props); manager->priv->critical_alert_loop_props = NULL; manager->priv->critical_alert_timeout_id = 0; return TRUE; } static gboolean play_loop_start (CsdPowerManager *manager, const gchar *id, const gchar *desc, gboolean force, guint timeout) { ca_context *context; if (timeout == 0) { g_warning ("received invalid timeout"); return FALSE; } /* if a sound loop is already running, stop the existing loop */ if (manager->priv->critical_alert_timeout_id != 0) { g_warning ("was instructed to play a sound loop with one already playing"); play_loop_stop (manager); } ca_proplist_create (&(manager->priv->critical_alert_loop_props)); ca_proplist_sets (manager->priv->critical_alert_loop_props, CA_PROP_EVENT_ID, id); ca_proplist_sets (manager->priv->critical_alert_loop_props, CA_PROP_EVENT_DESCRIPTION, desc); manager->priv->critical_alert_timeout_id = g_timeout_add_seconds (timeout, (GSourceFunc) play_loop_timeout_cb, manager); g_source_set_name_by_id (manager->priv->critical_alert_timeout_id, "[CsdPowerManager] play-loop"); /* play the sound, using sounds from the naming spec */ context = ca_gtk_context_get_for_screen (gdk_screen_get_default ()); ca_context_play (context, 0, CA_PROP_EVENT_ID, id, CA_PROP_EVENT_DESCRIPTION, desc, NULL); return TRUE; } static gboolean should_lock_on_suspend (CsdPowerManager *manager) { gboolean lock; lock = g_settings_get_boolean (manager->priv->settings, "lock-on-suspend"); return lock; } static void notify_close_if_showing (NotifyNotification *notification) { gboolean ret; GError *error = NULL; if (notification == NULL) return; ret = notify_notification_close (notification, &error); if (!ret) { g_warning ("failed to close notification: %s", error->message); g_error_free (error); } } static const gchar * get_first_themed_icon_name (GIcon *icon) { const gchar* const *icon_names; const gchar *icon_name = NULL; /* no icon */ if (icon == NULL) goto out; /* just use the first icon */ icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon)); if (icon_names != NULL) icon_name = icon_names[0]; out: return icon_name; } typedef enum { WARNING_NONE = 0, WARNING_DISCHARGING = 1, WARNING_LOW = 2, WARNING_CRITICAL = 3, WARNING_ACTION = 4 } CsdPowerManagerWarning; static void engine_emit_changed (CsdPowerManager *manager, gboolean icon_changed, gboolean state_changed) { /* not yet connected to the bus */ if (manager->priv->power_iface == NULL) return; gboolean need_flush = FALSE; if (icon_changed) { GIcon *gicon; gchar *gicon_str; gicon = engine_get_icon (manager); gicon_str = g_icon_to_string (gicon); csd_power_set_icon (manager->priv->power_iface, gicon_str); need_flush = TRUE; g_free (gicon_str); g_object_unref (gicon); } if (state_changed) { gchar *tooltip; tooltip = engine_get_summary (manager); csd_power_set_tooltip (manager->priv->power_iface, tooltip); need_flush = TRUE; g_free (tooltip); } if (need_flush) { g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (manager->priv->power_iface)); } } static CsdPowerManagerWarning engine_get_warning_csr (CsdPowerManager *manager, UpDevice *device) { gdouble percentage; /* get device properties */ g_object_get (device, "percentage", &percentage, NULL); if (percentage < 26.0f) return WARNING_LOW; else if (percentage < 13.0f) return WARNING_CRITICAL; return WARNING_NONE; } static CsdPowerManagerWarning engine_get_warning_percentage (CsdPowerManager *manager, UpDevice *device) { gdouble percentage; /* get device properties */ g_object_get (device, "percentage", &percentage, NULL); if (percentage <= manager->priv->action_percentage) return WARNING_ACTION; if (percentage <= manager->priv->critical_percentage) return WARNING_CRITICAL; if (percentage <= manager->priv->low_percentage) return WARNING_LOW; return WARNING_NONE; } static CsdPowerManagerWarning engine_get_warning_time (CsdPowerManager *manager, UpDevice *device) { UpDeviceKind kind; gint64 time_to_empty; /* get device properties */ g_object_get (device, "kind", &kind, "time-to-empty", &time_to_empty, NULL); /* this is probably an error condition */ if (time_to_empty == 0) { g_debug ("time zero, falling back to percentage for %s", up_device_kind_to_string (kind)); return engine_get_warning_percentage (manager, device); } if (time_to_empty <= manager->priv->action_time) return WARNING_ACTION; if (time_to_empty <= manager->priv->critical_time) return WARNING_CRITICAL; if (time_to_empty <= manager->priv->low_time) return WARNING_LOW; return WARNING_NONE; } /** * This gets the possible engine state for the device according to the * policy, which could be per-percent, or per-time. **/ static CsdPowerManagerWarning engine_get_warning (CsdPowerManager *manager, UpDevice *device) { UpDeviceKind kind; UpDeviceState state; CsdPowerManagerWarning warning_type; /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, NULL); /* default to no engine */ warning_type = WARNING_NONE; /* if the device in question is on ac, don't give a warning */ if (state == UP_DEVICE_STATE_CHARGING) goto out; /* filter out unwanted warnings */ if (kind == UP_DEVICE_KIND_KEYBOARD) { if (!manager->priv->notify_keyboard) goto out; } else if (kind == UP_DEVICE_KIND_MOUSE) { if (!manager->priv->notify_mouse) goto out; } else if (kind != UP_DEVICE_KIND_BATTERY && kind != UP_DEVICE_KIND_UPS) { if (!manager->priv->notify_other_devices) goto out; } if (kind == UP_DEVICE_KIND_MOUSE || kind == UP_DEVICE_KIND_KEYBOARD) { warning_type = engine_get_warning_csr (manager, device); } else if (kind == UP_DEVICE_KIND_UPS || kind == UP_DEVICE_KIND_MEDIA_PLAYER || kind == UP_DEVICE_KIND_TABLET || kind == UP_DEVICE_KIND_COMPUTER || kind == UP_DEVICE_KIND_PDA) { warning_type = engine_get_warning_percentage (manager, device); } else if (kind == UP_DEVICE_KIND_PHONE) { warning_type = engine_get_warning_percentage (manager, device); } else if (kind == UP_DEVICE_KIND_BATTERY) { /* only use the time when it is accurate, and settings is not disabled */ if (manager->priv->use_time_primary) warning_type = engine_get_warning_time (manager, device); else warning_type = engine_get_warning_percentage (manager, device); } /* If we have no important engines, we should test for discharging */ if (warning_type == WARNING_NONE) { if (state == UP_DEVICE_STATE_DISCHARGING) warning_type = WARNING_DISCHARGING; } out: return warning_type; } static gchar * engine_get_summary (CsdPowerManager *manager) { guint i; GPtrArray *array; UpDevice *device; UpDeviceState state; GString *tooltip = NULL; gchar *part; gboolean is_present; /* need to get AC state */ tooltip = g_string_new (""); /* do we have specific device types? */ array = manager->priv->devices_array; for (i=0;ilen;i++) { device = g_ptr_array_index (array, i); g_object_get (device, "is-present", &is_present, "state", &state, NULL); if (!is_present) continue; if (state == UP_DEVICE_STATE_EMPTY) continue; part = gpm_upower_get_device_summary (device); if (part != NULL) g_string_append_printf (tooltip, "%s\n", part); g_free (part); } /* remove the last \n */ g_string_truncate (tooltip, tooltip->len-1); g_debug ("tooltip: %s", tooltip->str); return g_string_free (tooltip, FALSE); } static GIcon * engine_get_icon_priv (CsdPowerManager *manager, UpDeviceKind device_kind, CsdPowerManagerWarning warning, gboolean use_state) { guint i; GPtrArray *array; UpDevice *device; CsdPowerManagerWarning warning_temp; UpDeviceKind kind; UpDeviceState state; gboolean is_present; /* do we have specific device types? */ array = manager->priv->devices_array; for (i=0;ilen;i++) { device = g_ptr_array_index (array, i); /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, "is-present", &is_present, NULL); /* if battery then use composite device to cope with multiple batteries */ if (kind == UP_DEVICE_KIND_BATTERY) device = engine_get_composite_device (manager, device); warning_temp = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old")); if (kind == device_kind && is_present) { if (warning != WARNING_NONE) { if (warning_temp == warning) return gpm_upower_get_device_icon (device, TRUE); continue; } if (use_state) { if (state == UP_DEVICE_STATE_CHARGING || state == UP_DEVICE_STATE_DISCHARGING) return gpm_upower_get_device_icon (device, TRUE); continue; } return gpm_upower_get_device_icon (device, TRUE); } } return NULL; } static GIcon * engine_get_icon (CsdPowerManager *manager) { GIcon *icon = NULL; /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */ icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_BATTERY, WARNING_CRITICAL, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_UPS, WARNING_CRITICAL, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_MOUSE, WARNING_CRITICAL, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_KEYBOARD, WARNING_CRITICAL, FALSE); if (icon != NULL) return icon; /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */ icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_BATTERY, WARNING_LOW, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_UPS, WARNING_LOW, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_MOUSE, WARNING_LOW, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_KEYBOARD, WARNING_LOW, FALSE); if (icon != NULL) return icon; /* we try (DIS)CHARGING: BATTERY, UPS */ icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_BATTERY, WARNING_NONE, TRUE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_UPS, WARNING_NONE, TRUE); if (icon != NULL) return icon; /* we try PRESENT: BATTERY, UPS */ icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_BATTERY, WARNING_NONE, FALSE); if (icon != NULL) return icon; icon = engine_get_icon_priv (manager, UP_DEVICE_KIND_UPS, WARNING_NONE, FALSE); if (icon != NULL) return icon; /* do not show an icon */ return NULL; } static gboolean engine_recalculate_state_icon (CsdPowerManager *manager) { GIcon *icon; /* show a different icon if we are disconnected */ icon = engine_get_icon (manager); if (icon == NULL) { /* none before, now none */ if (manager->priv->previous_icon == NULL) return FALSE; g_object_unref (manager->priv->previous_icon); manager->priv->previous_icon = NULL; return TRUE; } /* no icon before, now icon */ if (manager->priv->previous_icon == NULL) { manager->priv->previous_icon = icon; return TRUE; } /* icon before, now different */ if (!g_icon_equal (manager->priv->previous_icon, icon)) { g_object_unref (manager->priv->previous_icon); manager->priv->previous_icon = icon; return TRUE; } g_debug ("no change"); /* nothing to do */ g_object_unref (icon); return FALSE; } static gboolean engine_recalculate_state_summary (CsdPowerManager *manager) { gchar *summary; summary = engine_get_summary (manager); if (manager->priv->previous_summary == NULL) { manager->priv->previous_summary = summary; return TRUE; } if (strcmp (manager->priv->previous_summary, summary) != 0) { g_free (manager->priv->previous_summary); manager->priv->previous_summary = summary; return TRUE; } g_debug ("no change"); /* nothing to do */ g_free (summary); return FALSE; } static void engine_recalculate_state (CsdPowerManager *manager) { gboolean icon_changed = FALSE; gboolean state_changed = FALSE; icon_changed = engine_recalculate_state_icon (manager); state_changed = engine_recalculate_state_summary (manager); /* only emit if the icon or summary has changed */ if (icon_changed || state_changed) engine_emit_changed (manager, icon_changed, state_changed); } static UpDevice * engine_get_composite_device (CsdPowerManager *manager, UpDevice *original_device) { guint battery_devices = 0; GPtrArray *array; UpDevice *device; UpDeviceKind kind; UpDeviceKind original_kind; guint i; /* get the type of the original device */ g_object_get (original_device, "kind", &original_kind, NULL); /* find out how many batteries in the system */ array = manager->priv->devices_array; for (i=0;ilen;i++) { device = g_ptr_array_index (array, i); g_object_get (device, "kind", &kind, NULL); if (kind == original_kind) battery_devices++; } /* just use the original device if only one primary battery */ if (battery_devices <= 1) { g_debug ("using original device as only one primary battery"); device = original_device; goto out; } /* use the composite device */ device = manager->priv->device_composite; out: /* return composite device or original device */ return device; } static UpDevice * engine_update_composite_device (CsdPowerManager *manager, UpDevice *original_device) { guint i; gdouble percentage = 0.0; gdouble energy = 0.0; gdouble energy_full = 0.0; gdouble energy_rate = 0.0; gdouble energy_total = 0.0; gdouble energy_full_total = 0.0; gdouble energy_rate_total = 0.0; gint64 time_to_empty = 0; gint64 time_to_full = 0; guint battery_devices = 0; gboolean is_charging = FALSE; gboolean is_discharging = FALSE; gboolean is_fully_charged = TRUE; GPtrArray *array; UpDevice *device; UpDeviceState state; UpDeviceKind kind; UpDeviceKind original_kind; /* get the type of the original device */ g_object_get (original_device, "kind", &original_kind, NULL); /* update the composite device */ array = manager->priv->devices_array; for (i=0;ilen;i++) { device = g_ptr_array_index (array, i); g_object_get (device, "kind", &kind, "state", &state, "energy", &energy, "energy-full", &energy_full, "energy-rate", &energy_rate, NULL); if (kind != original_kind) continue; /* one of these will be charging or discharging */ if (state == UP_DEVICE_STATE_CHARGING) is_charging = TRUE; if (state == UP_DEVICE_STATE_DISCHARGING) is_discharging = TRUE; if (state != UP_DEVICE_STATE_FULLY_CHARGED) is_fully_charged = FALSE; /* sum up composite */ energy_total += energy; energy_full_total += energy_full; energy_rate_total += energy_rate; battery_devices++; } /* just use the original device if only one primary battery */ if (battery_devices == 1) { g_debug ("using original device as only one primary battery"); device = original_device; goto out; } /* use percentage weighted for each battery capacity */ if (energy_full_total > 0.0) percentage = 100.0 * energy_total / energy_full_total; /* set composite state */ if (is_charging) state = UP_DEVICE_STATE_CHARGING; else if (is_discharging) state = UP_DEVICE_STATE_DISCHARGING; else if (is_fully_charged) state = UP_DEVICE_STATE_FULLY_CHARGED; else state = UP_DEVICE_STATE_UNKNOWN; /* calculate a quick and dirty time remaining value */ if (energy_rate_total > 0) { if (state == UP_DEVICE_STATE_DISCHARGING) time_to_empty = 3600 * (energy_total / energy_rate_total); else if (state == UP_DEVICE_STATE_CHARGING) time_to_full = 3600 * ((energy_full_total - energy_total) / energy_rate_total); } /* okay, we can use the composite device */ device = manager->priv->device_composite; g_debug ("printing composite device"); g_object_set (device, "energy", energy, "energy-full", energy_full, "energy-rate", energy_rate, "time-to-empty", time_to_empty, "time-to-full", time_to_full, "percentage", percentage, "state", state, NULL); out: /* force update of icon */ engine_recalculate_state (manager); /* return composite device or original device */ return device; } static void engine_device_add (CsdPowerManager *manager, UpDevice *device) { CsdPowerManagerWarning warning; UpDeviceState state; UpDeviceKind kind; UpDevice *composite; /* assign warning */ warning = engine_get_warning (manager, device); g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning)); /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, NULL); /* add old state for transitions */ g_debug ("adding %s with state %s", up_device_get_object_path (device), up_device_state_to_string (state)); g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state)); #if UP_CHECK_VERSION(0,99,0) g_ptr_array_add (manager->priv->devices_array, g_object_ref(device)); g_signal_connect (device, "notify", G_CALLBACK (device_properties_changed_cb), manager); #endif if (kind == UP_DEVICE_KIND_BATTERY) { g_debug ("updating because we added a device"); composite = engine_update_composite_device (manager, device); /* get the same values for the composite device */ warning = engine_get_warning (manager, composite); if (warning == WARNING_LOW) { g_debug ("** EMIT: charge-low"); engine_charge_low (manager, device); } else if (warning == WARNING_CRITICAL) { g_debug ("** EMIT: charge-critical"); engine_charge_critical (manager, device); } else if (warning == WARNING_ACTION) { g_debug ("charge-action"); engine_charge_action (manager, device); } g_object_set_data (G_OBJECT(composite), "engine-warning-old", GUINT_TO_POINTER(warning)); g_object_get (composite, "state", &state, NULL); g_object_set_data (G_OBJECT(composite), "engine-state-old", GUINT_TO_POINTER(state)); } } static gboolean engine_coldplug (CsdPowerManager *manager) { guint i; GPtrArray *array = NULL; UpDevice *device; #if ! UP_CHECK_VERSION(0,99,0) gboolean ret; GError *error = NULL; /* get devices from UPower */ ret = up_client_enumerate_devices_sync (manager->priv->up_client, NULL, &error); if (!ret) { g_warning ("failed to get device list: %s", error->message); g_error_free (error); goto out; } #endif /* connected mobile phones */ gpm_phone_coldplug (manager->priv->phone); engine_recalculate_state (manager); /* add to database */ array = up_client_get_devices (manager->priv->up_client); for (i = 0; array != NULL && i < array->len; i++) { device = g_ptr_array_index (array, i); engine_device_add (manager, device); } #if ! UP_CHECK_VERSION(0,99,0) out: #endif if (array != NULL) g_ptr_array_unref (array); /* never repeat */ return FALSE; } static void engine_device_added_cb (UpClient *client, UpDevice *device, CsdPowerManager *manager) { /* add to list */ g_ptr_array_add (manager->priv->devices_array, g_object_ref (device)); engine_recalculate_state (manager); } static void #if UP_CHECK_VERSION(0,99,0) engine_device_removed_cb (UpClient *client, const char *object_path, CsdPowerManager *manager) { guint i; for (i = 0; i < manager->priv->devices_array->len; i++) { UpDevice *device = g_ptr_array_index (manager->priv->devices_array, i); if (g_strcmp0 (object_path, up_device_get_object_path (device)) == 0) { g_ptr_array_remove_index (manager->priv->devices_array, i); break; } } engine_recalculate_state (manager); } #else engine_device_removed_cb (UpClient *client, UpDevice *device, CsdPowerManager *manager) { gboolean ret; ret = g_ptr_array_remove (manager->priv->devices_array, device); if (!ret) return; engine_recalculate_state (manager); } #endif static void on_notification_closed (NotifyNotification *notification, gpointer data) { g_object_unref (notification); } static void create_notification (const char *summary, const char *body, const char *icon, NotifyNotification **weak_pointer_location) { NotifyNotification *notification; notification = notify_notification_new (summary, body, icon); *weak_pointer_location = notification; g_object_add_weak_pointer (G_OBJECT (notification), (gpointer *) weak_pointer_location); g_signal_connect (notification, "closed", G_CALLBACK (on_notification_closed), NULL); } static void engine_ups_discharging (CsdPowerManager *manager, UpDevice *device) { const gchar *title; gboolean ret; gchar *remaining_text = NULL; gdouble percentage; GError *error = NULL; GIcon *icon = NULL; gint64 time_to_empty; GString *message; UpDeviceKind kind; /* get device properties */ g_object_get (device, "kind", &kind, "percentage", &percentage, "time-to-empty", &time_to_empty, NULL); if (kind != UP_DEVICE_KIND_UPS) return; /* only show text if there is a valid time */ if (time_to_empty > 0) remaining_text = gpm_get_timestring (time_to_empty); /* TRANSLATORS: UPS is now discharging */ title = _("UPS Discharging"); message = g_string_new (""); if (remaining_text != NULL) { /* TRANSLATORS: tell the user how much time they have got */ g_string_append_printf (message, _("%s of UPS backup power remaining"), remaining_text); } else { g_string_append (message, gpm_device_to_localised_string (device)); } g_string_append_printf (message, " (%.0f%%)", percentage); icon = gpm_upower_get_device_icon (device, TRUE); /* close any existing notification of this class */ notify_close_if_showing (manager->priv->notification_discharging); /* create a new notification */ create_notification (title, message->str, get_first_themed_icon_name (icon), &manager->priv->notification_discharging); notify_notification_set_timeout (manager->priv->notification_discharging, CSD_POWER_MANAGER_NOTIFY_TIMEOUT_LONG); notify_notification_set_urgency (manager->priv->notification_discharging, NOTIFY_URGENCY_NORMAL); /* TRANSLATORS: this is the notification application name */ notify_notification_set_app_name (manager->priv->notification_discharging, _("Power")); notify_notification_set_hint (manager->priv->notification_discharging, "transient", g_variant_new_boolean (TRUE)); /* try to show */ ret = notify_notification_show (manager->priv->notification_discharging, &error); if (!ret) { g_warning ("failed to show notification: %s", error->message); g_error_free (error); g_object_unref (manager->priv->notification_discharging); } g_string_free (message, TRUE); if (icon != NULL) g_object_unref (icon); g_free (remaining_text); } static CsdPowerActionType manager_critical_action_get (CsdPowerManager *manager, gboolean is_ups) { CsdPowerActionType policy; policy = g_settings_get_enum (manager->priv->settings, "critical-battery-action"); if (policy == CSD_POWER_ACTION_SUSPEND) { if (is_ups == FALSE #if ! UP_CHECK_VERSION(0,99,0) && up_client_get_can_suspend (manager->priv->up_client) #endif ) return policy; return CSD_POWER_ACTION_SHUTDOWN; } else if (policy == CSD_POWER_ACTION_HIBERNATE) { #if ! UP_CHECK_VERSION(0,99,0) if (up_client_get_can_hibernate (manager->priv->up_client)) #endif return policy; return CSD_POWER_ACTION_SHUTDOWN; } return policy; } static gboolean manager_critical_action_do (CsdPowerManager *manager, gboolean is_ups) { CsdPowerActionType action_type; /* stop playing the alert as it's too late to do anything now */ if (manager->priv->critical_alert_timeout_id > 0) play_loop_stop (manager); action_type = manager_critical_action_get (manager, is_ups); do_power_action_type (manager, action_type); return FALSE; } static gboolean manager_critical_action_do_cb (CsdPowerManager *manager) { manager_critical_action_do (manager, FALSE); return FALSE; } static gboolean manager_critical_ups_action_do_cb (CsdPowerManager *manager) { manager_critical_action_do (manager, TRUE); return FALSE; } static gboolean engine_just_laptop_battery (CsdPowerManager *manager) { UpDevice *device; UpDeviceKind kind; GPtrArray *array; gboolean ret = TRUE; guint i; /* find if there are any other device types that mean we have to * be more specific in our wording */ array = manager->priv->devices_array; for (i=0; ilen; i++) { device = g_ptr_array_index (array, i); g_object_get (device, "kind", &kind, NULL); if (kind != UP_DEVICE_KIND_BATTERY) { ret = FALSE; break; } } return ret; } static void engine_charge_low (CsdPowerManager *manager, UpDevice *device) { const gchar *title = NULL; gboolean ret; gchar *message = NULL; gchar *tmp; gchar *remaining_text; gdouble percentage; GIcon *icon = NULL; gint64 time_to_empty; UpDeviceKind kind; GError *error = NULL; /* get device properties */ g_object_get (device, "kind", &kind, "percentage", &percentage, "time-to-empty", &time_to_empty, NULL); /* check to see if the batteries have not noticed we are on AC */ if (kind == UP_DEVICE_KIND_BATTERY) { if (!system_on_battery (manager)) { g_warning ("ignoring low message as we are not on battery power"); goto out; } } if (kind == UP_DEVICE_KIND_BATTERY) { /* if the user has no other batteries, drop the "Laptop" wording */ ret = engine_just_laptop_battery (manager); if (ret) { /* TRANSLATORS: laptop battery low, and we only have one battery */ title = _("Battery low"); } else { /* TRANSLATORS: laptop battery low, and we have more than one kind of battery */ title = _("Laptop battery low"); } tmp = gpm_get_timestring (time_to_empty); remaining_text = g_strconcat ("", tmp, "", NULL); g_free (tmp); /* TRANSLATORS: tell the user how much time they have got */ message = g_strdup_printf (_("Approximately %s remaining (%.0f%%)"), remaining_text, percentage); g_free (remaining_text); } else if (kind == UP_DEVICE_KIND_UPS) { /* TRANSLATORS: UPS is starting to get a little low */ title = _("UPS low"); tmp = gpm_get_timestring (time_to_empty); remaining_text = g_strconcat ("", tmp, "", NULL); g_free (tmp); /* TRANSLATORS: tell the user how much time they have got */ message = g_strdup_printf (_("Approximately %s of remaining UPS backup power (%.0f%%)"), remaining_text, percentage); g_free (remaining_text); } else if (kind == UP_DEVICE_KIND_MOUSE) { /* TRANSLATORS: mouse is getting a little low */ title = _("Mouse battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Wireless mouse is low in power")); } else if (kind == UP_DEVICE_KIND_KEYBOARD) { /* TRANSLATORS: keyboard is getting a little low */ title = _("Keyboard battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Wireless keyboard is low in power")); } else if (kind == UP_DEVICE_KIND_PDA) { /* TRANSLATORS: PDA is getting a little low */ title = _("PDA battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("PDA is low in power (%.0f%%)"), percentage); } else if (kind == UP_DEVICE_KIND_PHONE) { /* TRANSLATORS: cell phone (mobile) is getting a little low */ title = _("Cell phone battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Cell phone is low in power (%.0f%%)"), percentage); } else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) { /* TRANSLATORS: media player, e.g. mp3 is getting a little low */ title = _("Media player battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Media player is low in power (%.0f%%)"), percentage); } else if (kind == UP_DEVICE_KIND_TABLET) { /* TRANSLATORS: graphics tablet, e.g. wacom is getting a little low */ title = _("Tablet battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Tablet is low in power (%.0f%%)"), percentage); } else if (kind == UP_DEVICE_KIND_COMPUTER) { /* TRANSLATORS: computer, e.g. ipad is getting a little low */ title = _("Attached computer battery low"); /* TRANSLATORS: tell user more details */ message = g_strdup_printf (_("Attached computer is low in power (%.0f%%)"), percentage); } /* get correct icon */ icon = gpm_upower_get_device_icon (device, TRUE); /* close any existing notification of this class */ notify_close_if_showing (manager->priv->notification_low); /* create a new notification */ create_notification (title, message, get_first_themed_icon_name (icon), &manager->priv->notification_low); notify_notification_set_timeout (manager->priv->notification_low, CSD_POWER_MANAGER_NOTIFY_TIMEOUT_LONG); notify_notification_set_urgency (manager->priv->notification_low, NOTIFY_URGENCY_NORMAL); notify_notification_set_app_name (manager->priv->notification_low, _("Power")); notify_notification_set_hint (manager->priv->notification_low, "transient", g_variant_new_boolean (TRUE)); /* try to show */ ret = notify_notification_show (manager->priv->notification_low, &error); if (!ret) { g_warning ("failed to show notification: %s", error->message); g_error_free (error); g_object_unref (manager->priv->notification_low); } /* play the sound, using sounds from the naming spec */ ca_context_play (manager->priv->canberra_context, 0, CA_PROP_EVENT_ID, "battery-low", /* TRANSLATORS: this is the sound description */ CA_PROP_EVENT_DESCRIPTION, _("Battery is low"), NULL); out: if (icon != NULL) g_object_unref (icon); g_free (message); } static void engine_charge_critical (CsdPowerManager *manager, UpDevice *device) { const gchar *title = NULL; gboolean ret; gchar *message = NULL; gdouble percentage; GIcon *icon = NULL; gint64 time_to_empty; CsdPowerActionType policy; UpDeviceKind kind; GError *error = NULL; /* get device properties */ g_object_get (device, "kind", &kind, "percentage", &percentage, "time-to-empty", &time_to_empty, NULL); /* check to see if the batteries have not noticed we are on AC */ if (kind == UP_DEVICE_KIND_BATTERY) { if (!system_on_battery (manager)) { g_warning ("ignoring critically low message as we are not on battery power"); goto out; } } if (kind == UP_DEVICE_KIND_BATTERY) { /* if the user has no other batteries, drop the "Laptop" wording */ ret = engine_just_laptop_battery (manager); if (ret) { /* TRANSLATORS: laptop battery critically low, and only have one kind of battery */ title = _("Battery critically low"); } else { /* TRANSLATORS: laptop battery critically low, and we have more than one type of battery */ title = _("Laptop battery critically low"); } /* we have to do different warnings depending on the policy */ policy = manager_critical_action_get (manager, FALSE); /* use different text for different actions */ if (policy == CSD_POWER_ACTION_NOTHING) { /* TRANSLATORS: tell the use to insert the plug, as we're not going to do anything */ message = g_strdup (_("Plug in your AC adapter to avoid losing data.")); } else if (policy == CSD_POWER_ACTION_SUSPEND) { /* TRANSLATORS: give the user a ultimatum */ message = g_strdup_printf (_("Computer will suspend very soon unless it is plugged in.")); } else if (policy == CSD_POWER_ACTION_HIBERNATE) { /* TRANSLATORS: give the user a ultimatum */ message = g_strdup_printf (_("Computer will hibernate very soon unless it is plugged in.")); } else if (policy == CSD_POWER_ACTION_SHUTDOWN) { /* TRANSLATORS: give the user a ultimatum */ message = g_strdup_printf (_("Computer will shutdown very soon unless it is plugged in.")); } } else if (kind == UP_DEVICE_KIND_UPS) { gchar *remaining_text; gchar *tmp; /* TRANSLATORS: the UPS is very low */ title = _("UPS critically low"); tmp = gpm_get_timestring (time_to_empty); remaining_text = g_strconcat ("", tmp, "", NULL); g_free (tmp); /* TRANSLATORS: give the user a ultimatum */ message = g_strdup_printf (_("Approximately %s of remaining UPS power (%.0f%%). " "Restore AC power to your computer to avoid losing data."), remaining_text, percentage); g_free (remaining_text); } else if (kind == UP_DEVICE_KIND_MOUSE) { /* TRANSLATORS: the mouse battery is very low */ title = _("Mouse battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Wireless mouse is very low in power. " "This device will soon stop functioning if not charged.")); } else if (kind == UP_DEVICE_KIND_KEYBOARD) { /* TRANSLATORS: the keyboard battery is very low */ title = _("Keyboard battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Wireless keyboard is very low in power. " "This device will soon stop functioning if not charged.")); } else if (kind == UP_DEVICE_KIND_PDA) { /* TRANSLATORS: the PDA battery is very low */ title = _("PDA battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("PDA is very low in power (%.0f%%). " "This device will soon stop functioning if not charged."), percentage); } else if (kind == UP_DEVICE_KIND_PHONE) { /* TRANSLATORS: the cell battery is very low */ title = _("Cell phone battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Cell phone is very low in power (%.0f%%). " "This device will soon stop functioning if not charged."), percentage); } else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) { /* TRANSLATORS: the cell battery is very low */ title = _("Cell phone battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Media player is very low in power (%.0f%%). " "This device will soon stop functioning if not charged."), percentage); } else if (kind == UP_DEVICE_KIND_TABLET) { /* TRANSLATORS: the cell battery is very low */ title = _("Tablet battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Tablet is very low in power (%.0f%%). " "This device will soon stop functioning if not charged."), percentage); } else if (kind == UP_DEVICE_KIND_COMPUTER) { /* TRANSLATORS: the cell battery is very low */ title = _("Attached computer battery low"); /* TRANSLATORS: the device is just going to stop working */ message = g_strdup_printf (_("Attached computer is very low in power (%.0f%%). " "The device will soon shutdown if not charged."), percentage); } /* get correct icon */ icon = gpm_upower_get_device_icon (device, TRUE); /* close any existing notification of this class */ notify_close_if_showing (manager->priv->notification_low); /* create a new notification */ create_notification (title, message, get_first_themed_icon_name (icon), &manager->priv->notification_low); notify_notification_set_timeout (manager->priv->notification_low, CSD_POWER_MANAGER_NOTIFY_TIMEOUT_LONG); notify_notification_set_urgency (manager->priv->notification_low, NOTIFY_URGENCY_CRITICAL); notify_notification_set_app_name (manager->priv->notification_low, _("Power")); /* try to show */ ret = notify_notification_show (manager->priv->notification_low, &error); if (!ret) { g_warning ("failed to show notification: %s", error->message); g_error_free (error); g_object_unref (manager->priv->notification_low); } switch (kind) { case UP_DEVICE_KIND_BATTERY: case UP_DEVICE_KIND_UPS: g_debug ("critical charge level reached, starting sound loop"); play_loop_start (manager, "battery-caution", _("Battery is critically low"), TRUE, CSD_POWER_MANAGER_CRITICAL_ALERT_TIMEOUT); break; default: /* play the sound, using sounds from the naming spec */ ca_context_play (manager->priv->canberra_context, 0, CA_PROP_EVENT_ID, "battery-caution", /* TRANSLATORS: this is the sound description */ CA_PROP_EVENT_DESCRIPTION, _("Battery is critically low"), NULL); break; } out: if (icon != NULL) g_object_unref (icon); g_free (message); } static void engine_charge_action (CsdPowerManager *manager, UpDevice *device) { const gchar *title = NULL; gboolean ret; gchar *message = NULL; GError *error = NULL; GIcon *icon = NULL; CsdPowerActionType policy; guint timer_id; UpDeviceKind kind; /* get device properties */ g_object_get (device, "kind", &kind, NULL); /* check to see if the batteries have not noticed we are on AC */ if (kind == UP_DEVICE_KIND_BATTERY) { if (!system_on_battery (manager)) { g_warning ("ignoring critically low message as we are not on battery power"); goto out; } } if (kind == UP_DEVICE_KIND_BATTERY) { /* TRANSLATORS: laptop battery is really, really, low */ title = _("Laptop battery critically low"); /* we have to do different warnings depending on the policy */ policy = manager_critical_action_get (manager, FALSE); /* use different text for different actions */ if (policy == CSD_POWER_ACTION_NOTHING) { /* TRANSLATORS: computer will shutdown without saving data */ message = g_strdup (_("The battery is below the critical level and " "this computer will power-off when the " "battery becomes completely empty.")); } else if (policy == CSD_POWER_ACTION_SUSPEND) { /* TRANSLATORS: computer will suspend */ message = g_strdup (_("The battery is below the critical level and " "this computer is about to suspend.\n" "NOTE: A small amount of power is required " "to keep your computer in a suspended state.")); } else if (policy == CSD_POWER_ACTION_HIBERNATE) { /* TRANSLATORS: computer will hibernate */ message = g_strdup (_("The battery is below the critical level and " "this computer is about to hibernate.")); } else if (policy == CSD_POWER_ACTION_SHUTDOWN) { /* TRANSLATORS: computer will just shutdown */ message = g_strdup (_("The battery is below the critical level and " "this computer is about to shutdown.")); } /* wait 20 seconds for user-panic */ timer_id = g_timeout_add_seconds (20, (GSourceFunc) manager_critical_action_do_cb, manager); g_source_set_name_by_id (timer_id, "[CsdPowerManager] battery critical-action"); } else if (kind == UP_DEVICE_KIND_UPS) { /* TRANSLATORS: UPS is really, really, low */ title = _("UPS critically low"); /* we have to do different warnings depending on the policy */ policy = manager_critical_action_get (manager, TRUE); /* use different text for different actions */ if (policy == CSD_POWER_ACTION_NOTHING) { /* TRANSLATORS: computer will shutdown without saving data */ message = g_strdup (_("UPS is below the critical level and " "this computer will power-off when the " "UPS becomes completely empty.")); } else if (policy == CSD_POWER_ACTION_HIBERNATE) { /* TRANSLATORS: computer will hibernate */ message = g_strdup (_("UPS is below the critical level and " "this computer is about to hibernate.")); } else if (policy == CSD_POWER_ACTION_SHUTDOWN) { /* TRANSLATORS: computer will just shutdown */ message = g_strdup (_("UPS is below the critical level and " "this computer is about to shutdown.")); } /* wait 20 seconds for user-panic */ timer_id = g_timeout_add_seconds (20, (GSourceFunc) manager_critical_ups_action_do_cb, manager); g_source_set_name_by_id (timer_id, "[CsdPowerManager] ups critical-action"); } /* not all types have actions */ if (title == NULL) { g_free (message); return; } /* get correct icon */ icon = gpm_upower_get_device_icon (device, TRUE); /* close any existing notification of this class */ notify_close_if_showing (manager->priv->notification_low); /* create a new notification */ create_notification (title, message, get_first_themed_icon_name (icon), &manager->priv->notification_low); notify_notification_set_timeout (manager->priv->notification_low, CSD_POWER_MANAGER_NOTIFY_TIMEOUT_LONG); notify_notification_set_urgency (manager->priv->notification_low, NOTIFY_URGENCY_CRITICAL); notify_notification_set_app_name (manager->priv->notification_low, _("Power")); /* try to show */ ret = notify_notification_show (manager->priv->notification_low, &error); if (!ret) { g_warning ("failed to show notification: %s", error->message); g_error_free (error); g_object_unref (manager->priv->notification_low); } /* play the sound, using sounds from the naming spec */ ca_context_play (manager->priv->canberra_context, 0, CA_PROP_EVENT_ID, "battery-caution", /* TRANSLATORS: this is the sound description */ CA_PROP_EVENT_DESCRIPTION, _("Battery is critically low"), NULL); out: if (icon != NULL) g_object_unref (icon); g_free (message); } static void #if UP_CHECK_VERSION(0,99,0) device_properties_changed_cb (UpDevice *device, GParamSpec *pspec, CsdPowerManager *manager) #else engine_device_changed_cb (UpClient *client, UpDevice *device, CsdPowerManager *manager) #endif { UpDeviceKind kind; UpDeviceState state; UpDeviceState state_old; CsdPowerManagerWarning warning_old; CsdPowerManagerWarning warning; /* get device properties */ g_object_get (device, "kind", &kind, NULL); /* if battery then use composite device to cope with multiple batteries */ if (kind == UP_DEVICE_KIND_BATTERY) { g_debug ("updating because %s changed", up_device_get_object_path (device)); device = engine_update_composite_device (manager, device); } /* get device properties (may be composite) */ g_object_get (device, "state", &state, NULL); g_debug ("%s state is now %s", up_device_get_object_path (device), up_device_state_to_string (state)); /* see if any interesting state changes have happened */ state_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-state-old")); if (state_old != state) { if (state == UP_DEVICE_STATE_DISCHARGING) { g_debug ("discharging"); engine_ups_discharging (manager, device); } else if (state == UP_DEVICE_STATE_FULLY_CHARGED || state == UP_DEVICE_STATE_CHARGING) { g_debug ("fully charged or charging, hiding notifications if any"); notify_close_if_showing (manager->priv->notification_low); notify_close_if_showing (manager->priv->notification_discharging); } /* save new state */ g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state)); } /* check the warning state has not changed */ warning_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old")); warning = engine_get_warning (manager, device); if (warning != warning_old) { if (warning == WARNING_LOW) { g_debug ("** EMIT: charge-low"); engine_charge_low (manager, device); } else if (warning == WARNING_CRITICAL) { g_debug ("** EMIT: charge-critical"); engine_charge_critical (manager, device); } else if (warning == WARNING_ACTION) { g_debug ("charge-action"); engine_charge_action (manager, device); } /* save new state */ g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning)); } engine_recalculate_state (manager); } static void refresh_notification_settings (CsdPowerManager *manager) { manager->priv->notify_keyboard = g_settings_get_boolean (manager->priv->settings, "power-notifications-for-keyboard"); manager->priv->notify_mouse = g_settings_get_boolean (manager->priv->settings, "power-notifications-for-mouse"); manager->priv->notify_other_devices = g_settings_get_boolean (manager->priv->settings, "power-notifications-for-other-devices"); } static UpDevice * engine_get_primary_device (CsdPowerManager *manager) { guint i; UpDevice *device = NULL; UpDevice *device_tmp; UpDeviceKind kind; UpDeviceState state; gboolean is_present; for (i=0; ipriv->devices_array->len; i++) { device_tmp = g_ptr_array_index (manager->priv->devices_array, i); /* get device properties */ g_object_get (device_tmp, "kind", &kind, "state", &state, "is-present", &is_present, NULL); /* not present */ if (!is_present) continue; /* not discharging */ if (state != UP_DEVICE_STATE_DISCHARGING) continue; /* not battery */ if (kind != UP_DEVICE_KIND_BATTERY) continue; /* use composite device to cope with multiple batteries */ device = g_object_ref (engine_get_composite_device (manager, device_tmp)); break; } return device; } static void phone_device_added_cb (GpmPhone *phone, guint idx, CsdPowerManager *manager) { UpDevice *device; device = up_device_new (); g_debug ("phone added %i", idx); /* get device properties */ g_object_set (device, "kind", UP_DEVICE_KIND_PHONE, "is-rechargeable", TRUE, "native-path", g_strdup_printf ("dummy:phone_%i", idx), "is-present", TRUE, NULL); /* state changed */ engine_device_add (manager, device); g_ptr_array_add (manager->priv->devices_array, g_object_ref (device)); engine_recalculate_state (manager); } static void phone_device_removed_cb (GpmPhone *phone, guint idx, CsdPowerManager *manager) { guint i; UpDevice *device; UpDeviceKind kind; g_debug ("phone removed %i", idx); for (i=0; ipriv->devices_array->len; i++) { device = g_ptr_array_index (manager->priv->devices_array, i); /* get device properties */ g_object_get (device, "kind", &kind, NULL); if (kind == UP_DEVICE_KIND_PHONE) { g_ptr_array_remove_index (manager->priv->devices_array, i); break; } } /* state changed */ engine_recalculate_state (manager); } static void phone_device_refresh_cb (GpmPhone *phone, guint idx, CsdPowerManager *manager) { guint i; UpDevice *device; UpDeviceKind kind; UpDeviceState state; gboolean is_present; gdouble percentage; g_debug ("phone refresh %i", idx); for (i=0; ipriv->devices_array->len; i++) { device = g_ptr_array_index (manager->priv->devices_array, i); /* get device properties */ g_object_get (device, "kind", &kind, "state", &state, "percentage", &percentage, "is-present", &is_present, NULL); if (kind == UP_DEVICE_KIND_PHONE) { is_present = gpm_phone_get_present (phone, idx); state = gpm_phone_get_on_ac (phone, idx) ? UP_DEVICE_STATE_CHARGING : UP_DEVICE_STATE_DISCHARGING; percentage = gpm_phone_get_percentage (phone, idx); break; } } /* state changed */ engine_recalculate_state (manager); } static void cinnamon_session_shutdown_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *result; GError *error = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("couldn't shutdown using cinnamon-session: %s", error->message); g_error_free (error); } else { g_variant_unref (result); } } static void cinnamon_session_shutdown (void) { GError *error = NULL; GDBusProxy *proxy; /* ask cinnamon-session to show the shutdown dialog with a timeout */ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_INTERFACE, NULL, &error); if (proxy == NULL) { g_warning ("cannot connect to cinnamon-session: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, "Shutdown", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, cinnamon_session_shutdown_cb, NULL); g_object_unref (proxy); } static void turn_monitors_off (CsdPowerManager *manager) { gboolean ret; GError *error = NULL; ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_OFF, &error); if (!ret) { g_warning ("failed to turn the panel off for policy action: %s", error->message); g_error_free (error); } } static void do_power_action_type (CsdPowerManager *manager, CsdPowerActionType action_type) { switch (action_type) { case CSD_POWER_ACTION_SUSPEND: if (should_lock_on_suspend (manager)) { activate_screensaver (manager, TRUE); } turn_monitors_off (manager); gboolean hybrid = g_settings_get_boolean (manager->priv->settings_cinnamon_session, "prefer-hybrid-sleep"); gboolean suspend_then_hibernate = g_settings_get_boolean (manager->priv->settings_cinnamon_session, "suspend-then-hibernate"); csd_power_suspend (hybrid, suspend_then_hibernate); break; case CSD_POWER_ACTION_INTERACTIVE: cinnamon_session_shutdown (); break; case CSD_POWER_ACTION_HIBERNATE: if (should_lock_on_suspend (manager)) { activate_screensaver (manager, TRUE); } turn_monitors_off (manager); csd_power_hibernate (); break; case CSD_POWER_ACTION_SHUTDOWN: /* this is only used on critically low battery where * hibernate is not available and is marginally better * than just powering down the computer mid-write */ csd_power_poweroff (); break; case CSD_POWER_ACTION_BLANK: /* Lock first or else xrandr might reconfigure stuff and the ss's coverage * may be incorrect upon return. */ activate_screensaver (manager, FALSE); turn_monitors_off (manager); break; case CSD_POWER_ACTION_NOTHING: break; } } static gboolean upower_kbd_get_percentage (CsdPowerManager *manager, GError **error) { GVariant *k_now = NULL; k_now = g_dbus_proxy_call_sync (manager->priv->upower_kbd_proxy, "GetBrightness", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (k_now != NULL) { g_variant_get (k_now, "(i)", &manager->priv->kbd_brightness_now); g_variant_unref (k_now); return TRUE; } return FALSE; } static void upower_kbd_emit_changed (CsdPowerManager *manager) { /* not yet connected to the bus */ if (manager->priv->keyboard_iface == NULL) return; csd_keyboard_emit_changed (manager->priv->keyboard_iface); } static gboolean upower_kbd_set_brightness (CsdPowerManager *manager, guint value, GError **error) { GVariant *retval; /* same as before */ if (manager->priv->kbd_brightness_now == value) return TRUE; /* update h/w value */ retval = g_dbus_proxy_call_sync (manager->priv->upower_kbd_proxy, "SetBrightness", g_variant_new ("(i)", (gint) value), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (retval == NULL) return FALSE; /* save new value */ manager->priv->kbd_brightness_now = value; g_variant_unref (retval); upower_kbd_emit_changed(manager); return TRUE; } static gboolean upower_kbd_toggle (CsdPowerManager *manager, GError **error) { gboolean ret; if (manager->priv->kbd_brightness_old >= 0) { g_debug ("keyboard toggle off"); ret = upower_kbd_set_brightness (manager, manager->priv->kbd_brightness_old, error); if (ret) { /* succeeded, set to -1 since now no old value */ manager->priv->kbd_brightness_old = -1; } } else { g_debug ("keyboard toggle on"); /* save the current value to restore later when untoggling */ manager->priv->kbd_brightness_old = manager->priv->kbd_brightness_now; ret = upower_kbd_set_brightness (manager, 0, error); if (!ret) { /* failed, reset back to -1 */ manager->priv->kbd_brightness_old = -1; } } upower_kbd_emit_changed(manager); return ret; } static void upower_kbd_handle_changed (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); g_debug("keyboard changed signal"); if (g_strcmp0 (signal_name, "BrightnessChangedWithSource") == 0) { g_debug ("Received upower kbdbacklight BrightnessChangedWithSource"); const gchar *source; gint brightness; g_variant_get (parameters, "(i&s)", &brightness, &source); if (g_strcmp0 (source, "external") == 0) { return; } manager->priv->kbd_brightness_now = brightness; upower_kbd_emit_changed(manager); } } static gboolean suspend_on_lid_close (CsdPowerManager *manager) { CsdXrandrBootBehaviour val; if (!external_monitor_is_connected (manager->priv->x11_screen)) return TRUE; val = g_settings_get_enum (manager->priv->settings_xrandr, "default-monitors-setup"); return val == CSD_XRANDR_BOOT_BEHAVIOUR_DO_NOTHING; } static gboolean inhibit_lid_switch_timer_cb (CsdPowerManager *manager) { if (suspend_on_lid_close (manager)) { g_debug ("no external monitors for a while; uninhibiting lid close"); uninhibit_lid_switch (manager); manager->priv->inhibit_lid_switch_timer_id = 0; return G_SOURCE_REMOVE; } g_debug ("external monitor still there; trying again later"); return G_SOURCE_CONTINUE; } /* Sets up a timer to be triggered some seconds after closing the laptop lid * when the laptop is *not* suspended for some reason. We'll check conditions * again in the timeout handler to see if we can suspend then. */ static void setup_inhibit_lid_switch_timer (CsdPowerManager *manager) { if (manager->priv->inhibit_lid_switch_timer_id != 0) { g_debug ("lid close safety timer already set up"); return; } g_debug ("setting up lid close safety timer"); manager->priv->inhibit_lid_switch_timer_id = g_timeout_add_seconds (CSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT, (GSourceFunc) inhibit_lid_switch_timer_cb, manager); g_source_set_name_by_id (manager->priv->inhibit_lid_switch_timer_id, "[CsdPowerManager] lid close safety timer"); } static void restart_inhibit_lid_switch_timer (CsdPowerManager *manager) { if (manager->priv->inhibit_lid_switch_timer_id != 0) { g_debug ("restarting lid close safety timer"); g_source_remove (manager->priv->inhibit_lid_switch_timer_id); manager->priv->inhibit_lid_switch_timer_id = 0; setup_inhibit_lid_switch_timer (manager); } } static gboolean randr_output_is_on (GnomeRROutput *output) { GnomeRRCrtc *crtc; crtc = gnome_rr_output_get_crtc (output); if (!crtc) return FALSE; return gnome_rr_crtc_get_current_mode (crtc) != NULL; } static gboolean external_monitor_is_connected (GnomeRRScreen *screen) { GnomeRROutput **outputs; guint i; /* see if we have more than one screen plugged in */ outputs = gnome_rr_screen_list_outputs (screen); for (i = 0; outputs[i] != NULL; i++) { if (randr_output_is_on (outputs[i]) && !gnome_rr_output_is_builtin_display (outputs[i])) return TRUE; } return FALSE; } static void on_randr_event (GnomeRRScreen *screen, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); if (suspend_on_lid_close (manager)) { restart_inhibit_lid_switch_timer (manager); return; } /* when a second monitor is plugged in, we take the * handle-lid-switch inhibitor lock of logind to prevent * it from suspending. * * Uninhibiting is done in the inhibit_lid_switch_timer, * since we want to give users a few seconds when unplugging * and replugging an external monitor, not suspend right away. */ inhibit_lid_switch (manager); setup_inhibit_lid_switch_timer (manager); } static void do_lid_open_action (CsdPowerManager *manager) { gboolean ret; GError *error = NULL; /* play a sound, using sounds from the naming spec */ ca_context_play (manager->priv->canberra_context, 0, CA_PROP_EVENT_ID, "lid-open", /* TRANSLATORS: this is the sound description */ CA_PROP_EVENT_DESCRIPTION, _("Lid has been opened"), NULL); /* ensure we turn the panel back on after lid open */ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_ON, &error); if (!ret) { g_warning ("failed to turn the panel on after lid open: %s", error->message); g_clear_error (&error); } /* only toggle keyboard if present and already toggled off */ if (manager->priv->upower_kbd_proxy != NULL && manager->priv->kbd_brightness_old != -1) { ret = upower_kbd_toggle (manager, &error); if (!ret) { g_warning ("failed to turn the kbd backlight on: %s", error->message); g_error_free (error); } } kill_lid_close_safety_timer (manager); } static gboolean is_on (GnomeRROutput *output) { GnomeRRCrtc *crtc; crtc = gnome_rr_output_get_crtc (output); if (!crtc) return FALSE; return gnome_rr_crtc_get_current_mode (crtc) != NULL; } static gboolean non_laptop_outputs_are_all_off (GnomeRRScreen *screen) { GnomeRROutput **outputs; int i; outputs = gnome_rr_screen_list_outputs (screen); for (i = 0; outputs[i] != NULL; i++) { if (gnome_rr_output_is_builtin_display (outputs[i])) continue; if (is_on (outputs[i])) return FALSE; } return TRUE; } /* Timeout callback used to check conditions when the laptop's lid is closed but * the machine is not suspended yet. We try to suspend again, so that the laptop * won't overheat if placed in a backpack. */ static gboolean lid_close_safety_timer_cb (CsdPowerManager *manager) { manager->priv->lid_close_safety_timer_id = 0; g_debug ("lid has been closed for a while; trying to suspend again"); do_lid_closed_action (manager); return FALSE; } /* Sets up a timer to be triggered some seconds after closing the laptop lid * when the laptop is *not* suspended for some reason. We'll check conditions * again in the timeout handler to see if we can suspend then. */ static void setup_lid_close_safety_timer (CsdPowerManager *manager) { if (manager->priv->lid_close_safety_timer_id != 0) return; manager->priv->lid_close_safety_timer_id = g_timeout_add_seconds (CSD_POWER_MANAGER_LID_CLOSE_SAFETY_TIMEOUT, (GSourceFunc) lid_close_safety_timer_cb, manager); g_source_set_name_by_id (manager->priv->lid_close_safety_timer_id, "[CsdPowerManager] lid close safety timer"); } static void kill_lid_close_safety_timer (CsdPowerManager *manager) { if (manager->priv->lid_close_safety_timer_id != 0) { g_source_remove (manager->priv->lid_close_safety_timer_id); manager->priv->lid_close_safety_timer_id = 0; } } static void suspend_with_lid_closed (CsdPowerManager *manager) { gboolean ret; GError *error = NULL; CsdPowerActionType action_type; /* we have different settings depending on AC state */ if (system_on_battery (manager)) { action_type = g_settings_get_enum (manager->priv->settings, "lid-close-battery-action"); } else { action_type = g_settings_get_enum (manager->priv->settings, "lid-close-ac-action"); } /* check we won't melt when the lid is closed */ if (action_type != CSD_POWER_ACTION_SUSPEND && action_type != CSD_POWER_ACTION_HIBERNATE) { #if ! UP_CHECK_VERSION(0,99,0) if (up_client_get_lid_force_sleep (manager->priv->up_client)) { g_warning ("to prevent damage, now forcing suspend"); do_power_action_type (manager, CSD_POWER_ACTION_SUSPEND); return; } #endif } /* only toggle keyboard if present and not already toggled */ if (manager->priv->upower_kbd_proxy && manager->priv->kbd_brightness_old == -1) { ret = upower_kbd_toggle (manager, &error); if (!ret) { g_warning ("failed to turn the kbd backlight off: %s", error->message); g_error_free (error); } } do_power_action_type (manager, action_type); } static void do_lid_closed_action (CsdPowerManager *manager) { /* play a sound, using sounds from the naming spec */ ca_context_play (manager->priv->canberra_context, 0, CA_PROP_EVENT_ID, "lid-close", /* TRANSLATORS: this is the sound description */ CA_PROP_EVENT_DESCRIPTION, _("Lid has been closed"), NULL); /* refresh RANDR so we get an accurate view of what monitors are plugged in when the lid is closed */ gnome_rr_screen_refresh (manager->priv->x11_screen, NULL); /* NULL-GError */ /* perform policy action */ if (g_settings_get_boolean (manager->priv->settings, "lid-close-suspend-with-external-monitor") || non_laptop_outputs_are_all_off (manager->priv->x11_screen)) { g_debug ("lid is closed; suspending or hibernating"); suspend_with_lid_closed (manager); } else { g_debug ("lid is closed; not suspending nor hibernating since some external monitor outputs are still active"); setup_lid_close_safety_timer (manager); } } static void #if UP_CHECK_VERSION(0,99,0) lid_state_changed_cb (UpClient *client, GParamSpec *pspec, CsdPowerManager *manager) #else up_client_changed_cb (UpClient *client, CsdPowerManager *manager) #endif { gboolean lid_is_closed; gboolean on_battery; on_battery = system_on_battery(manager); if (!on_battery) { /* if we are playing a critical charge sound loop on AC, stop it */ if (manager->priv->critical_alert_timeout_id > 0) { g_debug ("stopping alert loop due to ac being present"); play_loop_stop (manager); } notify_close_if_showing (manager->priv->notification_low); } /* same state */ lid_is_closed = up_client_get_lid_is_closed (manager->priv->up_client); if (manager->priv->lid_is_closed == lid_is_closed && manager->priv->on_battery == on_battery) return; manager->priv->lid_is_closed = lid_is_closed; manager->priv->on_battery = on_battery; /* fake a keypress */ if (lid_is_closed) do_lid_closed_action (manager); else do_lid_open_action (manager); engine_recalculate_state (manager); } typedef enum { SESSION_STATUS_CODE_AVAILABLE = 0, SESSION_STATUS_CODE_INVISIBLE, SESSION_STATUS_CODE_BUSY, SESSION_STATUS_CODE_IDLE, SESSION_STATUS_CODE_UNKNOWN } SessionStatusCode; typedef enum { SESSION_INHIBIT_MASK_LOGOUT = 1, SESSION_INHIBIT_MASK_SWITCH = 2, SESSION_INHIBIT_MASK_SUSPEND = 4, SESSION_INHIBIT_MASK_IDLE = 8 } SessionInhibitMask; static const gchar * idle_mode_to_string (CsdPowerIdleMode mode) { if (mode == CSD_POWER_IDLE_MODE_NORMAL) return "normal"; if (mode == CSD_POWER_IDLE_MODE_DIM) return "dim"; if (mode == CSD_POWER_IDLE_MODE_BLANK) return "blank"; if (mode == CSD_POWER_IDLE_MODE_SLEEP) return "sleep"; return "unknown"; } static GnomeRROutput * get_primary_output (CsdPowerManager *manager) { GnomeRROutput *output = NULL; GnomeRROutput **outputs; guint i; /* search all X11 outputs for the device id */ outputs = gnome_rr_screen_list_outputs (manager->priv->x11_screen); if (outputs == NULL) goto out; for (i = 0; outputs[i] != NULL; i++) { if (gnome_rr_output_is_connected (outputs[i]) && gnome_rr_output_is_builtin_display (outputs[i])) { output = outputs[i]; break; } } out: return output; } static void backlight_override_settings_refresh (CsdPowerManager *manager) { int i = 0; /* update all the stored backlight override properties * this is called on startup and by engine_settings_key_changed_cb */ manager->priv->backlight_helper_force = g_settings_get_boolean (manager->priv->settings, "backlight-helper-force"); /* concatenate all the search preferences into a single argument string */ gchar** backlight_preference_order = g_settings_get_strv (manager->priv->settings, "backlight-helper-preference-order"); gchar* tmp1 = NULL; gchar* tmp2 = NULL; if (backlight_preference_order[0] != NULL) { tmp1 = g_strdup_printf("-b %s", backlight_preference_order[0]); } for (i=1; backlight_preference_order[i] != NULL; i++ ) { tmp2 = tmp1; tmp1 = g_strdup_printf("%s -b %s", tmp2, backlight_preference_order[i]); g_free(tmp2); } tmp2 = manager->priv->backlight_helper_preference_args; manager->priv->backlight_helper_preference_args = tmp1; g_free(tmp2); tmp2 = NULL; g_free(backlight_preference_order); backlight_preference_order = NULL; } /** * backlight_helper_get_value: * * Gets a brightness value from the PolicyKit helper. * * Return value: the signed integer value from the helper, or -1 * for failure. If -1 then @error is set. **/ static gint64 backlight_helper_get_value (const gchar *argument, CsdPowerManager* manager, GError **error) { gboolean ret; gchar *stdout_data = NULL; gint exit_status = 0; gint64 value = -1; gchar *command = NULL; gchar *endptr = NULL; /* get the data */ command = g_strdup_printf (LIBEXECDIR "/csd-backlight-helper --%s %s", argument, manager->priv->backlight_helper_preference_args); ret = g_spawn_command_line_sync (command, &stdout_data, NULL, &exit_status, error); g_debug ("executed %s retval: %i", command, exit_status); if (!ret) goto out; if (WEXITSTATUS (exit_status) != 0) { g_set_error (error, CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_FAILED, "csd-backlight-helper failed: %s", stdout_data ? stdout_data : "No reason"); goto out; } /* parse */ value = g_ascii_strtoll (stdout_data, &endptr, 10); /* parsing error */ if (endptr == stdout_data) { value = -1; g_set_error (error, CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_FAILED, "failed to parse value: %s", stdout_data); goto out; } /* out of range */ if (value > G_MAXINT) { value = -1; g_set_error (error, CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_FAILED, "value out of range: %s", stdout_data); goto out; } /* Fetching the value failed, for some other reason */ if (value < 0) { g_set_error (error, CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_FAILED, "value negative, but helper did not fail: %s", stdout_data); goto out; } out: g_free (command); g_free (stdout_data); return value; } /** * backlight_helper_set_value: * * Sets a brightness value using the PolicyKit helper. * * Return value: Success. If FALSE then @error is set. **/ static gboolean backlight_helper_set_value (const gchar *argument, gint value, CsdPowerManager* manager, GError **error) { gboolean ret; gint exit_status = 0; gchar *command = NULL; #ifndef __linux__ /* non-Linux platforms won't have /sys/class/backlight */ g_set_error_literal (error, CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_FAILED, "The sysfs backlight helper is only for Linux"); goto out; #endif /* get the data */ command = g_strdup_printf ("pkexec " LIBEXECDIR "/csd-backlight-helper --%s %i %s", argument, value, manager->priv->backlight_helper_preference_args); ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, error); g_debug ("executed %s retval: %i", command, exit_status); if (!ret || WEXITSTATUS (exit_status) != 0) goto out; out: g_free (command); return ret; } static void backlight_get_output_id (CsdPowerManager *manager, gint *xout, gint *yout) { GnomeRROutput *output = NULL; GnomeRROutput **outputs; GnomeRRCrtc *crtc; gint x, y; guint i; outputs = gnome_rr_screen_list_outputs (manager->priv->x11_screen); if (outputs == NULL) return; for (i = 0; outputs[i] != NULL; i++) { if (gnome_rr_output_is_connected (outputs[i]) && gnome_rr_output_is_builtin_display (outputs[i])) { output = outputs[i]; break; } } if (output == NULL) return; crtc = gnome_rr_output_get_crtc (output); if (crtc == NULL) return; gnome_rr_crtc_get_position (crtc, &x, &y); *xout = x; *yout = y; } static gint min_abs_brightness (CsdPowerManager *manager, gint min, gint max) { guint min_percent = g_settings_get_uint (manager->priv->settings, "minimum-display-brightness"); return (min + ((max - min) / 100 * min_percent)); } static gint backlight_get_percentage (CsdPowerManager *manager, GError **error) { GnomeRROutput *output; gint now; gint value = -1; gint min = 0; gint max; /* prioritize user override settings */ if (!manager->priv->skip_unsupported_xrandr && !manager->priv->backlight_helper_force) { /* prefer xbacklight */ output = get_primary_output (manager); if (output != NULL) { // proxy for backlight supported if (gnome_rr_output_get_min_backlight_step (output) > 0) { value = gnome_rr_output_get_backlight (output); } else { // Skip gnome_rr_ calls if any fail, to avoid extra future traffic. g_message ("gnome-rr not supported for display backlight, using backlight-helper for future calls"); manager->priv->skip_unsupported_xrandr = TRUE; } } } /* fall back to the polkit helper */ max = backlight_helper_get_value ("get-max-brightness", manager, error); if (max < 0) { goto out; } now = backlight_helper_get_value ("get-brightness", manager, error); if (now < 0) { goto out; } value = ABS_TO_PERCENTAGE (min_abs_brightness (manager, min, max), max, now); out: return value; } static void backlight_emit_changed (CsdPowerManager *manager) { /* not yet connected to the bus */ if (manager->priv->screen_iface == NULL) return; csd_screen_emit_changed (manager->priv->screen_iface); } static gboolean backlight_set_percentage (CsdPowerManager *manager, guint value, gboolean emit_changed, GError **error) { GnomeRROutput *output; gboolean ret = FALSE; /* prioritize user override settings */ if (!manager->priv->skip_unsupported_xrandr && !manager->priv->backlight_helper_force) { /* prefer xbacklight */ output = get_primary_output (manager); if (output != NULL) { // proxy for backlight supported if (gnome_rr_output_get_min_backlight_step (output) > 0) { GError *grr_error = NULL; ret = gnome_rr_output_set_backlight (output, CLAMP (value, 0, 100), &grr_error); if (grr_error != NULL) { g_debug ("Could not set backlight using xrandr: %s", grr_error->message); g_error_free (grr_error); } } else { // Skip gnome_rr_ calls if any fail, to avoid extra future traffic. g_message ("gnome-rr not supported for display backlight, using backlight-helper for future calls"); manager->priv->skip_unsupported_xrandr = TRUE; } } } gint min = 0; gint max = 0; gint new; /* fall back to the polkit helper */ max = backlight_helper_get_value ("get-max-brightness", manager, error); if (max < 0) goto out; new = CLAMP (PERCENTAGE_TO_ABS (min_abs_brightness (manager, min, max), max, value), min_abs_brightness (manager, min, max), max); ret = backlight_helper_set_value ("set-brightness", new, manager, error); out: if (ret && emit_changed) backlight_emit_changed (manager); return ret; } static gint backlight_step_up (CsdPowerManager *manager, GError **error) { GnomeRROutput *output; gboolean ret = FALSE; gint current; gint step; gint new; gint percentage_value = 0; GnomeRRCrtc *crtc; /* prioritize user override settings */ if (!manager->priv->skip_unsupported_xrandr && !manager->priv->backlight_helper_force) { /* prefer xbacklight */ output = get_primary_output (manager); if (output != NULL) { crtc = gnome_rr_output_get_crtc (output); if (crtc != NULL) { step = gnome_rr_output_get_min_backlight_step (output); if (step > 0) { GError *grr_error = NULL; current = gnome_rr_output_get_backlight (output); new = CLAMP (step + current, 0, 100); ret = gnome_rr_output_set_backlight (output, new, &grr_error); if (ret) { percentage_value = new; goto out; } else { if (grr_error != NULL) { g_debug ("Could not step up backlight using xrandr: %s", grr_error->message); g_error_free (grr_error); } } } else { // Skip gnome_rr_ calls if any fail, to avoid extra future traffic. g_message ("gnome-rr not supported for display backlight, using backlight-helper for future calls"); manager->priv->skip_unsupported_xrandr = TRUE; } } } } gint max = 0; gint min = 0; /* fall back to the polkit helper */ current = backlight_helper_get_value ("get-brightness", manager, error); if (current < 0) goto out; max = backlight_helper_get_value ("get-max-brightness", manager, error); if (max < 0) goto out; step = BRIGHTNESS_STEP_AMOUNT (max - min_abs_brightness (manager, min, max)); new = MIN (current + step, max); ret = backlight_helper_set_value ("set-brightness", new, manager, error); if (ret) percentage_value = ABS_TO_PERCENTAGE (min_abs_brightness (manager, min, max), max, new); out: if (ret) backlight_emit_changed (manager); return percentage_value; } static gint backlight_step_down (CsdPowerManager *manager, GError **error) { GnomeRROutput *output; gboolean ret = FALSE; gint percentage_value = -1; gint current; gint step; gint new; GnomeRRCrtc *crtc; /* prioritize user override settings */ if (!manager->priv->skip_unsupported_xrandr && !manager->priv->backlight_helper_force) { /* prefer xbacklight */ output = get_primary_output (manager); if (output != NULL) { crtc = gnome_rr_output_get_crtc (output); if (crtc != NULL) { step = gnome_rr_output_get_min_backlight_step (output); if (step > 0) { GError *grr_error = NULL; current = gnome_rr_output_get_backlight (output); new = CLAMP (current - step, 0, 100); ret = gnome_rr_output_set_backlight (output, new, &grr_error); if (ret) { percentage_value = new; goto out; } else { if (grr_error != NULL) { g_debug ("Could not step down backlight using xrandr: %s", grr_error->message); g_error_free (grr_error); } } } else { // Skip gnome_rr_ calls if any fail, to avoid extra future traffic. g_message ("gnome-rr not supported for display backlight, using backlight-helper for future calls"); manager->priv->skip_unsupported_xrandr = TRUE; } } } } gint min = 0; gint max = 0; /* fall back to the polkit helper */ current = backlight_helper_get_value ("get-brightness", manager, error); if (current < 0) goto out; max = backlight_helper_get_value ("get-max-brightness", manager, error); if (max < 0) goto out; step = BRIGHTNESS_STEP_AMOUNT (max - min_abs_brightness (manager, min, max)); new = MAX (current - step, min_abs_brightness (manager, min, max)); ret = backlight_helper_set_value ("set-brightness", new, manager, error); if (ret) percentage_value = ABS_TO_PERCENTAGE (min_abs_brightness (manager, min, max), max, new); out: if (ret) backlight_emit_changed (manager); return percentage_value; } static gboolean display_backlight_dim (CsdPowerManager *manager, gint idle_percentage, GError **error) { gint current; gboolean ret = FALSE; current = backlight_get_percentage (manager, error); if (current < 0) { goto out; } /* is the dim brightness actually *dimmer* than the * brightness we have now? */ if (idle_percentage > current) { g_debug ("brightness already now %i%%, so " "ignoring dim to %i%%", current, idle_percentage); ret = TRUE; goto out; } ret = backlight_set_percentage (manager, idle_percentage, FALSE, error); if (!ret) { goto out; } /* save for undim */ manager->priv->pre_dim_brightness = current; out: return ret; } static gboolean kbd_backlight_dim (CsdPowerManager *manager, gint idle_percentage, GError **error) { gboolean ret; gint idle; gint max; gint now; if (manager->priv->upower_kbd_proxy == NULL) return TRUE; now = manager->priv->kbd_brightness_now; max = manager->priv->kbd_brightness_max; idle = PERCENTAGE_TO_ABS (0, max, idle_percentage); if (idle > now) { g_debug ("kbd brightness already now %i/%i, so " "ignoring dim to %i/%i", now, max, idle, max); return TRUE; } ret = upower_kbd_set_brightness (manager, idle, error); if (!ret) return FALSE; /* save for undim */ manager->priv->kbd_brightness_pre_dim = now; return TRUE; } static void idle_set_mode (CsdPowerManager *manager, CsdPowerIdleMode mode) { gboolean ret = FALSE; GError *error = NULL; gint idle_percentage; CsdPowerActionType action_type; CinnamonSettingsSessionState state; if (mode == manager->priv->current_idle_mode) return; /* Ignore attempts to set "less idle" modes */ if (mode < manager->priv->current_idle_mode && mode != CSD_POWER_IDLE_MODE_NORMAL) return; /* ensure we're still on an active console */ state = cinnamon_settings_session_get_state (manager->priv->session); if (state == CINNAMON_SETTINGS_SESSION_STATE_INACTIVE) { g_debug ("ignoring state transition to %s as inactive", idle_mode_to_string (mode)); return; } manager->priv->current_idle_mode = mode; g_debug ("Doing a state transition: %s", idle_mode_to_string (mode)); /* don't do any power saving if we're a VM */ if (manager->priv->is_virtual_machine) { g_debug ("ignoring state transition to %s as virtual machine", idle_mode_to_string (mode)); return; } /* save current brightness, and set dim level */ if (mode == CSD_POWER_IDLE_MODE_DIM) { /* have we disabled the action */ if (system_on_battery (manager)) { ret = g_settings_get_boolean (manager->priv->settings, "idle-dim-battery"); } else { ret = g_settings_get_boolean (manager->priv->settings, "idle-dim-ac"); } if (!ret) { g_debug ("not dimming due to policy"); return; } /* display backlight */ idle_percentage = g_settings_get_int (manager->priv->settings, "idle-brightness"); ret = display_backlight_dim (manager, idle_percentage, &error); if (!ret) { g_warning ("failed to set dim backlight to %i%%: %s", idle_percentage, error->message); g_clear_error (&error); } /* keyboard backlight */ ret = kbd_backlight_dim (manager, idle_percentage, &error); if (!ret) { g_warning ("failed to set dim kbd backlight to %i%%: %s", idle_percentage, error->message); g_clear_error (&error); } /* turn off screen and kbd */ } else if (mode == CSD_POWER_IDLE_MODE_BLANK) { ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_OFF, &error); if (!ret) { g_warning ("failed to turn the panel off: %s", error->message); g_clear_error (&error); } /* only toggle keyboard if present and not already toggled */ if (manager->priv->upower_kbd_proxy && manager->priv->kbd_brightness_old == -1) { ret = upower_kbd_toggle (manager, &error); if (!ret) { g_warning ("failed to turn the kbd backlight off: %s", error->message); g_error_free (error); } } /* sleep */ } else if (mode == CSD_POWER_IDLE_MODE_SLEEP) { if (system_on_battery (manager)) { action_type = g_settings_get_enum (manager->priv->settings, "sleep-inactive-battery-type"); } else { action_type = g_settings_get_enum (manager->priv->settings, "sleep-inactive-ac-type"); } do_power_action_type (manager, action_type); /* turn on screen and restore user-selected brightness level */ } else if (mode == CSD_POWER_IDLE_MODE_NORMAL) { ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_ON, &error); if (!ret) { g_warning ("failed to turn the panel on: %s", error->message); g_clear_error (&error); } /* reset brightness if we dimmed */ if (manager->priv->pre_dim_brightness >= 0) { ret = backlight_set_percentage (manager, manager->priv->pre_dim_brightness, FALSE, &error); if (!ret) { g_warning ("failed to restore backlight to %i: %s", manager->priv->pre_dim_brightness, error->message); g_clear_error (&error); } else { manager->priv->pre_dim_brightness = -1; } } /* only toggle keyboard if present and already toggled off */ if (manager->priv->upower_kbd_proxy && manager->priv->kbd_brightness_old != -1) { ret = upower_kbd_toggle (manager, &error); if (!ret) { g_warning ("failed to turn the kbd backlight on: %s", error->message); g_clear_error (&error); } } /* reset kbd brightness if we dimmed */ if (manager->priv->kbd_brightness_pre_dim >= 0) { ret = upower_kbd_set_brightness (manager, manager->priv->kbd_brightness_pre_dim, &error); if (!ret) { g_warning ("failed to restore kbd backlight to %i: %s", manager->priv->kbd_brightness_pre_dim, error->message); g_error_free (error); } manager->priv->kbd_brightness_pre_dim = -1; } } } static gboolean idle_is_session_inhibited (CsdPowerManager *manager, guint mask) { gboolean ret; GVariant *retval = NULL; GError *error = NULL; /* not yet connected to cinnamon-session */ if (manager->priv->session_proxy == NULL) { g_debug ("session inhibition not available, cinnamon-session is not available"); return FALSE; } retval = g_dbus_proxy_call_sync (manager->priv->session_proxy, "IsInhibited", g_variant_new ("(u)", mask), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (retval == NULL) { /* abort as the DBUS method failed */ g_warning ("IsInhibited failed: %s", error->message); g_error_free (error); return FALSE; } g_variant_get (retval, "(b)", &ret); g_variant_unref (retval); return ret; } /** * idle_adjust_timeout: * @idle_time: Current idle time, in seconds. * @timeout: The new timeout we want to set, in seconds. * * On slow machines, or machines that have lots to load duing login, * the current idle time could be bigger than the requested timeout. * In this case the scheduled idle timeout will never fire, unless * some user activity (keyboard, mouse) resets the current idle time. * Instead of relying on user activity to correct this issue, we need * to adjust timeout, as related to current idle time, so the idle * timeout will fire as designed. * * Return value: timeout to set, adjusted according to current idle time. **/ static guint idle_adjust_timeout (guint idle_time, guint timeout) { /* allow 2 sec margin for messaging delay. */ idle_time += 2; /* Double timeout until it's larger than current idle time. * Give up for ultra slow machines. (86400 sec = 24 hours) */ while (timeout < idle_time && timeout < 86400 && timeout > 0) { timeout *= 2; } return timeout; } /** * @timeout: The new timeout we want to set, in seconds **/ static void idle_set_timeout_dim (CsdPowerManager *manager, guint timeout) { guint idle_time; gboolean is_idle_inhibited; /* are we inhibited from going idle */ is_idle_inhibited = idle_is_session_inhibited (manager, SESSION_INHIBIT_MASK_IDLE); if (is_idle_inhibited) { g_debug ("inhibited, so using normal state"); idle_set_mode (manager, CSD_POWER_IDLE_MODE_NORMAL); gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_DIM_ID); return; } idle_time = gpm_idletime_get_time (manager->priv->idletime) / 1000; g_debug ("Setting dim idle timeout: %ds", timeout); if (timeout > 0) { gpm_idletime_alarm_set (manager->priv->idletime, CSD_POWER_IDLETIME_DIM_ID, idle_adjust_timeout (idle_time, timeout) * 1000); } else { gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_DIM_ID); } return; } static void refresh_idle_dim_settings (CsdPowerManager *manager) { gint timeout_dim; timeout_dim = g_settings_get_int (manager->priv->settings, "idle-dim-time"); g_debug ("idle dim set with timeout %i", timeout_dim); idle_set_timeout_dim (manager, timeout_dim); } /** * idle_adjust_timeout_blank: * @idle_time: current idle time, in seconds. * @timeout: the new timeout we want to set, in seconds. * * Same as idle_adjust_timeout(), but also accounts for the duration * of the fading animation in the screensaver (so that blanking happens * exactly at the end of it, if configured with the same timeouts) */ static guint idle_adjust_timeout_blank (guint idle_time, guint timeout) { return idle_adjust_timeout (idle_time, timeout + SCREENSAVER_FADE_TIME); } static void idle_configure (CsdPowerManager *manager) { gboolean is_idle_inhibited; guint current_idle_time; guint timeout_lock; guint timeout_blank; guint timeout_sleep; gboolean on_battery; /* are we inhibited from going idle */ is_idle_inhibited = idle_is_session_inhibited (manager, SESSION_INHIBIT_MASK_IDLE); if (is_idle_inhibited) { g_debug ("inhibited, so using normal state"); idle_set_mode (manager, CSD_POWER_IDLE_MODE_NORMAL); gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_LOCK_ID); gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_BLANK_ID); gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_SLEEP_ID); refresh_idle_dim_settings (manager); return; } current_idle_time = gpm_idletime_get_time (manager->priv->idletime) / 1000; /* set up blank callback even when session is not idle, * but only if we actually want to blank. */ on_battery = system_on_battery (manager); if (on_battery) { timeout_blank = g_settings_get_int (manager->priv->settings, "sleep-display-battery"); } else { timeout_blank = g_settings_get_int (manager->priv->settings, "sleep-display-ac"); } /* set up custom screensaver lock after idle time trigger */ timeout_lock = g_settings_get_uint (manager->priv->settings_desktop_session, "idle-delay"); if (timeout_lock != 0) { if (timeout_blank != 0 && timeout_lock > timeout_blank) { g_debug ("reducing lock timeout to match blank timeout"); timeout_lock = timeout_blank; } g_debug ("setting up lock callback for %is", timeout_lock); gpm_idletime_alarm_set (manager->priv->idletime, CSD_POWER_IDLETIME_LOCK_ID, idle_adjust_timeout (current_idle_time, timeout_lock) * 1000); } else { gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_LOCK_ID); } if (timeout_blank != 0) { g_debug ("setting up blank callback for %is", timeout_blank); gpm_idletime_alarm_set (manager->priv->idletime, CSD_POWER_IDLETIME_BLANK_ID, idle_adjust_timeout_blank (current_idle_time, timeout_blank) * 1000); } else { gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_BLANK_ID); } gboolean is_sleep_inhibited = idle_is_session_inhibited (manager, SESSION_INHIBIT_MASK_SUSPEND); /* only do the sleep timeout when the session is idle * and we aren't inhibited from sleeping */ if (on_battery) { timeout_sleep = g_settings_get_int (manager->priv->settings, "sleep-inactive-battery-timeout"); } else { timeout_sleep = g_settings_get_int (manager->priv->settings, "sleep-inactive-ac-timeout"); } if (!is_sleep_inhibited && timeout_sleep != 0) { g_debug ("setting up sleep callback %is", timeout_sleep); gpm_idletime_alarm_set (manager->priv->idletime, CSD_POWER_IDLETIME_SLEEP_ID, idle_adjust_timeout (current_idle_time, timeout_sleep) * 1000); } else { gpm_idletime_alarm_remove (manager->priv->idletime, CSD_POWER_IDLETIME_SLEEP_ID); } refresh_idle_dim_settings (manager); } #if UP_CHECK_VERSION(0,99,0) static void up_client_on_battery_cb (UpClient *client, GParamSpec *pspec, CsdPowerManager *manager) { idle_configure (manager); lid_state_changed_cb(client, pspec, manager); } #endif static void csd_power_manager_class_init (CsdPowerManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_power_manager_finalize; g_type_class_add_private (klass, sizeof (CsdPowerManagerPrivate)); } static void setup_locker_process (gpointer user_data) { /* This function should only contain signal safe code, as it is invoked * between fork and exec. See signal-safety(7) for more information. */ CsdPowerManager *manager = user_data; /* close all FDs except stdin, stdout, stderr and the inhibition fd */ for (gint fd = 3; fd < manager->priv->fd_close_loop_end; fd++) if (fd != manager->priv->inhibit_suspend_fd) close (fd); /* make sure the inhibit fd does not get closed on exec, as it's options * are not specified in the logind inhibitor interface documentation. */ if (-1 != manager->priv->inhibit_suspend_fd) fcntl (manager->priv->inhibit_suspend_fd, F_SETFD, ~FD_CLOEXEC & fcntl (manager->priv->inhibit_suspend_fd, F_GETFD)); } static void lock_screen_with_custom_saver (CsdPowerManager *manager, gchar *custom_saver, gboolean idle_lock) { gboolean res; gchar *fd = NULL; gchar **argv = NULL; gchar **env = NULL; GError *error = NULL; /* environment setup */ fd = g_strdup_printf ("%d", manager->priv->inhibit_suspend_fd); if (!fd) { g_warning ("failed to printf inhibit_suspend_fd"); goto quit; } if (!(env = g_get_environ ())) { g_warning ("failed to get environment"); goto quit; } env = g_environ_setenv (env, "XSS_SLEEP_LOCK_FD", fd, FALSE); if (!env) { g_warning ("failed to set XSS_SLEEP_LOCK_FD"); goto quit; } env = g_environ_setenv (env, "LOCKED_BY_SESSION_IDLE", idle_lock ? "true" : "false", TRUE); if (!env) { g_warning ("failed to set LOCKED_BY_SESSION_IDLE"); goto quit; } /* argv setup */ res = g_shell_parse_argv (custom_saver, NULL, &argv, &error); if (!res) { g_warning ("failed to parse custom saver cmd '%s': %s", custom_saver, error->message); goto quit; } /* get the max number of open file descriptors */ manager->priv->fd_close_loop_end = sysconf (_SC_OPEN_MAX); if (-1 == manager->priv->fd_close_loop_end) /* use some sane default */ manager->priv->fd_close_loop_end = 32768; /* spawn the custom screen locker */ res = g_spawn_async (NULL, argv, env, G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_SEARCH_PATH, &setup_locker_process, manager, NULL, &error); if (!res) g_warning ("failed to run custom screensaver '%s': %s", custom_saver, error->message); quit: g_free (fd); g_strfreev (argv); g_strfreev (env); g_clear_error (&error); } static void activate_screensaver (CsdPowerManager *manager, gboolean force_lock) { GError *error; gboolean ret; gchar *custom_saver = g_settings_get_string (manager->priv->settings_screensaver, "custom-screensaver-command"); g_debug ("Locking screen before sleep/hibernate"); if (custom_saver && g_strcmp0 (custom_saver, "") != 0) { lock_screen_with_custom_saver (manager, custom_saver, FALSE); goto quit; } /* if we fail to get the gsettings entry, or if the user did not select * a custom screen saver, default to invoking cinnamon-screensaver */ /* do this sync to ensure it's on the screen when we start suspending */ error = NULL; if (force_lock) { ret = g_spawn_command_line_sync ("cinnamon-screensaver-command --lock", NULL, NULL, NULL, &error); } else { ret = g_spawn_command_line_sync ("cinnamon-screensaver-command -a", NULL, NULL, NULL, &error); } if (!ret) { g_warning ("Couldn't lock screen: %s", error->message); g_error_free (error); } quit: g_free (custom_saver); } static void idle_dbus_signal_cb (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); if (g_strcmp0 (signal_name, "InhibitorAdded") == 0 || g_strcmp0 (signal_name, "InhibitorRemoved") == 0) { g_debug ("Received gnome session inhibitor change"); idle_configure (manager); } if (g_strcmp0 (signal_name, "StatusChanged") == 0) { guint status; g_variant_get (parameters, "(u)", &status); g_dbus_proxy_set_cached_property (proxy, "status", g_variant_new ("u", status)); g_debug ("Received gnome session status change"); idle_configure (manager); } } static void session_proxy_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); manager->priv->session_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (manager->priv->session_proxy == NULL) { g_warning ("Could not connect to cinnamon-session: %s", error->message); g_error_free (error); } else { g_signal_connect (manager->priv->session_proxy, "g-signal", G_CALLBACK (idle_dbus_signal_cb), manager); } idle_configure (manager); } static void session_presence_proxy_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); manager->priv->session_presence_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (manager->priv->session_presence_proxy == NULL) { g_warning ("Could not connect to gnome-sesson: %s", error->message); g_error_free (error); return; } g_signal_connect (manager->priv->session_presence_proxy, "g-signal", G_CALLBACK (idle_dbus_signal_cb), manager); } static void power_keyboard_proxy_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *k_now = NULL; GVariant *k_max = NULL; GError *error = NULL; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); manager->priv->upower_kbd_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (manager->priv->upower_kbd_proxy == NULL) { g_warning ("Could not connect to UPower: %s", error->message); g_error_free (error); goto out; } k_now = g_dbus_proxy_call_sync (manager->priv->upower_kbd_proxy, "GetBrightness", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (k_now == NULL) { if (error->domain != G_DBUS_ERROR || error->code != G_DBUS_ERROR_UNKNOWN_METHOD) { g_warning ("Failed to get brightness: %s", error->message); } g_error_free (error); goto out; } k_max = g_dbus_proxy_call_sync (manager->priv->upower_kbd_proxy, "GetMaxBrightness", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (k_max == NULL) { g_warning ("Failed to get max brightness: %s", error->message); g_error_free (error); goto out; } g_signal_connect (manager->priv->upower_kbd_proxy, "g-signal", G_CALLBACK(upower_kbd_handle_changed), manager); g_variant_get (k_now, "(i)", &manager->priv->kbd_brightness_now); g_variant_get (k_max, "(i)", &manager->priv->kbd_brightness_max); /* Set keyboard brightness to zero if the current value is out of valid range. Unlike display brightness, keyboard backlight brightness should be dim by default.*/ if ((manager->priv->kbd_brightness_now < 0) || (manager->priv->kbd_brightness_now > manager->priv->kbd_brightness_max)) { gboolean ret; ret = upower_kbd_set_brightness (manager, 0, &error); if (!ret) { g_warning ("failed to initialize kbd backlight to %i: %s", 0, error->message); g_error_free (error); } } out: if (k_now != NULL) g_variant_unref (k_now); if (k_max != NULL) g_variant_unref (k_max); } static void idle_idletime_alarm_expired_cb (GpmIdletime *idletime, guint alarm_id, CsdPowerManager *manager) { g_debug ("idletime alarm: %i", alarm_id); switch (alarm_id) { case CSD_POWER_IDLETIME_DIM_ID: idle_set_mode (manager, CSD_POWER_IDLE_MODE_DIM); break; case CSD_POWER_IDLETIME_LOCK_ID: ; /* empty statement, because C does not allow a declaration to * follow a label */ gchar *custom_saver = g_settings_get_string (manager->priv->settings_screensaver, "custom-screensaver-command"); if (custom_saver && g_strcmp0 (custom_saver, "") != 0) { lock_screen_with_custom_saver (manager, custom_saver, TRUE); } else { activate_screensaver (manager, FALSE); } g_free (custom_saver); break; case CSD_POWER_IDLETIME_BLANK_ID: idle_set_mode (manager, CSD_POWER_IDLE_MODE_BLANK); break; case CSD_POWER_IDLETIME_SLEEP_ID: idle_set_mode (manager, CSD_POWER_IDLE_MODE_SLEEP); break; } } static void idle_idletime_reset_cb (GpmIdletime *idletime, CsdPowerManager *manager) { g_debug ("idletime reset"); idle_set_mode (manager, CSD_POWER_IDLE_MODE_NORMAL); } static void engine_settings_key_changed_cb (GSettings *settings, const gchar *key, CsdPowerManager *manager) { /* note: you *have* to check if your key was changed here before * doing anything here. this gets invoked on module stop, and * will crash c-s-d if you don't. */ if (g_strcmp0 (key, "use-time-for-policy") == 0) { manager->priv->use_time_primary = g_settings_get_boolean (settings, key); return; } if (g_strcmp0 (key, "idle-dim-time") == 0) { refresh_idle_dim_settings (manager); return; } if (g_str_has_prefix (key, "sleep-inactive") || g_str_has_prefix (key, "sleep-display") || g_str_has_prefix (key, "idle-delay")) { idle_configure (manager); return; } if (g_str_has_prefix (key, "backlight-helper")) { backlight_override_settings_refresh (manager); return; } if (g_str_has_prefix (key, "power-notifications")) { refresh_notification_settings (manager); return; } } static void engine_session_active_changed_cb (CinnamonSettingsSession *session, GParamSpec *pspec, CsdPowerManager *manager) { /* when doing the fast-user-switch into a new account, * ensure the new account is undimmed and with the backlight on */ idle_set_mode (manager, CSD_POWER_IDLE_MODE_NORMAL); } /* This timer goes off every few minutes, whether the user is idle or not, to try and clean up anything that has gone wrong. It calls disable_builtin_screensaver() so that if xset has been used, or some other program (like xlock) has messed with the XSetScreenSaver() settings, they will be set back to sensible values (if a server extension is in use, messing with xlock can cause the screensaver to never get a wakeup event, and could cause monitor power-saving to occur, and all manner of heinousness.) This code was originally part of cinnamon-screensaver, see http://git.gnome.org/browse/cinnamon-screensaver/tree/src/gs-watcher-x11.c?id=fec00b12ec46c86334cfd36b37771cc4632f0d4d#n530 */ static gboolean disable_builtin_screensaver (gpointer unused) { int current_server_timeout, current_server_interval; int current_prefer_blank, current_allow_exp; int desired_server_timeout, desired_server_interval; int desired_prefer_blank, desired_allow_exp; XGetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), ¤t_server_timeout, ¤t_server_interval, ¤t_prefer_blank, ¤t_allow_exp); desired_server_timeout = current_server_timeout; desired_server_interval = current_server_interval; desired_prefer_blank = current_prefer_blank; desired_allow_exp = current_allow_exp; desired_server_interval = 0; /* I suspect (but am not sure) that DontAllowExposures might have something to do with powering off the monitor as well, at least on some systems that don't support XDPMS? Who know... */ desired_allow_exp = AllowExposures; /* When we're not using an extension, set the server-side timeout to 0, so that the server never gets involved with screen blanking, and we do it all ourselves. (However, when we *are* using an extension, we tell the server when to notify us, and rather than blanking the screen, the server will send us an X event telling us to blank.) */ desired_server_timeout = 0; if (desired_server_timeout != current_server_timeout || desired_server_interval != current_server_interval || desired_prefer_blank != current_prefer_blank || desired_allow_exp != current_allow_exp) { g_debug ("disabling server builtin screensaver:" " (xset s %d %d; xset s %s; xset s %s)", desired_server_timeout, desired_server_interval, (desired_prefer_blank ? "blank" : "noblank"), (desired_allow_exp ? "expose" : "noexpose")); XSetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), desired_server_timeout, desired_server_interval, desired_prefer_blank, desired_allow_exp); XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); } return TRUE; } static void inhibit_lid_switch_done (GObject *source, GAsyncResult *result, gpointer user_data) { GDBusProxy *proxy = G_DBUS_PROXY (source); CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); GError *error = NULL; GVariant *res; GUnixFDList *fd_list = NULL; gint idx; res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); if (res == NULL) { g_warning ("Unable to inhibit lid switch: %s", error->message); g_error_free (error); } else { g_variant_get (res, "(h)", &idx); manager->priv->inhibit_lid_switch_fd = g_unix_fd_list_get (fd_list, idx, &error); if (manager->priv->inhibit_lid_switch_fd == -1) { g_warning ("Failed to receive system inhibitor fd: %s", error->message); g_error_free (error); } g_debug ("System inhibitor fd is %d", manager->priv->inhibit_lid_switch_fd); g_object_unref (fd_list); g_variant_unref (res); } } static void inhibit_lid_switch (CsdPowerManager *manager) { if (!manager->priv->inhibit_lid_switch_enabled) { // The users asks us not to interfere with what logind does // w.r.t. handling the lid switch g_debug ("inhibiting lid-switch disabled"); return; } GVariant *params; if (manager->priv->inhibit_lid_switch_taken) { g_debug ("already inhibited lid-switch"); return; } g_debug ("Adding lid switch system inhibitor"); manager->priv->inhibit_lid_switch_taken = TRUE; params = g_variant_new ("(ssss)", "handle-lid-switch", g_get_user_name (), "Multiple displays attached", "block"); g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, "Inhibit", params, 0, G_MAXINT, NULL, NULL, inhibit_lid_switch_done, manager); } static void uninhibit_lid_switch (CsdPowerManager *manager) { if (manager->priv->inhibit_lid_switch_fd == -1) { g_debug ("no lid-switch inhibitor"); return; } g_debug ("Removing lid switch system inhibitor"); close (manager->priv->inhibit_lid_switch_fd); manager->priv->inhibit_lid_switch_fd = -1; manager->priv->inhibit_lid_switch_taken = FALSE; } static void inhibit_suspend_done (GObject *source, GAsyncResult *result, gpointer user_data) { GDBusProxy *proxy = G_DBUS_PROXY (source); CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); GError *error = NULL; GVariant *res; GUnixFDList *fd_list = NULL; gint idx; res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); if (res == NULL) { g_warning ("Unable to inhibit suspend: %s", error->message); g_error_free (error); } else { g_variant_get (res, "(h)", &idx); manager->priv->inhibit_suspend_fd = g_unix_fd_list_get (fd_list, idx, &error); if (manager->priv->inhibit_suspend_fd == -1) { g_warning ("Failed to receive system inhibitor fd: %s", error->message); g_error_free (error); } g_debug ("System inhibitor fd is %d", manager->priv->inhibit_suspend_fd); g_object_unref (fd_list); g_variant_unref (res); } } /* We take a delay inhibitor here, which causes logind to send a * PrepareToSleep signal, which gives us a chance to lock the screen * and do some other preparations. */ static void inhibit_suspend (CsdPowerManager *manager) { if (manager->priv->inhibit_suspend_taken) { g_debug ("already inhibited lid-switch"); return; } g_debug ("Adding suspend delay inhibitor"); manager->priv->inhibit_suspend_taken = TRUE; g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, "Inhibit", g_variant_new ("(ssss)", "sleep", g_get_user_name (), "Cinnamon needs to lock the screen", "delay"), 0, G_MAXINT, NULL, NULL, inhibit_suspend_done, manager); } static void uninhibit_suspend (CsdPowerManager *manager) { if (manager->priv->inhibit_suspend_fd == -1) { g_debug ("no suspend delay inhibitor"); return; } g_debug ("Removing suspend delay inhibitor"); close (manager->priv->inhibit_suspend_fd); manager->priv->inhibit_suspend_fd = -1; manager->priv->inhibit_suspend_taken = FALSE; } static void handle_suspend_actions (CsdPowerManager *manager) { /* Is this even necessary? We lock ahead of the suspend initiation, * during do_power_action_type(). This is a signal from logind or * upower that we're about to suspend. That may have originated in * this module, or elsewhere (cinnamon-session via menu or user * applet. Lock is handled there as well... but just in case I * suppose.) */ if (should_lock_on_suspend (manager)) { activate_screensaver (manager, TRUE); } /* lift the delay inhibit, so logind can proceed */ uninhibit_suspend (manager); } static void handle_resume_actions (CsdPowerManager *manager) { gboolean ret; GError *error = NULL; /* this displays the unlock dialogue so the user doesn't have * to move the mouse or press any key before the window comes up */ g_dbus_connection_call (manager->priv->connection, GS_DBUS_NAME, GS_DBUS_PATH, GS_DBUS_INTERFACE, "SimulateUserActivity", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); /* close existing notifications on resume, the system power * state is probably different now */ notify_close_if_showing (manager->priv->notification_low); notify_close_if_showing (manager->priv->notification_discharging); /* ensure we turn the panel back on after resume */ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_ON, &error); if (!ret) { g_warning ("failed to turn the panel on after resume: %s", error->message); g_error_free (error); } /* set up the delay again */ inhibit_suspend (manager); } #if ! UP_CHECK_VERSION(0,99,0) static void upower_notify_sleep_cb (UpClient *client, UpSleepKind sleep_kind, CsdPowerManager *manager) { handle_suspend_actions (manager); } static void upower_notify_resume_cb (UpClient *client, UpSleepKind sleep_kind, CsdPowerManager *manager) { handle_resume_actions (manager); } #endif static void logind_proxy_signal_cb (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); gboolean is_about_to_suspend; if (g_strcmp0 (signal_name, "PrepareForSleep") != 0) return; g_variant_get (parameters, "(b)", &is_about_to_suspend); if (is_about_to_suspend) { handle_suspend_actions (manager); } else { handle_resume_actions (manager); } } static gboolean is_hardware_a_virtual_machine (void) { const gchar *str; gboolean ret = FALSE; GError *error = NULL; GVariant *inner; GVariant *variant = NULL; GDBusConnection *connection; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_warning ("system bus not available: %s", error->message); g_error_free (error); goto out; } variant = g_dbus_connection_call_sync (connection, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.DBus.Properties", "Get", g_variant_new ("(ss)", "org.freedesktop.systemd1.Manager", "Virtualization"), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (variant == NULL) { g_debug ("Failed to get property '%s': %s", "Virtualization", error->message); g_error_free (error); goto out; } /* on bare-metal hardware this is the empty string, * otherwise an identifier such as "kvm", "vmware", etc. */ g_variant_get (variant, "(v)", &inner); str = g_variant_get_string (inner, NULL); if (str != NULL && str[0] != '\0') ret = TRUE; out: if (connection != NULL) g_object_unref (connection); if (variant != NULL) g_variant_unref (variant); return ret; } static void on_rr_screen_acquired (GObject *object, GAsyncResult *result, gpointer user_data) { CsdPowerManager *manager = user_data; GError *error = NULL; gboolean ret; cinnamon_settings_profile_start (NULL); manager->priv->x11_screen = gnome_rr_screen_new_finish (result, &error); if (error) { g_warning ("Could not create GnomeRRScreen: %s\n", error->message); g_error_free (error); cinnamon_settings_profile_end (NULL); return; } g_signal_connect (manager->priv->logind_proxy, "g-signal", G_CALLBACK (logind_proxy_signal_cb), manager); /* Set up a delay inhibitor to be informed about suspend attempts */ inhibit_suspend (manager); /* track the active session */ manager->priv->session = cinnamon_settings_session_new (); g_signal_connect (manager->priv->session, "notify::state", G_CALLBACK (engine_session_active_changed_cb), manager); manager->priv->kbd_brightness_old = -1; manager->priv->kbd_brightness_pre_dim = -1; manager->priv->pre_dim_brightness = -1; g_signal_connect (manager->priv->settings, "changed", G_CALLBACK (engine_settings_key_changed_cb), manager); g_signal_connect (manager->priv->settings_desktop_session, "changed", G_CALLBACK (engine_settings_key_changed_cb), manager); manager->priv->inhibit_lid_switch_enabled = g_settings_get_boolean (manager->priv->settings, "inhibit-lid-switch"); /* Disable logind's lid handling while g-s-d is active */ inhibit_lid_switch (manager); manager->priv->up_client = up_client_new (); #if ! UP_CHECK_VERSION(0,99,0) g_signal_connect (manager->priv->up_client, "notify-sleep", G_CALLBACK (upower_notify_sleep_cb), manager); g_signal_connect (manager->priv->up_client, "notify-resume", G_CALLBACK (upower_notify_resume_cb), manager); #endif manager->priv->lid_is_closed = up_client_get_lid_is_closed (manager->priv->up_client); manager->priv->on_battery = up_client_get_on_battery(manager->priv->up_client); g_signal_connect (manager->priv->up_client, "device-added", G_CALLBACK (engine_device_added_cb), manager); g_signal_connect (manager->priv->up_client, "device-removed", G_CALLBACK (engine_device_removed_cb), manager); #if UP_CHECK_VERSION(0,99,0) g_signal_connect_after (manager->priv->up_client, "notify::lid-is-closed", G_CALLBACK (lid_state_changed_cb), manager); g_signal_connect (manager->priv->up_client, "notify::on-battery", G_CALLBACK (up_client_on_battery_cb), manager); #else g_signal_connect (manager->priv->up_client, "device-changed", G_CALLBACK (engine_device_changed_cb), manager); g_signal_connect_after (manager->priv->up_client, "changed", G_CALLBACK (up_client_changed_cb), manager); #endif /* connect to UPower for keyboard backlight control */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, UPOWER_DBUS_NAME, UPOWER_DBUS_PATH_KBDBACKLIGHT, UPOWER_DBUS_INTERFACE_KBDBACKLIGHT, NULL, power_keyboard_proxy_ready_cb, manager); /* connect to the session */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_INTERFACE, NULL, session_proxy_ready_cb, manager); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, 0, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH_PRESENCE, GNOME_SESSION_DBUS_INTERFACE_PRESENCE, NULL, session_presence_proxy_ready_cb, manager); manager->priv->canberra_context = ca_gtk_context_get_for_screen (gdk_screen_get_default ()); connect_power_iface (manager); connect_screen_iface (manager); connect_keyboard_iface (manager); manager->priv->phone = gpm_phone_new (); g_signal_connect (manager->priv->phone, "device-added", G_CALLBACK (phone_device_added_cb), manager); g_signal_connect (manager->priv->phone, "device-removed", G_CALLBACK (phone_device_removed_cb), manager); g_signal_connect (manager->priv->phone, "device-refresh", G_CALLBACK (phone_device_refresh_cb), manager); /* create a fake virtual composite battery */ manager->priv->device_composite = up_device_new (); g_object_set (manager->priv->device_composite, "kind", UP_DEVICE_KIND_BATTERY, "is-rechargeable", TRUE, "native-path", "dummy:composite_battery", "power-supply", TRUE, "is-present", TRUE, NULL); /* get backlight setting overrides */ manager->priv->backlight_helper_preference_args = NULL; backlight_override_settings_refresh (manager); /* get percentage policy */ manager->priv->low_percentage = g_settings_get_int (manager->priv->settings, "percentage-low"); manager->priv->critical_percentage = g_settings_get_int (manager->priv->settings, "percentage-critical"); manager->priv->action_percentage = g_settings_get_int (manager->priv->settings, "percentage-action"); /* get time policy */ manager->priv->low_time = g_settings_get_int (manager->priv->settings, "time-low"); manager->priv->critical_time = g_settings_get_int (manager->priv->settings, "time-critical"); manager->priv->action_time = g_settings_get_int (manager->priv->settings, "time-action"); /* we can disable this if the time remaining is inaccurate or just plain wrong */ manager->priv->use_time_primary = g_settings_get_boolean (manager->priv->settings, "use-time-for-policy"); refresh_notification_settings (manager); /* create IDLETIME watcher */ manager->priv->idletime = gpm_idletime_new (); g_signal_connect (manager->priv->idletime, "reset", G_CALLBACK (idle_idletime_reset_cb), manager); g_signal_connect (manager->priv->idletime, "alarm-expired", G_CALLBACK (idle_idletime_alarm_expired_cb), manager); /* set up the screens */ g_signal_connect (manager->priv->x11_screen, "changed", G_CALLBACK (on_randr_event), manager); on_randr_event (manager->priv->x11_screen, manager); /* ensure the default dpms timeouts are cleared */ ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen, GNOME_RR_DPMS_ON, &error); if (!ret) { g_warning ("Failed set DPMS mode: %s", error->message); g_clear_error (&error); } /* coldplug the engine */ engine_coldplug (manager); /* Make sure that Xorg's DPMS extension never gets in our way. The defaults seem to have changed in Xorg 1.14 * being "0" by default to being "600" by default * https://bugzilla.gnome.org/show_bug.cgi?id=709114 */ gdk_x11_display_error_trap_push (gdk_display_get_default ()); int dummy; if (DPMSQueryExtension(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &dummy, &dummy)) { DPMSSetTimeouts (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, 0, 0); } gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); manager->priv->xscreensaver_watchdog_timer_id = g_timeout_add_seconds (XSCREENSAVER_WATCHDOG_TIMEOUT, disable_builtin_screensaver, NULL); /* don't blank inside a VM */ manager->priv->is_virtual_machine = is_hardware_a_virtual_machine (); } gboolean csd_power_manager_start (CsdPowerManager *manager, GError **error) { g_debug ("Starting power manager"); cinnamon_settings_profile_start (NULL); /* Set up the logind proxy */ manager->priv->logind_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, NULL, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, NULL, error); /* coldplug the list of screens */ gnome_rr_screen_new_async (gdk_screen_get_default (), on_rr_screen_acquired, manager); manager->priv->settings = g_settings_new (CSD_POWER_SETTINGS_SCHEMA); manager->priv->settings_screensaver = g_settings_new (CSD_SAVER_SETTINGS_SCHEMA); manager->priv->settings_xrandr = g_settings_new (CSD_XRANDR_SETTINGS_SCHEMA); manager->priv->settings_desktop_session = g_settings_new (CSD_SESSION_SETTINGS_SCHEMA); manager->priv->settings_cinnamon_session = g_settings_new (CSD_CINNAMON_SESSION_SCHEMA); manager->priv->devices_array = g_ptr_array_new_with_free_func (g_object_unref); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_power_manager_stop (CsdPowerManager *manager) { g_debug ("Stopping power manager"); if (manager->priv->bus_cancellable != NULL) { g_cancellable_cancel (manager->priv->bus_cancellable); g_object_unref (manager->priv->bus_cancellable); manager->priv->bus_cancellable = NULL; } kill_lid_close_safety_timer (manager); g_signal_handlers_disconnect_by_data (manager->priv->up_client, manager); if (manager->priv->connection != NULL) { g_object_unref (manager->priv->connection); manager->priv->connection = NULL; } if (manager->priv->session != NULL) { g_object_unref (manager->priv->session); manager->priv->session = NULL; } if (manager->priv->settings != NULL) { g_object_unref (manager->priv->settings); manager->priv->settings = NULL; } if (manager->priv->settings_screensaver != NULL) { g_object_unref (manager->priv->settings_screensaver); manager->priv->settings_screensaver = NULL; } if (manager->priv->settings_xrandr != NULL) { g_object_unref (manager->priv->settings_xrandr); manager->priv->settings_xrandr = NULL; } if (manager->priv->settings_desktop_session != NULL) { g_object_unref (manager->priv->settings_desktop_session); manager->priv->settings_desktop_session = NULL; } if (manager->priv->settings_cinnamon_session != NULL) { g_object_unref (manager->priv->settings_cinnamon_session); manager->priv->settings_cinnamon_session = NULL; } if (manager->priv->up_client != NULL) { g_object_unref (manager->priv->up_client); manager->priv->up_client = NULL; } if (manager->priv->inhibit_lid_switch_fd != -1) { close (manager->priv->inhibit_lid_switch_fd); manager->priv->inhibit_lid_switch_fd = -1; manager->priv->inhibit_lid_switch_taken = FALSE; } if (manager->priv->inhibit_suspend_fd != -1) { close (manager->priv->inhibit_suspend_fd); manager->priv->inhibit_suspend_fd = -1; manager->priv->inhibit_suspend_taken = FALSE; } if (manager->priv->logind_proxy != NULL) { g_object_unref (manager->priv->logind_proxy); manager->priv->logind_proxy = NULL; } g_free (manager->priv->backlight_helper_preference_args); manager->priv->backlight_helper_preference_args = NULL; if (manager->priv->x11_screen != NULL) { g_object_unref (manager->priv->x11_screen); manager->priv->x11_screen = NULL; } g_ptr_array_unref (manager->priv->devices_array); manager->priv->devices_array = NULL; if (manager->priv->phone != NULL) { g_object_unref (manager->priv->phone); manager->priv->phone = NULL; } if (manager->priv->device_composite != NULL) { g_object_unref (manager->priv->device_composite); manager->priv->device_composite = NULL; } if (manager->priv->previous_icon != NULL) { g_object_unref (manager->priv->previous_icon); manager->priv->previous_icon = NULL; } g_free (manager->priv->previous_summary); manager->priv->previous_summary = NULL; if (manager->priv->session_proxy != NULL) { g_object_unref (manager->priv->session_proxy); manager->priv->session_proxy = NULL; } if (manager->priv->session_presence_proxy != NULL) { g_object_unref (manager->priv->session_presence_proxy); manager->priv->session_presence_proxy = NULL; } if (manager->priv->critical_alert_timeout_id > 0) { g_source_remove (manager->priv->critical_alert_timeout_id); manager->priv->critical_alert_timeout_id = 0; } g_signal_handlers_disconnect_by_func (manager->priv->idletime, idle_idletime_reset_cb, manager); g_signal_handlers_disconnect_by_func (manager->priv->idletime, idle_idletime_alarm_expired_cb, manager); if (manager->priv->idletime != NULL) { g_object_unref (manager->priv->idletime); manager->priv->idletime = NULL; } if (manager->priv->xscreensaver_watchdog_timer_id > 0) { g_source_remove (manager->priv->xscreensaver_watchdog_timer_id); manager->priv->xscreensaver_watchdog_timer_id = 0; } g_clear_object (&manager->priv->power_iface); g_clear_object (&manager->priv->screen_iface); g_clear_object (&manager->priv->keyboard_iface); } static void csd_power_manager_init (CsdPowerManager *manager) { manager->priv = CSD_POWER_MANAGER_GET_PRIVATE (manager); manager->priv->inhibit_lid_switch_fd = -1; manager->priv->inhibit_suspend_fd = -1; } static void csd_power_manager_finalize (GObject *object) { CsdPowerManager *manager; manager = CSD_POWER_MANAGER (object); g_return_if_fail (manager->priv != NULL); if (manager->priv->p_name_id != 0) g_bus_unown_name (manager->priv->p_name_id); if (manager->priv->s_name_id != 0) g_bus_unown_name (manager->priv->s_name_id); if (manager->priv->k_name_id != 0) g_bus_unown_name (manager->priv->k_name_id); G_OBJECT_CLASS (csd_power_manager_parent_class)->finalize (object); } #if !UP_CHECK_VERSION(0,99,0) #define UP_DEVICE_LEVEL_NONE 1 #endif static GVariant * device_to_variant_blob (UpDevice *device) { const gchar *object_path, *vendor, *model; gchar *device_icon; gdouble percentage; GIcon *icon; guint64 time_empty, time_full; guint64 time_state = 0; GVariant *value; UpDeviceKind kind; UpDeviceState state; gint battery_level; icon = gpm_upower_get_device_icon (device, TRUE); device_icon = g_icon_to_string (icon); g_object_get (device, "vendor", &vendor, "model", &model, "kind", &kind, "percentage", &percentage, "state", &state, "time-to-empty", &time_empty, "time-to-full", &time_full, NULL); /* upower < 0.99.5 compatibility */ if (g_object_class_find_property (G_OBJECT_GET_CLASS (device), "battery-level")) { g_object_get (device, "battery-level", &battery_level, NULL); } else { battery_level = UP_DEVICE_LEVEL_NONE; } /* only return time for these simple states */ if (state == UP_DEVICE_STATE_DISCHARGING) time_state = time_empty; else if (state == UP_DEVICE_STATE_CHARGING) time_state = time_full; /* get an object path, even for the composite device */ object_path = up_device_get_object_path (device); if (object_path == NULL) object_path = CSD_POWER_DBUS_PATH; /* format complex object */ value = g_variant_new ("(sssusduut)", object_path, vendor, model, kind, device_icon, percentage, state, battery_level, time_state); g_free (device_icon); g_object_unref (icon); return value; } /* returns new level */ static void handle_method_call_keyboard (CsdPowerManager *manager, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation) { gint step; gint value = -1; gboolean ret; guint percentage; GError *error = NULL; if (manager->priv->kbd_brightness_max == 0) { error = g_error_new (CSD_POWER_MANAGER_ERROR, CSD_POWER_MANAGER_ERROR_NOT_SUPPORTED, "Keyboard backlight control is not supported"); g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); return; } if (g_strcmp0 (method_name, "GetPercentage") == 0) { g_debug ("keyboard get percentage"); ret = upower_kbd_get_percentage (manager, &error); value = manager->priv->kbd_brightness_now; } else if (g_strcmp0 (method_name, "SetPercentage") == 0) { g_debug ("keyboard set percentage"); guint value_tmp; g_variant_get (parameters, "(u)", &percentage); value_tmp = PERCENTAGE_TO_ABS (0, manager->priv->kbd_brightness_max, percentage); ret = upower_kbd_set_brightness (manager, value_tmp, &error); if (ret) value = value_tmp; } else if (g_strcmp0 (method_name, "StepUp") == 0) { g_debug ("keyboard step up"); step = BRIGHTNESS_STEP_AMOUNT (manager->priv->kbd_brightness_max); value = MIN (manager->priv->kbd_brightness_now + step, manager->priv->kbd_brightness_max); ret = upower_kbd_set_brightness (manager, value, &error); } else if (g_strcmp0 (method_name, "StepDown") == 0) { g_debug ("keyboard step down"); step = BRIGHTNESS_STEP_AMOUNT (manager->priv->kbd_brightness_max); value = MAX (manager->priv->kbd_brightness_now - step, 0); ret = upower_kbd_set_brightness (manager, value, &error); } else if (g_strcmp0 (method_name, "GetStep") == 0) { g_debug ("keyboard get step"); value = BRIGHTNESS_STEP_AMOUNT (manager->priv->kbd_brightness_max); ret = (value > 0); } else if (g_strcmp0 (method_name, "Toggle") == 0) { ret = upower_kbd_toggle (manager, &error); value = manager->priv->kbd_brightness_now; } else { g_assert_not_reached (); } /* return value */ if (!ret) { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { percentage = ABS_TO_PERCENTAGE (0, manager->priv->kbd_brightness_max, value); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", percentage)); } } static void handle_method_call_screen (CsdPowerManager *manager, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation) { gboolean ret = FALSE; gint value = -1; guint value_tmp; GError *error = NULL; if ((g_strcmp0 (method_name, "GetPercentage") == 0) || (g_strcmp0 (method_name, "SetPercentage") == 0)) { if (g_strcmp0 (method_name, "GetPercentage") == 0) { g_debug ("screen get percentage"); value = backlight_get_percentage (manager, &error); } else if (g_strcmp0 (method_name, "SetPercentage") == 0) { g_debug ("screen set percentage"); g_variant_get (parameters, "(u)", &value_tmp); ret = backlight_set_percentage (manager, value_tmp, TRUE, &error); if (ret) value = value_tmp; } /* return value */ if (value < 0) { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", value)); } } else if ((g_strcmp0 (method_name, "StepUp") == 0) || (g_strcmp0 (method_name, "StepDown") == 0)) { if (g_strcmp0 (method_name, "StepUp") == 0) { g_debug ("screen step up"); value = backlight_step_up (manager, &error); } else if (g_strcmp0 (method_name, "StepDown") == 0) { g_debug ("screen step down"); value = backlight_step_down (manager, &error); } /* return value */ if (value < 0) { g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); } else { // Gdk is not trustworthy for getting a monitor index - they could // be out of order from muffin's opinion, so send the output's // position and let Cinnamon tell us which monitor to react on. gint x, y; x = y = 0; backlight_get_output_id (manager, &x, &y); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(uii)", value, x, y)); } } else { g_assert_not_reached (); } } static gboolean screen_iface_method_cb (CsdScreen *object, GDBusMethodInvocation *invocation, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); handle_method_call_screen (manager, g_dbus_method_invocation_get_method_name (invocation), g_dbus_method_invocation_get_parameters (invocation), invocation); return TRUE; } static gboolean screen_iface_set_method_cb (CsdScreen *object, GDBusMethodInvocation *invocation, guint percent, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); handle_method_call_screen (manager, g_dbus_method_invocation_get_method_name (invocation), g_dbus_method_invocation_get_parameters (invocation), invocation); return TRUE; } static gboolean keyboard_iface_method_cb (CsdScreen *object, GDBusMethodInvocation *invocation, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); handle_method_call_keyboard (manager, g_dbus_method_invocation_get_method_name (invocation), g_dbus_method_invocation_get_parameters (invocation), invocation); return TRUE; } static gboolean keyboard_iface_set_method_cb (CsdScreen *object, GDBusMethodInvocation *invocation, guint percent, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); handle_method_call_keyboard (manager, g_dbus_method_invocation_get_method_name (invocation), g_dbus_method_invocation_get_parameters (invocation), invocation); return TRUE; } static gboolean power_iface_handle_get_primary_device (CsdPower *object, GDBusMethodInvocation *invocation, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); UpDevice *device; GVariant *tuple = NULL; GVariant *value = NULL; g_debug ("Handling Power interface method GetPrimaryDevice"); /* get the virtual device */ device = engine_get_primary_device (manager); if (device == NULL) { g_dbus_method_invocation_return_dbus_error (invocation, "org.cinnamon.SettingsDaemon.Power.Failed", "There is no primary device."); return TRUE; } /* return the value */ value = device_to_variant_blob (device); tuple = g_variant_new_tuple (&value, 1); g_dbus_method_invocation_return_value (invocation, tuple); g_object_unref (device); return TRUE; } static gboolean power_iface_handle_get_devices (CsdPower *object, GDBusMethodInvocation *invocation, gpointer user_data) { CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); UpDevice *device; GPtrArray *array; guint i; GVariantBuilder *builder; GVariant *tuple = NULL; GVariant *value = NULL; g_debug ("Handling Power interface method GetDevices"); /* create builder */ builder = g_variant_builder_new (G_VARIANT_TYPE("a(sssusduut)")); /* add each tuple to the array */ array = manager->priv->devices_array; for (i=0; ilen; i++) { device = g_ptr_array_index (array, i); value = device_to_variant_blob (device); g_variant_builder_add_value (builder, value); } /* return the value */ value = g_variant_builder_end (builder); tuple = g_variant_new_tuple (&value, 1); g_dbus_method_invocation_return_value (invocation, tuple); g_variant_builder_unref (builder); return TRUE; } static void connect_power_iface (CsdPowerManager *manager) { g_signal_connect (manager->priv->power_iface, "handle-get-primary-device", G_CALLBACK (power_iface_handle_get_primary_device), manager); g_signal_connect (manager->priv->power_iface, "handle-get-devices", G_CALLBACK (power_iface_handle_get_devices), manager); engine_recalculate_state (manager); } static void power_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { CsdPower *iface; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); iface = csd_power_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (iface), connection, CSD_POWER_DBUS_PATH, NULL); manager->priv->power_iface = iface; } static void connect_screen_iface (CsdPowerManager *manager) { g_signal_connect (manager->priv->screen_iface, "handle-get-percentage", G_CALLBACK (screen_iface_method_cb), manager); g_signal_connect (manager->priv->screen_iface, "handle-set-percentage", G_CALLBACK (screen_iface_set_method_cb), manager); g_signal_connect (manager->priv->screen_iface, "handle-step-down", G_CALLBACK (screen_iface_method_cb), manager); g_signal_connect (manager->priv->screen_iface, "handle-step-up", G_CALLBACK (screen_iface_method_cb), manager); backlight_emit_changed (manager); } static void screen_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { CsdScreen *iface; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); iface = csd_screen_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (iface), connection, CSD_POWER_DBUS_PATH, NULL); manager->priv->screen_iface = iface; } static void connect_keyboard_iface (CsdPowerManager *manager) { g_signal_connect (manager->priv->keyboard_iface, "handle-get-percentage", G_CALLBACK (keyboard_iface_method_cb), manager); g_signal_connect (manager->priv->keyboard_iface, "handle-set-percentage", G_CALLBACK (keyboard_iface_set_method_cb), manager); g_signal_connect (manager->priv->keyboard_iface, "handle-step-down", G_CALLBACK (keyboard_iface_method_cb), manager); g_signal_connect (manager->priv->keyboard_iface, "handle-step-up", G_CALLBACK (keyboard_iface_method_cb), manager); g_signal_connect (manager->priv->keyboard_iface, "handle-get-step", G_CALLBACK (keyboard_iface_method_cb), manager); g_signal_connect (manager->priv->keyboard_iface, "handle-toggle", G_CALLBACK (keyboard_iface_method_cb), manager); upower_kbd_emit_changed (manager); } static void keyboard_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { CsdKeyboard *iface; CsdPowerManager *manager = CSD_POWER_MANAGER (user_data); iface = csd_keyboard_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (iface), connection, CSD_POWER_DBUS_PATH, NULL); manager->priv->keyboard_iface = iface; } static void on_bus_gotten (GObject *source_object, GAsyncResult *res, CsdPowerManager *manager) { GDBusConnection *connection; GError *error = NULL; if (manager->priv->bus_cancellable == NULL || g_cancellable_is_cancelled (manager->priv->bus_cancellable)) { g_warning ("Operation has been cancelled, so not retrieving session bus"); return; } connection = g_bus_get_finish (res, &error); if (connection == NULL) { g_warning ("Could not get session bus: %s", error->message); g_error_free (error); return; } manager->priv->connection = connection; manager->priv->p_name_id = g_bus_own_name_on_connection (connection, CSD_POWER_DBUS_INTERFACE, G_BUS_NAME_OWNER_FLAGS_NONE, power_name_acquired, NULL, manager, NULL); manager->priv->s_name_id = g_bus_own_name_on_connection (connection, CSD_POWER_DBUS_INTERFACE_SCREEN, G_BUS_NAME_OWNER_FLAGS_NONE, screen_name_acquired, NULL, manager, NULL); manager->priv->k_name_id = g_bus_own_name_on_connection (connection, CSD_POWER_DBUS_INTERFACE_KEYBOARD, G_BUS_NAME_OWNER_FLAGS_NONE, keyboard_name_acquired, NULL, manager, NULL); } static void register_manager_dbus (CsdPowerManager *manager) { manager->priv->bus_cancellable = g_cancellable_new (); g_bus_get (G_BUS_TYPE_SESSION, manager->priv->bus_cancellable, (GAsyncReadyCallback) on_bus_gotten, manager); } CsdPowerManager * csd_power_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_POWER_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); register_manager_dbus (manager_object); } return CSD_POWER_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/power/org.cinnamon.SettingsDaemon.Power.Screen.xml0000664000175000017500000000176114733247605030554 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/plugins/power/org.cinnamon.settings-daemon.plugins.power.policy.in0000664000175000017500000000223114733247605032330 0ustar fabiofabio Cinnamon Settings Daemon http://git.gnome.org/browse/cinnamon-settings-daemon battery Modify the laptop brightness Authentication is required to modify the laptop brightness no no yes @libexecdir@/csd-backlight-helper cinnamon-settings-daemon-6.4.3/plugins/power/csd-power-manager.h0000664000175000017500000000475414733247605023677 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_POWER_MANAGER_H #define __CSD_POWER_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_POWER_MANAGER (csd_power_manager_get_type ()) #define CSD_POWER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_POWER_MANAGER, CsdPowerManager)) #define CSD_POWER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_POWER_MANAGER, CsdPowerManagerClass)) #define CSD_IS_POWER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_POWER_MANAGER)) #define CSD_IS_POWER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_POWER_MANAGER)) #define CSD_POWER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_POWER_MANAGER, CsdPowerManagerClass)) #define CSD_POWER_MANAGER_ERROR (csd_power_manager_error_quark ()) typedef struct CsdPowerManagerPrivate CsdPowerManagerPrivate; typedef struct { GObject parent; CsdPowerManagerPrivate *priv; } CsdPowerManager; typedef struct { GObjectClass parent_class; } CsdPowerManagerClass; enum { CSD_POWER_MANAGER_ERROR_FAILED, CSD_POWER_MANAGER_ERROR_NOT_SUPPORTED }; GType csd_power_manager_get_type (void); GQuark csd_power_manager_error_quark (void); CsdPowerManager * csd_power_manager_new (void); gboolean csd_power_manager_start (CsdPowerManager *manager, GError **error); void csd_power_manager_stop (CsdPowerManager *manager); G_END_DECLS #endif /* __CSD_POWER_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/color/0000775000175000017500000000000014733247605020163 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/color/gnome-datetime-source.h0000664000175000017500000000243514733247605024535 0ustar fabiofabio/* gnome-rr.h * * Copyright 2011, Red Hat, Inc. * * This file is part of the Gnome Library. * * The Gnome Library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The Gnome 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Author: Colin Walters */ #ifndef GNOME_DATETIME_SOURCE_H #define GNOME_DATETIME_SOURCE_H #ifndef GNOME_DESKTOP_USE_UNSTABLE_API #error This is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API #endif #include GSource *_gnome_datetime_source_new (GDateTime *now, GDateTime *expiry, gboolean cancel_on_set); #endif /* GNOME_DATETIME_SOURCE_H */ cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-state.c0000664000175000017500000016506414733247605023346 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #include "config.h" #include #include #include #include #include #include #define GNOME_DESKTOP_USE_UNSTABLE_API #include #ifdef GDK_WINDOWING_X11 #include #endif #include "cinnamon-session-dbus.h" #include "csd-color-manager.h" #include "csd-color-state.h" #include "ccm-edid.h" #define CSD_DBUS_NAME "org.gnome.SettingsDaemon" #define CSD_DBUS_PATH "/org/gnome/SettingsDaemon" #define CSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" static void ccm_session_set_gamma_for_all_devices (CsdColorState *state); struct _CsdColorState { GObject parent; GCancellable *cancellable; GDBusProxy *session; CdClient *client; GnomeRRScreen *state_screen; GHashTable *edid_cache; GdkWindow *gdk_window; gboolean session_is_active; GHashTable *device_assign_hash; guint color_temperature; }; static void csd_color_state_class_init (CsdColorStateClass *klass); static void csd_color_state_init (CsdColorState *color_state); static void csd_color_state_finalize (GObject *object); G_DEFINE_TYPE (CsdColorState, csd_color_state, G_TYPE_OBJECT) /* see http://www.oyranos.org/wiki/index.php?title=ICC_Profiles_in_X_Specification_0.3 */ #define CCM_ICC_PROFILE_IN_X_VERSION_MAJOR 0 #define CCM_ICC_PROFILE_IN_X_VERSION_MINOR 3 typedef struct { guint32 red; guint32 green; guint32 blue; } GnomeRROutputClutItem; GQuark csd_color_state_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("csd_color_state_error"); return quark; } static CcmEdid * ccm_session_get_output_edid (CsdColorState *state, GnomeRROutput *output, GError **error) { const guint8 *data; gsize size; CcmEdid *edid = NULL; gboolean ret; /* can we find it in the cache */ edid = g_hash_table_lookup (state->edid_cache, gnome_rr_output_get_name (output)); if (edid != NULL) { g_object_ref (edid); return edid; } /* parse edid */ data = gnome_rr_output_get_edid_data (output, &size); if (data == NULL || size == 0) { g_set_error_literal (error, GNOME_RR_ERROR, GNOME_RR_ERROR_UNKNOWN, "unable to get EDID for output"); return NULL; } edid = ccm_edid_new (); ret = ccm_edid_parse (edid, data, size, error); if (!ret) { g_object_unref (edid); return NULL; } /* add to cache */ g_hash_table_insert (state->edid_cache, g_strdup (gnome_rr_output_get_name (output)), g_object_ref (edid)); return edid; } static gboolean ccm_session_screen_set_icc_profile (CsdColorState *state, const gchar *filename, GError **error) { gchar *data = NULL; gsize length; guint version_data; g_return_val_if_fail (filename != NULL, FALSE); /* wayland */ if (state->gdk_window == NULL) { g_debug ("not setting atom as running under wayland"); return TRUE; } g_debug ("setting root window ICC profile atom from %s", filename); /* get contents of file */ if (!g_file_get_contents (filename, &data, &length, error)) return FALSE; /* set profile property */ gdk_property_change (state->gdk_window, gdk_atom_intern_static_string ("_ICC_PROFILE"), gdk_atom_intern_static_string ("CARDINAL"), 8, GDK_PROP_MODE_REPLACE, (const guchar *) data, length); /* set version property */ version_data = CCM_ICC_PROFILE_IN_X_VERSION_MAJOR * 100 + CCM_ICC_PROFILE_IN_X_VERSION_MINOR * 1; gdk_property_change (state->gdk_window, gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION"), gdk_atom_intern_static_string ("CARDINAL"), 8, GDK_PROP_MODE_REPLACE, (const guchar *) &version_data, 1); g_free (data); return TRUE; } void csd_color_state_set_temperature (CsdColorState *state, guint temperature) { g_return_if_fail (CSD_IS_COLOR_STATE (state)); if (state->color_temperature == temperature) return; state->color_temperature = temperature; ccm_session_set_gamma_for_all_devices (state); } guint csd_color_state_get_temperature (CsdColorState *state) { g_return_val_if_fail (CSD_IS_COLOR_STATE (state), 0); return state->color_temperature; } static gchar * ccm_session_get_output_id (CsdColorState *state, GnomeRROutput *output) { const gchar *name; const gchar *serial; const gchar *vendor; CcmEdid *edid = NULL; GString *device_id; GError *error = NULL; /* all output devices are prefixed with this */ device_id = g_string_new ("xrandr"); /* get the output EDID if possible */ edid = ccm_session_get_output_edid (state, output, &error); if (edid == NULL) { g_debug ("no edid for %s [%s], falling back to connection name", gnome_rr_output_get_name (output), error->message); g_error_free (error); g_string_append_printf (device_id, "-%s", gnome_rr_output_get_name (output)); goto out; } /* check EDID data is okay to use */ vendor = ccm_edid_get_vendor_name (edid); name = ccm_edid_get_monitor_name (edid); serial = ccm_edid_get_serial_number (edid); if (vendor == NULL && name == NULL && serial == NULL) { g_debug ("edid invalid for %s, falling back to connection name", gnome_rr_output_get_name (output)); g_string_append_printf (device_id, "-%s", gnome_rr_output_get_name (output)); goto out; } /* use EDID data */ if (vendor != NULL) g_string_append_printf (device_id, "-%s", vendor); if (name != NULL) g_string_append_printf (device_id, "-%s", name); if (serial != NULL) g_string_append_printf (device_id, "-%s", serial); out: if (edid != NULL) g_object_unref (edid); return g_string_free (device_id, FALSE); } typedef struct { CsdColorState *state; CdProfile *profile; CdDevice *device; guint32 output_id; } CcmSessionAsyncHelper; static void ccm_session_async_helper_free (CcmSessionAsyncHelper *helper) { if (helper->state != NULL) g_object_unref (helper->state); if (helper->profile != NULL) g_object_unref (helper->profile); if (helper->device != NULL) g_object_unref (helper->device); g_free (helper); } static gboolean ccm_utils_mkdir_for_filename (GFile *file, GError **error) { gboolean ret = FALSE; GFile *parent_dir = NULL; /* get parent directory */ parent_dir = g_file_get_parent (file); if (parent_dir == NULL) { g_set_error_literal (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "could not get parent dir"); goto out; } /* ensure desination does not already exist */ ret = g_file_query_exists (parent_dir, NULL); if (ret) goto out; ret = g_file_make_directory_with_parents (parent_dir, NULL, error); if (!ret) goto out; out: if (parent_dir != NULL) g_object_unref (parent_dir); return ret; } static gboolean ccm_get_system_icc_profile (CsdColorState *state, GFile *file) { const char efi_path[] = "/sys/firmware/efi/efivars/INTERNAL_PANEL_COLOR_INFO-01e1ada1-79f2-46b3-8d3e-71fc0996ca6b"; /* efi variables have a 4-byte header */ const int efi_var_header_length = 4; g_autoptr(GFile) efi_file = g_file_new_for_path (efi_path); gboolean ret; g_autofree char *data = NULL; gsize length; g_autoptr(GError) error = NULL; ret = g_file_query_exists (efi_file, NULL); if (!ret) return FALSE; ret = g_file_load_contents (efi_file, NULL /* cancellable */, &data, &length, NULL /* etag_out */, &error); if (!ret) { g_warning ("failed to read EFI system color profile: %s", error->message); return FALSE; } if (length <= efi_var_header_length) { g_warning ("EFI system color profile was too short"); return FALSE; } ret = g_file_replace_contents (file, data + efi_var_header_length, length - efi_var_header_length, NULL /* etag */, FALSE /* make_backup */, G_FILE_CREATE_NONE, NULL /* new_etag */, NULL /* cancellable */, &error); if (!ret) { g_warning ("failed to write system color profile: %s", error->message); return FALSE; } return TRUE; } static gboolean ccm_apply_create_icc_profile_for_edid (CsdColorState *state, CdDevice *device, CcmEdid *edid, GFile *file, GError **error) { CdIcc *icc = NULL; const gchar *data; gboolean ret = FALSE; /* ensure the per-user directory exists */ ret = ccm_utils_mkdir_for_filename (file, error); if (!ret) goto out; /* create our generated profile */ icc = cd_icc_new (); ret = cd_icc_create_from_edid (icc, ccm_edid_get_gamma (edid), ccm_edid_get_red (edid), ccm_edid_get_green (edid), ccm_edid_get_blue (edid), ccm_edid_get_white (edid), error); if (!ret) goto out; /* set copyright */ cd_icc_set_copyright (icc, NULL, /* deliberately not translated */ "This profile is free of known copyright restrictions."); /* set model and title */ data = ccm_edid_get_monitor_name (edid); if (data == NULL) data = cd_client_get_system_model (state->client); if (data == NULL) data = "Unknown monitor"; cd_icc_set_model (icc, NULL, data); cd_icc_set_description (icc, NULL, data); /* get manufacturer */ data = ccm_edid_get_vendor_name (edid); if (data == NULL) data = cd_client_get_system_vendor (state->client); if (data == NULL) data = "Unknown vendor"; cd_icc_set_manufacturer (icc, NULL, data); /* set the framework creator metadata */ cd_icc_add_metadata (icc, CD_PROFILE_METADATA_CMF_PRODUCT, PACKAGE_NAME); cd_icc_add_metadata (icc, CD_PROFILE_METADATA_CMF_BINARY, PACKAGE_NAME); cd_icc_add_metadata (icc, CD_PROFILE_METADATA_CMF_VERSION, PACKAGE_VERSION); cd_icc_add_metadata (icc, CD_PROFILE_METADATA_MAPPING_DEVICE_ID, cd_device_get_id (device)); /* set 'ICC meta Tag for Monitor Profiles' data */ cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MD5, ccm_edid_get_checksum (edid)); data = ccm_edid_get_monitor_name (edid); if (data != NULL) cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MODEL, data); data = ccm_edid_get_serial_number (edid); if (data != NULL) cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_SERIAL, data); data = ccm_edid_get_pnp_id (edid); if (data != NULL) cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_MNFT, data); data = ccm_edid_get_vendor_name (edid); if (data != NULL) cd_icc_add_metadata (icc, CD_PROFILE_METADATA_EDID_VENDOR, data); /* save */ ret = cd_icc_save_file (icc, file, CD_ICC_SAVE_FLAGS_NONE, NULL, error); if (!ret) goto out; out: if (icc != NULL) g_object_unref (icc); return ret; } static GPtrArray * ccm_session_generate_vcgt (CdProfile *profile, guint color_temperature, guint size) { GnomeRROutputClutItem *tmp; GPtrArray *array = NULL; const cmsToneCurve **vcgt; cmsFloat32Number in; guint i; cmsHPROFILE lcms_profile; CdIcc *icc = NULL; CdColorRGB temp; /* invalid size */ if (size == 0) goto out; /* open file */ icc = cd_profile_load_icc (profile, CD_ICC_LOAD_FLAGS_NONE, NULL, NULL); if (icc == NULL) goto out; /* get tone curves from profile */ lcms_profile = cd_icc_get_handle (icc); vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag); if (vcgt == NULL || vcgt[0] == NULL) { g_debug ("profile does not have any VCGT data"); goto out; } /* get the color temperature */ if (!cd_color_get_blackbody_rgb_full (color_temperature, &temp, CD_COLOR_BLACKBODY_FLAG_USE_PLANCKIAN)) { g_warning ("failed to get blackbody for %uK", color_temperature); cd_color_rgb_set (&temp, 1.0, 1.0, 1.0); } else { g_debug ("using VCGT gamma of %uK = %.1f,%.1f,%.1f", color_temperature, temp.R, temp.G, temp.B); } /* create array */ array = g_ptr_array_new_with_free_func (g_free); for (i = 0; i < size; i++) { in = (gdouble) i / (gdouble) (size - 1); tmp = g_new0 (GnomeRROutputClutItem, 1); tmp->red = cmsEvalToneCurveFloat(vcgt[0], in) * temp.R * (gdouble) 0xffff; tmp->green = cmsEvalToneCurveFloat(vcgt[1], in) * temp.G * (gdouble) 0xffff; tmp->blue = cmsEvalToneCurveFloat(vcgt[2], in) * temp.B * (gdouble) 0xffff; g_ptr_array_add (array, tmp); } out: if (icc != NULL) g_object_unref (icc); return array; } static guint gnome_rr_output_get_gamma_size (GnomeRROutput *output) { GnomeRRCrtc *crtc; gint len = 0; crtc = gnome_rr_output_get_crtc (output); if (crtc == NULL) return 0; gnome_rr_crtc_get_gamma (crtc, &len, NULL, NULL, NULL); return (guint) len; } static gboolean ccm_session_output_set_gamma (GnomeRROutput *output, GPtrArray *array, GError **error) { gboolean ret = TRUE; guint16 *red = NULL; guint16 *green = NULL; guint16 *blue = NULL; guint i; GnomeRROutputClutItem *data; GnomeRRCrtc *crtc; /* no length? */ if (array->len == 0) { ret = FALSE; g_set_error_literal (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "no data in the CLUT array"); goto out; } /* convert to a type X understands */ red = g_new (guint16, array->len); green = g_new (guint16, array->len); blue = g_new (guint16, array->len); for (i = 0; i < array->len; i++) { data = g_ptr_array_index (array, i); red[i] = data->red; green[i] = data->green; blue[i] = data->blue; } /* send to LUT */ crtc = gnome_rr_output_get_crtc (output); if (crtc == NULL) { ret = FALSE; g_set_error (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "failed to get ctrc for %s", gnome_rr_output_get_name (output)); goto out; } gnome_rr_crtc_set_gamma (crtc, array->len, red, green, blue); out: g_free (red); g_free (green); g_free (blue); return ret; } static gboolean ccm_session_device_set_gamma (GnomeRROutput *output, CdProfile *profile, guint color_temperature, GError **error) { gboolean ret = FALSE; guint size; GPtrArray *clut = NULL; /* create a lookup table */ size = gnome_rr_output_get_gamma_size (output); if (size == 0) { ret = TRUE; goto out; } clut = ccm_session_generate_vcgt (profile, color_temperature, size); if (clut == NULL) { g_set_error_literal (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "failed to generate vcgt"); goto out; } /* apply the vcgt to this output */ ret = ccm_session_output_set_gamma (output, clut, error); if (!ret) goto out; out: if (clut != NULL) g_ptr_array_unref (clut); return ret; } static gboolean ccm_session_device_reset_gamma (GnomeRROutput *output, guint color_temperature, GError **error) { gboolean ret; guint i; guint size; guint32 value; GPtrArray *clut; GnomeRROutputClutItem *data; CdColorRGB temp; /* create a linear ramp */ g_debug ("falling back to dummy ramp"); clut = g_ptr_array_new_with_free_func (g_free); size = gnome_rr_output_get_gamma_size (output); if (size == 0) { ret = TRUE; goto out; } /* get the color temperature */ if (!cd_color_get_blackbody_rgb_full (color_temperature, &temp, CD_COLOR_BLACKBODY_FLAG_USE_PLANCKIAN)) { g_warning ("failed to get blackbody for %uK", color_temperature); cd_color_rgb_set (&temp, 1.0, 1.0, 1.0); } else { g_debug ("using reset gamma of %uK = %.1f,%.1f,%.1f", color_temperature, temp.R, temp.G, temp.B); } for (i = 0; i < size; i++) { value = (i * 0xffff) / (size - 1); data = g_new0 (GnomeRROutputClutItem, 1); data->red = value * temp.R; data->green = value * temp.G; data->blue = value * temp.B; g_ptr_array_add (clut, data); } /* apply the vcgt to this output */ ret = ccm_session_output_set_gamma (output, clut, error); if (!ret) goto out; out: g_ptr_array_unref (clut); return ret; } static GnomeRROutput * ccm_session_get_state_output_by_id (CsdColorState *state, const gchar *device_id, GError **error) { gchar *output_id; GnomeRROutput *output = NULL; GnomeRROutput **outputs = NULL; guint i; /* search all STATE outputs for the device id */ outputs = gnome_rr_screen_list_outputs (state->state_screen); if (outputs == NULL) { g_set_error_literal (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "Failed to get outputs"); goto out; } for (i = 0; outputs[i] != NULL && output == NULL; i++) { output_id = ccm_session_get_output_id (state, outputs[i]); if (g_strcmp0 (output_id, device_id) == 0) output = outputs[i]; g_free (output_id); } if (output == NULL) { g_set_error (error, CSD_COLOR_MANAGER_ERROR, CSD_COLOR_MANAGER_ERROR_FAILED, "Failed to find output %s", device_id); } out: return output; } /* this function is more complicated than it should be, due to the * fact that XOrg sometimes assigns no primary devices when using * "xrandr --auto" or when the version of RANDR is < 1.3 */ static gboolean ccm_session_use_output_profile_for_screen (CsdColorState *state, GnomeRROutput *output) { gboolean has_laptop = FALSE; gboolean has_primary = FALSE; GnomeRROutput **outputs; GnomeRROutput *connected = NULL; guint i; /* do we have any screens marked as primary */ outputs = gnome_rr_screen_list_outputs (state->state_screen); if (outputs == NULL || outputs[0] == NULL) { g_warning ("failed to get outputs"); return FALSE; } for (i = 0; outputs[i] != NULL; i++) { if (connected == NULL) connected = outputs[i]; if (gnome_rr_output_get_is_primary (outputs[i])) has_primary = TRUE; if (gnome_rr_output_is_builtin_display (outputs[i])) has_laptop = TRUE; } /* we have an assigned primary device, are we that? */ if (has_primary) return gnome_rr_output_get_is_primary (output); /* choosing the internal panel is probably sane */ if (has_laptop) return gnome_rr_output_is_builtin_display (output); /* we have to choose one, so go for the first connected device */ if (connected != NULL) return gnome_rr_output_get_id (connected) == gnome_rr_output_get_id (output); return FALSE; } /* TODO: remove when we can dep on a released version of colord */ #ifndef CD_PROFILE_METADATA_SCREEN_BRIGHTNESS #define CD_PROFILE_METADATA_SCREEN_BRIGHTNESS "SCREEN_brightness" #endif #define CSD_DBUS_NAME_POWER CSD_DBUS_NAME ".Power" #define CSD_DBUS_INTERFACE_POWER_SCREEN CSD_DBUS_BASE_INTERFACE ".Power.Screen" #define CSD_DBUS_PATH_POWER CSD_DBUS_PATH "/Power" static void ccm_session_set_output_percentage (guint percentage) { GDBusConnection *connection; /* get a ref to the existing bus connection */ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (connection == NULL) return; g_dbus_connection_call (connection, CSD_DBUS_NAME_POWER, CSD_DBUS_PATH_POWER, "org.freedesktop.DBus.Properties", "Set", g_variant_new_parsed ("('" CSD_DBUS_INTERFACE_POWER_SCREEN "'," "'Brightness', %v)", g_variant_new_int32 (percentage)), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); g_object_unref (connection); } static void ccm_session_device_assign_profile_connect_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdProfile *profile = CD_PROFILE (object); const gchar *brightness_profile; const gchar *filename; gboolean ret; GError *error = NULL; GnomeRROutput *output; guint brightness_percentage; CcmSessionAsyncHelper *helper = (CcmSessionAsyncHelper *) user_data; CsdColorState *state = CSD_COLOR_STATE (helper->state); /* get properties */ ret = cd_profile_connect_finish (profile, res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to connect to profile: %s", error->message); g_error_free (error); goto out; } /* get the filename */ filename = cd_profile_get_filename (profile); g_assert (filename != NULL); /* get the output (can't save in helper as GnomeRROutput isn't * a GObject, just a pointer */ output = gnome_rr_screen_get_output_by_id (state->state_screen, helper->output_id); if (output == NULL) goto out; /* if output is a laptop screen and the profile has a * calibration brightness then set this new brightness */ brightness_profile = cd_profile_get_metadata_item (profile, CD_PROFILE_METADATA_SCREEN_BRIGHTNESS); if (gnome_rr_output_is_builtin_display (output) && brightness_profile != NULL) { /* the percentage is stored in the profile metadata as * a string, not ideal, but it's all we have... */ brightness_percentage = atoi (brightness_profile); ccm_session_set_output_percentage (brightness_percentage); } /* set the _ICC_PROFILE atom */ ret = ccm_session_use_output_profile_for_screen (state, output); if (ret) { ret = ccm_session_screen_set_icc_profile (state, filename, &error); if (!ret) { g_warning ("failed to set screen _ICC_PROFILE: %s", error->message); g_clear_error (&error); } } /* create a vcgt for this icc file */ ret = cd_profile_get_has_vcgt (profile); if (ret) { ret = ccm_session_device_set_gamma (output, profile, state->color_temperature, &error); if (!ret) { g_warning ("failed to set %s gamma tables: %s", cd_device_get_id (helper->device), error->message); g_error_free (error); goto out; } } else { ret = ccm_session_device_reset_gamma (output, state->color_temperature, &error); if (!ret) { g_warning ("failed to reset %s gamma tables: %s", cd_device_get_id (helper->device), error->message); g_error_free (error); goto out; } } out: ccm_session_async_helper_free (helper); } /* * Check to see if the on-disk profile has the MAPPING_device_id * metadata, and if not, we should delete the profile and re-create it * so that it gets mapped by the daemon. */ static gboolean ccm_session_check_profile_device_md (GFile *file) { const gchar *key_we_need = CD_PROFILE_METADATA_MAPPING_DEVICE_ID; CdIcc *icc; gboolean ret; icc = cd_icc_new (); ret = cd_icc_load_file (icc, file, CD_ICC_LOAD_FLAGS_METADATA, NULL, NULL); if (!ret) goto out; ret = cd_icc_get_metadata_item (icc, key_we_need) != NULL; if (!ret) { g_debug ("auto-edid profile is old, and contains no %s data", key_we_need); } out: g_object_unref (icc); return ret; } static void ccm_session_device_assign_connect_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdDeviceKind kind; CdProfile *profile = NULL; gboolean ret; gchar *autogen_filename = NULL; gchar *autogen_path = NULL; CcmEdid *edid = NULL; GnomeRROutput *output = NULL; GError *error = NULL; GFile *file = NULL; const gchar *xrandr_id; CcmSessionAsyncHelper *helper; CdDevice *device = CD_DEVICE (object); CsdColorState *state = CSD_COLOR_STATE (user_data); /* remove from assign array */ g_hash_table_remove (state->device_assign_hash, cd_device_get_object_path (device)); /* get properties */ ret = cd_device_connect_finish (device, res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to connect to device: %s", error->message); g_error_free (error); goto out; } /* check we care */ kind = cd_device_get_kind (device); if (kind != CD_DEVICE_KIND_DISPLAY) goto out; g_debug ("need to assign display device %s", cd_device_get_id (device)); /* get the GnomeRROutput for the device id */ xrandr_id = cd_device_get_id (device); output = ccm_session_get_state_output_by_id (state, xrandr_id, &error); if (output == NULL) { g_warning ("no %s device found: %s", cd_device_get_id (device), error->message); g_error_free (error); goto out; } /* create profile from device edid if it exists */ edid = ccm_session_get_output_edid (state, output, &error); if (edid == NULL) { g_warning ("unable to get EDID for %s: %s", cd_device_get_id (device), error->message); g_clear_error (&error); } else { autogen_filename = g_strdup_printf ("edid-%s.icc", ccm_edid_get_checksum (edid)); autogen_path = g_build_filename (g_get_user_data_dir (), "icc", autogen_filename, NULL); /* check if auto-profile has up-to-date metadata */ file = g_file_new_for_path (autogen_path); if (ccm_session_check_profile_device_md (file)) { g_debug ("auto-profile edid %s exists with md", autogen_path); } else { g_debug ("auto-profile edid does not exist, creating as %s", autogen_path); /* check if the system has a built-in profile */ ret = gnome_rr_output_is_builtin_display (output) && ccm_get_system_icc_profile (state, file); /* try creating one from the EDID */ if (!ret) { ret = ccm_apply_create_icc_profile_for_edid (state, device, edid, file, &error); } if (!ret) { g_warning ("failed to create profile from EDID data: %s", error->message); g_clear_error (&error); } } } /* get the default profile for the device */ profile = cd_device_get_default_profile (device); if (profile == NULL) { g_debug ("%s has no default profile to set", cd_device_get_id (device)); /* the default output? */ if (gnome_rr_output_get_is_primary (output) && state->gdk_window != NULL) { gdk_property_delete (state->gdk_window, gdk_atom_intern_static_string ("_ICC_PROFILE")); gdk_property_delete (state->gdk_window, gdk_atom_intern_static_string ("_ICC_PROFILE_IN_X_VERSION")); } /* reset, as we want linear profiles for profiling */ ret = ccm_session_device_reset_gamma (output, state->color_temperature, &error); if (!ret) { g_warning ("failed to reset %s gamma tables: %s", cd_device_get_id (device), error->message); g_error_free (error); goto out; } goto out; } /* get properties */ helper = g_new0 (CcmSessionAsyncHelper, 1); helper->output_id = gnome_rr_output_get_id (output); helper->state = g_object_ref (state); helper->device = g_object_ref (device); cd_profile_connect (profile, state->cancellable, ccm_session_device_assign_profile_connect_cb, helper); out: g_free (autogen_filename); g_free (autogen_path); if (file != NULL) g_object_unref (file); if (edid != NULL) g_object_unref (edid); if (profile != NULL) g_object_unref (profile); } static void ccm_session_device_assign (CsdColorState *state, CdDevice *device) { const gchar *key; gpointer found; /* are we already assigning this device */ key = cd_device_get_object_path (device); found = g_hash_table_lookup (state->device_assign_hash, key); if (found != NULL) { g_debug ("assign for %s already in progress", key); return; } g_hash_table_insert (state->device_assign_hash, g_strdup (key), GINT_TO_POINTER (TRUE)); cd_device_connect (device, state->cancellable, ccm_session_device_assign_connect_cb, state); } static void ccm_session_device_added_assign_cb (CdClient *client, CdDevice *device, CsdColorState *state) { ccm_session_device_assign (state, device); } static void ccm_session_device_changed_assign_cb (CdClient *client, CdDevice *device, CsdColorState *state) { g_debug ("%s changed", cd_device_get_object_path (device)); ccm_session_device_assign (state, device); } static void ccm_session_create_device_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdDevice *device; GError *error = NULL; device = cd_client_create_device_finish (CD_CLIENT (object), res, &error); if (device == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && !g_error_matches (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_ALREADY_EXISTS)) g_warning ("failed to create device: %s", error->message); g_error_free (error); return; } g_object_unref (device); } static void ccm_session_add_state_output (CsdColorState *state, GnomeRROutput *output) { const gchar *edid_checksum = NULL; const gchar *model = NULL; const gchar *output_name = NULL; const gchar *serial = NULL; const gchar *vendor = NULL; gboolean ret; gchar *device_id = NULL; CcmEdid *edid; GError *error = NULL; GHashTable *device_props = NULL; /* VNC creates a fake device that cannot be color managed */ output_name = gnome_rr_output_get_name (output); if (output_name != NULL && g_str_has_prefix (output_name, "VNC-")) { g_debug ("ignoring %s as fake VNC device detected", output_name); return; } /* try to get edid */ edid = ccm_session_get_output_edid (state, output, &error); if (edid == NULL) { g_warning ("failed to get edid: %s", error->message); g_clear_error (&error); } /* prefer DMI data for the internal output */ ret = gnome_rr_output_is_builtin_display (output); if (ret) { model = cd_client_get_system_model (state->client); vendor = cd_client_get_system_vendor (state->client); } /* use EDID data if we have it */ if (edid != NULL) { edid_checksum = ccm_edid_get_checksum (edid); if (model == NULL) model = ccm_edid_get_monitor_name (edid); if (vendor == NULL) vendor = ccm_edid_get_vendor_name (edid); if (serial == NULL) serial = ccm_edid_get_serial_number (edid); } /* ensure mandatory fields are set */ if (model == NULL) model = gnome_rr_output_get_name (output); if (vendor == NULL) vendor = "unknown"; if (serial == NULL) serial = "unknown"; device_id = ccm_session_get_output_id (state, output); g_debug ("output %s added", device_id); device_props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_KIND, (gpointer) cd_device_kind_to_string (CD_DEVICE_KIND_DISPLAY)); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_MODE, (gpointer) cd_device_mode_to_string (CD_DEVICE_MODE_PHYSICAL)); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_COLORSPACE, (gpointer) cd_colorspace_to_string (CD_COLORSPACE_RGB)); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_VENDOR, (gpointer) vendor); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_MODEL, (gpointer) model); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_SERIAL, (gpointer) serial); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_METADATA_XRANDR_NAME, (gpointer) gnome_rr_output_get_name (output)); g_hash_table_insert (device_props, (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY, gnome_rr_output_get_is_primary (output) ? (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_PRIMARY : (gpointer) CD_DEVICE_METADATA_OUTPUT_PRIORITY_SECONDARY); if (edid_checksum != NULL) { g_hash_table_insert (device_props, (gpointer) CD_DEVICE_METADATA_OUTPUT_EDID_MD5, (gpointer) edid_checksum); } /* set this so we can call the device a 'Laptop Screen' in the * control center main panel */ if (gnome_rr_output_is_builtin_display (output)) { g_hash_table_insert (device_props, (gpointer) CD_DEVICE_PROPERTY_EMBEDDED, NULL); } cd_client_create_device (state->client, device_id, CD_OBJECT_SCOPE_TEMP, device_props, state->cancellable, ccm_session_create_device_cb, state); g_free (device_id); if (device_props != NULL) g_hash_table_unref (device_props); if (edid != NULL) g_object_unref (edid); } static void gnome_rr_screen_output_added_cb (GnomeRRScreen *screen, GnomeRROutput *output, CsdColorState *state) { ccm_session_add_state_output (state, output); } static void ccm_session_screen_removed_delete_device_cb (GObject *object, GAsyncResult *res, gpointer user_data) { gboolean ret; GError *error = NULL; /* deleted device */ ret = cd_client_delete_device_finish (CD_CLIENT (object), res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to delete device: %s", error->message); g_error_free (error); } } static void ccm_session_screen_removed_find_device_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CdDevice *device; CsdColorState *state = CSD_COLOR_STATE (user_data); device = cd_client_find_device_finish (state->client, res, &error); if (device == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to find device: %s", error->message); g_error_free (error); return; } g_debug ("output %s found, and will be removed", cd_device_get_object_path (device)); cd_client_delete_device (state->client, device, state->cancellable, ccm_session_screen_removed_delete_device_cb, state); g_object_unref (device); } static void gnome_rr_screen_output_removed_cb (GnomeRRScreen *screen, GnomeRROutput *output, CsdColorState *state) { g_debug ("output %s removed", gnome_rr_output_get_name (output)); g_hash_table_remove (state->edid_cache, gnome_rr_output_get_name (output)); cd_client_find_device_by_property (state->client, CD_DEVICE_METADATA_XRANDR_NAME, gnome_rr_output_get_name (output), state->cancellable, ccm_session_screen_removed_find_device_cb, state); } static void ccm_session_get_devices_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdDevice *device; GError *error = NULL; GPtrArray *array; guint i; CsdColorState *state = CSD_COLOR_STATE (user_data); array = cd_client_get_devices_finish (CD_CLIENT (object), res, &error); if (array == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to get devices: %s", error->message); g_error_free (error); return; } for (i = 0; i < array->len; i++) { device = g_ptr_array_index (array, i); ccm_session_device_assign (state, device); } if (array != NULL) g_ptr_array_unref (array); } static void ccm_session_profile_gamma_find_device_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdClient *client = CD_CLIENT (object); CdDevice *device = NULL; GError *error = NULL; CsdColorState *state = CSD_COLOR_STATE (user_data); device = cd_client_find_device_by_property_finish (client, res, &error); if (device == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("could not find device: %s", error->message); g_error_free (error); return; } /* get properties */ cd_device_connect (device, state->cancellable, ccm_session_device_assign_connect_cb, state); if (device != NULL) g_object_unref (device); } static void ccm_session_set_gamma_for_all_devices (CsdColorState *state) { GnomeRROutput **outputs; guint i; /* setting the temperature before we get the list of devices is fine, * as we use the temperature in the calculation */ if (state->state_screen == NULL) return; /* get STATE outputs */ outputs = gnome_rr_screen_list_outputs (state->state_screen); if (outputs == NULL) { g_warning ("failed to get outputs"); return; } for (i = 0; outputs[i] != NULL; i++) { /* get CdDevice for this output */ cd_client_find_device_by_property (state->client, CD_DEVICE_METADATA_XRANDR_NAME, gnome_rr_output_get_name (outputs[i]), state->cancellable, ccm_session_profile_gamma_find_device_cb, state); } } /* We have to reset the gamma tables each time as if the primary output * has changed then different crtcs are going to be used. * See https://bugzilla.gnome.org/show_bug.cgi?id=660164 for an example */ static void gnome_rr_screen_output_changed_cb (GnomeRRScreen *screen, CsdColorState *state) { ccm_session_set_gamma_for_all_devices (state); } static gboolean has_changed (char **strv, const char *str) { guint i; for (i = 0; strv[i] != NULL; i++) { if (g_str_equal (str, strv[i])) return TRUE; } return FALSE; } static void ccm_session_active_changed_cb (GDBusProxy *session, GVariant *changed, char **invalidated, CsdColorState *state) { GVariant *active_v = NULL; gboolean is_active; if (has_changed (invalidated, "SessionIsActive")) return; /* not yet connected to the daemon */ if (!cd_client_get_connected (state->client)) return; active_v = g_dbus_proxy_get_cached_property (session, "SessionIsActive"); g_return_if_fail (active_v != NULL); is_active = g_variant_get_boolean (active_v); g_variant_unref (active_v); /* When doing the fast-user-switch into a new account, load the * new users chosen profiles. * * If this is the first time the GnomeSettingsSession has been * loaded, then we'll get a change from unknown to active * and we want to avoid reprobing the devices for that. */ if (is_active && !state->session_is_active) { g_debug ("Done switch to new account, reload devices"); cd_client_get_devices (state->client, state->cancellable, ccm_session_get_devices_cb, state); } state->session_is_active = is_active; } static void ccm_session_client_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gboolean ret; GError *error = NULL; GnomeRROutput **outputs; guint i; CsdColorState *state = CSD_COLOR_STATE (user_data); /* connected */ ret = cd_client_connect_finish (state->client, res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to connect to colord: %s", error->message); g_error_free (error); return; } /* is there an available colord instance? */ ret = cd_client_get_has_server (state->client); if (!ret) { g_warning ("There is no colord server available"); return; } /* watch if sessions change */ g_signal_connect_object (state->session, "g-properties-changed", G_CALLBACK (ccm_session_active_changed_cb), state, 0); /* add screens */ gnome_rr_screen_refresh (state->state_screen, &error); if (error != NULL) { g_warning ("failed to refresh: %s", error->message); g_error_free (error); return; } /* get STATE outputs */ outputs = gnome_rr_screen_list_outputs (state->state_screen); if (outputs == NULL) { g_warning ("failed to get outputs"); return; } for (i = 0; outputs[i] != NULL; i++) { ccm_session_add_state_output (state, outputs[i]); } /* only connect when colord is awake */ g_signal_connect (state->state_screen, "output-connected", G_CALLBACK (gnome_rr_screen_output_added_cb), state); g_signal_connect (state->state_screen, "output-disconnected", G_CALLBACK (gnome_rr_screen_output_removed_cb), state); g_signal_connect (state->state_screen, "changed", G_CALLBACK (gnome_rr_screen_output_changed_cb), state); g_signal_connect (state->client, "device-added", G_CALLBACK (ccm_session_device_added_assign_cb), state); g_signal_connect (state->client, "device-changed", G_CALLBACK (ccm_session_device_changed_assign_cb), state); /* set for each device that already exist */ cd_client_get_devices (state->client, state->cancellable, ccm_session_get_devices_cb, state); } static void on_rr_screen_acquired (GObject *object, GAsyncResult *result, gpointer data) { CsdColorState *state = data; GnomeRRScreen *screen; GError *error = NULL; /* gnome_rr_screen_new_async() does not take a GCancellable */ if (g_cancellable_is_cancelled (state->cancellable)) goto out; screen = gnome_rr_screen_new_finish (result, &error); if (screen == NULL) { g_warning ("failed to get screens: %s", error->message); g_error_free (error); goto out; } state->state_screen = screen; cd_client_connect (state->client, state->cancellable, ccm_session_client_connect_cb, state); out: /* manually added */ g_object_unref (state); } void csd_color_state_start (CsdColorState *state) { /* use a fresh cancellable for each start->stop operation */ g_cancellable_cancel (state->cancellable); g_clear_object (&state->cancellable); state->cancellable = g_cancellable_new (); /* coldplug the list of screens */ gnome_rr_screen_new_async (gdk_screen_get_default (), on_rr_screen_acquired, g_object_ref (state)); } void csd_color_state_stop (CsdColorState *state) { g_cancellable_cancel (state->cancellable); } static void csd_color_state_class_init (CsdColorStateClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_color_state_finalize; } static void csd_color_state_init (CsdColorState *state) { /* track the active session */ state->session = G_DBUS_PROXY (gnome_session_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, "org.gnome.SessionManager", "/org/gnome/SessionManager", NULL, NULL)); #ifdef GDK_WINDOWING_X11 /* set the _ICC_PROFILE atoms on the root screen */ if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) state->gdk_window = gdk_screen_get_root_window (gdk_screen_get_default ()); #endif /* parsing the EDID is expensive */ state->edid_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); /* we don't want to assign devices multiple times at startup */ state->device_assign_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); /* default color temperature */ state->color_temperature = CSD_COLOR_TEMPERATURE_DEFAULT; state->client = cd_client_new (); } static void csd_color_state_finalize (GObject *object) { CsdColorState *state; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_COLOR_STATE (object)); state = CSD_COLOR_STATE (object); g_cancellable_cancel (state->cancellable); g_clear_object (&state->cancellable); g_clear_object (&state->client); g_clear_object (&state->session); g_clear_pointer (&state->edid_cache, g_hash_table_destroy); g_clear_pointer (&state->device_assign_hash, g_hash_table_destroy); g_clear_object (&state->state_screen); G_OBJECT_CLASS (csd_color_state_parent_class)->finalize (object); } CsdColorState * csd_color_state_new (void) { CsdColorState *state; state = g_object_new (CSD_TYPE_COLOR_STATE, NULL); return CSD_COLOR_STATE (state); } cinnamon-settings-daemon-6.4.3/plugins/color/meson.build0000664000175000017500000000337714733247605022337 0ustar fabiofabioplugin_name='color' built_sources = gnome.gdbus_codegen( 'cinnamon-session-dbus', sources: 'org.gnome.SessionManager.xml', interface_prefix: 'org.', ) sources = files( 'ccm-edid.c', 'gnome-datetime-source.c', 'csd-color-calibrate.c', 'csd-color-manager.c', 'csd-color-profiles.c', 'csd-color-state.c', 'csd-night-light.c', 'csd-night-light-common.c', 'main.c' ) color_deps = [ canberra, cinnamon_desktop, common_dep, csd_dep, colord, lcms, libnotify, math, ] executable( 'csd-' + plugin_name, sources + built_sources, include_directories: [include_dirs, common_inc], dependencies: color_deps, c_args: [ '-DPLUGIN_NAME="@0@"'.format(plugin_name), '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DBINDIR="@0@"'.format(bindir), ], install: true, install_rpath: join_paths(prefix, apilibdir), install_dir: libexecdir ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-color') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-color') endif configure_file( input: 'cinnamon-settings-daemon-color.desktop.in', output: 'cinnamon-settings-daemon-color.desktop', configuration: desktop_conf, install_dir: autostartdir, ) sources = files( 'ccm-edid.c', 'ccm-self-test.c', 'gnome-datetime-source.c', 'csd-night-light.c', 'csd-night-light-common.c' ) # test_unit = 'ccm-self-test' # exe = executable( # test_unit, # sources, # include_directories: include_dirs, # dependencies: color_deps, # c_args: '-DTESTDATADIR="@0@"'.format(join_paths(meson.current_source_dir(), 'test-data')) # ) # envs = ['GSETTINGS_SCHEMA_DIR=@0@'.format(join_paths(meson.build_root(), 'data'))] # test(test_unit, exe, env: envs) cinnamon-settings-daemon-6.4.3/plugins/color/generate-tz-header.py0000775000175000017500000000216214733247605024214 0ustar fabiofabio#!/usr/bin/python3 import re d = {} with open("/usr/share/zoneinfo/zone.tab", "r") as f: for line in f: if line.startswith("#"): continue res = re.search(r"([A-Z]{2})\s([0-9-+]+)\s([\w/_\-]+)\s", line) code, coords, tz = res.groups() res = re.search(r"([+-]{1})([0-9]+)([+-]{1})([0-9]+)", coords) lat_sign, lat_val, long_sign, long_val = res.groups() lat_str = lat_sign + lat_val[0:2] + "." + lat_val[2:] long_str = long_sign + long_val[0:3] + "." + long_val[3:] lat = float(lat_str) long = float(long_str) d[tz] = [lat, long] header = """ // Generated from /usr/share/zoneinfo/zone.tab, used by csd-nightlight.c to calculate sunrise and sunset based on the system timezone typedef struct { const char *timezone; double latitude; double longitude; } TZCoords; static TZCoords tz_coord_list[] = { """ for zone in sorted(d.keys()): latitude, longitude = d[zone] header += " { \"%s\", %f, %f },\n" % (zone, latitude, longitude) header += "};" with open("tz-coords.h", "w") as f: f.write(header) quit()cinnamon-settings-daemon-6.4.3/plugins/color/cinnamon-settings-daemon-color.desktop.in0000664000175000017500000000033214733247605030176 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - color Exec=csd-color OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/color/ccm-self-test.c0000664000175000017500000004601214733247605023000 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2007-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "ccm-edid.h" #include "csd-color-state.h" #include "csd-night-light.h" #include "csd-night-light-common.h" GMainLoop *mainloop; static void on_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { guint *cnt = (guint *) user_data; (*cnt)++; } static gboolean quit_mainloop (gpointer user_data) { g_main_loop_quit (mainloop); return FALSE; } static void ccm_test_night_light (void) { gboolean ret; guint active_cnt = 0; guint disabled_until_tmw_cnt = 0; guint sunrise_cnt = 0; guint sunset_cnt = 0; guint temperature_cnt = 0; g_autoptr(GDateTime) datetime_override = NULL; g_autoptr(GError) error = NULL; g_autoptr(CsdNightLight) nlight = NULL; g_autoptr(GSettings) settings = NULL; nlight = csd_night_light_new (); g_assert (CSD_IS_NIGHT_LIGHT (nlight)); g_signal_connect (nlight, "notify::active", G_CALLBACK (on_notify), &active_cnt); g_signal_connect (nlight, "notify::sunset", G_CALLBACK (on_notify), &sunset_cnt); g_signal_connect (nlight, "notify::sunrise", G_CALLBACK (on_notify), &sunrise_cnt); g_signal_connect (nlight, "notify::temperature", G_CALLBACK (on_notify), &temperature_cnt); g_signal_connect (nlight, "notify::disabled-until-tmw", G_CALLBACK (on_notify), &disabled_until_tmw_cnt); /* hardcode a specific date and time */ datetime_override = g_date_time_new_utc (2017, 2, 8, 20, 0, 0); csd_night_light_set_date_time_now (nlight, datetime_override); /* do not smooth the transition */ csd_night_light_set_smooth_enabled (nlight, FALSE); /* switch off */ settings = g_settings_new ("org.gnome.settings-daemon.plugins.color"); g_settings_set_boolean (settings, "night-light-schedule-automatic", FALSE); g_settings_set_boolean (settings, "night-light-enabled", FALSE); g_settings_set_uint (settings, "night-light-temperature", 4000); /* check default values */ g_assert (!csd_night_light_get_active (nlight)); g_assert_cmpint ((gint) csd_night_light_get_sunrise (nlight), ==, -1); g_assert_cmpint ((gint) csd_night_light_get_sunset (nlight), ==, -1); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); g_assert (!csd_night_light_get_disabled_until_tmw (nlight)); /* start module, disabled */ ret = csd_night_light_start (nlight, &error); g_assert_no_error (error); g_assert (ret); g_assert (!csd_night_light_get_active (nlight)); g_assert_cmpint (active_cnt, ==, 0); g_assert_cmpint (sunset_cnt, ==, 0); g_assert_cmpint (sunrise_cnt, ==, 0); g_assert_cmpint (temperature_cnt, ==, 0); g_assert_cmpint (disabled_until_tmw_cnt, ==, 0); /* enable automatic mode */ g_settings_set_value (settings, "night-light-last-coordinates", g_variant_new ("(dd)", 51.5, -0.1278)); g_settings_set_boolean (settings, "night-light-schedule-automatic", TRUE); g_settings_set_boolean (settings, "night-light-enabled", TRUE); g_assert (csd_night_light_get_active (nlight)); g_assert_cmpint (active_cnt, ==, 1); g_assert_cmpint (sunset_cnt, ==, 1); g_assert_cmpint (sunrise_cnt, ==, 1); g_assert_cmpint (temperature_cnt, ==, 1); g_assert_cmpint (disabled_until_tmw_cnt, ==, 0); g_assert_cmpint ((gint) csd_night_light_get_sunrise (nlight), ==, 7); g_assert_cmpint ((gint) csd_night_light_get_sunset (nlight), ==, 17); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, 4000); g_assert (!csd_night_light_get_disabled_until_tmw (nlight)); /* disable for one day */ csd_night_light_set_disabled_until_tmw (nlight, TRUE); csd_night_light_set_disabled_until_tmw (nlight, TRUE); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); g_assert (csd_night_light_get_active (nlight)); g_assert (csd_night_light_get_disabled_until_tmw (nlight)); g_assert_cmpint (temperature_cnt, ==, 2); g_assert_cmpint (disabled_until_tmw_cnt, ==, 1); /* change our mind */ csd_night_light_set_disabled_until_tmw (nlight, FALSE); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, 4000); g_assert (csd_night_light_get_active (nlight)); g_assert (!csd_night_light_get_disabled_until_tmw (nlight)); g_assert_cmpint (active_cnt, ==, 1); g_assert_cmpint (temperature_cnt, ==, 3); g_assert_cmpint (disabled_until_tmw_cnt, ==, 2); /* enabled manual mode (night shift) */ g_settings_set_double (settings, "night-light-schedule-from", 4.0); g_settings_set_double (settings, "night-light-schedule-to", 16.f); g_settings_set_boolean (settings, "night-light-schedule-automatic", FALSE); g_assert_cmpint (active_cnt, ==, 2); g_assert_cmpint (sunset_cnt, ==, 1); g_assert_cmpint (sunrise_cnt, ==, 1); g_assert_cmpint (temperature_cnt, ==, 4); g_assert_cmpint (disabled_until_tmw_cnt, ==, 2); g_assert (!csd_night_light_get_active (nlight)); g_assert_cmpint ((gint) csd_night_light_get_sunrise (nlight), ==, 7); g_assert_cmpint ((gint) csd_night_light_get_sunset (nlight), ==, 17); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); g_assert (!csd_night_light_get_disabled_until_tmw (nlight)); /* disable, with no changes */ g_settings_set_boolean (settings, "night-light-enabled", FALSE); g_assert (!csd_night_light_get_active (nlight)); g_assert_cmpint (active_cnt, ==, 2); g_assert_cmpint (sunset_cnt, ==, 1); g_assert_cmpint (sunrise_cnt, ==, 1); g_assert_cmpint (temperature_cnt, ==, 4); g_assert_cmpint (disabled_until_tmw_cnt, ==, 2); /* Finally, check that cancelling a smooth transition works */ csd_night_light_set_smooth_enabled (nlight, TRUE); /* Enable night light and automatic scheduling */ g_settings_set_boolean (settings, "night-light-schedule-automatic", TRUE); g_settings_set_boolean (settings, "night-light-enabled", TRUE); /* It should be active again, and a smooth transition is being done, * so the color temperature is still the default at this point. */ g_assert (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); /* Turn off immediately, before the first timeout event is fired. */ g_settings_set_boolean (settings, "night-light-schedule-automatic", FALSE); g_settings_set_boolean (settings, "night-light-enabled", FALSE); g_assert (!csd_night_light_get_active (nlight)); /* Now, sleep for a bit (the smooth transition time is 5 seconds) */ g_timeout_add (5000, quit_mainloop, NULL); g_main_loop_run (mainloop); /* Ensure that the color temperature is still the default one.*/ g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); /* Check that disabled until tomorrow resets again correctly. */ g_settings_set_double (settings, "night-light-schedule-from", 17.0); g_settings_set_double (settings, "night-light-schedule-to", 7.f); g_settings_set_boolean (settings, "night-light-enabled", TRUE); csd_night_light_set_disabled_until_tmw (nlight, TRUE); /* Move time past midnight */ g_clear_pointer (&datetime_override, g_date_time_unref); datetime_override = g_date_time_new_utc (2017, 2, 9, 1, 0, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_true (csd_night_light_get_disabled_until_tmw (nlight)); /* Move past sunrise */ g_clear_pointer (&datetime_override, g_date_time_unref); datetime_override = g_date_time_new_utc (2017, 2, 9, 8, 0, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_false (csd_night_light_get_disabled_until_tmw (nlight)); csd_night_light_set_disabled_until_tmw (nlight, TRUE); /* Move into night more than 24h in the future */ g_clear_pointer (&datetime_override, g_date_time_unref); datetime_override = g_date_time_new_utc (2017, 2, 10, 20, 0, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_false (csd_night_light_get_disabled_until_tmw (nlight)); /* Check that we are always in night mode if from/to are equal. */ csd_night_light_set_smooth_enabled (nlight, FALSE); g_settings_set_double (settings, "night-light-schedule-from", 6.0); g_settings_set_double (settings, "night-light-schedule-to", 6.0); g_settings_set_boolean (settings, "night-light-enabled", TRUE); datetime_override = g_date_time_new_utc (2017, 2, 10, 5, 50, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, 4000); datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 0, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, 4000); datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 10, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, 4000); /* Check that the smearing time is lowered correctly when the times are close. */ g_settings_set_double (settings, "night-light-schedule-from", 6.0); g_settings_set_double (settings, "night-light-schedule-to", 6.1); /* Not enabled 10 minutes before sunset */ datetime_override = g_date_time_new_utc (2017, 2, 10, 5, 50, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_false (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); /* Not enabled >10 minutes after sunrise */ datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 20, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_false (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), ==, CSD_COLOR_TEMPERATURE_DEFAULT); /* ~50% smeared 3 min before sunrise (sunrise at 6 past) */ datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 3, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_true (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), <=, (CSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 + 20); g_assert_cmpint (csd_night_light_get_temperature (nlight), >=, (CSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 - 20); /* ~50% smeared 3 min before sunset (sunset at 6 past) */ g_settings_set_double (settings, "night-light-schedule-from", 6.1); g_settings_set_double (settings, "night-light-schedule-to", 6.0); datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 3, 0); csd_night_light_set_date_time_now (nlight, datetime_override); g_assert_true (csd_night_light_get_active (nlight)); g_assert_cmpint (csd_night_light_get_temperature (nlight), <=, (CSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 + 20); g_assert_cmpint (csd_night_light_get_temperature (nlight), >=, (CSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 - 20); } static const gboolean ccm_vendor_is_goldstar (const char * const vendor) { if (g_strcmp0 (vendor, "Goldstar Company Ltd") == 0) return TRUE; /* Goldstar was changed to LG in hwdb (systemd) 240. * https://github.com/systemd/systemd/commit/c6d7a5e9a3836f8 */ if (g_strcmp0 (vendor, "LG Electronics") == 0) return TRUE; return FALSE; } static void ccm_test_edid_func (void) { CcmEdid *edid; gchar *data; gboolean ret; GError *error = NULL; gsize length = 0; edid = ccm_edid_new (); g_assert (edid != NULL); /* LG 21" LCD panel */ ret = g_file_get_contents (TESTDATADIR "/LG-L225W-External.bin", &data, &length, &error); g_assert_no_error (error); g_assert (ret); ret = ccm_edid_parse (edid, (const guint8 *) data, length, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpstr (ccm_edid_get_monitor_name (edid), ==, "L225W"); g_printerr ("ff: %s\n", ccm_edid_get_vendor_name (edid)); g_assert_true (ccm_vendor_is_goldstar (ccm_edid_get_vendor_name (edid))); g_assert_cmpstr (ccm_edid_get_serial_number (edid), ==, "34398"); g_assert_cmpstr (ccm_edid_get_eisa_id (edid), ==, NULL); g_assert_cmpstr (ccm_edid_get_checksum (edid), ==, "0bb44865bb29984a4bae620656c31368"); g_assert_cmpstr (ccm_edid_get_pnp_id (edid), ==, "GSM"); g_assert_cmpint (ccm_edid_get_height (edid), ==, 30); g_assert_cmpint (ccm_edid_get_width (edid), ==, 47); g_assert_cmpfloat (ccm_edid_get_gamma (edid), >=, 2.2f - 0.01); g_assert_cmpfloat (ccm_edid_get_gamma (edid), <, 2.2f + 0.01); g_free (data); /* Lenovo T61 internal Panel */ ret = g_file_get_contents (TESTDATADIR "/Lenovo-T61-Internal.bin", &data, &length, &error); g_assert_no_error (error); g_assert (ret); ret = ccm_edid_parse (edid, (const guint8 *) data, length, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpstr (ccm_edid_get_monitor_name (edid), ==, NULL); g_assert_cmpstr (ccm_edid_get_vendor_name (edid), ==, "IBM Brasil"); g_assert_cmpstr (ccm_edid_get_serial_number (edid), ==, NULL); g_assert_cmpstr (ccm_edid_get_eisa_id (edid), ==, "LTN154P2-L05"); g_assert_cmpstr (ccm_edid_get_checksum (edid), ==, "e1865128c7cd5e5ed49ecfc8102f6f9c"); g_assert_cmpstr (ccm_edid_get_pnp_id (edid), ==, "IBM"); g_assert_cmpint (ccm_edid_get_height (edid), ==, 21); g_assert_cmpint (ccm_edid_get_width (edid), ==, 33); g_assert_cmpfloat (ccm_edid_get_gamma (edid), >=, 2.2f - 0.01); g_assert_cmpfloat (ccm_edid_get_gamma (edid), <, 2.2f + 0.01); g_free (data); g_object_unref (edid); } static void ccm_test_sunset_sunrise (void) { gdouble sunrise; gdouble sunrise_actual = 7.6; gdouble sunset; gdouble sunset_actual = 16.8; g_autoptr(GDateTime) dt = g_date_time_new_utc (2007, 2, 1, 0, 0, 0); /* get for London, today */ csd_night_light_get_sunrise_sunset (dt, 51.5, -0.1278, &sunrise, &sunset); g_assert_cmpfloat (sunrise, <, sunrise_actual + 0.1); g_assert_cmpfloat (sunrise, >, sunrise_actual - 0.1); g_assert_cmpfloat (sunset, <, sunset_actual + 0.1); g_assert_cmpfloat (sunset, >, sunset_actual - 0.1); } static void ccm_test_sunset_sunrise_fractional_timezone (void) { gdouble sunrise; gdouble sunrise_actual = 7.6 + 1.5; gdouble sunset; gdouble sunset_actual = 16.8 + 1.5; g_autoptr(GTimeZone) tz = NULL; g_autoptr(GDateTime) dt = NULL; tz = g_time_zone_new ("+01:30"); dt = g_date_time_new (tz, 2007, 2, 1, 0, 0, 0); /* get for our made up timezone, today */ csd_night_light_get_sunrise_sunset (dt, 51.5, -0.1278, &sunrise, &sunset); g_assert_cmpfloat (sunrise, <, sunrise_actual + 0.1); g_assert_cmpfloat (sunrise, >, sunrise_actual - 0.1); g_assert_cmpfloat (sunset, <, sunset_actual + 0.1); g_assert_cmpfloat (sunset, >, sunset_actual - 0.1); } static void ccm_test_frac_day (void) { g_autoptr(GDateTime) dt = g_date_time_new_utc (2007, 2, 1, 12, 59, 59); gdouble fd; gdouble fd_actual = 12.99; /* test for 12:59:59 */ fd = csd_night_light_frac_day_from_dt (dt); g_assert_cmpfloat (fd, >, fd_actual - 0.01); g_assert_cmpfloat (fd, <, fd_actual + 0.01); /* test same day */ g_assert_true (csd_night_light_frac_day_is_between (12, 6, 20)); g_assert_false (csd_night_light_frac_day_is_between (5, 6, 20)); g_assert_true (csd_night_light_frac_day_is_between (12, 0, 24)); g_assert_true (csd_night_light_frac_day_is_between (12, -1, 25)); /* test rollover to next day */ g_assert_true (csd_night_light_frac_day_is_between (23, 20, 6)); g_assert_false (csd_night_light_frac_day_is_between (12, 20, 6)); /* test rollover to the previous day */ g_assert_true (csd_night_light_frac_day_is_between (5, 16, 8)); /* test equality */ g_assert_true (csd_night_light_frac_day_is_between (12, 0.5, 24.5)); g_assert_true (csd_night_light_frac_day_is_between (0.5, 0.5, 0.5)); } int main (int argc, char **argv) { g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); g_test_init (&argc, &argv, NULL); mainloop = g_main_loop_new (g_main_context_default (), FALSE); g_test_add_func ("/color/edid", ccm_test_edid_func); g_test_add_func ("/color/sunset-sunrise", ccm_test_sunset_sunrise); g_test_add_func ("/color/sunset-sunrise/fractional-timezone", ccm_test_sunset_sunrise_fractional_timezone); g_test_add_func ("/color/fractional-day", ccm_test_frac_day); g_test_add_func ("/color/night-light", ccm_test_night_light); return g_test_run (); } cinnamon-settings-daemon-6.4.3/plugins/color/tz-coords.h0000664000175000017500000005143514733247605022270 0ustar fabiofabio // Generated from /usr/share/zoneinfo/zone.tab, used by csd-nightlight.c to calculate sunrise and sunset based on the system timezone typedef struct { const gchar *timezone; double latitude; double longitude; } TZCoords; static TZCoords tz_coord_list[] = { { "Africa/Abidjan", 5.190000, -4.020000 }, { "Africa/Accra", 5.330000, -0.130000 }, { "Africa/Addis_Ababa", 9.020000, 38.420000 }, { "Africa/Algiers", 36.470000, 3.030000 }, { "Africa/Asmara", 15.200000, 38.530000 }, { "Africa/Bamako", 12.390000, -8.000000 }, { "Africa/Bangui", 4.220000, 18.350000 }, { "Africa/Banjul", 13.280000, -16.390000 }, { "Africa/Bissau", 11.510000, -15.350000 }, { "Africa/Blantyre", -15.470000, 35.000000 }, { "Africa/Brazzaville", -4.160000, 15.170000 }, { "Africa/Bujumbura", -3.230000, 29.220000 }, { "Africa/Cairo", 30.030000, 31.150000 }, { "Africa/Casablanca", 33.390000, -7.350000 }, { "Africa/Ceuta", 35.530000, -5.190000 }, { "Africa/Conakry", 9.310000, -13.430000 }, { "Africa/Dakar", 14.400000, -17.260000 }, { "Africa/Dar_es_Salaam", -6.480000, 39.170000 }, { "Africa/Djibouti", 11.360000, 43.090000 }, { "Africa/Douala", 4.030000, 9.420000 }, { "Africa/El_Aaiun", 27.090000, -13.120000 }, { "Africa/Freetown", 8.300000, -13.150000 }, { "Africa/Gaborone", -24.390000, 25.550000 }, { "Africa/Harare", -17.500000, 31.030000 }, { "Africa/Johannesburg", -26.150000, 28.000000 }, { "Africa/Juba", 4.510000, 31.370000 }, { "Africa/Kampala", 0.190000, 32.250000 }, { "Africa/Khartoum", 15.360000, 32.320000 }, { "Africa/Kigali", -1.570000, 30.040000 }, { "Africa/Kinshasa", -4.180000, 15.180000 }, { "Africa/Lagos", 6.270000, 3.240000 }, { "Africa/Libreville", 0.230000, 9.270000 }, { "Africa/Lome", 6.080000, 1.130000 }, { "Africa/Luanda", -8.480000, 13.140000 }, { "Africa/Lubumbashi", -11.400000, 27.280000 }, { "Africa/Lusaka", -15.250000, 28.170000 }, { "Africa/Malabo", 3.450000, 8.470000 }, { "Africa/Maputo", -25.580000, 32.350000 }, { "Africa/Maseru", -29.280000, 27.300000 }, { "Africa/Mbabane", -26.180000, 31.060000 }, { "Africa/Mogadishu", 2.040000, 45.220000 }, { "Africa/Monrovia", 6.180000, -10.470000 }, { "Africa/Nairobi", -1.170000, 36.490000 }, { "Africa/Ndjamena", 12.070000, 15.030000 }, { "Africa/Niamey", 13.310000, 2.070000 }, { "Africa/Nouakchott", 18.060000, -15.570000 }, { "Africa/Ouagadougou", 12.220000, -1.310000 }, { "Africa/Porto-Novo", 6.290000, 2.370000 }, { "Africa/Sao_Tome", 0.200000, 6.440000 }, { "Africa/Tripoli", 32.540000, 13.110000 }, { "Africa/Tunis", 36.480000, 10.110000 }, { "Africa/Windhoek", -22.340000, 17.060000 }, { "America/Adak", 51.524800, -176.392900 }, { "America/Anchorage", 61.130500, -149.540100 }, { "America/Anguilla", 18.120000, -63.040000 }, { "America/Antigua", 17.030000, -61.480000 }, { "America/Araguaina", -7.120000, -48.120000 }, { "America/Argentina/Buenos_Aires", -34.360000, -58.270000 }, { "America/Argentina/Catamarca", -28.280000, -65.470000 }, { "America/Argentina/Cordoba", -31.240000, -64.110000 }, { "America/Argentina/Jujuy", -24.110000, -65.180000 }, { "America/Argentina/La_Rioja", -29.260000, -66.510000 }, { "America/Argentina/Mendoza", -32.530000, -68.490000 }, { "America/Argentina/Rio_Gallegos", -51.380000, -69.130000 }, { "America/Argentina/Salta", -24.470000, -65.250000 }, { "America/Argentina/San_Juan", -31.320000, -68.310000 }, { "America/Argentina/San_Luis", -33.190000, -66.210000 }, { "America/Argentina/Tucuman", -26.490000, -65.130000 }, { "America/Argentina/Ushuaia", -54.480000, -68.180000 }, { "America/Aruba", 12.300000, -69.580000 }, { "America/Asuncion", -25.160000, -57.400000 }, { "America/Atikokan", 48.453100, -91.371800 }, { "America/Bahia", -12.590000, -38.310000 }, { "America/Bahia_Banderas", 20.480000, -105.150000 }, { "America/Barbados", 13.060000, -59.370000 }, { "America/Belem", -1.270000, -48.290000 }, { "America/Belize", 17.300000, -88.120000 }, { "America/Blanc-Sablon", 51.250000, -57.070000 }, { "America/Boa_Vista", 2.490000, -60.400000 }, { "America/Bogota", 4.360000, -74.050000 }, { "America/Boise", 43.364900, -116.120900 }, { "America/Cambridge_Bay", 69.065000, -105.031000 }, { "America/Campo_Grande", -20.270000, -54.370000 }, { "America/Cancun", 21.050000, -86.460000 }, { "America/Caracas", 10.300000, -66.560000 }, { "America/Cayenne", 4.560000, -52.200000 }, { "America/Cayman", 19.180000, -81.230000 }, { "America/Chicago", 41.510000, -87.390000 }, { "America/Chihuahua", 28.380000, -106.050000 }, { "America/Ciudad_Juarez", 31.440000, -106.290000 }, { "America/Costa_Rica", 9.560000, -84.050000 }, { "America/Creston", 49.060000, -116.310000 }, { "America/Cuiaba", -15.350000, -56.050000 }, { "America/Curacao", 12.110000, -69.000000 }, { "America/Danmarkshavn", 76.460000, -18.400000 }, { "America/Dawson", 64.040000, -139.250000 }, { "America/Dawson_Creek", 55.460000, -120.140000 }, { "America/Denver", 39.442100, -104.590300 }, { "America/Detroit", 42.195300, -83.024500 }, { "America/Dominica", 15.180000, -61.240000 }, { "America/Edmonton", 53.330000, -113.280000 }, { "America/Eirunepe", -6.400000, -69.520000 }, { "America/El_Salvador", 13.420000, -89.120000 }, { "America/Fort_Nelson", 58.480000, -122.420000 }, { "America/Fortaleza", -3.430000, -38.300000 }, { "America/Glace_Bay", 46.120000, -59.570000 }, { "America/Goose_Bay", 53.200000, -60.250000 }, { "America/Grand_Turk", 21.280000, -71.080000 }, { "America/Grenada", 12.030000, -61.450000 }, { "America/Guadeloupe", 16.140000, -61.320000 }, { "America/Guatemala", 14.380000, -90.310000 }, { "America/Guayaquil", -2.100000, -79.500000 }, { "America/Guyana", 6.480000, -58.100000 }, { "America/Halifax", 44.390000, -63.360000 }, { "America/Havana", 23.080000, -82.220000 }, { "America/Hermosillo", 29.040000, -110.580000 }, { "America/Indiana/Indianapolis", 39.460600, -86.092900 }, { "America/Indiana/Knox", 41.174500, -86.373000 }, { "America/Indiana/Marengo", 38.223200, -86.204100 }, { "America/Indiana/Petersburg", 38.293100, -87.164300 }, { "America/Indiana/Tell_City", 37.571100, -86.454100 }, { "America/Indiana/Vevay", 38.445200, -85.040200 }, { "America/Indiana/Vincennes", 38.403800, -87.314300 }, { "America/Indiana/Winamac", 41.030500, -86.361100 }, { "America/Inuvik", 68.205900, -133.430000 }, { "America/Iqaluit", 63.440000, -68.280000 }, { "America/Jamaica", 17.580500, -76.473600 }, { "America/Juneau", 58.180700, -134.251100 }, { "America/Kentucky/Louisville", 38.151500, -85.453400 }, { "America/Kentucky/Monticello", 36.494700, -84.505700 }, { "America/Kralendijk", 12.090300, -68.163600 }, { "America/La_Paz", -16.300000, -68.090000 }, { "America/Lima", -12.030000, -77.030000 }, { "America/Los_Angeles", 34.030800, -118.143400 }, { "America/Lower_Princes", 18.030500, -63.025000 }, { "America/Maceio", -9.400000, -35.430000 }, { "America/Managua", 12.090000, -86.170000 }, { "America/Manaus", -3.080000, -60.010000 }, { "America/Marigot", 18.040000, -63.050000 }, { "America/Martinique", 14.360000, -61.050000 }, { "America/Matamoros", 25.500000, -97.300000 }, { "America/Mazatlan", 23.130000, -106.250000 }, { "America/Menominee", 45.062800, -87.365100 }, { "America/Merida", 20.580000, -89.370000 }, { "America/Metlakatla", 55.073700, -131.343500 }, { "America/Mexico_City", 19.240000, -99.090000 }, { "America/Miquelon", 47.030000, -56.200000 }, { "America/Moncton", 46.060000, -64.470000 }, { "America/Monterrey", 25.400000, -100.190000 }, { "America/Montevideo", -34.543300, -56.124500 }, { "America/Montserrat", 16.430000, -62.130000 }, { "America/Nassau", 25.050000, -77.210000 }, { "America/New_York", 40.425100, -74.002300 }, { "America/Nome", 64.300400, -165.242300 }, { "America/Noronha", -3.510000, -32.250000 }, { "America/North_Dakota/Beulah", 47.155100, -101.464000 }, { "America/North_Dakota/Center", 47.065900, -101.175700 }, { "America/North_Dakota/New_Salem", 46.504200, -101.243900 }, { "America/Nuuk", 64.110000, -51.440000 }, { "America/Ojinaga", 29.340000, -104.250000 }, { "America/Panama", 8.580000, -79.320000 }, { "America/Paramaribo", 5.500000, -55.100000 }, { "America/Phoenix", 33.265400, -112.042400 }, { "America/Port-au-Prince", 18.320000, -72.200000 }, { "America/Port_of_Spain", 10.390000, -61.310000 }, { "America/Porto_Velho", -8.460000, -63.540000 }, { "America/Puerto_Rico", 18.280600, -66.062200 }, { "America/Punta_Arenas", -53.090000, -70.550000 }, { "America/Rankin_Inlet", 62.490000, -92.045900 }, { "America/Recife", -8.030000, -34.540000 }, { "America/Regina", 50.240000, -104.390000 }, { "America/Resolute", 74.414400, -94.494500 }, { "America/Rio_Branco", -9.580000, -67.480000 }, { "America/Santarem", -2.260000, -54.520000 }, { "America/Santiago", -33.270000, -70.400000 }, { "America/Santo_Domingo", 18.280000, -69.540000 }, { "America/Sao_Paulo", -23.320000, -46.370000 }, { "America/Scoresbysund", 70.290000, -21.580000 }, { "America/Sitka", 57.103500, -135.180700 }, { "America/St_Barthelemy", 17.530000, -62.510000 }, { "America/St_Johns", 47.340000, -52.430000 }, { "America/St_Kitts", 17.180000, -62.430000 }, { "America/St_Lucia", 14.010000, -61.000000 }, { "America/St_Thomas", 18.210000, -64.560000 }, { "America/St_Vincent", 13.090000, -61.140000 }, { "America/Swift_Current", 50.170000, -107.500000 }, { "America/Tegucigalpa", 14.060000, -87.130000 }, { "America/Thule", 76.340000, -68.470000 }, { "America/Tijuana", 32.320000, -117.010000 }, { "America/Toronto", 43.390000, -79.230000 }, { "America/Tortola", 18.270000, -64.370000 }, { "America/Vancouver", 49.160000, -123.070000 }, { "America/Whitehorse", 60.430000, -135.030000 }, { "America/Winnipeg", 49.530000, -97.090000 }, { "America/Yakutat", 59.324900, -139.433800 }, { "Antarctica/Casey", -66.170000, 110.310000 }, { "Antarctica/Davis", -68.350000, 77.580000 }, { "Antarctica/DumontDUrville", -66.400000, 140.010000 }, { "Antarctica/Macquarie", -54.300000, 158.570000 }, { "Antarctica/Mawson", -67.360000, 62.530000 }, { "Antarctica/McMurdo", -77.500000, 166.360000 }, { "Antarctica/Palmer", -64.480000, -64.060000 }, { "Antarctica/Rothera", -67.340000, -68.080000 }, { "Antarctica/Syowa", -69.002200, 39.352400 }, { "Antarctica/Troll", -72.004100, 2.320600 }, { "Antarctica/Vostok", -78.240000, 106.540000 }, { "Arctic/Longyearbyen", 78.000000, 16.000000 }, { "Asia/Aden", 12.450000, 45.120000 }, { "Asia/Almaty", 43.150000, 76.570000 }, { "Asia/Amman", 31.570000, 35.560000 }, { "Asia/Anadyr", 64.450000, 177.290000 }, { "Asia/Aqtau", 44.310000, 50.160000 }, { "Asia/Aqtobe", 50.170000, 57.100000 }, { "Asia/Ashgabat", 37.570000, 58.230000 }, { "Asia/Atyrau", 47.070000, 51.560000 }, { "Asia/Baghdad", 33.210000, 44.250000 }, { "Asia/Bahrain", 26.230000, 50.350000 }, { "Asia/Baku", 40.230000, 49.510000 }, { "Asia/Bangkok", 13.450000, 100.310000 }, { "Asia/Barnaul", 53.220000, 83.450000 }, { "Asia/Beirut", 33.530000, 35.300000 }, { "Asia/Bishkek", 42.540000, 74.360000 }, { "Asia/Brunei", 4.560000, 114.550000 }, { "Asia/Chita", 52.030000, 113.280000 }, { "Asia/Choibalsan", 48.040000, 114.300000 }, { "Asia/Colombo", 6.560000, 79.510000 }, { "Asia/Damascus", 33.300000, 36.180000 }, { "Asia/Dhaka", 23.430000, 90.250000 }, { "Asia/Dili", -8.330000, 125.350000 }, { "Asia/Dubai", 25.180000, 55.180000 }, { "Asia/Dushanbe", 38.350000, 68.480000 }, { "Asia/Famagusta", 35.070000, 33.570000 }, { "Asia/Gaza", 31.300000, 34.280000 }, { "Asia/Hebron", 31.320000, 35.054200 }, { "Asia/Ho_Chi_Minh", 10.450000, 106.400000 }, { "Asia/Hong_Kong", 22.170000, 114.090000 }, { "Asia/Hovd", 48.010000, 91.390000 }, { "Asia/Irkutsk", 52.160000, 104.200000 }, { "Asia/Jakarta", -6.100000, 106.480000 }, { "Asia/Jayapura", -2.320000, 140.420000 }, { "Asia/Jerusalem", 31.465000, 35.132600 }, { "Asia/Kabul", 34.310000, 69.120000 }, { "Asia/Kamchatka", 53.010000, 158.390000 }, { "Asia/Karachi", 24.520000, 67.030000 }, { "Asia/Kathmandu", 27.430000, 85.190000 }, { "Asia/Khandyga", 62.392300, 135.331400 }, { "Asia/Kolkata", 22.320000, 88.220000 }, { "Asia/Krasnoyarsk", 56.010000, 92.500000 }, { "Asia/Kuala_Lumpur", 3.100000, 101.420000 }, { "Asia/Kuching", 1.330000, 110.200000 }, { "Asia/Kuwait", 29.200000, 47.590000 }, { "Asia/Macau", 22.115000, 113.323000 }, { "Asia/Magadan", 59.340000, 150.480000 }, { "Asia/Makassar", -5.070000, 119.240000 }, { "Asia/Manila", 14.350000, 121.000000 }, { "Asia/Muscat", 23.360000, 58.350000 }, { "Asia/Nicosia", 35.100000, 33.220000 }, { "Asia/Novokuznetsk", 53.450000, 87.070000 }, { "Asia/Novosibirsk", 55.020000, 82.550000 }, { "Asia/Omsk", 55.000000, 73.240000 }, { "Asia/Oral", 51.130000, 51.210000 }, { "Asia/Phnom_Penh", 11.330000, 104.550000 }, { "Asia/Pontianak", -0.020000, 109.200000 }, { "Asia/Pyongyang", 39.010000, 125.450000 }, { "Asia/Qatar", 25.170000, 51.320000 }, { "Asia/Qostanay", 53.120000, 63.370000 }, { "Asia/Qyzylorda", 44.480000, 65.280000 }, { "Asia/Riyadh", 24.380000, 46.430000 }, { "Asia/Sakhalin", 46.580000, 142.420000 }, { "Asia/Samarkand", 39.400000, 66.480000 }, { "Asia/Seoul", 37.330000, 126.580000 }, { "Asia/Shanghai", 31.140000, 121.280000 }, { "Asia/Singapore", 1.170000, 103.510000 }, { "Asia/Srednekolymsk", 67.280000, 153.430000 }, { "Asia/Taipei", 25.030000, 121.300000 }, { "Asia/Tashkent", 41.200000, 69.180000 }, { "Asia/Tbilisi", 41.430000, 44.490000 }, { "Asia/Tehran", 35.400000, 51.260000 }, { "Asia/Thimphu", 27.280000, 89.390000 }, { "Asia/Tokyo", 35.391600, 139.444100 }, { "Asia/Tomsk", 56.300000, 84.580000 }, { "Asia/Ulaanbaatar", 47.550000, 106.530000 }, { "Asia/Urumqi", 43.480000, 87.350000 }, { "Asia/Ust-Nera", 64.333700, 143.133600 }, { "Asia/Vientiane", 17.580000, 102.360000 }, { "Asia/Vladivostok", 43.100000, 131.560000 }, { "Asia/Yakutsk", 62.000000, 129.400000 }, { "Asia/Yangon", 16.470000, 96.100000 }, { "Asia/Yekaterinburg", 56.510000, 60.360000 }, { "Asia/Yerevan", 40.110000, 44.300000 }, { "Atlantic/Azores", 37.440000, -25.400000 }, { "Atlantic/Bermuda", 32.170000, -64.460000 }, { "Atlantic/Canary", 28.060000, -15.240000 }, { "Atlantic/Cape_Verde", 14.550000, -23.310000 }, { "Atlantic/Faroe", 62.010000, -6.460000 }, { "Atlantic/Madeira", 32.380000, -16.540000 }, { "Atlantic/Reykjavik", 64.090000, -21.510000 }, { "Atlantic/South_Georgia", -54.160000, -36.320000 }, { "Atlantic/St_Helena", -15.550000, -5.420000 }, { "Atlantic/Stanley", -51.420000, -57.510000 }, { "Australia/Adelaide", -34.550000, 138.350000 }, { "Australia/Brisbane", -27.280000, 153.020000 }, { "Australia/Broken_Hill", -31.570000, 141.270000 }, { "Australia/Darwin", -12.280000, 130.500000 }, { "Australia/Eucla", -31.430000, 128.520000 }, { "Australia/Hobart", -42.530000, 147.190000 }, { "Australia/Lindeman", -20.160000, 149.000000 }, { "Australia/Lord_Howe", -31.330000, 159.050000 }, { "Australia/Melbourne", -37.490000, 144.580000 }, { "Australia/Perth", -31.570000, 115.510000 }, { "Australia/Sydney", -33.520000, 151.130000 }, { "Europe/Amsterdam", 52.220000, 4.540000 }, { "Europe/Andorra", 42.300000, 1.310000 }, { "Europe/Astrakhan", 46.210000, 48.030000 }, { "Europe/Athens", 37.580000, 23.430000 }, { "Europe/Belgrade", 44.500000, 20.300000 }, { "Europe/Berlin", 52.300000, 13.220000 }, { "Europe/Bratislava", 48.090000, 17.070000 }, { "Europe/Brussels", 50.500000, 4.200000 }, { "Europe/Bucharest", 44.260000, 26.060000 }, { "Europe/Budapest", 47.300000, 19.050000 }, { "Europe/Busingen", 47.420000, 8.410000 }, { "Europe/Chisinau", 47.000000, 28.500000 }, { "Europe/Copenhagen", 55.400000, 12.350000 }, { "Europe/Dublin", 53.200000, -6.150000 }, { "Europe/Gibraltar", 36.080000, -5.210000 }, { "Europe/Guernsey", 49.271700, -2.321000 }, { "Europe/Helsinki", 60.100000, 24.580000 }, { "Europe/Isle_of_Man", 54.090000, -4.280000 }, { "Europe/Istanbul", 41.010000, 28.580000 }, { "Europe/Jersey", 49.110100, -2.062400 }, { "Europe/Kaliningrad", 54.430000, 20.300000 }, { "Europe/Kirov", 58.360000, 49.390000 }, { "Europe/Kyiv", 50.260000, 30.310000 }, { "Europe/Lisbon", 38.430000, -9.080000 }, { "Europe/Ljubljana", 46.030000, 14.310000 }, { "Europe/London", 51.303000, -0.073100 }, { "Europe/Luxembourg", 49.360000, 6.090000 }, { "Europe/Madrid", 40.240000, -3.410000 }, { "Europe/Malta", 35.540000, 14.310000 }, { "Europe/Mariehamn", 60.060000, 19.570000 }, { "Europe/Minsk", 53.540000, 27.340000 }, { "Europe/Monaco", 43.420000, 7.230000 }, { "Europe/Moscow", 55.452100, 37.370400 }, { "Europe/Oslo", 59.550000, 10.450000 }, { "Europe/Paris", 48.520000, 2.200000 }, { "Europe/Podgorica", 42.260000, 19.160000 }, { "Europe/Prague", 50.050000, 14.260000 }, { "Europe/Riga", 56.570000, 24.060000 }, { "Europe/Rome", 41.540000, 12.290000 }, { "Europe/Samara", 53.120000, 50.090000 }, { "Europe/San_Marino", 43.550000, 12.280000 }, { "Europe/Sarajevo", 43.520000, 18.250000 }, { "Europe/Saratov", 51.340000, 46.020000 }, { "Europe/Simferopol", 44.570000, 34.060000 }, { "Europe/Skopje", 41.590000, 21.260000 }, { "Europe/Sofia", 42.410000, 23.190000 }, { "Europe/Stockholm", 59.200000, 18.030000 }, { "Europe/Tallinn", 59.250000, 24.450000 }, { "Europe/Tirane", 41.200000, 19.500000 }, { "Europe/Ulyanovsk", 54.200000, 48.240000 }, { "Europe/Vaduz", 47.090000, 9.310000 }, { "Europe/Vatican", 41.540800, 12.271100 }, { "Europe/Vienna", 48.130000, 16.200000 }, { "Europe/Vilnius", 54.410000, 25.190000 }, { "Europe/Volgograd", 48.440000, 44.250000 }, { "Europe/Warsaw", 52.150000, 21.000000 }, { "Europe/Zagreb", 45.480000, 15.580000 }, { "Europe/Zurich", 47.230000, 8.320000 }, { "Indian/Antananarivo", -18.550000, 47.310000 }, { "Indian/Chagos", -7.200000, 72.250000 }, { "Indian/Christmas", -10.250000, 105.430000 }, { "Indian/Cocos", -12.100000, 96.550000 }, { "Indian/Comoro", -11.410000, 43.160000 }, { "Indian/Kerguelen", -49.211000, 70.130300 }, { "Indian/Mahe", -4.400000, 55.280000 }, { "Indian/Maldives", 4.100000, 73.300000 }, { "Indian/Mauritius", -20.100000, 57.300000 }, { "Indian/Mayotte", -12.470000, 45.140000 }, { "Indian/Reunion", -20.520000, 55.280000 }, { "Pacific/Apia", -13.500000, -171.440000 }, { "Pacific/Auckland", -36.520000, 174.460000 }, { "Pacific/Bougainville", -6.130000, 155.340000 }, { "Pacific/Chatham", -43.570000, -176.330000 }, { "Pacific/Chuuk", 7.250000, 151.470000 }, { "Pacific/Easter", -27.090000, -109.260000 }, { "Pacific/Efate", -17.400000, 168.250000 }, { "Pacific/Fakaofo", -9.220000, -171.140000 }, { "Pacific/Fiji", -18.080000, 178.250000 }, { "Pacific/Funafuti", -8.310000, 179.130000 }, { "Pacific/Galapagos", -0.540000, -89.360000 }, { "Pacific/Gambier", -23.080000, -134.570000 }, { "Pacific/Guadalcanal", -9.320000, 160.120000 }, { "Pacific/Guam", 13.280000, 144.450000 }, { "Pacific/Honolulu", 21.182500, -157.513000 }, { "Pacific/Kanton", -2.470000, -171.430000 }, { "Pacific/Kiritimati", 1.520000, -157.200000 }, { "Pacific/Kosrae", 5.190000, 162.590000 }, { "Pacific/Kwajalein", 9.050000, 167.200000 }, { "Pacific/Majuro", 7.090000, 171.120000 }, { "Pacific/Marquesas", -9.000000, -139.300000 }, { "Pacific/Midway", 28.130000, -177.220000 }, { "Pacific/Nauru", -0.310000, 166.550000 }, { "Pacific/Niue", -19.010000, -169.550000 }, { "Pacific/Norfolk", -29.030000, 167.580000 }, { "Pacific/Noumea", -22.160000, 166.270000 }, { "Pacific/Pago_Pago", -14.160000, -170.420000 }, { "Pacific/Palau", 7.200000, 134.290000 }, { "Pacific/Pitcairn", -25.040000, -130.050000 }, { "Pacific/Pohnpei", 6.580000, 158.130000 }, { "Pacific/Port_Moresby", -9.300000, 147.100000 }, { "Pacific/Rarotonga", -21.140000, -159.460000 }, { "Pacific/Saipan", 15.120000, 145.450000 }, { "Pacific/Tahiti", -17.320000, -149.340000 }, { "Pacific/Tarawa", 1.250000, 173.000000 }, { "Pacific/Tongatapu", -21.080000, -175.120000 }, { "Pacific/Wake", 19.170000, 166.370000 }, { "Pacific/Wallis", -13.180000, -176.100000 }, };cinnamon-settings-daemon-6.4.3/plugins/color/ccm-edid.h0000664000175000017500000000570214733247605022005 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2009-2010 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CCM_EDID_H #define __CCM_EDID_H #include #include G_BEGIN_DECLS #define CCM_TYPE_EDID (ccm_edid_get_type ()) G_DECLARE_FINAL_TYPE (CcmEdid, ccm_edid, CCM, EDID, GObject) #define CCM_EDID_ERROR (ccm_edid_error_quark ()) enum { CCM_EDID_ERROR_FAILED_TO_PARSE }; GQuark ccm_edid_error_quark (void); CcmEdid *ccm_edid_new (void); void ccm_edid_reset (CcmEdid *edid); gboolean ccm_edid_parse (CcmEdid *edid, const guint8 *data, gsize length, GError **error); const gchar *ccm_edid_get_monitor_name (CcmEdid *edid); const gchar *ccm_edid_get_vendor_name (CcmEdid *edid); const gchar *ccm_edid_get_serial_number (CcmEdid *edid); const gchar *ccm_edid_get_eisa_id (CcmEdid *edid); const gchar *ccm_edid_get_checksum (CcmEdid *edid); const gchar *ccm_edid_get_pnp_id (CcmEdid *edid); guint ccm_edid_get_width (CcmEdid *edid); guint ccm_edid_get_height (CcmEdid *edid); gfloat ccm_edid_get_gamma (CcmEdid *edid); const CdColorYxy *ccm_edid_get_red (CcmEdid *edid); const CdColorYxy *ccm_edid_get_green (CcmEdid *edid); const CdColorYxy *ccm_edid_get_blue (CcmEdid *edid); const CdColorYxy *ccm_edid_get_white (CcmEdid *edid); G_END_DECLS #endif /* __CCM_EDID_H */ cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-profiles.h0000664000175000017500000000306414733247605024045 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #ifndef __CSD_COLOR_PROFILES_H #define __CSD_COLOR_PROFILES_H #include G_BEGIN_DECLS #define CSD_TYPE_COLOR_PROFILES (csd_color_profiles_get_type ()) G_DECLARE_FINAL_TYPE (CsdColorProfiles, csd_color_profiles, CSD, COLOR_PROFILES, GObject) GQuark csd_color_profiles_error_quark (void); CsdColorProfiles * csd_color_profiles_new (void); gboolean csd_color_profiles_start (CsdColorProfiles *profiles, GError **error); void csd_color_profiles_stop (CsdColorProfiles *profiles); G_END_DECLS #endif /* __CSD_COLOR_PROFILES_H */ cinnamon-settings-daemon-6.4.3/plugins/color/main.c0000664000175000017500000000123714733247605021256 0ustar fabiofabio#define NEW csd_color_manager_new #define START csd_color_manager_start #define STOP csd_color_manager_stop #define MANAGER CsdColorManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING FALSE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND FALSE #include "csd-color-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/color/ccm-edid.c0000664000175000017500000003341614733247605022003 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2008 Soren Sandmann * Copyright (C) 2009-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "ccm-edid.h" static void ccm_edid_finalize (GObject *object); struct _CcmEdid { GObject parent; gchar *monitor_name; gchar *vendor_name; gchar *serial_number; gchar *eisa_id; gchar *checksum; gchar *pnp_id; guint width; guint height; gfloat gamma; CdColorYxy *red; CdColorYxy *green; CdColorYxy *blue; CdColorYxy *white; GnomePnpIds *pnp_ids; }; G_DEFINE_TYPE (CcmEdid, ccm_edid, G_TYPE_OBJECT) #define CCM_EDID_OFFSET_PNPID 0x08 #define CCM_EDID_OFFSET_SERIAL 0x0c #define CCM_EDID_OFFSET_SIZE 0x15 #define CCM_EDID_OFFSET_GAMMA 0x17 #define CCM_EDID_OFFSET_DATA_BLOCKS 0x36 #define CCM_EDID_OFFSET_LAST_BLOCK 0x6c #define CCM_EDID_OFFSET_EXTENSION_BLOCK_COUNT 0x7e #define CCM_DESCRIPTOR_DISPLAY_PRODUCT_NAME 0xfc #define CCM_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER 0xff #define CCM_DESCRIPTOR_COLOR_MANAGEMENT_DATA 0xf9 #define CCM_DESCRIPTOR_ALPHANUMERIC_DATA_STRING 0xfe #define CCM_DESCRIPTOR_COLOR_POINT 0xfb GQuark ccm_edid_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("ccm_edid_error"); return quark; } const gchar * ccm_edid_get_monitor_name (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->monitor_name; } const gchar * ccm_edid_get_vendor_name (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); if (edid->vendor_name == NULL) edid->vendor_name = gnome_pnp_ids_get_pnp_id (edid->pnp_ids, edid->pnp_id); return edid->vendor_name; } const gchar * ccm_edid_get_serial_number (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->serial_number; } const gchar * ccm_edid_get_eisa_id (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->eisa_id; } const gchar * ccm_edid_get_checksum (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->checksum; } const gchar * ccm_edid_get_pnp_id (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->pnp_id; } guint ccm_edid_get_width (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), 0); return edid->width; } guint ccm_edid_get_height (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), 0); return edid->height; } gfloat ccm_edid_get_gamma (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), 0.0f); return edid->gamma; } const CdColorYxy * ccm_edid_get_red (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->red; } const CdColorYxy * ccm_edid_get_green (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->green; } const CdColorYxy * ccm_edid_get_blue (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->blue; } const CdColorYxy * ccm_edid_get_white (CcmEdid *edid) { g_return_val_if_fail (CCM_IS_EDID (edid), NULL); return edid->white; } void ccm_edid_reset (CcmEdid *edid) { g_return_if_fail (CCM_IS_EDID (edid)); /* free old data */ g_free (edid->monitor_name); g_free (edid->vendor_name); g_free (edid->serial_number); g_free (edid->eisa_id); g_free (edid->checksum); /* do not deallocate, just blank */ edid->pnp_id[0] = '\0'; /* set to default values */ edid->monitor_name = NULL; edid->vendor_name = NULL; edid->serial_number = NULL; edid->eisa_id = NULL; edid->checksum = NULL; edid->width = 0; edid->height = 0; edid->gamma = 0.0f; } static gint ccm_edid_get_bit (gint in, gint bit) { return (in & (1 << bit)) >> bit; } /** * ccm_edid_get_bits: **/ static gint ccm_edid_get_bits (gint in, gint begin, gint end) { gint mask = (1 << (end - begin + 1)) - 1; return (in >> begin) & mask; } /** * ccm_edid_decode_fraction: **/ static gdouble ccm_edid_decode_fraction (gint high, gint low) { gdouble result = 0.0; gint i; high = (high << 2) | low; for (i = 0; i < 10; ++i) result += ccm_edid_get_bit (high, i) * pow (2, i - 10); return result; } static gchar * ccm_edid_parse_string (const guint8 *data) { gchar *text; guint i; guint replaced = 0; /* this is always 13 bytes, but we can't guarantee it's null * terminated or not junk. */ text = g_strndup ((const gchar *) data, 13); /* remove insane newline chars */ g_strdelimit (text, "\n\r", '\0'); /* remove spaces */ g_strchomp (text); /* nothing left? */ if (text[0] == '\0') { g_free (text); text = NULL; goto out; } /* ensure string is printable */ for (i = 0; text[i] != '\0'; i++) { if (!g_ascii_isprint (text[i])) { text[i] = '-'; replaced++; } } /* if the string is junk, ignore the string */ if (replaced > 4) { g_free (text); text = NULL; goto out; } out: return text; } gboolean ccm_edid_parse (CcmEdid *edid, const guint8 *data, gsize length, GError **error) { gboolean ret = TRUE; guint i; guint32 serial; gchar *tmp; /* check header */ if (length < 128) { g_set_error_literal (error, CCM_EDID_ERROR, CCM_EDID_ERROR_FAILED_TO_PARSE, "EDID length is too small"); ret = FALSE; goto out; } if (data[0] != 0x00 || data[1] != 0xff) { g_set_error_literal (error, CCM_EDID_ERROR, CCM_EDID_ERROR_FAILED_TO_PARSE, "Failed to parse EDID header"); ret = FALSE; goto out; } /* free old data */ ccm_edid_reset (edid); /* decode the PNP ID from three 5 bit words packed into 2 bytes * /--08--\/--09--\ * 7654321076543210 * |\---/\---/\---/ * R C1 C2 C3 */ edid->pnp_id[0] = 'A' + ((data[CCM_EDID_OFFSET_PNPID+0] & 0x7c) / 4) - 1; edid->pnp_id[1] = 'A' + ((data[CCM_EDID_OFFSET_PNPID+0] & 0x3) * 8) + ((data[CCM_EDID_OFFSET_PNPID+1] & 0xe0) / 32) - 1; edid->pnp_id[2] = 'A' + (data[CCM_EDID_OFFSET_PNPID+1] & 0x1f) - 1; /* maybe there isn't a ASCII serial number descriptor, so use this instead */ serial = (guint32) data[CCM_EDID_OFFSET_SERIAL+0]; serial += (guint32) data[CCM_EDID_OFFSET_SERIAL+1] * 0x100; serial += (guint32) data[CCM_EDID_OFFSET_SERIAL+2] * 0x10000; serial += (guint32) data[CCM_EDID_OFFSET_SERIAL+3] * 0x1000000; if (serial > 0) edid->serial_number = g_strdup_printf ("%" G_GUINT32_FORMAT, serial); /* get the size */ edid->width = data[CCM_EDID_OFFSET_SIZE+0]; edid->height = data[CCM_EDID_OFFSET_SIZE+1]; /* we don't care about aspect */ if (edid->width == 0 || edid->height == 0) { edid->width = 0; edid->height = 0; } /* get gamma */ if (data[CCM_EDID_OFFSET_GAMMA] == 0xff) { edid->gamma = 1.0f; } else { edid->gamma = ((gfloat) data[CCM_EDID_OFFSET_GAMMA] / 100) + 1; } /* get color red */ edid->red->x = ccm_edid_decode_fraction (data[0x1b], ccm_edid_get_bits (data[0x19], 6, 7)); edid->red->y = ccm_edid_decode_fraction (data[0x1c], ccm_edid_get_bits (data[0x19], 4, 5)); /* get color green */ edid->green->x = ccm_edid_decode_fraction (data[0x1d], ccm_edid_get_bits (data[0x19], 2, 3)); edid->green->y = ccm_edid_decode_fraction (data[0x1e], ccm_edid_get_bits (data[0x19], 0, 1)); /* get color blue */ edid->blue->x = ccm_edid_decode_fraction (data[0x1f], ccm_edid_get_bits (data[0x1a], 6, 7)); edid->blue->y = ccm_edid_decode_fraction (data[0x20], ccm_edid_get_bits (data[0x1a], 4, 5)); /* get color white */ edid->white->x = ccm_edid_decode_fraction (data[0x21], ccm_edid_get_bits (data[0x1a], 2, 3)); edid->white->y = ccm_edid_decode_fraction (data[0x22], ccm_edid_get_bits (data[0x1a], 0, 1)); /* parse EDID data */ for (i = CCM_EDID_OFFSET_DATA_BLOCKS; i <= CCM_EDID_OFFSET_LAST_BLOCK; i += 18) { /* ignore pixel clock data */ if (data[i] != 0) continue; if (data[i+2] != 0) continue; /* any useful blocks? */ if (data[i+3] == CCM_DESCRIPTOR_DISPLAY_PRODUCT_NAME) { tmp = ccm_edid_parse_string (&data[i+5]); if (tmp != NULL) { g_free (edid->monitor_name); edid->monitor_name = tmp; } } else if (data[i+3] == CCM_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) { tmp = ccm_edid_parse_string (&data[i+5]); if (tmp != NULL) { g_free (edid->serial_number); edid->serial_number = tmp; } } else if (data[i+3] == CCM_DESCRIPTOR_COLOR_MANAGEMENT_DATA) { g_warning ("failing to parse color management data"); } else if (data[i+3] == CCM_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) { tmp = ccm_edid_parse_string (&data[i+5]); if (tmp != NULL) { g_free (edid->eisa_id); edid->eisa_id = tmp; } } else if (data[i+3] == CCM_DESCRIPTOR_COLOR_POINT) { if (data[i+3+9] != 0xff) { /* extended EDID block(1) which contains * a better gamma value */ edid->gamma = ((gfloat) data[i+3+9] / 100) + 1; } if (data[i+3+14] != 0xff) { /* extended EDID block(2) which contains * a better gamma value */ edid->gamma = ((gfloat) data[i+3+9] / 100) + 1; } } } /* calculate checksum */ edid->checksum = g_compute_checksum_for_data (G_CHECKSUM_MD5, data, length); out: return ret; } static void ccm_edid_class_init (CcmEdidClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = ccm_edid_finalize; } static void ccm_edid_init (CcmEdid *edid) { edid->pnp_ids = gnome_pnp_ids_new (); edid->pnp_id = g_new0 (gchar, 4); edid->red = cd_color_yxy_new (); edid->green = cd_color_yxy_new (); edid->blue = cd_color_yxy_new (); edid->white = cd_color_yxy_new (); } static void ccm_edid_finalize (GObject *object) { CcmEdid *edid = CCM_EDID (object); g_free (edid->monitor_name); g_free (edid->vendor_name); g_free (edid->serial_number); g_free (edid->eisa_id); g_free (edid->checksum); g_free (edid->pnp_id); cd_color_yxy_free (edid->white); cd_color_yxy_free (edid->red); cd_color_yxy_free (edid->green); cd_color_yxy_free (edid->blue); g_object_unref (edid->pnp_ids); G_OBJECT_CLASS (ccm_edid_parent_class)->finalize (object); } CcmEdid * ccm_edid_new (void) { CcmEdid *edid; edid = g_object_new (CCM_TYPE_EDID, NULL); return CCM_EDID (edid); } cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-state.h0000664000175000017500000000356214733247605023345 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #ifndef __CSD_COLOR_STATE_H #define __CSD_COLOR_STATE_H #include G_BEGIN_DECLS #define CSD_TYPE_COLOR_STATE (csd_color_state_get_type ()) G_DECLARE_FINAL_TYPE (CsdColorState, csd_color_state, CSD, COLOR_STATE, GObject) #define CSD_COLOR_TEMPERATURE_MIN 1000 /* Kelvin */ #define CSD_COLOR_TEMPERATURE_DEFAULT 6500 /* Kelvin, is RGB [1.0,1.0,1.0] */ #define CSD_COLOR_TEMPERATURE_MAX 10000 /* Kelvin */ GQuark csd_color_state_error_quark (void); CsdColorState * csd_color_state_new (void); void csd_color_state_start (CsdColorState *state); void csd_color_state_stop (CsdColorState *state); void csd_color_state_set_temperature (CsdColorState *state, guint temperature); guint csd_color_state_get_temperature (CsdColorState *state); G_END_DECLS #endif /* __CSD_COLOR_STATE_H */ cinnamon-settings-daemon-6.4.3/plugins/color/csd-night-light-common.h0000664000175000017500000000322614733247605024612 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * 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 . * */ #ifndef __CSD_NIGHT_LIGHT_COMMON_H #define __CSD_NIGHT_LIGHT_COMMON_H #include G_BEGIN_DECLS gboolean csd_night_light_get_sunrise_sunset (GDateTime *dt, gdouble pos_lat, gdouble pos_long, gdouble *sunrise, gdouble *sunset); gdouble csd_night_light_frac_day_from_dt (GDateTime *dt); gchar * csd_night_light_time_string_from_frac (gdouble fraction); gboolean csd_night_light_frac_day_is_between (gdouble value, gdouble start, gdouble end); G_END_DECLS #endif /* __CSD_NIGHT_LIGHT_COMMON_H */ cinnamon-settings-daemon-6.4.3/plugins/color/org.cinnamon.SettingsDaemon.Color.desktop.in0000664000175000017500000000042514733247605030554 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon's color plugin Exec=@libexecdir@/csd-color OnlyShowIn=GNOME; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true X-GNOME-HiddenUnderSystemd=@systemd_hidden@ cinnamon-settings-daemon-6.4.3/plugins/color/gnome-datetime-source.c0000664000175000017500000002046114733247605024527 0ustar fabiofabio/* -*- mode: C; c-file-style: "linux"; indent-tabs-mode: t -*- * gdatetime-source.c - copy&paste from https://bugzilla.gnome.org/show_bug.cgi?id=655129 * * Copyright (C) 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * Author: Colin Walters */ #include "config.h" #define GNOME_DESKTOP_USE_UNSTABLE_API #include "gnome-datetime-source.h" #if HAVE_TIMERFD #include #include #include #endif typedef struct _GDateTimeSource GDateTimeSource; struct _GDateTimeSource { GSource source; gint64 real_expiration; gint64 wakeup_expiration; gboolean cancel_on_set : 1; gboolean initially_expired : 1; GPollFD pollfd; }; static inline void g_datetime_source_reschedule (GDateTimeSource *datetime_source, gint64 from_monotonic) { datetime_source->wakeup_expiration = from_monotonic + G_TIME_SPAN_SECOND; } static gboolean g_datetime_source_is_expired (GDateTimeSource *datetime_source) { gint64 real_now; gint64 monotonic_now; real_now = g_get_real_time (); monotonic_now = g_source_get_time ((GSource*)datetime_source); if (datetime_source->initially_expired) return TRUE; if (datetime_source->real_expiration <= real_now) return TRUE; /* We can't really detect without system support when things * change; so just trigger every second (i.e. our wakeup * expiration) */ if (datetime_source->cancel_on_set && monotonic_now >= datetime_source->wakeup_expiration) return TRUE; return FALSE; } /* In prepare, we're just checking the monotonic time against * our projected wakeup. */ static gboolean g_datetime_source_prepare (GSource *source, gint *timeout) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; gint64 monotonic_now; #if HAVE_TIMERFD if (datetime_source->pollfd.fd != -1) { *timeout = -1; return datetime_source->initially_expired; /* Should be TRUE at most one time, FALSE forever after */ } #endif monotonic_now = g_source_get_time (source); if (monotonic_now < datetime_source->wakeup_expiration) { /* Round up to ensure that we don't try again too early */ *timeout = (datetime_source->wakeup_expiration - monotonic_now + 999) / 1000; return FALSE; } *timeout = 0; return g_datetime_source_is_expired (datetime_source); } /* In check, we're looking at the wall clock. */ static gboolean g_datetime_source_check (GSource *source) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; #if HAVE_TIMERFD if (datetime_source->pollfd.fd != -1) return datetime_source->pollfd.revents != 0; #endif if (g_datetime_source_is_expired (datetime_source)) return TRUE; g_datetime_source_reschedule (datetime_source, g_source_get_time (source)); return FALSE; } static gboolean g_datetime_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; datetime_source->initially_expired = FALSE; if (!callback) { g_warning ("Timeout source dispatched without callback\n" "You must call g_source_set_callback()."); return FALSE; } (callback) (user_data); /* Always false as this source is documented to run once */ return FALSE; } static void g_datetime_source_finalize (GSource *source) { #if HAVE_TIMERFD GDateTimeSource *datetime_source = (GDateTimeSource*)source; if (datetime_source->pollfd.fd != -1) close (datetime_source->pollfd.fd); #endif } static GSourceFuncs g_datetime_source_funcs = { g_datetime_source_prepare, g_datetime_source_check, g_datetime_source_dispatch, g_datetime_source_finalize }; #if HAVE_TIMERFD static gboolean g_datetime_source_init_timerfd (GDateTimeSource *datetime_source, gint64 expected_now_seconds, gint64 unix_seconds) { struct itimerspec its; int settime_flags; datetime_source->pollfd.fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC); if (datetime_source->pollfd.fd == -1) return FALSE; memset (&its, 0, sizeof (its)); its.it_value.tv_sec = (time_t) unix_seconds; /* http://article.gmane.org/gmane.linux.kernel/1132138 */ #ifndef TFD_TIMER_CANCEL_ON_SET #define TFD_TIMER_CANCEL_ON_SET (1 << 1) #endif settime_flags = TFD_TIMER_ABSTIME; if (datetime_source->cancel_on_set) settime_flags |= TFD_TIMER_CANCEL_ON_SET; if (timerfd_settime (datetime_source->pollfd.fd, settime_flags, &its, NULL) < 0) { close (datetime_source->pollfd.fd); datetime_source->pollfd.fd = -1; return FALSE; } /* Now we need to check that the clock didn't go backwards before we * had the timerfd set up. See * https://bugzilla.gnome.org/show_bug.cgi?id=655129 */ clock_gettime (CLOCK_REALTIME, &its.it_value); if (its.it_value.tv_sec < expected_now_seconds) datetime_source->initially_expired = TRUE; datetime_source->pollfd.events = G_IO_IN; g_source_add_poll ((GSource*) datetime_source, &datetime_source->pollfd); return TRUE; } #endif /** * _gnome_date_time_source_new: * @now: The expected current time * @expiry: Time to await * @cancel_on_set: Also invoke callback if the system clock changes discontiguously * * This function is designed for programs that want to schedule an * event based on real (wall clock) time, as returned by * g_get_real_time(). For example, HOUR:MINUTE wall-clock displays * and calendaring software. The callback will be invoked when the * specified wall clock time @expiry is reached. This includes * events such as the system clock being set past the given time. * * Compare versus g_timeout_source_new() which is defined to use * monotonic time as returned by g_get_monotonic_time(). * * The parameter @now is necessary to avoid a race condition in * between getting the current time and calling this function. * * If @cancel_on_set is given, the callback will also be invoked at * most a second after the system clock is changed. This includes * being set backwards or forwards, and system * resume from suspend. Not all operating systems allow detecting all * relevant events efficiently - this function may cause the process * to wake up once a second in those cases. * * A wall clock display should use @cancel_on_set; a calendaring * program shouldn't need to. * * Note that the return value from the associated callback will be * ignored; this is a one time watch. * * This function currently does not detect time zone * changes. On Linux, your program should also monitor the * /etc/timezone file using * #GFileMonitor. * * Clock exampleFIXME: MISSING XINCLUDE CONTENT * * Return value: A newly-constructed #GSource * * Since: 2.30 **/ GSource * _gnome_datetime_source_new (GDateTime *now, GDateTime *expiry, gboolean cancel_on_set) { GDateTimeSource *datetime_source; gint64 unix_seconds; unix_seconds = g_date_time_to_unix (expiry); datetime_source = (GDateTimeSource*) g_source_new (&g_datetime_source_funcs, sizeof (GDateTimeSource)); datetime_source->cancel_on_set = cancel_on_set; #if HAVE_TIMERFD { gint64 expected_now_seconds = g_date_time_to_unix (now); if (g_datetime_source_init_timerfd (datetime_source, expected_now_seconds, unix_seconds)) return (GSource*)datetime_source; /* Fall through to non-timerfd code */ } #endif datetime_source->real_expiration = unix_seconds * 1000000; g_datetime_source_reschedule (datetime_source, g_get_monotonic_time ()); return (GSource*)datetime_source; } cinnamon-settings-daemon-6.4.3/plugins/color/org.gnome.SessionManager.xml0000664000175000017500000000113114733247605025511 0ustar fabiofabio If true, the session is currently in the foreground and available for user input. cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-manager.h0000664000175000017500000000323514733247605023634 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011 Richard Hughes * * 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 . * */ #ifndef __CSD_COLOR_MANAGER_H #define __CSD_COLOR_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_COLOR_MANAGER (csd_color_manager_get_type ()) #define CSD_COLOR_MANAGER_ERROR (csd_color_manager_error_quark ()) G_DECLARE_FINAL_TYPE (CsdColorManager, csd_color_manager, CSD, COLOR_MANAGER, GObject) enum { CSD_COLOR_MANAGER_ERROR_FAILED }; GQuark csd_color_manager_error_quark (void); CsdColorManager * csd_color_manager_new (void); gboolean csd_color_manager_start (CsdColorManager *manager, GError **error); void csd_color_manager_stop (CsdColorManager *manager); G_END_DECLS #endif /* __CSD_COLOR_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/color/csd-night-light-common.c0000664000175000017500000001452114733247605024605 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * 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 . * */ #include "config.h" #include #include #include "csd-night-light-common.h" static gdouble deg2rad (gdouble degrees) { return (M_PI * degrees) / 180.f; } static gdouble rad2deg (gdouble radians) { return radians * (180.f / M_PI); } /* * Formulas taken from https://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html * * The returned values are fractional hours, so 6am would be 6.0 and 4:30pm * would be 16.5. * * The values returned by this function might not make sense for locations near * the polar regions. For example, in the north of Lapland there might not be * a sunrise at all. */ gboolean csd_night_light_get_sunrise_sunset (GDateTime *dt, gdouble pos_lat, gdouble pos_long, gdouble *sunrise, gdouble *sunset) { g_autoptr(GDateTime) dt_zero = g_date_time_new_utc (1900, 1, 1, 0, 0, 0); GTimeSpan ts = g_date_time_difference (dt, dt_zero); g_return_val_if_fail (pos_lat <= 90.f && pos_lat >= -90.f, FALSE); g_return_val_if_fail (pos_long <= 180.f && pos_long >= -180.f, FALSE); gdouble tz_offset = (gdouble) g_date_time_get_utc_offset (dt) / G_USEC_PER_SEC / 60 / 60; // B5 gdouble date_as_number = ts / G_USEC_PER_SEC / 24 / 60 / 60 + 2; // B7 gdouble time_past_local_midnight = 0; // E2, unused in this calculation gdouble julian_day = date_as_number + 2415018.5 + time_past_local_midnight - tz_offset / 24; gdouble julian_century = (julian_day - 2451545) / 36525; gdouble geom_mean_long_sun = fmod (280.46646 + julian_century * (36000.76983 + julian_century * 0.0003032), 360); // I2 gdouble geom_mean_anom_sun = 357.52911 + julian_century * (35999.05029 - 0.0001537 * julian_century); // J2 gdouble eccent_earth_orbit = 0.016708634 - julian_century * (0.000042037 + 0.0000001267 * julian_century); // K2 gdouble sun_eq_of_ctr = sin (deg2rad (geom_mean_anom_sun)) * (1.914602 - julian_century * (0.004817 + 0.000014 * julian_century)) + sin (deg2rad (2 * geom_mean_anom_sun)) * (0.019993 - 0.000101 * julian_century) + sin (deg2rad (3 * geom_mean_anom_sun)) * 0.000289; // L2 gdouble sun_true_long = geom_mean_long_sun + sun_eq_of_ctr; // M2 gdouble sun_app_long = sun_true_long - 0.00569 - 0.00478 * sin (deg2rad (125.04 - 1934.136 * julian_century)); // P2 gdouble mean_obliq_ecliptic = 23 + (26 + ((21.448 - julian_century * (46.815 + julian_century * (0.00059 - julian_century * 0.001813)))) / 60) / 60; // Q2 gdouble obliq_corr = mean_obliq_ecliptic + 0.00256 * cos (deg2rad (125.04 - 1934.136 * julian_century)); // R2 gdouble sun_declin = rad2deg (asin (sin (deg2rad (obliq_corr)) * sin (deg2rad (sun_app_long)))); // T2 gdouble var_y = tan (deg2rad (obliq_corr/2)) * tan (deg2rad (obliq_corr / 2)); // U2 gdouble eq_of_time = 4 * rad2deg (var_y * sin (2 * deg2rad (geom_mean_long_sun)) - 2 * eccent_earth_orbit * sin (deg2rad (geom_mean_anom_sun)) + 4 * eccent_earth_orbit * var_y * sin (deg2rad (geom_mean_anom_sun)) * cos (2 * deg2rad (geom_mean_long_sun)) - 0.5 * var_y * var_y * sin (4 * deg2rad (geom_mean_long_sun)) - 1.25 * eccent_earth_orbit * eccent_earth_orbit * sin (2 * deg2rad (geom_mean_anom_sun))); // V2 gdouble ha_sunrise = rad2deg (acos (cos (deg2rad (90.833)) / (cos (deg2rad (pos_lat)) * cos (deg2rad (sun_declin))) - tan (deg2rad (pos_lat)) * tan (deg2rad (sun_declin)))); // W2 gdouble solar_noon = (720 - 4 * pos_long - eq_of_time + tz_offset * 60) / 1440; // X2 gdouble sunrise_time = solar_noon - ha_sunrise * 4 / 1440; // Y2 gdouble sunset_time = solar_noon + ha_sunrise * 4 / 1440; // Z2 /* convert to hours */ if (sunrise != NULL) *sunrise = sunrise_time * 24; if (sunset != NULL) *sunset = sunset_time * 24; return TRUE; } gdouble csd_night_light_frac_day_from_dt (GDateTime *dt) { return g_date_time_get_hour (dt) + (gdouble) g_date_time_get_minute (dt) / 60.f + (gdouble) g_date_time_get_second (dt) / 3600.f; } gchar * csd_night_light_time_string_from_frac (gdouble fraction) { g_autoptr(GDateTime) dt = g_date_time_new_local (2000, 1, 1, (int) trunc (fraction), (int) ((fraction - trunc(fraction)) * 60.0f), 0); return g_date_time_format (dt, "%H:%M"); } gboolean csd_night_light_frac_day_is_between (gdouble value, gdouble start, gdouble end) { /* wrap end to the next day if it is before start, * considering equal values as a full 24h period */ if (end <= start) end += 24; /* wrap value to the next day if it is before the range */ if (value < start && value < end) value += 24; /* Check whether value falls into range; together with the 24h * wrap around above this means that TRUE is always returned when * start == end. */ return value >= start && value < end; } cinnamon-settings-daemon-6.4.3/plugins/color/csd-night-light.c0000664000175000017500000006362714733247605023332 0ustar fabiofabio/* * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #define GNOME_DESKTOP_USE_UNSTABLE_API #include "gnome-datetime-source.h" #include "csd-color-state.h" #include "csd-night-light.h" #include "csd-night-light-common.h" #include "tz-coords.h" struct _CsdNightLight { GObject parent; GSettings *settings; gboolean forced; gboolean disabled_until_tmw; GDateTime *disabled_until_tmw_dt; GSource *source; guint validate_id; gdouble cached_sunrise; gdouble cached_sunset; gdouble cached_temperature; gboolean cached_active; gboolean smooth_enabled; GTimer *smooth_timer; guint smooth_id; gdouble smooth_target_temperature; GCancellable *cancellable; GDateTime *datetime_override; }; enum { PROP_0, PROP_ACTIVE, PROP_SUNRISE, PROP_SUNSET, PROP_TEMPERATURE, PROP_DISABLED_UNTIL_TMW, PROP_FORCED, PROP_LAST }; enum { NIGHT_LIGHT_SCHEDULE_AUTO = 0, NIGHT_LIGHT_SCHEDULE_MANUAL = 1 }; #define CSD_NIGHT_LIGHT_SCHEDULE_TIMEOUT 5 /* seconds */ #define CSD_NIGHT_LIGHT_POLL_TIMEOUT 60 /* seconds */ #define CSD_NIGHT_LIGHT_POLL_SMEAR 1 /* hours */ #define CSD_NIGHT_LIGHT_SMOOTH_SMEAR 5.f /* seconds */ #define CSD_FRAC_DAY_MAX_DELTA (1.f/60.f) /* 1 minute */ #define CSD_TEMPERATURE_MAX_DELTA (10.f) /* Kelvin */ static void poll_timeout_destroy (CsdNightLight *self); static void poll_timeout_create (CsdNightLight *self); static void night_light_recheck (CsdNightLight *self); G_DEFINE_TYPE (CsdNightLight, csd_night_light, G_TYPE_OBJECT); static GDateTime * csd_night_light_get_date_time_now (CsdNightLight *self) { if (self->datetime_override != NULL) return g_date_time_ref (self->datetime_override); return g_date_time_new_now_local (); } void csd_night_light_set_date_time_now (CsdNightLight *self, GDateTime *datetime) { if (self->datetime_override != NULL) g_date_time_unref (self->datetime_override); self->datetime_override = g_date_time_ref (datetime); night_light_recheck (self); } static void poll_smooth_destroy (CsdNightLight *self) { if (self->smooth_id != 0) { g_source_remove (self->smooth_id); self->smooth_id = 0; } if (self->smooth_timer != NULL) g_clear_pointer (&self->smooth_timer, g_timer_destroy); } void csd_night_light_set_smooth_enabled (CsdNightLight *self, gboolean smooth_enabled) { /* ensure the timeout is stopped if called at runtime */ if (!smooth_enabled) poll_smooth_destroy (self); self->smooth_enabled = smooth_enabled; } static gdouble linear_interpolate (gdouble val1, gdouble val2, gdouble factor) { g_return_val_if_fail (factor >= 0.f, -1.f); g_return_val_if_fail (factor <= 1.f, -1.f); return ((val1 - val2) * factor) + val2; } static gboolean update_cached_sunrise_sunset (CsdNightLight *self) { gboolean ret = FALSE; gdouble latitude; gdouble longitude; gdouble sunrise; gdouble sunset; g_autoptr(GVariant) tmp = NULL; g_autoptr(GDateTime) dt_now = csd_night_light_get_date_time_now (self); /* calculate the sunrise/sunset for the location */ tmp = g_settings_get_value (self->settings, "night-light-last-coordinates"); g_variant_get (tmp, "(dd)", &latitude, &longitude); if (latitude > 90.f || latitude < -90.f) return FALSE; if (longitude > 180.f || longitude < -180.f) return FALSE; if (!csd_night_light_get_sunrise_sunset (dt_now, latitude, longitude, &sunrise, &sunset)) { g_warning ("failed to get sunset/sunrise for %.3f,%.3f", latitude, longitude); return FALSE; } /* anything changed */ if (ABS (self->cached_sunrise - sunrise) > CSD_FRAC_DAY_MAX_DELTA) { self->cached_sunrise = sunrise; g_object_notify (G_OBJECT (self), "sunrise"); g_autofree gchar *formatted = csd_night_light_time_string_from_frac (sunrise); g_debug ("Sunrise updated: %.3f (%s)", sunrise, formatted); ret = TRUE; } if (ABS (self->cached_sunset - sunset) > CSD_FRAC_DAY_MAX_DELTA) { self->cached_sunset = sunset; g_object_notify (G_OBJECT (self), "sunset"); g_autofree gchar *formatted = csd_night_light_time_string_from_frac (sunset); g_debug ("Sunset updated: %.3f (%s)", sunset, formatted); ret = TRUE; } return ret; } static void csd_night_light_set_temperature_internal (CsdNightLight *self, gdouble temperature) { if (ABS (self->cached_temperature - temperature) <= CSD_TEMPERATURE_MAX_DELTA) return; self->cached_temperature = temperature; g_object_notify (G_OBJECT (self), "temperature"); } static gboolean csd_night_light_smooth_cb (gpointer user_data) { CsdNightLight *self = CSD_NIGHT_LIGHT (user_data); gdouble tmp; gdouble frac; /* find fraction */ frac = g_timer_elapsed (self->smooth_timer, NULL) / CSD_NIGHT_LIGHT_SMOOTH_SMEAR; if (frac >= 1.f) { csd_night_light_set_temperature_internal (self, self->smooth_target_temperature); self->smooth_id = 0; return G_SOURCE_REMOVE; } /* set new temperature step using log curve */ tmp = self->smooth_target_temperature - self->cached_temperature; tmp *= frac; tmp += self->cached_temperature; csd_night_light_set_temperature_internal (self, tmp); return G_SOURCE_CONTINUE; } static void poll_smooth_create (CsdNightLight *self, gdouble temperature) { g_assert (self->smooth_id == 0); self->smooth_target_temperature = temperature; self->smooth_timer = g_timer_new (); self->smooth_id = g_timeout_add (50, csd_night_light_smooth_cb, self); } static void csd_night_light_set_temperature (CsdNightLight *self, gdouble temperature) { /* immediate */ if (!self->smooth_enabled) { csd_night_light_set_temperature_internal (self, temperature); return; } /* Destroy any smooth transition, it will be recreated if neccessary */ poll_smooth_destroy (self); /* small jump */ if (ABS (temperature - self->cached_temperature) < CSD_TEMPERATURE_MAX_DELTA) { csd_night_light_set_temperature_internal (self, temperature); return; } /* smooth out the transition */ poll_smooth_create (self, temperature); } static void csd_night_light_set_active (CsdNightLight *self, gboolean active) { if (self->cached_active == active) return; self->cached_active = active; /* ensure set to unity temperature */ if (!active) csd_night_light_set_temperature (self, CSD_COLOR_TEMPERATURE_DEFAULT); g_object_notify (G_OBJECT (self), "active"); } static void night_light_recheck (CsdNightLight *self) { gdouble frac_day; gdouble schedule_from = -1.f; gdouble schedule_to = -1.f; gdouble smear = CSD_NIGHT_LIGHT_POLL_SMEAR; /* hours */ guint temperature; guint temp_smeared; g_autoptr(GDateTime) dt_now = csd_night_light_get_date_time_now (self); /* Forced mode, just set the temperature to night light. * Proper rechecking will happen once forced mode is disabled again */ if (self->forced) { temperature = g_settings_get_uint (self->settings, "night-light-temperature"); csd_night_light_set_temperature (self, temperature); return; } /* enabled */ if (!g_settings_get_boolean (self->settings, "night-light-enabled")) { g_debug ("night light disabled, resetting"); csd_night_light_set_active (self, FALSE); return; } /* calculate the position of the sun */ if (g_settings_get_enum (self->settings, "night-light-schedule-mode") == NIGHT_LIGHT_SCHEDULE_AUTO) { update_cached_sunrise_sunset (self); if (self->cached_sunrise > 0.f && self->cached_sunset > 0.f) { schedule_to = self->cached_sunrise; schedule_from = self->cached_sunset; } } /* fall back to manual settings */ if (schedule_to <= 0.f || schedule_from <= 0.f) { schedule_from = g_settings_get_double (self->settings, "night-light-schedule-from"); schedule_to = g_settings_get_double (self->settings, "night-light-schedule-to"); } /* get the current hour of a day as a fraction */ frac_day = csd_night_light_frac_day_from_dt (dt_now); g_debug ("fractional day = %.3f, limits = %.3f->%.3f", frac_day, schedule_from, schedule_to); /* disabled until tomorrow */ if (self->disabled_until_tmw) { GTimeSpan time_span; gboolean reset = FALSE; time_span = g_date_time_difference (dt_now, self->disabled_until_tmw_dt); /* Reset if disabled until tomorrow is more than 24h ago. */ if (time_span > (GTimeSpan) 24 * 60 * 60 * 1000000) { g_debug ("night light disabled until tomorrow is older than 24h, resetting disabled until tomorrow"); reset = TRUE; } else if (time_span > 0) { /* Or if a sunrise lies between the time it was disabled and now. */ gdouble frac_disabled; frac_disabled = csd_night_light_frac_day_from_dt (self->disabled_until_tmw_dt); if (frac_disabled != frac_day && csd_night_light_frac_day_is_between (schedule_to, frac_disabled, frac_day)) { g_debug ("night light sun rise happened, resetting disabled until tomorrow"); reset = TRUE; } } if (reset) { self->disabled_until_tmw = FALSE; g_clear_pointer(&self->disabled_until_tmw_dt, g_date_time_unref); g_object_notify (G_OBJECT (self), "disabled-until-tmw"); } else { g_debug ("night light still day-disabled, resetting"); csd_night_light_set_temperature (self, CSD_COLOR_TEMPERATURE_DEFAULT); return; } } /* lower smearing period to be smaller than the time between start/stop */ smear = MIN (smear, MIN ( ABS (schedule_to - schedule_from), 24 - ABS (schedule_to - schedule_from))); if (!csd_night_light_frac_day_is_between (frac_day, schedule_from - smear, schedule_to)) { g_debug ("not time for night-light"); csd_night_light_set_active (self, FALSE); return; } /* smear the temperature for a short duration before the set limits * * |----------------------| = from->to * |-| = smear down * |-| = smear up * * \ / * \ / * \--------------------/ */ temperature = g_settings_get_uint (self->settings, "night-light-temperature"); if (smear < 0.01) { /* Don't try to smear for extremely short or zero periods */ temp_smeared = temperature; } else if (csd_night_light_frac_day_is_between (frac_day, schedule_from - smear, schedule_from)) { gdouble factor = 1.f - ((frac_day - (schedule_from - smear)) / smear); temp_smeared = linear_interpolate (CSD_COLOR_TEMPERATURE_DEFAULT, temperature, factor); } else if (csd_night_light_frac_day_is_between (frac_day, schedule_to - smear, schedule_to)) { gdouble factor = (frac_day - (schedule_to - smear)) / smear; temp_smeared = linear_interpolate (CSD_COLOR_TEMPERATURE_DEFAULT, temperature, factor); } else { temp_smeared = temperature; } g_debug ("night light mode on, using temperature of %uK (aiming for %uK)", temp_smeared, temperature); csd_night_light_set_active (self, TRUE); csd_night_light_set_temperature (self, temp_smeared); } /* called when the time may have changed */ static gboolean night_light_recheck_cb (gpointer user_data) { CsdNightLight *self = CSD_NIGHT_LIGHT (user_data); /* recheck parameters, then reschedule a new timeout */ night_light_recheck (self); poll_timeout_destroy (self); poll_timeout_create (self); /* return value ignored for a one-time watch */ return G_SOURCE_REMOVE; } static void poll_timeout_create (CsdNightLight *self) { g_autoptr(GDateTime) dt_now = NULL; g_autoptr(GDateTime) dt_expiry = NULL; if (self->source != NULL) return; dt_now = csd_night_light_get_date_time_now (self); dt_expiry = g_date_time_add_seconds (dt_now, CSD_NIGHT_LIGHT_POLL_TIMEOUT); self->source = _gnome_datetime_source_new (dt_now, dt_expiry, TRUE); g_source_set_callback (self->source, night_light_recheck_cb, self, NULL); g_source_attach (self->source, NULL); } static void poll_timeout_destroy (CsdNightLight *self) { if (self->source == NULL) return; g_source_destroy (self->source); g_source_unref (self->source); self->source = NULL; } static void settings_changed_cb (GSettings *settings, gchar *key, gpointer user_data) { CsdNightLight *self = CSD_NIGHT_LIGHT (user_data); g_debug ("settings changed"); night_light_recheck (self); } static void update_location_from_timezone (CsdNightLight *self) { GTimeZone *tz = g_time_zone_new_local (); const gchar *id = g_time_zone_get_identifier (tz); for (int i = 0; i < G_N_ELEMENTS (tz_coord_list); i++) { const TZCoords coords = tz_coord_list[i]; if (g_strcmp0 (coords.timezone, id) == 0) { g_debug ("Coordinates updated, timezone: %s, lat:%.3f, long:%.3f.", id, coords.latitude, coords.longitude); g_settings_set_value (self->settings, "night-light-last-coordinates", g_variant_new ("(dd)", coords.latitude, coords.longitude)); break; } } g_time_zone_unref (tz); } void csd_night_light_set_disabled_until_tmw (CsdNightLight *self, gboolean value) { g_autoptr(GDateTime) dt = csd_night_light_get_date_time_now (self); if (self->disabled_until_tmw == value) return; self->disabled_until_tmw = value; g_clear_pointer (&self->disabled_until_tmw_dt, g_date_time_unref); if (self->disabled_until_tmw) self->disabled_until_tmw_dt = g_steal_pointer (&dt); night_light_recheck (self); g_object_notify (G_OBJECT (self), "disabled-until-tmw"); } gboolean csd_night_light_get_disabled_until_tmw (CsdNightLight *self) { return self->disabled_until_tmw; } void csd_night_light_set_forced (CsdNightLight *self, gboolean value) { if (self->forced == value) return; self->forced = value; g_object_notify (G_OBJECT (self), "forced"); /* A simple recheck might not reset the temperature if * night light is currently disabled. */ if (!self->forced && !self->cached_active) csd_night_light_set_temperature (self, CSD_COLOR_TEMPERATURE_DEFAULT); night_light_recheck (self); } gboolean csd_night_light_get_forced (CsdNightLight *self) { return self->forced; } gboolean csd_night_light_get_active (CsdNightLight *self) { return self->cached_active; } gdouble csd_night_light_get_sunrise (CsdNightLight *self) { return self->cached_sunrise; } gdouble csd_night_light_get_sunset (CsdNightLight *self) { return self->cached_sunset; } gdouble csd_night_light_get_temperature (CsdNightLight *self) { return self->cached_temperature; } gboolean csd_night_light_start (CsdNightLight *self, GError **error) { night_light_recheck (self); poll_timeout_create (self); /* care about changes */ g_signal_connect (self->settings, "changed", G_CALLBACK (settings_changed_cb), self); update_location_from_timezone (self); return TRUE; } static void csd_night_light_finalize (GObject *object) { CsdNightLight *self = CSD_NIGHT_LIGHT (object); poll_timeout_destroy (self); poll_smooth_destroy (self); g_clear_object (&self->settings); g_clear_pointer (&self->datetime_override, g_date_time_unref); g_clear_pointer (&self->disabled_until_tmw_dt, g_date_time_unref); if (self->validate_id > 0) { g_source_remove (self->validate_id); self->validate_id = 0; } G_OBJECT_CLASS (csd_night_light_parent_class)->finalize (object); } static void csd_night_light_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CsdNightLight *self = CSD_NIGHT_LIGHT (object); switch (prop_id) { case PROP_SUNRISE: self->cached_sunrise = g_value_get_double (value); break; case PROP_SUNSET: self->cached_sunset = g_value_get_double (value); break; case PROP_TEMPERATURE: self->cached_temperature = g_value_get_double (value); break; case PROP_DISABLED_UNTIL_TMW: csd_night_light_set_disabled_until_tmw (self, g_value_get_boolean (value)); break; case PROP_FORCED: csd_night_light_set_forced (self, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void csd_night_light_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdNightLight *self = CSD_NIGHT_LIGHT (object); switch (prop_id) { case PROP_ACTIVE: g_value_set_boolean (value, self->cached_active); break; case PROP_SUNRISE: g_value_set_double (value, self->cached_sunrise); break; case PROP_SUNSET: g_value_set_double (value, self->cached_sunrise); break; case PROP_TEMPERATURE: g_value_set_double (value, self->cached_sunrise); break; case PROP_DISABLED_UNTIL_TMW: g_value_set_boolean (value, csd_night_light_get_disabled_until_tmw (self)); break; case PROP_FORCED: g_value_set_boolean (value, csd_night_light_get_forced (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void csd_night_light_class_init (CsdNightLightClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_night_light_finalize; object_class->set_property = csd_night_light_set_property; object_class->get_property = csd_night_light_get_property; g_object_class_install_property (object_class, PROP_ACTIVE, g_param_spec_boolean ("active", "Active", "If night light functionality is active right now", FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_SUNRISE, g_param_spec_double ("sunrise", "Sunrise", "Sunrise in fractional hours", 0, 24.f, 12, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SUNSET, g_param_spec_double ("sunset", "Sunset", "Sunset in fractional hours", 0, 24.f, 12, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_TEMPERATURE, g_param_spec_double ("temperature", "Temperature", "Temperature in Kelvin", CSD_COLOR_TEMPERATURE_MIN, CSD_COLOR_TEMPERATURE_MAX, CSD_COLOR_TEMPERATURE_DEFAULT, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_DISABLED_UNTIL_TMW, g_param_spec_boolean ("disabled-until-tmw", "Disabled until tomorrow", "If the night light is disabled until the next day", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_FORCED, g_param_spec_boolean ("forced", "Forced", "Whether night light should be forced on, useful for previewing", FALSE, G_PARAM_READWRITE)); } static void csd_night_light_init (CsdNightLight *self) { self->smooth_enabled = TRUE; self->cached_sunrise = -1.f; self->cached_sunset = -1.f; self->cached_temperature = CSD_COLOR_TEMPERATURE_DEFAULT; self->settings = g_settings_new ("org.cinnamon.settings-daemon.plugins.color"); } CsdNightLight * csd_night_light_new (void) { return g_object_new (CSD_TYPE_NIGHT_LIGHT, NULL); } cinnamon-settings-daemon-6.4.3/plugins/color/csd-night-light.h0000664000175000017500000000462514733247605023330 0ustar fabiofabio/* * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CSD_NIGHT_LIGHT_H__ #define __CSD_NIGHT_LIGHT_H__ #include G_BEGIN_DECLS #define CSD_TYPE_NIGHT_LIGHT (csd_night_light_get_type ()) G_DECLARE_FINAL_TYPE (CsdNightLight, csd_night_light, CSD, NIGHT_LIGHT, GObject) CsdNightLight *csd_night_light_new (void); gboolean csd_night_light_start (CsdNightLight *self, GError **error); gboolean csd_night_light_get_active (CsdNightLight *self); gdouble csd_night_light_get_sunrise (CsdNightLight *self); gdouble csd_night_light_get_sunset (CsdNightLight *self); gdouble csd_night_light_get_temperature (CsdNightLight *self); gboolean csd_night_light_get_disabled_until_tmw (CsdNightLight *self); void csd_night_light_set_disabled_until_tmw (CsdNightLight *self, gboolean value); gboolean csd_night_light_get_forced (CsdNightLight *self); void csd_night_light_set_forced (CsdNightLight *self, gboolean value); void csd_night_light_set_date_time_now (CsdNightLight *self, GDateTime *datetime); void csd_night_light_set_smooth_enabled (CsdNightLight *self, gboolean smooth_enabled); G_END_DECLS #endif cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-profiles.c0000664000175000017500000002072714733247605024045 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #include "config.h" #include #include #include "csd-color-profiles.h" struct _CsdColorProfiles { GObject parent; GCancellable *cancellable; CdClient *client; CdIccStore *icc_store; }; static void csd_color_profiles_class_init (CsdColorProfilesClass *klass); static void csd_color_profiles_init (CsdColorProfiles *color_profiles); static void csd_color_profiles_finalize (GObject *object); G_DEFINE_TYPE (CsdColorProfiles, csd_color_profiles, G_TYPE_OBJECT) static void csd_color_profiles_class_init (CsdColorProfilesClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_color_profiles_finalize; } static void ccm_session_client_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gboolean ret; GError *error = NULL; CdClient *client = CD_CLIENT (source_object); CsdColorProfiles *profiles; /* connected */ ret = cd_client_connect_finish (client, res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("failed to connect to colord: %s", error->message); g_error_free (error); return; } /* is there an available colord instance? */ profiles = CSD_COLOR_PROFILES (user_data); ret = cd_client_get_has_server (profiles->client); if (!ret) { g_warning ("There is no colord server available"); return; } /* add profiles */ ret = cd_icc_store_search_kind (profiles->icc_store, CD_ICC_STORE_SEARCH_KIND_USER, CD_ICC_STORE_SEARCH_FLAGS_CREATE_LOCATION, profiles->cancellable, &error); if (!ret) { g_warning ("failed to add user icc: %s", error->message); g_error_free (error); } } gboolean csd_color_profiles_start (CsdColorProfiles *profiles, GError **error) { /* use a fresh cancellable for each start->stop operation */ g_cancellable_cancel (profiles->cancellable); g_clear_object (&profiles->cancellable); profiles->cancellable = g_cancellable_new (); cd_client_connect (profiles->client, profiles->cancellable, ccm_session_client_connect_cb, profiles); return TRUE; } void csd_color_profiles_stop (CsdColorProfiles *profiles) { g_cancellable_cancel (profiles->cancellable); } static void ccm_session_create_profile_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdProfile *profile; GError *error = NULL; CdClient *client = CD_CLIENT (object); profile = cd_client_create_profile_finish (client, res, &error); if (profile == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && !g_error_matches (error, CD_CLIENT_ERROR, CD_CLIENT_ERROR_ALREADY_EXISTS)) g_warning ("%s", error->message); g_error_free (error); return; } g_object_unref (profile); } static void ccm_session_icc_store_added_cb (CdIccStore *icc_store, CdIcc *icc, CsdColorProfiles *profiles) { cd_client_create_profile_for_icc (profiles->client, icc, CD_OBJECT_SCOPE_TEMP, profiles->cancellable, ccm_session_create_profile_cb, profiles); } static void ccm_session_delete_profile_cb (GObject *object, GAsyncResult *res, gpointer user_data) { gboolean ret; GError *error = NULL; CdClient *client = CD_CLIENT (object); ret = cd_client_delete_profile_finish (client, res, &error); if (!ret) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s", error->message); g_error_free (error); } } static void ccm_session_find_profile_by_filename_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CdProfile *profile; CdClient *client = CD_CLIENT (object); CsdColorProfiles *profiles = CSD_COLOR_PROFILES (user_data); profile = cd_client_find_profile_by_filename_finish (client, res, &error); if (profile == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s", error->message); g_error_free (error); goto out; } /* remove it from colord */ cd_client_delete_profile (profiles->client, profile, profiles->cancellable, ccm_session_delete_profile_cb, profiles); out: if (profile != NULL) g_object_unref (profile); } static void ccm_session_icc_store_removed_cb (CdIccStore *icc_store, CdIcc *icc, CsdColorProfiles *profiles) { /* find the ID for the filename */ g_debug ("filename %s removed", cd_icc_get_filename (icc)); cd_client_find_profile_by_filename (profiles->client, cd_icc_get_filename (icc), profiles->cancellable, ccm_session_find_profile_by_filename_cb, profiles); } static void csd_color_profiles_init (CsdColorProfiles *profiles) { /* have access to all user profiles */ profiles->client = cd_client_new (); profiles->icc_store = cd_icc_store_new (); cd_icc_store_set_load_flags (profiles->icc_store, CD_ICC_LOAD_FLAGS_FALLBACK_MD5); g_signal_connect (profiles->icc_store, "added", G_CALLBACK (ccm_session_icc_store_added_cb), profiles); g_signal_connect (profiles->icc_store, "removed", G_CALLBACK (ccm_session_icc_store_removed_cb), profiles); } static void csd_color_profiles_finalize (GObject *object) { CsdColorProfiles *profiles; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_COLOR_PROFILES (object)); profiles = CSD_COLOR_PROFILES (object); g_cancellable_cancel (profiles->cancellable); g_clear_object (&profiles->cancellable); g_clear_object (&profiles->icc_store); g_clear_object (&profiles->client); G_OBJECT_CLASS (csd_color_profiles_parent_class)->finalize (object); } CsdColorProfiles * csd_color_profiles_new (void) { CsdColorProfiles *profiles; profiles = g_object_new (CSD_TYPE_COLOR_PROFILES, NULL); return CSD_COLOR_PROFILES (profiles); } cinnamon-settings-daemon-6.4.3/plugins/color/test-data/0000775000175000017500000000000014733247605022051 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/color/test-data/LG-L225W-External.bin0000664000175000017500000000020014733247605025366 0ustar fabiofabioÿÿÿÿÿÿmcV^† ê/xêÔ%¤UI›'PT§k€••€@qO|. `@0 6Ú(!90b'@h°6Ú(ý8KS üL225W tcinnamon-settings-daemon-6.4.3/plugins/color/test-data/Lenovo-T61-Internal.bin0000664000175000017500000000020014733247605026117 0ustar fabiofabioÿÿÿÿÿÿ$M‡(€!x Íu‘UO‹&!PT¨/à`@ @KÏ·'à`@ @Kϳ 2³ (L£X3þLTN154P2-L05 §cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-calibrate.h0000664000175000017500000000256714733247605024157 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #ifndef __CSD_COLOR_CALIBRATE_H #define __CSD_COLOR_CALIBRATE_H #include G_BEGIN_DECLS #define CSD_TYPE_COLOR_CALIBRATE (csd_color_calibrate_get_type ()) G_DECLARE_FINAL_TYPE (CsdColorCalibrate, csd_color_calibrate, CSD, COLOR_CALIBRATE, GObject) GType csd_color_calibrate_get_type (void); GQuark csd_color_calibrate_error_quark (void); CsdColorCalibrate * csd_color_calibrate_new (void); G_END_DECLS #endif /* __CSD_COLOR_CALIBRATE_H */ cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-calibrate.c0000664000175000017500000003576414733247605024157 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #include "config.h" #include #include #include #include #include "csd-color-calibrate.h" #define CCM_SESSION_NOTIFY_TIMEOUT 30000 /* ms */ #define CCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD "recalibrate-printer-threshold" #define CCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD "recalibrate-display-threshold" struct _CsdColorCalibrate { GObject parent; CdClient *client; GSettings *settings; }; static void csd_color_calibrate_class_init (CsdColorCalibrateClass *klass); static void csd_color_calibrate_init (CsdColorCalibrate *color_calibrate); static void csd_color_calibrate_finalize (GObject *object); G_DEFINE_TYPE (CsdColorCalibrate, csd_color_calibrate, G_TYPE_OBJECT) typedef struct { CsdColorCalibrate *calibrate; CdProfile *profile; CdDevice *device; guint32 output_id; } CcmSessionAsyncHelper; static void ccm_session_async_helper_free (CcmSessionAsyncHelper *helper) { if (helper->calibrate != NULL) g_object_unref (helper->calibrate); if (helper->profile != NULL) g_object_unref (helper->profile); if (helper->device != NULL) g_object_unref (helper->device); g_free (helper); } static void ccm_session_exec_control_center (CsdColorCalibrate *calibrate) { gboolean ret; GError *error = NULL; GAppInfo *app_info; GdkAppLaunchContext *launch_context; /* setup the launch context so the startup notification is correct */ launch_context = gdk_display_get_app_launch_context (gdk_display_get_default ()); app_info = g_app_info_create_from_commandline (BINDIR "/gnome-control-center color", "gnome-control-center", G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION, &error); if (app_info == NULL) { g_warning ("failed to create application info: %s", error->message); g_error_free (error); goto out; } /* launch gnome-control-center */ ret = g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (launch_context), &error); if (!ret) { g_warning ("failed to launch gnome-control-center: %s", error->message); g_error_free (error); goto out; } out: g_object_unref (launch_context); if (app_info != NULL) g_object_unref (app_info); } static void ccm_session_notify_cb (NotifyNotification *notification, gchar *action, gpointer user_data) { CsdColorCalibrate *calibrate = CSD_COLOR_CALIBRATE (user_data); if (g_strcmp0 (action, "recalibrate") == 0) { notify_notification_close (notification, NULL); ccm_session_exec_control_center (calibrate); } } static void closed_cb (NotifyNotification *notification, gpointer data) { g_object_unref (notification); } static gboolean ccm_session_notify_recalibrate (CsdColorCalibrate *calibrate, const gchar *title, const gchar *message, CdDeviceKind kind) { gboolean ret; GError *error = NULL; NotifyNotification *notification; /* show a bubble */ notification = notify_notification_new (title, message, "preferences-color"); notify_notification_set_timeout (notification, CCM_SESSION_NOTIFY_TIMEOUT); notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW); notify_notification_set_app_name (notification, _("Color")); notify_notification_set_hint_string (notification, "desktop-entry", "gnome-color-panel"); notify_notification_add_action (notification, "recalibrate", /* TRANSLATORS: button: this is to open CCM */ _("Recalibrate now"), ccm_session_notify_cb, calibrate, NULL); g_signal_connect (notification, "closed", G_CALLBACK (closed_cb), NULL); ret = notify_notification_show (notification, &error); if (!ret) { g_warning ("failed to show notification: %s", error->message); g_error_free (error); } return ret; } static gchar * ccm_session_device_get_title (CdDevice *device) { const gchar *vendor; const gchar *model; model = cd_device_get_model (device); vendor = cd_device_get_vendor (device); if (model != NULL && vendor != NULL) return g_strdup_printf ("%s - %s", vendor, model); if (vendor != NULL) return g_strdup (vendor); if (model != NULL) return g_strdup (model); return g_strdup (cd_device_get_id (device)); } static void ccm_session_notify_device (CsdColorCalibrate *calibrate, CdDevice *device) { CdDeviceKind kind; const gchar *title; gchar *device_title = NULL; gchar *message; guint threshold; glong since; /* TRANSLATORS: this is when the device has not been recalibrated in a while */ title = _("Recalibration required"); device_title = ccm_session_device_get_title (device); /* check we care */ kind = cd_device_get_kind (device); if (kind == CD_DEVICE_KIND_DISPLAY) { /* get from GSettings */ threshold = g_settings_get_uint (calibrate->settings, CCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD); /* TRANSLATORS: this is when the display has not been recalibrated in a while */ message = g_strdup_printf (_("The display '%s' should be recalibrated soon."), device_title); } else { /* get from GSettings */ threshold = g_settings_get_uint (calibrate->settings, CCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD); /* TRANSLATORS: this is when the printer has not been recalibrated in a while */ message = g_strdup_printf (_("The printer '%s' should be recalibrated soon."), device_title); } /* check if we need to notify */ since = (g_get_real_time () - cd_device_get_modified (device)) / G_USEC_PER_SEC; if (threshold > since) ccm_session_notify_recalibrate (calibrate, title, message, kind); g_free (device_title); g_free (message); } static void ccm_session_profile_connect_cb (GObject *object, GAsyncResult *res, gpointer user_data) { const gchar *filename; gboolean ret; gchar *basename = NULL; const gchar *data_source; GError *error = NULL; CdProfile *profile = CD_PROFILE (object); CcmSessionAsyncHelper *helper = (CcmSessionAsyncHelper *) user_data; CsdColorCalibrate *calibrate = CSD_COLOR_CALIBRATE (helper->calibrate); ret = cd_profile_connect_finish (profile, res, &error); if (!ret) { g_warning ("failed to connect to profile: %s", error->message); g_error_free (error); goto out; } /* ensure it's a profile generated by us */ data_source = cd_profile_get_metadata_item (profile, CD_PROFILE_METADATA_DATA_SOURCE); if (data_source == NULL) { /* existing profiles from gnome-color-calibrate < 3.1 * won't have the extra metadata values added */ filename = cd_profile_get_filename (profile); if (filename == NULL) goto out; basename = g_path_get_basename (filename); if (!g_str_has_prefix (basename, "CCM")) { g_debug ("not a CCM profile for %s: %s", cd_device_get_id (helper->device), filename); goto out; } /* ensure it's been created from a calibration, rather than from * auto-EDID */ } else if (g_strcmp0 (data_source, CD_PROFILE_METADATA_DATA_SOURCE_CALIB) != 0) { g_debug ("not a calib profile for %s", cd_device_get_id (helper->device)); goto out; } /* handle device */ ccm_session_notify_device (calibrate, helper->device); out: ccm_session_async_helper_free (helper); g_free (basename); } static void ccm_session_device_connect_cb (GObject *object, GAsyncResult *res, gpointer user_data) { gboolean ret; GError *error = NULL; CdDeviceKind kind; CdProfile *profile = NULL; CdDevice *device = CD_DEVICE (object); CsdColorCalibrate *calibrate = CSD_COLOR_CALIBRATE (user_data); CcmSessionAsyncHelper *helper; ret = cd_device_connect_finish (device, res, &error); if (!ret) { g_warning ("failed to connect to device: %s", error->message); g_error_free (error); goto out; } /* check we care */ kind = cd_device_get_kind (device); if (kind != CD_DEVICE_KIND_DISPLAY && kind != CD_DEVICE_KIND_PRINTER) goto out; /* ensure we have a profile */ profile = cd_device_get_default_profile (device); if (profile == NULL) { g_debug ("no profile set for %s", cd_device_get_id (device)); goto out; } /* connect to the profile */ helper = g_new0 (CcmSessionAsyncHelper, 1); helper->calibrate = g_object_ref (calibrate); helper->device = g_object_ref (device); cd_profile_connect (profile, NULL, ccm_session_profile_connect_cb, helper); out: if (profile != NULL) g_object_unref (profile); } static void ccm_session_device_added_notify_cb (CdClient *client, CdDevice *device, CsdColorCalibrate *calibrate) { /* connect to the device to get properties */ cd_device_connect (device, NULL, ccm_session_device_connect_cb, calibrate); } static void ccm_session_sensor_added_cb (CdClient *client, CdSensor *sensor, CsdColorCalibrate *calibrate) { ca_context_play (ca_gtk_context_get (), 0, CA_PROP_EVENT_ID, "device-added", /* TRANSLATORS: this is the application name */ CA_PROP_APPLICATION_NAME, _("Cinnamon Settings Daemon Color Plugin"), /* TRANSLATORS: this is a sound description */ CA_PROP_EVENT_DESCRIPTION, _("Color calibration device added"), NULL); /* open up the color prefs window */ ccm_session_exec_control_center (calibrate); } static void ccm_session_sensor_removed_cb (CdClient *client, CdSensor *sensor, CsdColorCalibrate *calibrate) { ca_context_play (ca_gtk_context_get (), 0, CA_PROP_EVENT_ID, "device-removed", /* TRANSLATORS: this is the application name */ CA_PROP_APPLICATION_NAME, _("Cinnamon Settings Daemon Color Plugin"), /* TRANSLATORS: this is a sound description */ CA_PROP_EVENT_DESCRIPTION, _("Color calibration device removed"), NULL); } static void csd_color_calibrate_class_init (CsdColorCalibrateClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_color_calibrate_finalize; } static void csd_color_calibrate_init (CsdColorCalibrate *calibrate) { calibrate->settings = g_settings_new ("org.cinnamon.settings-daemon.plugins.color"); calibrate->client = cd_client_new (); g_signal_connect (calibrate->client, "device-added", G_CALLBACK (ccm_session_device_added_notify_cb), calibrate); g_signal_connect (calibrate->client, "sensor-added", G_CALLBACK (ccm_session_sensor_added_cb), calibrate); g_signal_connect (calibrate->client, "sensor-removed", G_CALLBACK (ccm_session_sensor_removed_cb), calibrate); } static void csd_color_calibrate_finalize (GObject *object) { CsdColorCalibrate *calibrate; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_COLOR_CALIBRATE (object)); calibrate = CSD_COLOR_CALIBRATE (object); g_clear_object (&calibrate->settings); g_clear_object (&calibrate->client); G_OBJECT_CLASS (csd_color_calibrate_parent_class)->finalize (object); } CsdColorCalibrate * csd_color_calibrate_new (void) { CsdColorCalibrate *calibrate; calibrate = g_object_new (CSD_TYPE_COLOR_CALIBRATE, NULL); return CSD_COLOR_CALIBRATE (calibrate); } cinnamon-settings-daemon-6.4.3/plugins/color/csd-color-manager.c0000664000175000017500000004454014733247605023633 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * Copyright (C) 2011-2013 Richard Hughes * * 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 . * */ #include "config.h" #include #include #include #include "cinnamon-settings-profile.h" #include "csd-color-calibrate.h" #include "csd-color-manager.h" #include "csd-color-profiles.h" #include "csd-color-state.h" #include "csd-night-light.h" #define CSD_DBUS_NAME "org.cinnamon.SettingsDaemon" #define CSD_DBUS_PATH "/org/cinnamon/SettingsDaemon" #define CSD_DBUS_BASE_INTERFACE "org.cinnamon.SettingsDaemon" #define CSD_COLOR_DBUS_NAME CSD_DBUS_NAME ".Color" #define CSD_COLOR_DBUS_PATH CSD_DBUS_PATH "/Color" #define CSD_COLOR_DBUS_INTERFACE CSD_DBUS_BASE_INTERFACE ".Color" static const gchar introspection_xml[] = "" " " " " " " " " " " " " " " " " " " " " ""; struct _CsdColorManager { GObject parent; /* D-Bus */ guint name_id; GDBusNodeInfo *introspection_data; GDBusConnection *connection; GCancellable *bus_cancellable; CsdColorCalibrate *calibrate; CsdColorProfiles *profiles; CsdColorState *state; CsdNightLight *nlight; guint nlight_forced_timeout_id; }; enum { PROP_0, }; static void csd_color_manager_class_init (CsdColorManagerClass *klass); static void csd_color_manager_init (CsdColorManager *color_manager); static void csd_color_manager_finalize (GObject *object); G_DEFINE_TYPE (CsdColorManager, csd_color_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; GQuark csd_color_manager_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("csd_color_manager_error"); return quark; } gboolean csd_color_manager_start (CsdColorManager *manager, GError **error) { gboolean ret; g_debug ("Starting color manager"); cinnamon_settings_profile_start (NULL); /* start the device probing */ csd_color_state_start (manager->state); /* start the profiles collection */ ret = csd_color_profiles_start (manager->profiles, error); if (!ret) goto out; out: cinnamon_settings_profile_end (NULL); return ret; } void csd_color_manager_stop (CsdColorManager *manager) { g_debug ("Stopping color manager"); csd_color_state_stop (manager->state); csd_color_profiles_stop (manager->profiles); } static void csd_color_manager_class_init (CsdColorManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_color_manager_finalize; } static void emit_property_changed (CsdColorManager *manager, const gchar *property_name, GVariant *property_value) { GVariantBuilder builder; GVariantBuilder invalidated_builder; /* not yet connected */ if (manager->connection == NULL) return; /* build the dict */ g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as")); g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); g_variant_builder_add (&builder, "{sv}", property_name, property_value); g_dbus_connection_emit_signal (manager->connection, NULL, CSD_COLOR_DBUS_PATH, "org.freedesktop.DBus.Properties", "PropertiesChanged", g_variant_new ("(sa{sv}as)", CSD_COLOR_DBUS_INTERFACE, &builder, &invalidated_builder), NULL); g_variant_builder_clear (&builder); g_variant_builder_clear (&invalidated_builder); } static void on_active_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); emit_property_changed (manager, "NightLightActive", g_variant_new_boolean (csd_night_light_get_active (manager->nlight))); } static void on_sunset_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); emit_property_changed (manager, "Sunset", g_variant_new_double (csd_night_light_get_sunset (manager->nlight))); } static void on_sunrise_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); emit_property_changed (manager, "Sunrise", g_variant_new_double (csd_night_light_get_sunrise (manager->nlight))); } static void on_disabled_until_tmw_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); emit_property_changed (manager, "DisabledUntilTomorrow", g_variant_new_boolean (csd_night_light_get_disabled_until_tmw (manager->nlight))); } static void on_temperature_notify (CsdNightLight *nlight, GParamSpec *pspec, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); gdouble temperature = csd_night_light_get_temperature (manager->nlight); csd_color_state_set_temperature (manager->state, temperature); emit_property_changed (manager, "Temperature", g_variant_new_double (temperature)); } static void csd_color_manager_init (CsdColorManager *manager) { /* setup calibration features */ manager->calibrate = csd_color_calibrate_new (); manager->profiles = csd_color_profiles_new (); manager->state = csd_color_state_new (); /* night light features */ manager->nlight = csd_night_light_new (); g_signal_connect (manager->nlight, "notify::active", G_CALLBACK (on_active_notify), manager); g_signal_connect (manager->nlight, "notify::sunset", G_CALLBACK (on_sunset_notify), manager); g_signal_connect (manager->nlight, "notify::sunrise", G_CALLBACK (on_sunrise_notify), manager); g_signal_connect (manager->nlight, "notify::temperature", G_CALLBACK (on_temperature_notify), manager); g_signal_connect (manager->nlight, "notify::disabled-until-tmw", G_CALLBACK (on_disabled_until_tmw_notify), manager); } static void csd_color_manager_finalize (GObject *object) { CsdColorManager *manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_COLOR_MANAGER (object)); manager = CSD_COLOR_MANAGER (object); csd_color_manager_stop (manager); if (manager->bus_cancellable != NULL) { g_cancellable_cancel (manager->bus_cancellable); g_clear_object (&manager->bus_cancellable); } g_clear_pointer (&manager->introspection_data, g_dbus_node_info_unref); g_clear_object (&manager->connection); if (manager->name_id != 0) { g_bus_unown_name (manager->name_id); manager->name_id = 0; } if (manager->nlight_forced_timeout_id) g_source_remove (manager->nlight_forced_timeout_id); g_clear_object (&manager->calibrate); g_clear_object (&manager->profiles); g_clear_object (&manager->state); g_clear_object (&manager->nlight); G_OBJECT_CLASS (csd_color_manager_parent_class)->finalize (object); } static gboolean nlight_forced_timeout_cb (gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); manager->nlight_forced_timeout_id = 0; csd_night_light_set_forced (manager->nlight, FALSE); return G_SOURCE_REMOVE; } static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); if (g_strcmp0 (method_name, "NightLightPreview") == 0) { guint32 duration = 0; if (!manager->nlight) { g_dbus_method_invocation_return_error_literal (invocation, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, "Night-light is currently unavailable"); return; } g_variant_get (parameters, "(u)", &duration); if (duration == 0 || duration > 120) { g_dbus_method_invocation_return_error_literal (invocation, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Duration is out of the range (0-120]."); return; } if (manager->nlight_forced_timeout_id) g_source_remove (manager->nlight_forced_timeout_id); manager->nlight_forced_timeout_id = g_timeout_add_seconds (duration, nlight_forced_timeout_cb, manager); csd_night_light_set_forced (manager->nlight, TRUE); g_dbus_method_invocation_return_value (invocation, NULL); } else { g_assert_not_reached (); } } static GVariant * handle_get_property (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *property_name, GError **error, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); if (g_strcmp0 (interface_name, CSD_COLOR_DBUS_INTERFACE) != 0) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such interface: %s", interface_name); return NULL; } if (g_strcmp0 (property_name, "NightLightActive") == 0) return g_variant_new_boolean (csd_night_light_get_active (manager->nlight)); if (g_strcmp0 (property_name, "Temperature") == 0) { guint temperature; temperature = csd_color_state_get_temperature (manager->state); return g_variant_new_uint32 (temperature); } if (g_strcmp0 (property_name, "DisabledUntilTomorrow") == 0) return g_variant_new_boolean (csd_night_light_get_disabled_until_tmw (manager->nlight)); if (g_strcmp0 (property_name, "Sunrise") == 0) return g_variant_new_double (csd_night_light_get_sunrise (manager->nlight)); if (g_strcmp0 (property_name, "Sunset") == 0) return g_variant_new_double (csd_night_light_get_sunset (manager->nlight)); g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Failed to get property: %s", property_name); return NULL; } static gboolean handle_set_property (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *property_name, GVariant *value, GError **error, gpointer user_data) { CsdColorManager *manager = CSD_COLOR_MANAGER (user_data); if (g_strcmp0 (interface_name, CSD_COLOR_DBUS_INTERFACE) != 0) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such interface: %s", interface_name); return FALSE; } if (g_strcmp0 (property_name, "Temperature") == 0) { guint32 temperature; g_variant_get (value, "u", &temperature); if (temperature < CSD_COLOR_TEMPERATURE_MIN) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "%" G_GUINT32_FORMAT "K is < min %" G_GUINT32_FORMAT "K", temperature, CSD_COLOR_TEMPERATURE_MIN); return FALSE; } if (temperature > CSD_COLOR_TEMPERATURE_MAX) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "%" G_GUINT32_FORMAT "K is > max %" G_GUINT32_FORMAT "K", temperature, CSD_COLOR_TEMPERATURE_MAX); return FALSE; } csd_color_state_set_temperature (manager->state, temperature); return TRUE; } if (g_strcmp0 (property_name, "DisabledUntilTomorrow") == 0) { csd_night_light_set_disabled_until_tmw (manager->nlight, g_variant_get_boolean (value)); return TRUE; } g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such property: %s", property_name); return FALSE; } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, handle_get_property, handle_set_property }; static void name_lost_handler_cb (GDBusConnection *connection, const gchar *name, gpointer user_data) { g_debug ("lost name, so exiting"); gtk_main_quit (); } static void on_bus_gotten (GObject *source_object, GAsyncResult *res, CsdColorManager *manager) { GDBusConnection *connection; GError *error = NULL; connection = g_bus_get_finish (res, &error); if (connection == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Could not get session bus: %s", error->message); g_error_free (error); return; } manager->connection = connection; g_dbus_connection_register_object (connection, CSD_COLOR_DBUS_PATH, manager->introspection_data->interfaces[0], &interface_vtable, manager, NULL, NULL); manager->name_id = g_bus_own_name_on_connection (connection, CSD_COLOR_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, name_lost_handler_cb, manager, NULL); /* setup night light module */ if (!csd_night_light_start (manager->nlight, &error)) { g_warning ("Could not start night light module: %s", error->message); g_error_free (error); } } static void register_manager_dbus (CsdColorManager *manager) { manager->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); g_assert (manager->introspection_data != NULL); manager->bus_cancellable = g_cancellable_new (); g_bus_get (G_BUS_TYPE_SESSION, manager->bus_cancellable, (GAsyncReadyCallback) on_bus_gotten, manager); } CsdColorManager * csd_color_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_COLOR_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); register_manager_dbus (manager_object); } return CSD_COLOR_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/print-notifications/0000775000175000017500000000000014733247605023050 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/print-notifications/meson.build0000664000175000017500000000263114733247605025214 0ustar fabiofabioplugin_name = 'print-notifications' print_notifications_sources = [ 'csd-print-notifications-manager.c', 'main.c', ] printer_sources = [ 'csd-printer.c', ] print_notifications_deps = [ common_dep, config_h, csd_dep, cups, libnotify, ] executable( 'csd-print-notifications', print_notifications_sources, include_directories: [include_dirs, common_inc], dependencies: print_notifications_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-print-notifications') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-print-notifications') endif executable( 'csd-printer', printer_sources, include_directories: [include_dirs, common_inc], dependencies: print_notifications_deps, install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-printer') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-printer') endif configure_file( input: 'cinnamon-settings-daemon-print-notifications.desktop.in', output: 'cinnamon-settings-daemon-print-notifications.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/print-notifications/csd-print-notifications-manager.h0000664000175000017500000000511214733247605031402 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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 . * */ #ifndef __CSD_PRINT_NOTIFICATIONS_MANAGER_H #define __CSD_PRINT_NOTIFICATIONS_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER (csd_print_notifications_manager_get_type ()) #define CSD_PRINT_NOTIFICATIONS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER, CsdPrintNotificationsManager)) #define CSD_PRINT_NOTIFICATIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER, CsdPrintNotificationsManagerClass)) #define CSD_IS_PRINT_NOTIFICATIONS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER)) #define CSD_IS_PRINT_NOTIFICATIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER)) #define CSD_PRINT_NOTIFICATIONS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER, CsdPrintNotificationsManagerClass)) typedef struct CsdPrintNotificationsManagerPrivate CsdPrintNotificationsManagerPrivate; typedef struct { GObject parent; CsdPrintNotificationsManagerPrivate *priv; } CsdPrintNotificationsManager; typedef struct { GObjectClass parent_class; } CsdPrintNotificationsManagerClass; GType csd_print_notifications_manager_get_type (void); CsdPrintNotificationsManager *csd_print_notifications_manager_new (void); gboolean csd_print_notifications_manager_start (CsdPrintNotificationsManager *manager, GError **error); void csd_print_notifications_manager_stop (CsdPrintNotificationsManager *manager); G_END_DECLS #endif /* __CSD_PRINT_NOTIFICATIONS_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/print-notifications/main.c0000664000175000017500000000122114733247605024134 0ustar fabiofabio#define NEW csd_print_notifications_manager_new #define START csd_print_notifications_manager_start #define STOP csd_print_notifications_manager_stop #define MANAGER CsdPrintNotificationsManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-print-notifications-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/print-notifications/csd-print-notifications-manager.c0000664000175000017500000022631114733247605031403 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Red Hat, Inc. * * 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 . * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-print-notifications-manager.h" #define CSD_PRINT_NOTIFICATIONS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER, CsdPrintNotificationsManagerPrivate)) #define CUPS_DBUS_NAME "org.cups.cupsd.Notifier" #define CUPS_DBUS_PATH "/org/cups/cupsd/Notifier" #define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier" #define RENEW_INTERVAL 3500 #define SUBSCRIPTION_DURATION 3600 #define CONNECTING_TIMEOUT 60 #define REASON_TIMEOUT 15000 #define CUPS_CONNECTION_TEST_INTERVAL 300 #define CHECK_INTERVAL 60 /* secs */ #define PRINTER_REMOVED_LIFETIME 7200000000 // (7200 sec * 1000 * 1000 (microseconds) */ #define PRINTER_REMOVED_UPDATE_INTERVAL 1260 /* 21 min (sec) */ #if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5) #define HAVE_CUPS_1_6 1 #endif #ifndef HAVE_CUPS_1_6 #define ippGetStatusCode(ipp) ipp->request.status.status_code #define ippGetInteger(attr, element) attr->values[element].integer #define ippGetString(attr, element, language) attr->values[element].string.text #define ippGetName(attr) attr->name #define ippGetCount(attr) attr->num_values #define ippGetBoolean(attr, index) attr->values[index].boolean static ipp_attribute_t * ippNextAttribute (ipp_t *ipp) { if (!ipp || !ipp->current) return (NULL); return (ipp->current = ipp->current->next); } #endif struct CsdPrintNotificationsManagerPrivate { GDBusConnection *cups_bus_connection; gint subscription_id; cups_dest_t *dests; gint num_dests; gboolean scp_handler_spawned; GPid scp_handler_pid; GList *timeouts; GHashTable *printing_printers; GHashTable *removed_printers; guint removed_printer_timeout_id; GList *active_notifications; guint cups_connection_timeout_id; guint check_source_id; guint cups_dbus_subscription_id; guint renew_source_id; gint last_notify_sequence_number; guint start_idle_id; }; static void csd_print_notifications_manager_finalize (GObject *object); static gboolean cups_connection_test (gpointer user_data); static gboolean process_new_notifications (gpointer user_data); G_DEFINE_TYPE (CsdPrintNotificationsManager, csd_print_notifications_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static const char * password_cb (const char *prompt, http_t *http, const char *method, const char *resource, void *user_data) { return NULL; } static char * get_dest_attr (const char *dest_name, const char *attr, cups_dest_t *dests, int num_dests) { cups_dest_t *dest; const char *value; char *ret; if (dest_name == NULL) return NULL; ret = NULL; dest = cupsGetDest (dest_name, NULL, num_dests, dests); if (dest == NULL) { g_debug ("Unable to find a printer named '%s'", dest_name); goto out; } value = cupsGetOption (attr, dest->num_options, dest->options); if (value == NULL) { g_debug ("Unable to get %s for '%s'", attr, dest_name); goto out; } ret = g_strdup (value); out: return ret; } static gboolean is_local_dest (const char *name, cups_dest_t *dests, int num_dests) { char *type_str; cups_ptype_t type; gboolean is_remote; is_remote = TRUE; type_str = get_dest_attr (name, "printer-type", dests, num_dests); if (type_str == NULL) { goto out; } type = atoi (type_str); is_remote = type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT); g_free (type_str); out: return !is_remote; } static gboolean server_is_local (const gchar *server_name) { if (server_name != NULL && (g_ascii_strncasecmp (server_name, "localhost", 9) == 0 || g_ascii_strncasecmp (server_name, "127.0.0.1", 9) == 0 || g_ascii_strncasecmp (server_name, "::1", 3) == 0 || server_name[0] == '/')) { return TRUE; } else { return FALSE; } } static int strcmp0(const void *a, const void *b) { return g_strcmp0 (*((gchar **) a), *((gchar **) b)); } typedef struct { gchar *printer_name; gchar *primary_text; gchar *secondary_text; guint timeout_id; CsdPrintNotificationsManager *manager; } TimeoutData; typedef struct { gchar *printer_name; gchar *reason; NotifyNotification *notification; gulong notification_close_id; CsdPrintNotificationsManager *manager; } ReasonData; static void free_timeout_data (gpointer user_data) { TimeoutData *data = (TimeoutData *) user_data; if (data) { g_free (data->printer_name); g_free (data->primary_text); g_free (data->secondary_text); g_free (data); } } static void free_reason_data (gpointer user_data) { ReasonData *data = (ReasonData *) user_data; if (data) { if (data->notification_close_id > 0 && g_signal_handler_is_connected (data->notification, data->notification_close_id)) g_signal_handler_disconnect (data->notification, data->notification_close_id); g_object_unref (data->notification); g_free (data->printer_name); g_free (data->reason); g_free (data); } } static void notification_closed_cb (NotifyNotification *notification, gpointer user_data) { ReasonData *data = (ReasonData *) user_data; if (data) { data->manager->priv->active_notifications = g_list_remove (data->manager->priv->active_notifications, data); free_reason_data (data); } } static gboolean show_notification (gpointer user_data) { NotifyNotification *notification; TimeoutData *data = (TimeoutData *) user_data; ReasonData *reason_data; GList *tmp; if (!data) return FALSE; notification = notify_notification_new (data->primary_text, data->secondary_text, "printer-symbolic"); notify_notification_set_app_name (notification, _("Printers")); notify_notification_set_hint (notification, "resident", g_variant_new_boolean (TRUE)); notify_notification_set_timeout (notification, REASON_TIMEOUT); reason_data = g_new0 (ReasonData, 1); reason_data->printer_name = g_strdup (data->printer_name); reason_data->reason = g_strdup ("connecting-to-device"); reason_data->notification = notification; reason_data->manager = data->manager; reason_data->notification_close_id = g_signal_connect (notification, "closed", G_CALLBACK (notification_closed_cb), reason_data); reason_data->manager->priv->active_notifications = g_list_append (reason_data->manager->priv->active_notifications, reason_data); notify_notification_show (notification, NULL); tmp = g_list_find (data->manager->priv->timeouts, data); if (tmp) { data->manager->priv->timeouts = g_list_remove_link (data->manager->priv->timeouts, tmp); g_list_free_full (tmp, free_timeout_data); } return FALSE; } static gboolean reason_is_blacklisted (const gchar *reason) { if (g_str_equal (reason, "none")) return TRUE; if (g_str_equal (reason, "other")) return TRUE; if (g_str_equal (reason, "com.apple.print.recoverable")) return TRUE; /* https://bugzilla.redhat.com/show_bug.cgi?id=883401 */ if (g_str_has_prefix (reason, "cups-remote-")) return TRUE; /* https://bugzilla.redhat.com/show_bug.cgi?id=1207154 */ if (g_str_equal (reason, "cups-waiting-for-job-completed")) return TRUE; return FALSE; } static void on_cups_notification (GDBusConnection *connection, const char *sender_name, const char *object_path, const char *interface_name, const char *signal_name, GVariant *parameters, gpointer user_data) { process_new_notifications (user_data); } typedef struct { CsdPrintNotificationsManager *manager; gint64 removed_time; } RemovePrinterData; static gboolean drop_expired_removal (const gchar *printer_name, RemovePrinterData *foreach_data, gpointer user_data) { RemovePrinterData *current_data = (RemovePrinterData *) user_data; if (current_data->removed_time > foreach_data->removed_time + PRINTER_REMOVED_LIFETIME) { g_debug ("Removing printer from removed-printers queue: %s (removed over %lds ago)", printer_name, PRINTER_REMOVED_LIFETIME / 1000 / 1000); return TRUE; } return FALSE; } static gboolean removed_cache_update (CsdPrintNotificationsManager *manager) { gint64 current_time = g_get_monotonic_time (); RemovePrinterData *current_data = g_new0 (RemovePrinterData, 1); g_debug ("Periodic update of removed-printers"); current_data->manager = manager; current_data->removed_time = current_time; g_hash_table_foreach_remove (manager->priv->removed_printers, (GHRFunc) drop_expired_removal, current_data); if (g_hash_table_size (manager->priv->removed_printers) == 0) { g_debug ("No more printers in removed-printers queue, stopping update timer."); manager->priv->removed_printer_timeout_id = 0; return G_SOURCE_REMOVE; } return G_SOURCE_CONTINUE; } static gboolean should_notify_new_printer (CsdPrintNotificationsManager *manager, const gchar *printer_name) { g_debug ("Checking if user should be notified about a new printer: %s", printer_name); RemovePrinterData *data = g_hash_table_lookup (manager->priv->removed_printers, printer_name); if (data) { g_hash_table_remove (manager->priv->removed_printers, printer_name); return FALSE; } return TRUE; } static void add_or_update_removed_cache (CsdPrintNotificationsManager *manager, const gchar *printer_name) { RemovePrinterData *data = g_new0 (RemovePrinterData, 1); data->removed_time = g_get_monotonic_time (); gboolean new; new = g_hash_table_replace (manager->priv->removed_printers, g_strdup (printer_name), data); if (new) { g_debug ("Printer %s has been removed, adding to removed-printers queue.", printer_name); } else { g_debug ("Printer %s has been re-removed, updating its removed timestamp.", printer_name); } if (g_hash_table_size (manager->priv->removed_printers) > 0 && manager->priv->removed_printer_timeout_id == 0) { g_debug ("Starting removed-printer timer"); manager->priv->removed_printer_timeout_id = g_timeout_add_seconds (PRINTER_REMOVED_UPDATE_INTERVAL, (GSourceFunc) removed_cache_update, manager); } } static gchar * get_statuses_second (guint i, const gchar *printer_name) { gchar *status; switch (i) { case 0: /* Translators: The printer is low on toner (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' is low on toner."), printer_name); break; case 1: /* Translators: The printer has no toner left (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' has no toner left."), printer_name); break; case 2: /* Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' may not be connected."), printer_name); break; case 3: /* Translators: One or more covers on the printer are open (same as in system-config-printer) */ status = g_strdup_printf (_("The cover is open on printer '%s'."), printer_name); break; case 4: /* Translators: A filter or backend is not installed (same as in system-config-printer) */ status = g_strdup_printf (_("There is a missing print filter for " "printer '%s'."), printer_name); break; case 5: /* Translators: One or more doors on the printer are open (same as in system-config-printer) */ status = g_strdup_printf (_("The door is open on printer '%s'."), printer_name); break; case 6: /* Translators: "marker" is one color bin of the printer */ status = g_strdup_printf (_("Printer '%s' is low on a marker supply."), printer_name); break; case 7: /* Translators: "marker" is one color bin of the printer */ status = g_strdup_printf (_("Printer '%s' is out of a marker supply."), printer_name); break; case 8: /* Translators: At least one input tray is low on media (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' is low on paper."), printer_name); break; case 9: /* Translators: At least one input tray is empty (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' is out of paper."), printer_name); break; case 10: /* Translators: The printer is offline (same as in system-config-printer) */ status = g_strdup_printf (_("Printer '%s' is currently off-line."), printer_name); break; case 11: /* Translators: The printer has detected an error (same as in system-config-printer) */ status = g_strdup_printf (_("There is a problem on printer '%s'."), printer_name); break; default: g_assert_not_reached (); } return status; } static void process_cups_notification (CsdPrintNotificationsManager *manager, const char *notify_subscribed_event, const char *notify_text, const char *notify_printer_uri, const char *printer_name, gint printer_state, const char *printer_state_reasons, gboolean printer_is_accepting_jobs, guint notify_job_id, gint job_state, const char *job_state_reasons, const char *job_name, gint job_impressions_completed) { ipp_attribute_t *attr; gboolean my_job = FALSE; gboolean known_reason; http_t *http; gchar *primary_text = NULL; gchar *secondary_text = NULL; gchar *job_uri = NULL; ipp_t *request, *response; static const char * const reasons[] = { "toner-low", "toner-empty", "connecting-to-device", "cover-open", "cups-missing-filter", "door-open", "marker-supply-low", "marker-supply-empty", "media-low", "media-empty", "offline", "other"}; static const char * statuses_first[] = { /* Translators: The printer is low on toner (same as in system-config-printer) */ N_("Toner low"), /* Translators: The printer has no toner left (same as in system-config-printer) */ N_("Toner empty"), /* Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) */ N_("Not connected?"), /* Translators: One or more covers on the printer are open (same as in system-config-printer) */ N_("Cover open"), /* Translators: A filter or backend is not installed (same as in system-config-printer) */ N_("Printer configuration error"), /* Translators: One or more doors on the printer are open (same as in system-config-printer) */ N_("Door open"), /* Translators: "marker" is one color bin of the printer */ N_("Marker supply low"), /* Translators: "marker" is one color bin of the printer */ N_("Out of a marker supply"), /* Translators: At least one input tray is low on media (same as in system-config-printer) */ N_("Paper low"), /* Translators: At least one input tray is empty (same as in system-config-printer) */ N_("Out of paper"), /* Translators: The printer is offline (same as in system-config-printer) */ N_("Printer off-line"), /* Translators: The printer has detected an error (same as in system-config-printer) */ N_("Printer error") }; if (g_strcmp0 (notify_subscribed_event, "printer-added") != 0 && g_strcmp0 (notify_subscribed_event, "printer-deleted") != 0 && g_strcmp0 (notify_subscribed_event, "printer-state-changed") != 0 && g_strcmp0 (notify_subscribed_event, "job-completed") != 0 && g_strcmp0 (notify_subscribed_event, "job-state-changed") != 0 && g_strcmp0 (notify_subscribed_event, "job-created") != 0) return; if (notify_job_id > 0) { if ((http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ())) == NULL) { g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ()); } else { job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", notify_job_id); request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "job-originating-user-name"); response = cupsDoRequest (http, request, "/"); if (response) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT && (attr = ippFindAttribute(response, "job-originating-user-name", IPP_TAG_NAME))) { if (g_strcmp0 (ippGetString (attr, 0, NULL), cupsUser ()) == 0) my_job = TRUE; } ippDelete(response); } g_free (job_uri); httpClose (http); } } if (g_strcmp0 (notify_subscribed_event, "printer-added") == 0) { cupsFreeDests (manager->priv->num_dests, manager->priv->dests); manager->priv->num_dests = cupsGetDests (&manager->priv->dests); if (is_local_dest (printer_name, manager->priv->dests, manager->priv->num_dests)) { /* Translators: New printer has been added */ if (should_notify_new_printer (manager, printer_name)) { primary_text = g_strdup (_("Printer added")); secondary_text = g_strdup (printer_name); } else { g_debug ("A recently-removed printer %s has been re-added, skipping notification.", printer_name); } } } else if (g_strcmp0 (notify_subscribed_event, "printer-deleted") == 0) { cupsFreeDests (manager->priv->num_dests, manager->priv->dests); manager->priv->num_dests = cupsGetDests (&manager->priv->dests); add_or_update_removed_cache (manager, printer_name); } else if (g_strcmp0 (notify_subscribed_event, "job-completed") == 0 && my_job) { g_hash_table_remove (manager->priv->printing_printers, printer_name); switch (job_state) { case IPP_JOB_PENDING: case IPP_JOB_HELD: case IPP_JOB_PROCESSING: break; case IPP_JOB_STOPPED: /* Translators: A print job has been stopped */ primary_text = g_strdup (_("Printing stopped")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_CANCELED: /* Translators: A print job has been canceled */ primary_text = g_strdup (_("Printing canceled")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_ABORTED: /* Translators: A print job has been aborted */ primary_text = g_strdup (_("Printing aborted")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_COMPLETED: /* Translators: A print job has been completed */ primary_text = g_strdup (_("Printing completed")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; } } else if (g_strcmp0 (notify_subscribed_event, "job-state-changed") == 0 && my_job) { switch (job_state) { case IPP_JOB_PROCESSING: g_hash_table_insert (manager->priv->printing_printers, g_strdup (printer_name), NULL); /* Translators: A job is printing */ primary_text = g_strdup (_("Printing")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_STOPPED: g_hash_table_remove (manager->priv->printing_printers, printer_name); /* Translators: A print job has been stopped */ primary_text = g_strdup (_("Printing stopped")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_CANCELED: g_hash_table_remove (manager->priv->printing_printers, printer_name); /* Translators: A print job has been canceled */ primary_text = g_strdup (_("Printing canceled")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_ABORTED: g_hash_table_remove (manager->priv->printing_printers, printer_name); /* Translators: A print job has been aborted */ primary_text = g_strdup (_("Printing aborted")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; case IPP_JOB_COMPLETED: g_hash_table_remove (manager->priv->printing_printers, printer_name); /* Translators: A print job has been completed */ primary_text = g_strdup (_("Printing completed")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); break; default: break; } } else if (g_strcmp0 (notify_subscribed_event, "job-created") == 0 && my_job) { if (job_state == IPP_JOB_PROCESSING) { g_hash_table_insert (manager->priv->printing_printers, g_strdup (printer_name), NULL); /* Translators: A job is printing */ primary_text = g_strdup (_("Printing")); /* Translators: "print-job xy" on a printer */ secondary_text = g_strdup_printf (_("'%s' on %s"), job_name, printer_name); } } else if (g_strcmp0 (notify_subscribed_event, "printer-state-changed") == 0) { cups_dest_t *dest = NULL; const gchar *tmp_printer_state_reasons = NULL; GSList *added_reasons = NULL; GSList *tmp_list = NULL; GList *tmp; gchar **old_state_reasons = NULL; gchar **new_state_reasons = NULL; gint i, j; /* Remove timeout which shows notification about possible disconnection of printer * if "connecting-to-device" has vanished. */ if (printer_state_reasons == NULL || g_strrstr (printer_state_reasons, "connecting-to-device") == NULL) { TimeoutData *data; for (tmp = manager->priv->timeouts; tmp; tmp = g_list_next (tmp)) { data = (TimeoutData *) tmp->data; if (g_strcmp0 (printer_name, data->printer_name) == 0) { g_source_remove (data->timeout_id); manager->priv->timeouts = g_list_remove_link (manager->priv->timeouts, tmp); g_list_free_full (tmp, free_timeout_data); break; } } } for (tmp = manager->priv->active_notifications; tmp; tmp = g_list_next (tmp)) { ReasonData *reason_data = (ReasonData *) tmp->data; GList *remove_list; if (printer_state_reasons == NULL || (g_strcmp0 (printer_name, reason_data->printer_name) == 0 && g_strrstr (printer_state_reasons, reason_data->reason) == NULL)) { if (reason_data->notification_close_id > 0 && g_signal_handler_is_connected (reason_data->notification, reason_data->notification_close_id)) { g_signal_handler_disconnect (reason_data->notification, reason_data->notification_close_id); reason_data->notification_close_id = 0; } notify_notification_close (reason_data->notification, NULL); remove_list = tmp; tmp = g_list_next (tmp); manager->priv->active_notifications = g_list_remove_link (manager->priv->active_notifications, remove_list); g_list_free_full (remove_list, free_reason_data); } } /* Check whether we are printing on this printer right now. */ if (g_hash_table_lookup_extended (manager->priv->printing_printers, printer_name, NULL, NULL)) { dest = cupsGetDest (printer_name, NULL, manager->priv->num_dests, manager->priv->dests); if (dest) tmp_printer_state_reasons = cupsGetOption ("printer-state-reasons", dest->num_options, dest->options); if (tmp_printer_state_reasons) old_state_reasons = g_strsplit (tmp_printer_state_reasons, ",", -1); cupsFreeDests (manager->priv->num_dests, manager->priv->dests); manager->priv->num_dests = cupsGetDests (&manager->priv->dests); dest = cupsGetDest (printer_name, NULL, manager->priv->num_dests, manager->priv->dests); if (dest) tmp_printer_state_reasons = cupsGetOption ("printer-state-reasons", dest->num_options, dest->options); if (tmp_printer_state_reasons) new_state_reasons = g_strsplit (tmp_printer_state_reasons, ",", -1); if (new_state_reasons) qsort (new_state_reasons, g_strv_length (new_state_reasons), sizeof (gchar *), strcmp0); if (old_state_reasons) { qsort (old_state_reasons, g_strv_length (old_state_reasons), sizeof (gchar *), strcmp0); j = 0; for (i = 0; new_state_reasons && i < g_strv_length (new_state_reasons); i++) { while (old_state_reasons[j] && g_strcmp0 (old_state_reasons[j], new_state_reasons[i]) < 0) j++; if (old_state_reasons[j] == NULL || g_strcmp0 (old_state_reasons[j], new_state_reasons[i]) != 0) added_reasons = g_slist_append (added_reasons, new_state_reasons[i]); } } else { for (i = 0; new_state_reasons && i < g_strv_length (new_state_reasons); i++) { added_reasons = g_slist_append (added_reasons, new_state_reasons[i]); } } for (tmp_list = added_reasons; tmp_list; tmp_list = tmp_list->next) { gchar *data = (gchar *) tmp_list->data; known_reason = FALSE; for (j = 0; j < G_N_ELEMENTS (reasons); j++) { if (strncmp (data, reasons[j], strlen (reasons[j])) == 0) { NotifyNotification *notification; known_reason = TRUE; if (g_strcmp0 (reasons[j], "connecting-to-device") == 0) { TimeoutData *data; data = g_new0 (TimeoutData, 1); data->printer_name = g_strdup (printer_name); data->primary_text = g_strdup ( _(statuses_first[j])); data->secondary_text = get_statuses_second (j, printer_name); data->manager = manager; data->timeout_id = g_timeout_add_seconds (CONNECTING_TIMEOUT, show_notification, data); g_source_set_name_by_id (data->timeout_id, "[cinnamon-settings-daemon] show_notification"); manager->priv->timeouts = g_list_append (manager->priv->timeouts, data); } else { ReasonData *reason_data; gchar *second_row = get_statuses_second (j, printer_name); notification = notify_notification_new ( _(statuses_first[j]), second_row, "printer-symbolic"); notify_notification_set_app_name (notification, _("Printers")); notify_notification_set_hint (notification, "resident", g_variant_new_boolean (TRUE)); notify_notification_set_timeout (notification, REASON_TIMEOUT); reason_data = g_new0 (ReasonData, 1); reason_data->printer_name = g_strdup (printer_name); reason_data->reason = g_strdup (reasons[j]); reason_data->notification = notification; reason_data->manager = manager; reason_data->notification_close_id = g_signal_connect (notification, "closed", G_CALLBACK (notification_closed_cb), reason_data); manager->priv->active_notifications = g_list_append (manager->priv->active_notifications, reason_data); notify_notification_show (notification, NULL); g_free (second_row); } } } if (!known_reason && !reason_is_blacklisted (data)) { NotifyNotification *notification; ReasonData *reason_data; gchar *first_row; gchar *second_row; gchar *text = NULL; gchar *ppd_file_name; ppd_file_t *ppd_file; char buffer[8192]; ppd_file_name = g_strdup (cupsGetPPD (printer_name)); if (ppd_file_name) { ppd_file = ppdOpenFile (ppd_file_name); if (ppd_file) { gchar **tmpv; static const char * const schemes[] = { "text", "http", "help", "file" }; tmpv = g_new0 (gchar *, G_N_ELEMENTS (schemes) + 1); i = 0; for (j = 0; j < G_N_ELEMENTS (schemes); j++) { if (ppdLocalizeIPPReason (ppd_file, data, schemes[j], buffer, sizeof (buffer))) { tmpv[i++] = g_strdup (buffer); } } if (i > 0) text = g_strjoinv (", ", tmpv); g_strfreev (tmpv); ppdClose (ppd_file); } g_unlink (ppd_file_name); g_free (ppd_file_name); } if (g_str_has_suffix (data, "-report")) /* Translators: This is a title of a report notification for a printer */ first_row = g_strdup (_("Printer report")); else if (g_str_has_suffix (data, "-warning")) /* Translators: This is a title of a warning notification for a printer */ first_row = g_strdup (_("Printer warning")); else /* Translators: This is a title of an error notification for a printer */ first_row = g_strdup (_("Printer error")); if (text == NULL) text = g_strdup (data); /* Translators: "Printer 'MyPrinterName': 'Description of the report/warning/error from a PPD file'." */ second_row = g_strdup_printf (_("Printer '%s': '%s'."), printer_name, text); g_free (text); notification = notify_notification_new (first_row, second_row, "printer-symbolic"); notify_notification_set_app_name (notification, _("Printers")); notify_notification_set_hint (notification, "resident", g_variant_new_boolean (TRUE)); notify_notification_set_timeout (notification, REASON_TIMEOUT); reason_data = g_new0 (ReasonData, 1); reason_data->printer_name = g_strdup (printer_name); reason_data->reason = g_strdup (data); reason_data->notification = notification; reason_data->manager = manager; reason_data->notification_close_id = g_signal_connect (notification, "closed", G_CALLBACK (notification_closed_cb), reason_data); manager->priv->active_notifications = g_list_append (manager->priv->active_notifications, reason_data); notify_notification_show (notification, NULL); g_free (first_row); g_free (second_row); } } g_slist_free (added_reasons); } if (new_state_reasons) g_strfreev (new_state_reasons); if (old_state_reasons) g_strfreev (old_state_reasons); } if (primary_text) { NotifyNotification *notification; notification = notify_notification_new (primary_text, secondary_text, "printer-symbolic"); notify_notification_set_app_name (notification, _("Printers")); notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE)); notify_notification_show (notification, NULL); g_object_unref (notification); g_free (primary_text); g_free (secondary_text); } } static gboolean process_new_notifications (gpointer user_data) { CsdPrintNotificationsManager *manager = (CsdPrintNotificationsManager *) user_data; ipp_attribute_t *attr; const gchar *notify_subscribed_event = NULL; const gchar *printer_name = NULL; const gchar *notify_text = NULL; const gchar *notify_printer_uri = NULL; const gchar *job_name = NULL; const char *attr_name; gboolean printer_is_accepting_jobs = FALSE; gchar *job_state_reasons = NULL; gchar *printer_state_reasons = NULL; gchar **reasons; guint notify_job_id = 0; ipp_t *request; ipp_t *response; gint printer_state = -1; gint job_state = -1; gint job_impressions_completed = -1; gint notify_sequence_number = -1; gint i; request = ippNewRequest (IPP_GET_NOTIFICATIONS); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-ids", manager->priv->subscription_id); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/printers/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, "/jobs/"); ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-sequence-numbers", manager->priv->last_notify_sequence_number + 1); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); for (attr = ippFindAttribute (response, "notify-sequence-number", IPP_TAG_INTEGER); attr != NULL; attr = ippNextAttribute (response)) { attr_name = ippGetName (attr); if (g_strcmp0 (attr_name, "notify-sequence-number") == 0) { notify_sequence_number = ippGetInteger (attr, 0); if (notify_sequence_number > manager->priv->last_notify_sequence_number) manager->priv->last_notify_sequence_number = notify_sequence_number; if (notify_subscribed_event != NULL) { process_cups_notification (manager, notify_subscribed_event, notify_text, notify_printer_uri, printer_name, printer_state, printer_state_reasons, printer_is_accepting_jobs, notify_job_id, job_state, job_state_reasons, job_name, job_impressions_completed); g_clear_pointer (&printer_state_reasons, g_free); g_clear_pointer (&job_state_reasons, g_free); } notify_subscribed_event = NULL; notify_text = NULL; notify_printer_uri = NULL; printer_name = NULL; printer_state = -1; printer_state_reasons = NULL; printer_is_accepting_jobs = FALSE; notify_job_id = 0; job_state = -1; job_state_reasons = NULL; job_name = NULL; job_impressions_completed = -1; } else if (g_strcmp0 (attr_name, "notify-subscribed-event") == 0) { notify_subscribed_event = ippGetString (attr, 0, NULL); } else if (g_strcmp0 (attr_name, "notify-text") == 0) { notify_text = ippGetString (attr, 0, NULL); } else if (g_strcmp0 (attr_name, "notify-printer-uri") == 0) { notify_printer_uri = ippGetString (attr, 0, NULL); } else if (g_strcmp0 (attr_name, "printer-name") == 0) { printer_name = ippGetString (attr, 0, NULL); } else if (g_strcmp0 (attr_name, "printer-state") == 0) { printer_state = ippGetInteger (attr, 0); } else if (g_strcmp0 (attr_name, "printer-state-reasons") == 0) { reasons = g_new0 (gchar *, ippGetCount (attr) + 1); for (i = 0; i < ippGetCount (attr); i++) reasons[i] = g_strdup (ippGetString (attr, i, NULL)); printer_state_reasons = g_strjoinv (",", reasons); g_strfreev (reasons); } else if (g_strcmp0 (attr_name, "printer-is-accepting-jobs") == 0) { printer_is_accepting_jobs = ippGetBoolean (attr, 0); } else if (g_strcmp0 (attr_name, "notify-job-id") == 0) { notify_job_id = ippGetInteger (attr, 0); } else if (g_strcmp0 (attr_name, "job-state") == 0) { job_state = ippGetInteger (attr, 0); } else if (g_strcmp0 (attr_name, "job-state-reasons") == 0) { reasons = g_new0 (gchar *, ippGetCount (attr) + 1); for (i = 0; i < ippGetCount (attr); i++) reasons[i] = g_strdup (ippGetString (attr, i, NULL)); job_state_reasons = g_strjoinv (",", reasons); g_strfreev (reasons); } else if (g_strcmp0 (attr_name, "job-name") == 0) { job_name = ippGetString (attr, 0, NULL); } else if (g_strcmp0 (attr_name, "job-impressions-completed") == 0) { job_impressions_completed = ippGetInteger (attr, 0); } } if (notify_subscribed_event != NULL) { process_cups_notification (manager, notify_subscribed_event, notify_text, notify_printer_uri, printer_name, printer_state, printer_state_reasons, printer_is_accepting_jobs, notify_job_id, job_state, job_state_reasons, job_name, job_impressions_completed); g_clear_pointer (&printer_state_reasons, g_free); g_clear_pointer (&job_state_reasons, g_free); } if (response != NULL) ippDelete (response); return TRUE; } static void scp_handler (CsdPrintNotificationsManager *manager, gboolean start) { if (start) { GError *error = NULL; char *args[2]; if (manager->priv->scp_handler_spawned) return; args[0] = LIBEXECDIR "/csd-printer"; args[1] = NULL; g_spawn_async (NULL, args, NULL, 0, NULL, NULL, &manager->priv->scp_handler_pid, &error); manager->priv->scp_handler_spawned = (error == NULL); if (error) { g_warning ("Could not execute system-config-printer-udev handler: %s", error->message); g_error_free (error); } } else if (manager->priv->scp_handler_spawned) { kill (manager->priv->scp_handler_pid, SIGHUP); g_spawn_close_pid (manager->priv->scp_handler_pid); manager->priv->scp_handler_spawned = FALSE; } } static void cancel_subscription (gint id) { http_t *http; ipp_t *request; if (id >= 0 && ((http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ())) != NULL)) { request = ippNewRequest (IPP_CANCEL_SUBSCRIPTION); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", id); ippDelete (cupsDoRequest (http, request, "/")); httpClose (http); } } static gboolean renew_subscription (gpointer data) { CsdPrintNotificationsManager *manager = (CsdPrintNotificationsManager *) data; ipp_attribute_t *attr = NULL; http_t *http; ipp_t *request; ipp_t *response; gint num_events = 7; static const char * const events[] = { "job-created", "job-completed", "job-state-changed", "job-state", "printer-added", "printer-deleted", "printer-state-changed"}; if ((http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ())) == NULL) { g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ()); } else { if (manager->priv->subscription_id >= 0) { request = ippNewRequest (IPP_RENEW_SUBSCRIPTION); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", manager->priv->subscription_id); ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", SUBSCRIPTION_DURATION); ippDelete (cupsDoRequest (http, request, "/")); } else { request = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddStrings (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", num_events, NULL, events); ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-pull-method", NULL, "ippget"); if (server_is_local (cupsServer ())) { ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://"); } ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", SUBSCRIPTION_DURATION); response = cupsDoRequest (http, request, "/"); if (response != NULL && ippGetStatusCode (response) <= IPP_OK_CONFLICT) { if ((attr = ippFindAttribute (response, "notify-subscription-id", IPP_TAG_INTEGER)) == NULL) g_debug ("No notify-subscription-id in response!\n"); else manager->priv->subscription_id = ippGetInteger (attr, 0); } if (response) ippDelete (response); } httpClose (http); } return TRUE; } static void renew_subscription_with_connection_test_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GSocketConnection *connection; GError *error = NULL; connection = g_socket_client_connect_to_host_finish (G_SOCKET_CLIENT (source_object), res, &error); if (connection) { g_debug ("Test connection to CUPS server \'%s:%d\' succeeded.", cupsServer (), ippPort ()); g_io_stream_close (G_IO_STREAM (connection), NULL, NULL); g_object_unref (connection); renew_subscription (user_data); } else { g_debug ("Test connection to CUPS server \'%s:%d\' failed.", cupsServer (), ippPort ()); } } static gboolean renew_subscription_with_connection_test (gpointer user_data) { GSocketClient *client; gchar *address; int port; port = ippPort (); address = g_strdup_printf ("%s:%d", cupsServer (), port); if (address && address[0] != '/') { client = g_socket_client_new (); g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), port); g_socket_client_connect_to_host_async (client, address, port, NULL, renew_subscription_with_connection_test_cb, user_data); g_object_unref (client); } else { renew_subscription (user_data); } g_free (address); return TRUE; } static void renew_subscription_timeout_enable (CsdPrintNotificationsManager *manager, gboolean enable, gboolean with_connection_test) { if (manager->priv->renew_source_id > 0) g_source_remove (manager->priv->renew_source_id); if (enable) { renew_subscription (manager); if (with_connection_test) { manager->priv->renew_source_id = g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription_with_connection_test, manager); g_source_set_name_by_id (manager->priv->renew_source_id, "[cinnamon-settings-daemon] renew_subscription_with_connection_test"); } else { manager->priv->renew_source_id = g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription, manager); g_source_set_name_by_id (manager->priv->renew_source_id, "[cinnamon-settings-daemon] renew_subscription"); } } else { manager->priv->renew_source_id = 0; } } static void cups_connection_test_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CsdPrintNotificationsManager *manager = (CsdPrintNotificationsManager *) user_data; GSocketConnection *connection; GError *error = NULL; connection = g_socket_client_connect_to_host_finish (G_SOCKET_CLIENT (source_object), res, &error); if (connection) { g_debug ("Test connection to CUPS server \'%s:%d\' succeeded.", cupsServer (), ippPort ()); g_io_stream_close (G_IO_STREAM (connection), NULL, NULL); g_object_unref (connection); manager->priv->num_dests = cupsGetDests (&manager->priv->dests); g_debug ("Got dests from remote CUPS server."); renew_subscription_timeout_enable (manager, TRUE, TRUE); manager->priv->check_source_id = g_timeout_add_seconds (CHECK_INTERVAL, process_new_notifications, manager); g_source_set_name_by_id (manager->priv->check_source_id, "[cinnamon-settings-daemon] process_new_notifications"); } else { g_debug ("Test connection to CUPS server \'%s:%d\' failed.", cupsServer (), ippPort ()); if (manager->priv->cups_connection_timeout_id == 0) { manager->priv->cups_connection_timeout_id = g_timeout_add_seconds (CUPS_CONNECTION_TEST_INTERVAL, cups_connection_test, manager); g_source_set_name_by_id (manager->priv->cups_connection_timeout_id, "[cinnamon-settings-daemon] cups_connection_test"); } } } static gboolean cups_connection_test (gpointer user_data) { CsdPrintNotificationsManager *manager = (CsdPrintNotificationsManager *) user_data; GSocketClient *client; gchar *address; int port = ippPort (); if (!manager->priv->dests) { address = g_strdup_printf ("%s:%d", cupsServer (), port); client = g_socket_client_new (); g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), port); g_socket_client_connect_to_host_async (client, address, port, NULL, cups_connection_test_cb, manager); g_object_unref (client); g_free (address); } if (manager->priv->dests) { manager->priv->cups_connection_timeout_id = 0; return FALSE; } else { return TRUE; } } static void csd_print_notifications_manager_got_dbus_connection (GObject *source_object, GAsyncResult *res, gpointer user_data) { CsdPrintNotificationsManager *manager = (CsdPrintNotificationsManager *) user_data; GError *error = NULL; manager->priv->cups_bus_connection = g_bus_get_finish (res, &error); if (manager->priv->cups_bus_connection != NULL) { manager->priv->cups_dbus_subscription_id = g_dbus_connection_signal_subscribe (manager->priv->cups_bus_connection, NULL, CUPS_DBUS_INTERFACE, NULL, CUPS_DBUS_PATH, NULL, 0, on_cups_notification, manager, NULL); } else { g_warning ("Connection to message bus failed: %s", error->message); g_error_free (error); } } static gboolean csd_print_notifications_manager_start_idle (gpointer data) { CsdPrintNotificationsManager *manager = data; cinnamon_settings_profile_start (NULL); manager->priv->printing_printers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); manager->priv->removed_printers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* * Set a password callback which cancels authentication * before we prepare a correct solution (see bug #725440). */ cupsSetPasswordCB2 (password_cb, NULL); if (server_is_local (cupsServer ())) { manager->priv->num_dests = cupsGetDests (&manager->priv->dests); g_debug ("Got dests from local CUPS server."); renew_subscription_timeout_enable (manager, TRUE, FALSE); g_bus_get (G_BUS_TYPE_SYSTEM, NULL, csd_print_notifications_manager_got_dbus_connection, data); } else { cups_connection_test (manager); } scp_handler (manager, TRUE); cinnamon_settings_profile_end (NULL); return G_SOURCE_REMOVE; } gboolean csd_print_notifications_manager_start (CsdPrintNotificationsManager *manager, GError **error) { g_debug ("Starting print-notifications manager"); cinnamon_settings_profile_start (NULL); manager->priv->subscription_id = -1; manager->priv->dests = NULL; manager->priv->num_dests = 0; manager->priv->scp_handler_spawned = FALSE; manager->priv->timeouts = NULL; manager->priv->printing_printers = NULL; manager->priv->removed_printers = NULL; manager->priv->removed_printer_timeout_id = 0; manager->priv->active_notifications = NULL; manager->priv->cups_bus_connection = NULL; manager->priv->cups_connection_timeout_id = 0; manager->priv->last_notify_sequence_number = -1; manager->priv->start_idle_id = g_idle_add (csd_print_notifications_manager_start_idle, manager); g_source_set_name_by_id (manager->priv->start_idle_id, "[cinnamon-settings-daemon] csd_print_notifications_manager_start_idle"); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_print_notifications_manager_stop (CsdPrintNotificationsManager *manager) { TimeoutData *data; ReasonData *reason_data; GList *tmp; g_debug ("Stopping print-notifications manager"); cupsFreeDests (manager->priv->num_dests, manager->priv->dests); manager->priv->num_dests = 0; manager->priv->dests = NULL; if (manager->priv->cups_dbus_subscription_id > 0 && manager->priv->cups_bus_connection != NULL) { g_dbus_connection_signal_unsubscribe (manager->priv->cups_bus_connection, manager->priv->cups_dbus_subscription_id); manager->priv->cups_dbus_subscription_id = 0; } renew_subscription_timeout_enable (manager, FALSE, FALSE); if (manager->priv->check_source_id > 0) { g_source_remove (manager->priv->check_source_id); manager->priv->check_source_id = 0; } if (manager->priv->subscription_id >= 0) cancel_subscription (manager->priv->subscription_id); g_clear_pointer (&manager->priv->printing_printers, g_hash_table_destroy); g_clear_pointer (&manager->priv->removed_printers, g_hash_table_destroy); g_clear_handle_id (&manager->priv->removed_printer_timeout_id, g_source_remove); g_clear_object (&manager->priv->cups_bus_connection); for (tmp = manager->priv->timeouts; tmp; tmp = g_list_next (tmp)) { data = (TimeoutData *) tmp->data; if (data) g_source_remove (data->timeout_id); } g_list_free_full (manager->priv->timeouts, free_timeout_data); for (tmp = manager->priv->active_notifications; tmp; tmp = g_list_next (tmp)) { reason_data = (ReasonData *) tmp->data; if (reason_data) { if (reason_data->notification_close_id > 0 && g_signal_handler_is_connected (reason_data->notification, reason_data->notification_close_id)) { g_signal_handler_disconnect (reason_data->notification, reason_data->notification_close_id); reason_data->notification_close_id = 0; } notify_notification_close (reason_data->notification, NULL); } } g_list_free_full (manager->priv->active_notifications, free_reason_data); scp_handler (manager, FALSE); } static void csd_print_notifications_manager_class_init (CsdPrintNotificationsManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_print_notifications_manager_finalize; notify_init ("cinnamon-settings-daemon"); g_type_class_add_private (klass, sizeof (CsdPrintNotificationsManagerPrivate)); } static void csd_print_notifications_manager_init (CsdPrintNotificationsManager *manager) { manager->priv = CSD_PRINT_NOTIFICATIONS_MANAGER_GET_PRIVATE (manager); } static void csd_print_notifications_manager_finalize (GObject *object) { CsdPrintNotificationsManager *manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_PRINT_NOTIFICATIONS_MANAGER (object)); manager = CSD_PRINT_NOTIFICATIONS_MANAGER (object); g_return_if_fail (manager->priv != NULL); csd_print_notifications_manager_stop (manager); if (manager->priv->start_idle_id != 0) g_source_remove (manager->priv->start_idle_id); G_OBJECT_CLASS (csd_print_notifications_manager_parent_class)->finalize (object); } CsdPrintNotificationsManager * csd_print_notifications_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_PRINT_NOTIFICATIONS_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_PRINT_NOTIFICATIONS_MANAGER (manager_object); } ././@LongLink0000644000000000000000000000016300000000000011603 Lustar rootrootcinnamon-settings-daemon-6.4.3/plugins/print-notifications/cinnamon-settings-daemon-print-notifications.desktop.incinnamon-settings-daemon-6.4.3/plugins/print-notifications/cinnamon-settings-daemon-print-notificati0000664000175000017500000000036614733247605033162 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - print-notifications Exec=csd-print-notifications OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/print-notifications/csd-printer.c0000664000175000017500000014736514733247605025466 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Red Hat, Inc. * * 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, see . * */ #include "config.h" #include #include #include #include #include #include #include #include static GDBusNodeInfo *npn_introspection_data = NULL; static GDBusNodeInfo *pdi_introspection_data = NULL; #define SCP_DBUS_NPN_NAME "com.redhat.NewPrinterNotification" #define SCP_DBUS_NPN_PATH "/com/redhat/NewPrinterNotification" #define SCP_DBUS_NPN_INTERFACE "com.redhat.NewPrinterNotification" #define SCP_DBUS_PDI_NAME "com.redhat.PrinterDriversInstaller" #define SCP_DBUS_PDI_PATH "/com/redhat/PrinterDriversInstaller" #define SCP_DBUS_PDI_INTERFACE "com.redhat.PrinterDriversInstaller" #define PACKAGE_KIT_BUS "org.freedesktop.PackageKit" #define PACKAGE_KIT_PATH "/org/freedesktop/PackageKit" #define PACKAGE_KIT_MODIFY_IFACE "org.freedesktop.PackageKit.Modify" #define PACKAGE_KIT_QUERY_IFACE "org.freedesktop.PackageKit.Query" #define SCP_BUS "org.fedoraproject.Config.Printing" #define SCP_PATH "/org/fedoraproject/Config/Printing" #define SCP_IFACE "org.fedoraproject.Config.Printing" #define MECHANISM_BUS "org.opensuse.CupsPkHelper.Mechanism" #define ALLOWED_CHARACTERS "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" #define DBUS_TIMEOUT 60000 #define DBUS_INSTALL_TIMEOUT 3600000 #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager" #define GNOME_SESSION_DBUS_IFACE "org.gnome.SessionManager" #define GNOME_SESSION_CLIENT_PRIVATE_DBUS_IFACE "org.gnome.SessionManager.ClientPrivate" #define GNOME_SESSION_PRESENCE_DBUS_PATH "/org/gnome/SessionManager/Presence" #define GNOME_SESSION_PRESENCE_DBUS_IFACE "org.gnome.SessionManager.Presence" #if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5) #define HAVE_CUPS_1_6 1 #endif #ifndef HAVE_CUPS_1_6 #define ippGetState(ipp) ipp->state #endif enum { PRESENCE_STATUS_AVAILABLE = 0, PRESENCE_STATUS_INVISIBLE, PRESENCE_STATUS_BUSY, PRESENCE_STATUS_IDLE, PRESENCE_STATUS_UNKNOWN }; static const gchar npn_introspection_xml[] = "" " " " " " " " " " " " " " " " " " " " " " " " " ""; static const gchar pdi_introspection_xml[] = "" " " " " " " " " " " " " " " ""; static GMainLoop *main_loop; static guint npn_registration_id; static guint pdi_registration_id; static guint npn_owner_id; static guint pdi_owner_id; static GHashTable * get_missing_executables (const gchar *ppd_file_name) { GHashTable *executables = NULL; GDBusProxy *proxy; GVariant *output; GVariant *array; GError *error = NULL; gint i; if (!ppd_file_name) return NULL; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, SCP_BUS, SCP_PATH, SCP_IFACE, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return NULL; } output = g_dbus_proxy_call_sync (proxy, "MissingExecutables", g_variant_new ("(s)", ppd_file_name), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output && g_variant_n_children (output) == 1) { array = g_variant_get_child_value (output, 0); if (array) { executables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < g_variant_n_children (array); i++) { g_hash_table_insert (executables, g_strdup (g_variant_get_string ( g_variant_get_child_value (array, i), NULL)), NULL); } } } if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); return executables; } static GHashTable * find_packages_for_executables (GHashTable *executables) { GHashTableIter exec_iter; GHashTable *packages = NULL; GDBusProxy *proxy; GVariant *output; gpointer key, value; GError *error = NULL; if (!executables || g_hash_table_size (executables) <= 0) return NULL; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, PACKAGE_KIT_BUS, PACKAGE_KIT_PATH, PACKAGE_KIT_QUERY_IFACE, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return NULL; } packages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_iter_init (&exec_iter, executables); while (g_hash_table_iter_next (&exec_iter, &key, &value)) { output = g_dbus_proxy_call_sync (proxy, "SearchFile", g_variant_new ("(ss)", (gchar *) key, ""), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output) { gboolean installed; gchar *package; g_variant_get (output, "(bs)", &installed, &package); if (!installed) g_hash_table_insert (packages, g_strdup (package), NULL); g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } } g_object_unref (proxy); return packages; } static void install_packages (GHashTable *packages) { GVariantBuilder array_builder; GHashTableIter pkg_iter; GDBusProxy *proxy; GVariant *output; gpointer key, value; GError *error = NULL; if (!packages || g_hash_table_size (packages) <= 0) return; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, PACKAGE_KIT_BUS, PACKAGE_KIT_PATH, PACKAGE_KIT_MODIFY_IFACE, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return; } g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as")); g_hash_table_iter_init (&pkg_iter, packages); while (g_hash_table_iter_next (&pkg_iter, &key, &value)) { g_variant_builder_add (&array_builder, "s", (gchar *) key); } output = g_dbus_proxy_call_sync (proxy, "InstallPackageNames", g_variant_new ("(uass)", 0, &array_builder, "hide-finished"), G_DBUS_CALL_FLAGS_NONE, DBUS_INSTALL_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); } static gchar * get_best_ppd (gchar *device_id, gchar *device_make_and_model, gchar *device_uri) { GDBusProxy *proxy; GVariant *output; GVariant *array; GVariant *tuple; GError *error = NULL; gchar *ppd_name = NULL; gint i, j; static const char * const match_levels[] = { "exact-cmd", "exact", "close", "generic", "none"}; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, SCP_BUS, SCP_PATH, SCP_IFACE, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return NULL; } output = g_dbus_proxy_call_sync (proxy, "GetBestDrivers", g_variant_new ("(sss)", device_id ? device_id : "", device_make_and_model ? device_make_and_model : "", device_uri ? device_uri : ""), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output && g_variant_n_children (output) >= 1) { array = g_variant_get_child_value (output, 0); if (array) for (j = 0; j < G_N_ELEMENTS (match_levels) && ppd_name == NULL; j++) for (i = 0; i < g_variant_n_children (array) && ppd_name == NULL; i++) { tuple = g_variant_get_child_value (array, i); if (tuple && g_variant_n_children (tuple) == 2) { if (g_strcmp0 (g_variant_get_string ( g_variant_get_child_value (tuple, 1), NULL), match_levels[j]) == 0) ppd_name = g_strdup (g_variant_get_string ( g_variant_get_child_value (tuple, 0), NULL)); } } } if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); return ppd_name; } static gchar * get_tag_value (const gchar *tag_string, const gchar *tag_name) { gchar **tag_string_splitted; gchar *tag_value = NULL; gint tag_name_length; gint i; if (!tag_string || !tag_name) return NULL; tag_name_length = strlen (tag_name); tag_string_splitted = g_strsplit (tag_string, ";", 0); if (tag_string_splitted) { for (i = 0; i < g_strv_length (tag_string_splitted); i++) if (g_ascii_strncasecmp (tag_string_splitted[i], tag_name, tag_name_length) == 0) if (strlen (tag_string_splitted[i]) > tag_name_length + 1) tag_value = g_strdup (tag_string_splitted[i] + tag_name_length + 1); g_strfreev (tag_string_splitted); } return tag_value; } static gchar * create_name (gchar *device_id) { cups_dest_t *dests; gboolean already_present = FALSE; gchar *name = NULL; gchar *new_name = NULL; gint num_dests; gint name_index = 2; gint j; g_return_val_if_fail (device_id != NULL, NULL); name = get_tag_value (device_id, "mdl"); if (!name) name = get_tag_value (device_id, "model"); if (name) name = g_strcanon (name, ALLOWED_CHARACTERS, '-'); num_dests = cupsGetDests (&dests); do { if (already_present) { new_name = g_strdup_printf ("%s-%d", name, name_index); name_index++; } else { new_name = g_strdup (name); } already_present = FALSE; for (j = 0; j < num_dests; j++) if (g_strcmp0 (dests[j].name, new_name) == 0) already_present = TRUE; if (already_present) { g_free (new_name); } else { g_free (name); name = new_name; } } while (already_present); cupsFreeDests (num_dests, dests); return name; } static gboolean add_printer (gchar *printer_name, gchar *device_uri, gchar *ppd_name, gchar *info, gchar *location) { cups_dest_t *dests; GDBusProxy *proxy; gboolean success = FALSE; GVariant *output; GError *error = NULL; gint num_dests; gint i; if (!printer_name || !device_uri || !ppd_name) return FALSE; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MECHANISM_BUS, "/", MECHANISM_BUS, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return FALSE; } output = g_dbus_proxy_call_sync (proxy, "PrinterAdd", g_variant_new ("(sssss)", printer_name, device_uri, ppd_name, info ? info : "", location ? location : ""), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); num_dests = cupsGetDests (&dests); for (i = 0; i < num_dests; i++) if (g_strcmp0 (dests[i].name, printer_name) == 0) success = TRUE; cupsFreeDests (num_dests, dests); return success; } static gboolean printer_set_enabled (const gchar *printer_name, gboolean enabled) { GDBusProxy *proxy; gboolean result = TRUE; GVariant *output; GError *error = NULL; if (!printer_name) return FALSE; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MECHANISM_BUS, "/", MECHANISM_BUS, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return FALSE; } output = g_dbus_proxy_call_sync (proxy, "PrinterSetEnabled", g_variant_new ("(sb)", printer_name, enabled), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); result = FALSE; } g_object_unref (proxy); return result; } static gboolean printer_set_accepting_jobs (const gchar *printer_name, gboolean accepting_jobs, const gchar *reason) { GDBusProxy *proxy; gboolean result = TRUE; GVariant *output; GError *error = NULL; if (!printer_name) return FALSE; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MECHANISM_BUS, "/", MECHANISM_BUS, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return FALSE; } output = g_dbus_proxy_call_sync (proxy, "PrinterSetAcceptJobs", g_variant_new ("(sbs)", printer_name, accepting_jobs, reason ? reason : ""), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); result = FALSE; } g_object_unref (proxy); return result; } static ipp_t * execute_maintenance_command (const char *printer_name, const char *command, const char *title) { http_t *http; GError *error = NULL; ipp_t *request = NULL; ipp_t *response = NULL; gchar *file_name = NULL; char *uri; int fd = -1; http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ()); if (!http) return NULL; request = ippNewRequest (IPP_PRINT_JOB); uri = g_strdup_printf ("ipp://localhost/printers/%s", printer_name); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); g_free (uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); ippAddString (request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", NULL, "application/vnd.cups-command"); fd = g_file_open_tmp ("ccXXXXXX", &file_name, &error); if (fd != -1) { FILE *file; file = fdopen (fd, "w"); fprintf (file, "#CUPS-COMMAND\n"); fprintf (file, "%s\n", command); fclose (file); response = cupsDoFileRequest (http, request, "/", file_name); g_unlink (file_name); } else { g_warning ("%s", error->message); g_error_free (error); } g_free (file_name); httpClose (http); return response; } static char * get_dest_attr (const char *dest_name, const char *attr) { cups_dest_t *dests; int num_dests; cups_dest_t *dest; const char *value; char *ret; if (dest_name == NULL) return NULL; ret = NULL; num_dests = cupsGetDests (&dests); if (num_dests < 1) { g_debug ("Unable to get printer destinations"); return NULL; } dest = cupsGetDest (dest_name, NULL, num_dests, dests); if (dest == NULL) { g_debug ("Unable to find a printer named '%s'", dest_name); goto out; } value = cupsGetOption (attr, dest->num_options, dest->options); if (value == NULL) { g_debug ("Unable to get %s for '%s'", attr, dest_name); goto out; } ret = g_strdup (value); out: cupsFreeDests (num_dests, dests); return ret; } static void printer_autoconfigure (gchar *printer_name) { gchar *commands; gchar *commands_lowercase; ipp_t *response = NULL; if (!printer_name) return; commands = get_dest_attr (printer_name, "printer-commands"); commands_lowercase = g_ascii_strdown (commands, -1); if (g_strrstr (commands_lowercase, "autoconfigure")) { response = execute_maintenance_command (printer_name, "AutoConfigure", ("Automatic configuration")); if (response) { if (ippGetState (response) == IPP_ERROR) g_warning ("An error has occurred during automatic configuration of new printer."); ippDelete (response); } } g_free (commands); g_free (commands_lowercase); } /* Returns default page size for current locale */ static const gchar * get_page_size_from_locale (void) { if (g_str_equal (gtk_paper_size_get_default (), GTK_PAPER_NAME_LETTER)) return "Letter"; else return "A4"; } static void set_default_paper_size (const gchar *printer_name, const gchar *ppd_file_name) { GDBusProxy *proxy; GVariant *output; GError *error = NULL; GVariantBuilder *builder; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MECHANISM_BUS, "/", MECHANISM_BUS, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); return; } /* Set default media size according to the locale * FIXME: Handle more than A4 and Letter: * https://bugzilla.gnome.org/show_bug.cgi?id=660769 */ builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); g_variant_builder_add (builder, "s", get_page_size_from_locale ()); output = g_dbus_proxy_call_sync (proxy, "PrinterAddOption", g_variant_new ("(ssas)", printer_name ? printer_name : "", "PageSize", builder), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { if (!(error->domain == G_DBUS_ERROR && (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN || error->code == G_DBUS_ERROR_UNKNOWN_METHOD))) g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); } /* * Setup new printer and returns TRUE if successful. */ static gboolean setup_printer (gchar *device_id, gchar *device_make_and_model, gchar *device_uri) { gboolean success = FALSE; gchar *ppd_name; gchar *printer_name; ppd_name = get_best_ppd (device_id, device_make_and_model, device_uri); printer_name = create_name (device_id); if (!ppd_name || !printer_name || !device_uri) { g_free (ppd_name); g_free (printer_name); return FALSE; } success = add_printer (printer_name, device_uri, ppd_name, NULL, NULL); /* Set some options of the new printer */ if (success) { const char *ppd_file_name; printer_set_accepting_jobs (printer_name, TRUE, NULL); printer_set_enabled (printer_name, TRUE); printer_autoconfigure (printer_name); ppd_file_name = cupsGetPPD (printer_name); if (ppd_file_name) { GHashTable *executables; GHashTable *packages; set_default_paper_size (printer_name, ppd_file_name); executables = get_missing_executables (ppd_file_name); packages = find_packages_for_executables (executables); install_packages (packages); if (executables) g_hash_table_destroy (executables); if (packages) g_hash_table_destroy (packages); g_unlink (ppd_file_name); } } g_free (printer_name); g_free (ppd_name); return success; } static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { gchar *primary_text = NULL; gchar *secondary_text = NULL; gchar *name = NULL; gchar *mfg = NULL; gchar *mdl = NULL; gchar *des = NULL; gchar *cmd = NULL; gchar *device = NULL; gchar *device_id; gchar *make_and_model; gint status = 0; if (g_strcmp0 (method_name, "GetReady") == 0) { /* Translators: We are configuring new printer */ primary_text = g_strdup (_("Configuring new printer")); /* Translators: Just wait */ secondary_text = g_strdup (_("Please wait...")); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "NewPrinter") == 0) { if (g_variant_n_children (parameters) == 6) { g_variant_get (parameters, "(i&s&s&s&s&s)", &status, &name, &mfg, &mdl, &des, &cmd); } if (g_strrstr (name, "/")) { /* name is a URI, no queue was generated, because no suitable * driver was found */ device_id = g_strdup_printf ("MFG:%s;MDL:%s;DES:%s;CMD:%s;", mfg, mdl, des, cmd); make_and_model = g_strdup_printf ("%s %s", mfg, mdl); if (!setup_printer (device_id, make_and_model, name)) { /* Translators: We have no driver installed for this printer */ primary_text = g_strdup (_("Missing printer driver")); if ((mfg && mdl) || des) { if (mfg && mdl) device = g_strdup_printf ("%s %s", mfg, mdl); else device = g_strdup (des); /* Translators: We have no driver installed for the device */ secondary_text = g_strdup_printf (_("No printer driver for %s."), device); g_free (device); } else /* Translators: We have no driver installed for this printer */ secondary_text = g_strdup (_("No driver for this printer.")); } g_free (make_and_model); g_free (device_id); } else { /* name is the name of the queue which hal_lpadmin has set up * automatically. */ const char *ppd_file_name; ppd_file_name = cupsGetPPD (name); if (ppd_file_name) { GHashTable *executables; GHashTable *packages; executables = get_missing_executables (ppd_file_name); packages = find_packages_for_executables (executables); install_packages (packages); if (executables) g_hash_table_destroy (executables); if (packages) g_hash_table_destroy (packages); g_unlink (ppd_file_name); } } g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "InstallDrivers") == 0) { GDBusProxy *proxy; GError *error = NULL; if (g_variant_n_children (parameters) == 3) { g_variant_get (parameters, "(&s&s&s)", &mfg, &mdl, &cmd); } if (mfg && mdl) device = g_strdup_printf ("MFG:%s;MDL:%s;", mfg, mdl); proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, PACKAGE_KIT_BUS, PACKAGE_KIT_PATH, PACKAGE_KIT_MODIFY_IFACE, NULL, &error); if (!proxy) { g_warning ("%s", error->message); g_error_free (error); } if (proxy && device) { GVariantBuilder *builder; GVariant *output; builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); g_variant_builder_add (builder, "s", device); output = g_dbus_proxy_call_sync (proxy, "InstallPrinterDrivers", g_variant_new ("(uass)", 0, builder, "hide-finished"), G_DBUS_CALL_FLAGS_NONE, DBUS_INSTALL_TIMEOUT, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); } g_dbus_method_invocation_return_value (invocation, NULL); } if (primary_text) { NotifyNotification *notification; notification = notify_notification_new (primary_text, secondary_text, "printer-symbolic"); notify_notification_set_app_name (notification, _("Printers")); notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE)); notify_notification_show (notification, NULL); g_object_unref (notification); g_free (primary_text); g_free (secondary_text); } } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, NULL }; static void unregister_objects () { GDBusConnection *system_connection; GError *error = NULL; system_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (npn_registration_id > 0) { g_dbus_connection_unregister_object (system_connection, npn_registration_id); npn_registration_id = 0; } if (pdi_registration_id > 0) { g_dbus_connection_unregister_object (system_connection, pdi_registration_id); pdi_registration_id = 0; } } static void unown_names () { if (npn_owner_id > 0) { g_bus_unown_name (npn_owner_id); npn_owner_id = 0; } if (pdi_owner_id > 0) { g_bus_unown_name (pdi_owner_id); pdi_owner_id = 0; } } static void on_npn_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { GError *error = NULL; npn_registration_id = g_dbus_connection_register_object (connection, SCP_DBUS_NPN_PATH, npn_introspection_data->interfaces[0], &interface_vtable, NULL, NULL, &error); if (npn_registration_id == 0) { g_warning ("Failed to register object: %s\n", error->message); g_error_free (error); } } static void on_pdi_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { GError *error = NULL; pdi_registration_id = g_dbus_connection_register_object (connection, SCP_DBUS_PDI_PATH, pdi_introspection_data->interfaces[0], &interface_vtable, NULL, NULL, &error); if (pdi_registration_id == 0) { g_warning ("Failed to register object: %s\n", error->message); g_error_free (error); } } static void on_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) { } static void on_name_lost (GDBusConnection *connection, const gchar *name, gpointer user_data) { unregister_objects (); } static void session_signal_handler (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { guint new_status; g_variant_get (parameters, "(u)", &new_status); if (new_status == PRESENCE_STATUS_IDLE || new_status == PRESENCE_STATUS_AVAILABLE) { unregister_objects (); unown_names (); if (new_status == PRESENCE_STATUS_AVAILABLE) { npn_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, SCP_DBUS_NPN_NAME, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE, on_npn_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); pdi_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, SCP_DBUS_PDI_NAME, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE, on_pdi_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); } } } static void client_signal_handler (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { GDBusProxy *proxy; GError *error = NULL; GVariant *output; if (g_strcmp0 (signal_name, "QueryEndSession") == 0 || g_strcmp0 (signal_name, "EndSession") == 0) { proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, sender_name, object_path, interface_name, NULL, &error); if (proxy) { output = g_dbus_proxy_call_sync (proxy, "EndSessionResponse", g_variant_new ("(bs)", TRUE, ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (output) { g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); } else { g_warning ("%s", error->message); g_error_free (error); } if (g_strcmp0 (signal_name, "EndSession") == 0) { g_main_loop_quit (main_loop); g_debug ("Exiting csd-printer"); } } } static gchar * register_gnome_session_client (const gchar *app_id, const gchar *client_startup_id) { GDBusProxy *proxy; GVariant *output = NULL; GError *error = NULL; const gchar *client_id = NULL; gchar *result = NULL; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_IFACE, NULL, &error); if (proxy) { output = g_dbus_proxy_call_sync (proxy, "RegisterClient", g_variant_new ("(ss)", app_id, client_startup_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (output) { g_variant_get (output, "(o)", &client_id); if (client_id) result = g_strdup (client_id); g_variant_unref (output); } else { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (proxy); } else { g_warning ("%s", error->message); g_error_free (error); } return result; } int main (int argc, char *argv[]) { GDBusConnection *connection; gboolean client_signal_subscription_set = FALSE; GError *error = NULL; guint client_signal_subscription_id; guint session_signal_subscription_id; gchar *object_path; bindtextdomain (GETTEXT_PACKAGE, CINNAMON_SETTINGS_LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); setlocale (LC_ALL, ""); npn_registration_id = 0; pdi_registration_id = 0; npn_owner_id = 0; pdi_owner_id = 0; notify_init ("cinnamon-settings-daemon-printer"); npn_introspection_data = g_dbus_node_info_new_for_xml (npn_introspection_xml, &error); if (npn_introspection_data == NULL) { g_warning ("Error parsing introspection XML: %s\n", error->message); g_error_free (error); goto error; } pdi_introspection_data = g_dbus_node_info_new_for_xml (pdi_introspection_xml, &error); if (pdi_introspection_data == NULL) { g_warning ("Error parsing introspection XML: %s\n", error->message); g_error_free (error); goto error; } connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); session_signal_subscription_id = g_dbus_connection_signal_subscribe (connection, NULL, GNOME_SESSION_PRESENCE_DBUS_IFACE, "StatusChanged", GNOME_SESSION_PRESENCE_DBUS_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, session_signal_handler, NULL, NULL); object_path = register_gnome_session_client ("csd-printer", ""); if (object_path) { client_signal_subscription_id = g_dbus_connection_signal_subscribe (connection, NULL, GNOME_SESSION_CLIENT_PRIVATE_DBUS_IFACE, NULL, object_path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, client_signal_handler, NULL, NULL); client_signal_subscription_set = TRUE; } if (npn_owner_id == 0) npn_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, SCP_DBUS_NPN_NAME, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE, on_npn_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); if (pdi_owner_id == 0) pdi_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, SCP_DBUS_PDI_NAME, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE, on_pdi_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); unregister_objects (); unown_names (); if (client_signal_subscription_set) g_dbus_connection_signal_unsubscribe (connection, client_signal_subscription_id); g_dbus_connection_signal_unsubscribe (connection, session_signal_subscription_id); g_free (object_path); g_dbus_node_info_unref (npn_introspection_data); g_dbus_node_info_unref (pdi_introspection_data); return 0; error: if (npn_introspection_data) g_dbus_node_info_unref (npn_introspection_data); if (pdi_introspection_data) g_dbus_node_info_unref (pdi_introspection_data); return 1; } cinnamon-settings-daemon-6.4.3/plugins/smartcard/0000775000175000017500000000000014733247605021025 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/smartcard/meson.build0000664000175000017500000000160714733247605023173 0ustar fabiofabioplugin_name = 'smartcard' smartcard_sources = [ 'csd-smartcard-manager.c', 'csd-smartcard.c', 'main.c', ] smartcard_deps = [ common_dep, csd_dep, libnotify, nss ] executable( 'csd-smartcard', smartcard_sources, include_directories: [include_dirs, common_inc], dependencies: smartcard_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-smartcard') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-smartcard') endif configure_file( input: 'cinnamon-settings-daemon-smartcard.desktop.in', output: 'cinnamon-settings-daemon-smartcard.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/smartcard/csd-smartcard-manager.h0000664000175000017500000000716314733247605025344 0ustar fabiofabio/* csd-smartcard-manager.h - object for monitoring smartcard insertion and * removal events * * Copyright (C) 2006, 2009 Red Hat, Inc. * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. * * Written by: Ray Strode */ #ifndef CSD_SMARTCARD_MANAGER_H #define CSD_SMARTCARD_MANAGER_H #define CSD_SMARTCARD_ENABLE_INTERNAL_API #include "csd-smartcard.h" #include #include G_BEGIN_DECLS #define CSD_TYPE_SMARTCARD_MANAGER (csd_smartcard_manager_get_type ()) #define CSD_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CSD_TYPE_SMARTCARD_MANAGER, CsdSmartcardManager)) #define CSD_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CSD_TYPE_SMARTCARD_MANAGER, CsdSmartcardManagerClass)) #define CSD_IS_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SMARTCARD_MANAGER)) #define CSD_IS_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SMARTCARD_MANAGER)) #define CSD_SMARTCARD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CSD_TYPE_SMARTCARD_MANAGER, CsdSmartcardManagerClass)) #define CSD_SMARTCARD_MANAGER_ERROR (csd_smartcard_manager_error_quark ()) typedef struct _CsdSmartcardManager CsdSmartcardManager; typedef struct _CsdSmartcardManagerClass CsdSmartcardManagerClass; typedef struct _CsdSmartcardManagerPrivate CsdSmartcardManagerPrivate; typedef enum _CsdSmartcardManagerError CsdSmartcardManagerError; struct _CsdSmartcardManager { GObject parent; /*< private > */ CsdSmartcardManagerPrivate *priv; }; struct _CsdSmartcardManagerClass { GObjectClass parent_class; /* Signals */ void (*smartcard_inserted) (CsdSmartcardManager *manager, CsdSmartcard *token); void (*smartcard_removed) (CsdSmartcardManager *manager, CsdSmartcard *token); void (*error) (CsdSmartcardManager *manager, GError *error); }; enum _CsdSmartcardManagerError { CSD_SMARTCARD_MANAGER_ERROR_GENERIC = 0, CSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, CSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, CSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, CSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS }; GType csd_smartcard_manager_get_type (void) G_GNUC_CONST; GQuark csd_smartcard_manager_error_quark (void) G_GNUC_CONST; CsdSmartcardManager *csd_smartcard_manager_new_default (void); CsdSmartcardManager *csd_smartcard_manager_new (const char *module); gboolean csd_smartcard_manager_start (CsdSmartcardManager *manager, GError **error); void csd_smartcard_manager_stop (CsdSmartcardManager *manager); char *csd_smartcard_manager_get_module_path (CsdSmartcardManager *manager); gboolean csd_smartcard_manager_login_card_is_inserted (CsdSmartcardManager *manager); G_END_DECLS #endif /* CSD_SMARTCARD_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/smartcard/main.c0000664000175000017500000000104114733247605022111 0ustar fabiofabio#define NEW csd_smartcard_manager_new_default #define START csd_smartcard_manager_start #define STOP csd_smartcard_manager_stop #define MANAGER CsdSmartcardManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-smartcard-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/smartcard/cinnamon-settings-daemon-smartcard.desktop.in0000664000175000017500000000034214733247605031703 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - smartcard Exec=csd-smartcard OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/smartcard/csd-smartcard-manager.c0000664000175000017500000014365714733247605025350 0ustar fabiofabio/* csd-smartcard-manager.c - object for monitoring smartcard insertion and * removal events * * Copyright (C) 2006, 2009 Red Hat, Inc. * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. * * Written By: Ray Strode */ #include "config.h" #include "csd-smartcard-manager.h" #define SMARTCARD_ENABLE_INTERNAL_API #include "csd-smartcard.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef CSD_SMARTCARD_MANAGER_DRIVER #define CSD_SMARTCARD_MANAGER_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so" #endif #ifndef CSD_SMARTCARD_MANAGER_NSS_DB #define CSD_SMARTCARD_MANAGER_NSS_DB SYSCONFDIR"/pki/nssdb" #endif #ifndef CSD_MAX_OPEN_FILE_DESCRIPTORS #define CSD_MAX_OPEN_FILE_DESCRIPTORS 1024 #endif #ifndef CSD_OPEN_FILE_DESCRIPTORS_DIR #define CSD_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd" #endif typedef enum _CsdSmartcardManagerState CsdSmartcardManagerState; typedef struct _CsdSmartcardManagerWorker CsdSmartcardManagerWorker; enum _CsdSmartcardManagerState { CSD_SMARTCARD_MANAGER_STATE_STOPPED = 0, CSD_SMARTCARD_MANAGER_STATE_STARTING, CSD_SMARTCARD_MANAGER_STATE_STARTED, CSD_SMARTCARD_MANAGER_STATE_STOPPING, }; struct _CsdSmartcardManagerPrivate { CsdSmartcardManagerState state; GList *modules; char *module_path; GList *workers; GPid smartcard_event_watcher_pid; GHashTable *smartcards; guint poll_timeout_id; guint32 is_unstoppable : 1; guint32 nss_is_loaded : 1; }; struct _CsdSmartcardManagerWorker { CsdSmartcardManager *manager; int manager_fd; GThread *thread; SECMODModule *module; GHashTable *smartcards; int fd; GSource *event_source; guint32 nss_is_loaded : 1; }; static void csd_smartcard_manager_finalize (GObject *object); static void csd_smartcard_manager_class_install_signals (CsdSmartcardManagerClass *service_class); static void csd_smartcard_manager_class_install_properties (CsdSmartcardManagerClass *service_class); static void csd_smartcard_manager_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void csd_smartcard_manager_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void csd_smartcard_manager_set_module_path (CsdSmartcardManager *manager, const char *module_path); static void csd_smartcard_manager_card_removed_handler (CsdSmartcardManager *manager, CsdSmartcard *card); static void csd_smartcard_manager_card_inserted_handler (CsdSmartcardManager *manager_class, CsdSmartcard *card); static gboolean csd_smartcard_manager_stop_now (CsdSmartcardManager *manager); static void csd_smartcard_manager_queue_stop (CsdSmartcardManager *manager); static CsdSmartcardManagerWorker *csd_smartcard_manager_create_worker (CsdSmartcardManager *manager, SECMODModule *module); static CsdSmartcardManagerWorker * csd_smartcard_manager_worker_new (CsdSmartcardManager *manager, int worker_fd, int manager_fd, SECMODModule *module); static void csd_smartcard_manager_worker_free (CsdSmartcardManagerWorker *worker); static gboolean open_pipe (int *write_fd, int *read_fd); static gboolean read_bytes (int fd, gpointer bytes, gsize num_bytes); static gboolean write_bytes (int fd, gconstpointer bytes, gsize num_bytes); static CsdSmartcard *read_smartcard (int fd, SECMODModule *module); static gboolean write_smartcard (int fd, CsdSmartcard *card); enum { PROP_0 = 0, PROP_MODULE_PATH, NUMBER_OF_PROPERTIES }; enum { SMARTCARD_INSERTED = 0, SMARTCARD_REMOVED, ERROR, NUMBER_OF_SIGNALS }; static guint csd_smartcard_manager_signals[NUMBER_OF_SIGNALS]; G_DEFINE_TYPE (CsdSmartcardManager, csd_smartcard_manager, G_TYPE_OBJECT); static void csd_smartcard_manager_class_init (CsdSmartcardManagerClass *manager_class) { GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (manager_class); gobject_class->finalize = csd_smartcard_manager_finalize; csd_smartcard_manager_class_install_signals (manager_class); csd_smartcard_manager_class_install_properties (manager_class); g_type_class_add_private (manager_class, sizeof (CsdSmartcardManagerPrivate)); } static void csd_smartcard_manager_class_install_properties (CsdSmartcardManagerClass *card_class) { GObjectClass *object_class; GParamSpec *param_spec; object_class = G_OBJECT_CLASS (card_class); object_class->set_property = csd_smartcard_manager_set_property; object_class->get_property = csd_smartcard_manager_get_property; param_spec = g_param_spec_string ("module-path", "Module Path", "path to smartcard PKCS #11 driver", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec); } static void csd_smartcard_manager_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CsdSmartcardManager *manager = CSD_SMARTCARD_MANAGER (object); switch (prop_id) { case PROP_MODULE_PATH: csd_smartcard_manager_set_module_path (manager, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_smartcard_manager_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdSmartcardManager *manager = CSD_SMARTCARD_MANAGER (object); char *module_path; switch (prop_id) { case PROP_MODULE_PATH: module_path = csd_smartcard_manager_get_module_path (manager); g_value_set_string (value, module_path); g_free (module_path); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } char * csd_smartcard_manager_get_module_path (CsdSmartcardManager *manager) { return manager->priv->module_path; } static void csd_smartcard_manager_set_module_path (CsdSmartcardManager *manager, const char *module_path) { if ((manager->priv->module_path == NULL) && (module_path == NULL)) { return; } if (((manager->priv->module_path == NULL) || (module_path == NULL) || (strcmp (manager->priv->module_path, module_path) != 0))) { g_free (manager->priv->module_path); manager->priv->module_path = g_strdup (module_path); g_object_notify (G_OBJECT (manager), "module-path"); } } static void csd_smartcard_manager_card_removed_handler (CsdSmartcardManager *manager, CsdSmartcard *card) { g_debug ("informing smartcard of its removal"); _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_REMOVED); g_debug ("done"); } static void csd_smartcard_manager_card_inserted_handler (CsdSmartcardManager *manager, CsdSmartcard *card) { g_debug ("informing smartcard of its insertion"); _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_INSERTED); g_debug ("done"); } static void csd_smartcard_manager_class_install_signals (CsdSmartcardManagerClass *manager_class) { GObjectClass *object_class; object_class = G_OBJECT_CLASS (manager_class); csd_smartcard_manager_signals[SMARTCARD_INSERTED] = g_signal_new ("smartcard-inserted", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (CsdSmartcardManagerClass, smartcard_inserted), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); manager_class->smartcard_inserted = csd_smartcard_manager_card_inserted_handler; csd_smartcard_manager_signals[SMARTCARD_REMOVED] = g_signal_new ("smartcard-removed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (CsdSmartcardManagerClass, smartcard_removed), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); manager_class->smartcard_removed = csd_smartcard_manager_card_removed_handler; csd_smartcard_manager_signals[ERROR] = g_signal_new ("error", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdSmartcardManagerClass, error), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); manager_class->error = NULL; } static gboolean slot_id_equal (CK_SLOT_ID *slot_id_1, CK_SLOT_ID *slot_id_2) { g_assert (slot_id_1 != NULL); g_assert (slot_id_2 != NULL); return *slot_id_1 == *slot_id_2; } static gboolean slot_id_hash (CK_SLOT_ID *slot_id) { guint32 upper_bits, lower_bits; int temp; if (sizeof (CK_SLOT_ID) == sizeof (int)) { return g_int_hash (slot_id); } upper_bits = ((*slot_id) >> 31) - 1; lower_bits = (*slot_id) & 0xffffffff; /* The upper bits are almost certainly always zero, * so let's degenerate to g_int_hash for the * (very) common case */ temp = lower_bits + upper_bits; return upper_bits + g_int_hash (&temp); } static void csd_smartcard_manager_init (CsdSmartcardManager *manager) { g_debug ("initializing smartcard manager"); manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, CSD_TYPE_SMARTCARD_MANAGER, CsdSmartcardManagerPrivate); manager->priv->poll_timeout_id = 0; manager->priv->is_unstoppable = FALSE; manager->priv->smartcards = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); } static void csd_smartcard_manager_finalize (GObject *object) { CsdSmartcardManager *manager; GObjectClass *gobject_class; manager = CSD_SMARTCARD_MANAGER (object); gobject_class = G_OBJECT_CLASS (csd_smartcard_manager_parent_class); csd_smartcard_manager_stop_now (manager); g_hash_table_destroy (manager->priv->smartcards); manager->priv->smartcards = NULL; gobject_class->finalize (object); } GQuark csd_smartcard_manager_error_quark (void) { static GQuark error_quark = 0; if (error_quark == 0) { error_quark = g_quark_from_static_string ("csd-smartcard-manager-error-quark"); } return error_quark; } CsdSmartcardManager * csd_smartcard_manager_new_default (void) { return csd_smartcard_manager_new (NULL); } CsdSmartcardManager * csd_smartcard_manager_new (const char *module_path) { CsdSmartcardManager *instance; instance = CSD_SMARTCARD_MANAGER (g_object_new (CSD_TYPE_SMARTCARD_MANAGER, "module-path", module_path, NULL)); return instance; } static void csd_smartcard_manager_emit_error (CsdSmartcardManager *manager, GError *error) { manager->priv->is_unstoppable = TRUE; g_signal_emit (manager, csd_smartcard_manager_signals[ERROR], 0, error); manager->priv->is_unstoppable = FALSE; } static void csd_smartcard_manager_emit_smartcard_inserted (CsdSmartcardManager *manager, CsdSmartcard *card) { manager->priv->is_unstoppable = TRUE; g_signal_emit (manager, csd_smartcard_manager_signals[SMARTCARD_INSERTED], 0, card); manager->priv->is_unstoppable = FALSE; } static void csd_smartcard_manager_emit_smartcard_removed (CsdSmartcardManager *manager, CsdSmartcard *card) { manager->priv->is_unstoppable = TRUE; g_signal_emit (manager, csd_smartcard_manager_signals[SMARTCARD_REMOVED], 0, card); manager->priv->is_unstoppable = FALSE; } static gboolean csd_smartcard_manager_check_for_and_process_events (GIOChannel *io_channel, GIOCondition condition, CsdSmartcardManagerWorker *worker) { CsdSmartcard *card; CsdSmartcardManager *manager; gboolean should_stop; guchar event_type; char *card_name; int fd; manager = worker->manager; g_debug ("event!"); card = NULL; should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR); if (should_stop) { g_debug ("received %s on event socket, stopping " "manager...", (condition & G_IO_HUP) && (condition & G_IO_ERR)? "error and hangup" : (condition & G_IO_HUP)? "hangup" : "error"); } if (!(condition & G_IO_IN)) { g_debug ("nevermind outta here!"); goto out; } fd = g_io_channel_unix_get_fd (io_channel); event_type = '\0'; if (!read_bytes (fd, &event_type, 1)) { g_debug ("could not read event type, stopping"); should_stop = TRUE; goto out; } card = read_smartcard (fd, worker->module); if (card == NULL) { g_debug ("could not read card, stopping"); should_stop = TRUE; goto out; } card_name = csd_smartcard_get_name (card); g_debug ("card '%s' had event %c", card_name, event_type); switch (event_type) { case 'I': g_hash_table_replace (manager->priv->smartcards, card_name, card); card_name = NULL; csd_smartcard_manager_emit_smartcard_inserted (manager, card); card = NULL; break; case 'R': csd_smartcard_manager_emit_smartcard_removed (manager, card); if (!g_hash_table_remove (manager->priv->smartcards, card_name)) { g_debug ("got removal event of unknown card!"); } g_free (card_name); card_name = NULL; card = NULL; break; default: g_free (card_name); card_name = NULL; g_object_unref (card); should_stop = TRUE; break; } out: if (should_stop) { GError *error; error = g_error_new (CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, "%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source")); csd_smartcard_manager_emit_error (manager, error); g_error_free (error); csd_smartcard_manager_stop_now (manager); return FALSE; } return TRUE; } static void stop_manager (CsdSmartcardManager *manager) { manager->priv->state = CSD_SMARTCARD_MANAGER_STATE_STOPPED; if (manager->priv->nss_is_loaded) { NSS_Shutdown (); manager->priv->nss_is_loaded = FALSE; } g_debug ("smartcard manager stopped"); } static void stop_worker (CsdSmartcardManagerWorker *worker) { CsdSmartcardManager *manager; manager = worker->manager; if (worker->event_source != NULL) { g_source_destroy (worker->event_source); worker->event_source = NULL; } if (worker->thread != NULL) { SECMOD_CancelWait (worker->module); worker->thread = NULL; } SECMOD_DestroyModule (worker->module); manager->priv->workers = g_list_remove (manager->priv->workers, worker); if (manager->priv->workers == NULL && manager->priv->state != CSD_SMARTCARD_MANAGER_STATE_STOPPED) { stop_manager (manager); } } static void csd_smartcard_manager_event_processing_stopped_handler (CsdSmartcardManagerWorker *worker) { worker->event_source = NULL; stop_worker (worker); } static gboolean open_pipe (int *write_fd, int *read_fd) { int pipe_fds[2] = { -1, -1 }; g_assert (write_fd != NULL); g_assert (read_fd != NULL); if (pipe (pipe_fds) < 0) { return FALSE; } if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) { close (pipe_fds[0]); close (pipe_fds[1]); return FALSE; } if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) { close (pipe_fds[0]); close (pipe_fds[1]); return FALSE; } *read_fd = pipe_fds[0]; *write_fd = pipe_fds[1]; return TRUE; } static void csd_smartcard_manager_stop_watching_for_events (CsdSmartcardManager *manager) { GList *node; node = manager->priv->workers; while (node != NULL) { CsdSmartcardManagerWorker *worker; GList *next_node; worker = (CsdSmartcardManagerWorker *) node->data; next_node = node->next; stop_worker (worker); node = next_node; } } static gboolean load_nss (GError **error) { SECStatus status = SECSuccess; static const guint32 flags = NSS_INIT_READONLY | NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD; g_debug ("attempting to load NSS database '%s'", CSD_SMARTCARD_MANAGER_NSS_DB); PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); status = NSS_Initialize (CSD_SMARTCARD_MANAGER_NSS_DB, "", "", SECMOD_DB, flags); if (status != SECSuccess) { gsize error_message_size; char *error_message; error_message_size = PR_GetErrorTextLength (); if (error_message_size == 0) { g_debug ("NSS security system could not be initialized"); g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, _("NSS security system could not be initialized")); goto out; } error_message = g_slice_alloc0 (error_message_size); PR_GetErrorText (error_message); g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, "%s", error_message); g_debug ("NSS security system could not be initialized - %s", error_message); g_slice_free1 (error_message_size, error_message); goto out; } g_debug ("NSS database successfully loaded"); return TRUE; out: g_debug ("NSS database couldn't be successfully loaded"); return FALSE; } static GList * get_available_modules (CsdSmartcardManager *manager) { SECMODModuleList *module_list, *tmp; GList *modules; g_debug ("Getting list of suitable modules"); module_list = SECMOD_GetDefaultModuleList (); modules = NULL; for (tmp = module_list; tmp != NULL; tmp = tmp->next) { if (!SECMOD_HasRemovableSlots (tmp->module) || !tmp->module->loaded) continue; g_debug ("Using module '%s'", tmp->module->commonName); modules = g_list_prepend (modules, SECMOD_ReferenceModule (tmp->module)); } return modules; } static gboolean load_driver (CsdSmartcardManager *manager, char *module_path, GError **error) { GList *modules; char *module_spec; gboolean module_explicitly_specified; g_debug ("attempting to load driver..."); modules = NULL; module_explicitly_specified = module_path != NULL; if (module_explicitly_specified) { SECMODModule *module; module_spec = g_strdup_printf ("library=\"%s\"", module_path); g_debug ("loading smartcard driver using spec '%s'", module_spec); module = SECMOD_LoadUserModule (module_spec, NULL /* parent */, FALSE /* recurse */); g_free (module_spec); module_spec = NULL; if (SECMOD_HasRemovableSlots (module) && module->loaded) { modules = g_list_prepend (modules, module); } else { g_debug ("fallback module found but not %s", SECMOD_HasRemovableSlots (module)? "removable" : "loaded"); SECMOD_DestroyModule (module); } } else { SECMODListLock *lock; lock = SECMOD_GetDefaultModuleListLock (); if (lock != NULL) { SECMOD_GetReadLock (lock); modules = get_available_modules (manager); SECMOD_ReleaseReadLock (lock); } /* fallback to compiled in driver path */ if (modules == NULL) { SECMODModule *module; module_path = CSD_SMARTCARD_MANAGER_DRIVER; module_spec = g_strdup_printf ("library=\"%s\"", module_path); g_debug ("loading smartcard driver using spec '%s'", module_spec); module = SECMOD_LoadUserModule (module_spec, NULL /* parent */, FALSE /* recurse */); g_free (module_spec); module_spec = NULL; if (SECMOD_HasRemovableSlots (module) && module->loaded) { modules = g_list_prepend (modules, module); } else { g_debug ("fallback module found but not loaded"); SECMOD_DestroyModule (module); } } } if (!module_explicitly_specified && modules == NULL) { g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, _("no suitable smartcard driver could be found")); } else if (modules == NULL) { gsize error_message_size; char *error_message; error_message_size = PR_GetErrorTextLength (); if (error_message_size == 0) { g_debug ("smartcard driver '%s' could not be loaded", module_path); g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, _("smartcard driver '%s' could not be " "loaded"), module_path); goto out; } error_message = g_slice_alloc0 (error_message_size); PR_GetErrorText (error_message); g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, "%s", error_message); g_debug ("smartcard driver '%s' could not be loaded - %s", module_path, error_message); g_slice_free1 (error_message_size, error_message); } manager->priv->modules = modules; out: return manager->priv->modules != NULL; } static void csd_smartcard_manager_get_all_cards (CsdSmartcardManager *manager) { GList *node; int i; node = manager->priv->workers; while (node != NULL) { CsdSmartcardManagerWorker *worker; worker = (CsdSmartcardManagerWorker *) node->data; for (i = 0; i < worker->module->slotCount; i++) { CsdSmartcard *card; CK_SLOT_ID slot_id; int slot_series; char *card_name; slot_id = PK11_GetSlotID (worker->module->slots[i]); slot_series = PK11_GetSlotSeries (worker->module->slots[i]); card = _csd_smartcard_new (worker->module, slot_id, slot_series); card_name = csd_smartcard_get_name (card); g_hash_table_replace (manager->priv->smartcards, card_name, card); } node = node->next; } } static CsdSmartcardManagerWorker * start_worker (CsdSmartcardManager *manager, SECMODModule *module, GError **error) { GIOChannel *io_channel; GSource *source; CsdSmartcardManagerWorker *worker; worker = csd_smartcard_manager_create_worker (manager, module); if (worker == NULL) { g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, _("could not watch for incoming card events - %s"), g_strerror (errno)); goto out; } io_channel = g_io_channel_unix_new (worker->manager_fd); source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP); g_io_channel_unref (io_channel); io_channel = NULL; worker->event_source = source; g_source_set_callback (worker->event_source, (GSourceFunc) (GIOFunc) csd_smartcard_manager_check_for_and_process_events, worker, (GDestroyNotify) csd_smartcard_manager_event_processing_stopped_handler); g_source_attach (worker->event_source, NULL); g_source_unref (worker->event_source); out: return worker; } static void start_workers (CsdSmartcardManager *manager) { GList *node; node = manager->priv->modules; while (node != NULL) { SECMODModule *module; CsdSmartcardManagerWorker *worker; GError *error; module = (SECMODModule *) node->data; error = NULL; worker = start_worker (manager, module, &error); if (worker == NULL) { g_warning ("%s", error->message); g_error_free (error); } else { manager->priv->workers = g_list_prepend (manager->priv->workers, worker); } node = node->next; } } gboolean csd_smartcard_manager_start (CsdSmartcardManager *manager, GError **error) { GError *nss_error; if (manager->priv->state == CSD_SMARTCARD_MANAGER_STATE_STARTED) { g_debug ("smartcard manager already started"); return TRUE; } manager->priv->state = CSD_SMARTCARD_MANAGER_STATE_STARTING; nss_error = NULL; if (!manager->priv->nss_is_loaded && !load_nss (&nss_error)) { g_propagate_error (error, nss_error); goto out; } manager->priv->nss_is_loaded = TRUE; if (manager->priv->modules == NULL) { if (!load_driver (manager, manager->priv->module_path, &nss_error)) { g_propagate_error (error, nss_error); goto out; } } start_workers (manager); /* populate the hash with cards that are already inserted */ csd_smartcard_manager_get_all_cards (manager); manager->priv->state = CSD_SMARTCARD_MANAGER_STATE_STARTED; out: /* don't leave it in a half started state */ if (manager->priv->state != CSD_SMARTCARD_MANAGER_STATE_STARTED) { g_debug ("smartcard manager could not be completely started"); csd_smartcard_manager_stop (manager); } else { g_debug ("smartcard manager started"); } return manager->priv->state == CSD_SMARTCARD_MANAGER_STATE_STARTED; } static gboolean csd_smartcard_manager_stop_now (CsdSmartcardManager *manager) { if (manager->priv->state == CSD_SMARTCARD_MANAGER_STATE_STOPPED) { return FALSE; } csd_smartcard_manager_stop_watching_for_events (manager); return FALSE; } static void csd_smartcard_manager_queue_stop (CsdSmartcardManager *manager) { manager->priv->state = CSD_SMARTCARD_MANAGER_STATE_STOPPING; g_idle_add ((GSourceFunc) csd_smartcard_manager_stop_now, manager); } void csd_smartcard_manager_stop (CsdSmartcardManager *manager) { if (manager->priv->state == CSD_SMARTCARD_MANAGER_STATE_STOPPED) { return; } if (manager->priv->is_unstoppable) { csd_smartcard_manager_queue_stop (manager); return; } csd_smartcard_manager_stop_now (manager); } static void csd_smartcard_manager_check_for_login_card (CK_SLOT_ID slot_id, CsdSmartcard *card, gboolean *is_inserted) { g_assert (is_inserted != NULL); if (csd_smartcard_is_login_card (card)) { *is_inserted = TRUE; } } gboolean csd_smartcard_manager_login_card_is_inserted (CsdSmartcardManager *manager) { gboolean is_inserted; is_inserted = FALSE; g_hash_table_foreach (manager->priv->smartcards, (GHFunc) csd_smartcard_manager_check_for_login_card, &is_inserted); return is_inserted; } static CsdSmartcardManagerWorker * csd_smartcard_manager_worker_new (CsdSmartcardManager *manager, int worker_fd, int manager_fd, SECMODModule *module) { CsdSmartcardManagerWorker *worker; worker = g_slice_new0 (CsdSmartcardManagerWorker); worker->manager = manager; worker->fd = worker_fd; worker->manager_fd = manager_fd; worker->module = module; worker->smartcards = g_hash_table_new_full ((GHashFunc) slot_id_hash, (GEqualFunc) slot_id_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); return worker; } static void csd_smartcard_manager_worker_free (CsdSmartcardManagerWorker *worker) { if (worker->smartcards != NULL) { g_hash_table_destroy (worker->smartcards); worker->smartcards = NULL; } g_slice_free (CsdSmartcardManagerWorker, worker); } static gboolean read_bytes (int fd, gpointer bytes, gsize num_bytes) { size_t bytes_left; size_t total_bytes_read; ssize_t bytes_read; bytes_left = (size_t) num_bytes; total_bytes_read = 0; do { bytes_read = read (fd, (char *) bytes + total_bytes_read, bytes_left); g_assert (bytes_read <= (ssize_t) bytes_left); if (bytes_read <= 0) { if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN)) { continue; } bytes_left = 0; } else { bytes_left -= bytes_read; total_bytes_read += bytes_read; } } while (bytes_left > 0); if (total_bytes_read < (size_t) num_bytes) { return FALSE; } return TRUE; } static gboolean write_bytes (int fd, gconstpointer bytes, gsize num_bytes) { size_t bytes_left; size_t total_bytes_written; ssize_t bytes_written; bytes_left = (size_t) num_bytes; total_bytes_written = 0; do { bytes_written = write (fd, (char *) bytes + total_bytes_written, bytes_left); g_assert (bytes_written <= (ssize_t) bytes_left); if (bytes_written <= 0) { if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN)) { continue; } bytes_left = 0; } else { bytes_left -= bytes_written; total_bytes_written += bytes_written; } } while (bytes_left > 0); if (total_bytes_written < (size_t) num_bytes) { return FALSE; } return TRUE; } static CsdSmartcard * read_smartcard (int fd, SECMODModule *module) { CsdSmartcard *card; char *card_name; gsize card_name_size; card_name_size = 0; if (!read_bytes (fd, &card_name_size, sizeof (card_name_size))) { return NULL; } card_name = g_slice_alloc0 (card_name_size); if (!read_bytes (fd, card_name, card_name_size)) { g_slice_free1 (card_name_size, card_name); return NULL; } card = _csd_smartcard_new_from_name (module, card_name); g_slice_free1 (card_name_size, card_name); return card; } static gboolean write_smartcard (int fd, CsdSmartcard *card) { gsize card_name_size; char *card_name; card_name = csd_smartcard_get_name (card); card_name_size = strlen (card_name) + 1; if (!write_bytes (fd, &card_name_size, sizeof (card_name_size))) { g_free (card_name); return FALSE; } if (!write_bytes (fd, card_name, card_name_size)) { g_free (card_name); return FALSE; } g_free (card_name); return TRUE; } static gboolean csd_smartcard_manager_worker_emit_smartcard_removed (CsdSmartcardManagerWorker *worker, CsdSmartcard *card, GError **error) { g_debug ("card '%s' removed!", csd_smartcard_get_name (card)); if (!write_bytes (worker->fd, "R", 1)) { goto error_out; } if (!write_smartcard (worker->fd, card)) { goto error_out; } return TRUE; error_out: g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, "%s", g_strerror (errno)); return FALSE; } static gboolean csd_smartcard_manager_worker_emit_smartcard_inserted (CsdSmartcardManagerWorker *worker, CsdSmartcard *card, GError **error) { g_debug ("card '%s' inserted!", csd_smartcard_get_name (card)); if (!write_bytes (worker->fd, "I", 1)) { goto error_out; } if (!write_smartcard (worker->fd, card)) { goto error_out; } return TRUE; error_out: g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, "%s", g_strerror (errno)); return FALSE; } static gboolean csd_smartcard_manager_worker_watch_for_and_process_event (CsdSmartcardManagerWorker *worker, GError **error) { PK11SlotInfo *slot; CK_SLOT_ID slot_id, *key = NULL; int slot_series, card_slot_series; CsdSmartcard *card; GError *processing_error; gboolean ret; g_debug ("waiting for card event"); ret = FALSE; slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1)); processing_error = NULL; if (slot == NULL) { int error_code; error_code = PORT_GetError (); if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) { g_debug ("spurious event occurred"); return TRUE; } /* FIXME: is there a function to convert from a PORT error * code to a translated string? */ g_set_error (error, CSD_SMARTCARD_MANAGER_ERROR, CSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, _("encountered unexpected error while " "waiting for smartcard events")); goto out; } /* the slot id and series together uniquely identify a card. * You can never have two cards with the same slot id at the * same time, however (I think), so we can key off of it. */ slot_id = PK11_GetSlotID (slot); slot_series = PK11_GetSlotSeries (slot); /* First check to see if there is a card that we're currently * tracking in the slot. */ key = g_new (CK_SLOT_ID, 1); *key = slot_id; card = g_hash_table_lookup (worker->smartcards, key); if (card != NULL) { card_slot_series = csd_smartcard_get_slot_series (card); } else { card_slot_series = -1; } if (PK11_IsPresent (slot)) { /* Now, check to see if their is a new card in the slot. * If there was a different card in the slot now than * there was before, then we need to emit a removed signal * for the old card (we don't want unpaired insertion events). */ if ((card != NULL) && card_slot_series != slot_series) { if (!csd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { g_propagate_error (error, processing_error); goto out; } } card = _csd_smartcard_new (worker->module, slot_id, slot_series); g_hash_table_replace (worker->smartcards, key, card); key = NULL; if (!csd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) { g_propagate_error (error, processing_error); goto out; } } else { /* if we aren't tracking the card, just discard the event. * We don't want unpaired remove events. Note on startup * NSS will generate an "insertion" event if a card is * already inserted in the slot. */ if ((card != NULL)) { /* FIXME: i'm not sure about this code. Maybe we * shouldn't do this at all, or maybe we should do it * n times (where n = slot_series - card_slot_series + 1) * * Right now, i'm just doing it once. */ if ((slot_series - card_slot_series) > 1) { if (!csd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { g_propagate_error (error, processing_error); goto out; } g_hash_table_remove (worker->smartcards, key); card = _csd_smartcard_new (worker->module, slot_id, slot_series); g_hash_table_replace (worker->smartcards, key, card); key = NULL; if (!csd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) { g_propagate_error (error, processing_error); goto out; } } if (!csd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { g_propagate_error (error, processing_error); goto out; } g_hash_table_remove (worker->smartcards, key); card = NULL; } else { g_debug ("got spurious remove event"); } } ret = TRUE; out: g_free (key); PK11_FreeSlot (slot); return ret; } static void csd_smartcard_manager_worker_run (CsdSmartcardManagerWorker *worker) { GError *error; gboolean should_continue; do { error = NULL; should_continue = csd_smartcard_manager_worker_watch_for_and_process_event (worker, &error); } while (should_continue); if (error != NULL) { g_debug ("could not process card event - %s", error->message); g_error_free (error); } csd_smartcard_manager_worker_free (worker); } static CsdSmartcardManagerWorker * csd_smartcard_manager_create_worker (CsdSmartcardManager *manager, SECMODModule *module) { CsdSmartcardManagerWorker *worker; int write_fd, read_fd; write_fd = -1; read_fd = -1; if (!open_pipe (&write_fd, &read_fd)) { return NULL; } worker = csd_smartcard_manager_worker_new (manager, write_fd, read_fd, module); worker->thread = g_thread_create ((GThreadFunc) csd_smartcard_manager_worker_run, worker, FALSE, NULL); if (worker->thread == NULL) { csd_smartcard_manager_worker_free (worker); return NULL; } return worker; } #ifdef CSD_SMARTCARD_MANAGER_ENABLE_TEST #include static GMainLoop *event_loop; static gboolean should_exit_on_next_remove = FALSE; static gboolean on_timeout (CsdSmartcardManager *manager) { GError *error; g_print ("Re-enabling manager.\n"); if (!csd_smartcard_manager_start (manager, &error)) { g_warning ("could not start smartcard manager - %s", error->message); g_error_free (error); return TRUE; } g_print ("Please re-insert smartcard\n"); should_exit_on_next_remove = TRUE; return FALSE; } static void on_device_inserted (CsdSmartcardManager *manager, CsdSmartcard *card) { g_print ("smartcard inserted!\n"); g_print ("Please remove it.\n"); } static void on_device_removed (CsdSmartcardManager *manager, CsdSmartcard *card) { g_print ("smartcard removed!\n"); if (should_exit_on_next_remove) { g_main_loop_quit (event_loop); } else { g_print ("disabling manager for 2 seconds\n"); csd_smartcard_manager_stop (manager); g_timeout_add_seconds (2, (GSourceFunc) on_timeout, manager); } } int main (int argc, char *argv[]) { CsdSmartcardManager *manager; GError *error; g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); g_message ("creating instance of 'smartcard manager' object..."); manager = csd_smartcard_manager_new (NULL); g_message ("'smartcard manager' object created successfully"); g_signal_connect (manager, "smartcard-inserted", G_CALLBACK (on_device_inserted), NULL); g_signal_connect (manager, "smartcard-removed", G_CALLBACK (on_device_removed), NULL); g_message ("starting listener..."); error = NULL; if (!csd_smartcard_manager_start (manager, &error)) { g_warning ("could not start smartcard manager - %s", error->message); g_error_free (error); return 1; } event_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (event_loop); g_main_loop_unref (event_loop); event_loop = NULL; g_message ("destroying previously created 'smartcard manager' object..."); g_object_unref (manager); manager = NULL; g_message ("'smartcard manager' object destroyed successfully"); return 0; } #endif cinnamon-settings-daemon-6.4.3/plugins/smartcard/csd-smartcard.c0000664000175000017500000004424314733247605023727 0ustar fabiofabio/* csd-smartcard.c - smartcard object * * Copyright (C) 2006 Ray Strode * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include "config.h" #define CSD_SMARTCARD_ENABLE_INTERNAL_API #include "csd-smartcard.h" #include #include #include #include #include #include #include #include #include #include #include struct _CsdSmartcardPrivate { SECMODModule *module; CsdSmartcardState state; CK_SLOT_ID slot_id; int slot_series; PK11SlotInfo *slot; char *name; CERTCertificate *signing_certificate; CERTCertificate *encryption_certificate; }; static void csd_smartcard_finalize (GObject *object); static void csd_smartcard_class_install_signals (CsdSmartcardClass *card_class); static void csd_smartcard_class_install_properties (CsdSmartcardClass *card_class); static void csd_smartcard_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void csd_smartcard_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void csd_smartcard_set_name (CsdSmartcard *card, const char *name); static void csd_smartcard_set_slot_id (CsdSmartcard *card, int slot_id); static void csd_smartcard_set_slot_series (CsdSmartcard *card, int slot_series); static void csd_smartcard_set_module (CsdSmartcard *card, SECMODModule *module); static PK11SlotInfo *csd_smartcard_find_slot_from_id (CsdSmartcard *card, int slot_id); static PK11SlotInfo *csd_smartcard_find_slot_from_card_name (CsdSmartcard *card, const char *card_name); #ifndef CSD_SMARTCARD_DEFAULT_SLOT_ID #define CSD_SMARTCARD_DEFAULT_SLOT_ID ((gulong) -1) #endif #ifndef CSD_SMARTCARD_DEFAULT_SLOT_SERIES #define CSD_SMARTCARD_DEFAULT_SLOT_SERIES -1 #endif enum { PROP_0 = 0, PROP_NAME, PROP_SLOT_ID, PROP_SLOT_SERIES, PROP_MODULE, NUMBER_OF_PROPERTIES }; enum { INSERTED, REMOVED, NUMBER_OF_SIGNALS }; static guint csd_smartcard_signals[NUMBER_OF_SIGNALS]; G_DEFINE_TYPE (CsdSmartcard, csd_smartcard, G_TYPE_OBJECT); static void csd_smartcard_class_init (CsdSmartcardClass *card_class) { GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (card_class); gobject_class->finalize = csd_smartcard_finalize; csd_smartcard_class_install_signals (card_class); csd_smartcard_class_install_properties (card_class); g_type_class_add_private (card_class, sizeof (CsdSmartcardPrivate)); } static void csd_smartcard_class_install_signals (CsdSmartcardClass *card_class) { GObjectClass *object_class; object_class = G_OBJECT_CLASS (card_class); csd_smartcard_signals[INSERTED] = g_signal_new ("inserted", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdSmartcardClass, inserted), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); csd_smartcard_signals[REMOVED] = g_signal_new ("removed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdSmartcardClass, removed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void csd_smartcard_class_install_properties (CsdSmartcardClass *card_class) { GObjectClass *object_class; GParamSpec *param_spec; object_class = G_OBJECT_CLASS (card_class); object_class->set_property = csd_smartcard_set_property; object_class->get_property = csd_smartcard_get_property; param_spec = g_param_spec_ulong ("slot-id", "Slot ID", "The slot the card is in", 1, G_MAXULONG, CSD_SMARTCARD_DEFAULT_SLOT_ID, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec); param_spec = g_param_spec_int ("slot-series", "Slot Series", "per-slot card identifier", -1, G_MAXINT, CSD_SMARTCARD_DEFAULT_SLOT_SERIES, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec); param_spec = g_param_spec_string ("name", "name", "name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_NAME, param_spec); param_spec = g_param_spec_pointer ("module", "Module", "smartcard driver", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_MODULE, param_spec); } static void csd_smartcard_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CsdSmartcard *card = CSD_SMARTCARD (object); switch (prop_id) { case PROP_NAME: csd_smartcard_set_name (card, g_value_get_string (value)); break; case PROP_SLOT_ID: csd_smartcard_set_slot_id (card, g_value_get_ulong (value)); break; case PROP_SLOT_SERIES: csd_smartcard_set_slot_series (card, g_value_get_int (value)); break; case PROP_MODULE: csd_smartcard_set_module (card, (SECMODModule *) g_value_get_pointer (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } CK_SLOT_ID csd_smartcard_get_slot_id (CsdSmartcard *card) { return card->priv->slot_id; } CsdSmartcardState csd_smartcard_get_state (CsdSmartcard *card) { return card->priv->state; } char * csd_smartcard_get_name (CsdSmartcard *card) { return g_strdup (card->priv->name); } gboolean csd_smartcard_is_login_card (CsdSmartcard *card) { const char *login_card_name; login_card_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME"); if ((login_card_name == NULL) || (card->priv->name == NULL)) { return FALSE; } if (strcmp (card->priv->name, login_card_name) == 0) { return TRUE; } return FALSE; } static void csd_smartcard_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdSmartcard *card = CSD_SMARTCARD (object); switch (prop_id) { case PROP_NAME: g_value_take_string (value, csd_smartcard_get_name (card)); break; case PROP_SLOT_ID: g_value_set_ulong (value, (gulong) csd_smartcard_get_slot_id (card)); break; case PROP_SLOT_SERIES: g_value_set_int (value, csd_smartcard_get_slot_series (card)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void csd_smartcard_set_name (CsdSmartcard *card, const char *name) { if (name == NULL) { return; } if ((card->priv->name == NULL) || (strcmp (card->priv->name, name) != 0)) { g_free (card->priv->name); card->priv->name = g_strdup (name); if (card->priv->slot == NULL) { card->priv->slot = csd_smartcard_find_slot_from_card_name (card, card->priv->name); if (card->priv->slot != NULL) { int slot_id, slot_series; slot_id = PK11_GetSlotID (card->priv->slot); if (slot_id != card->priv->slot_id) { csd_smartcard_set_slot_id (card, slot_id); } slot_series = PK11_GetSlotSeries (card->priv->slot); if (slot_series != card->priv->slot_series) { csd_smartcard_set_slot_series (card, slot_series); } _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_INSERTED); } else { _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_REMOVED); } } g_object_notify (G_OBJECT (card), "name"); } } static void csd_smartcard_set_slot_id (CsdSmartcard *card, int slot_id) { if (card->priv->slot_id != slot_id) { card->priv->slot_id = slot_id; if (card->priv->slot == NULL) { card->priv->slot = csd_smartcard_find_slot_from_id (card, card->priv->slot_id); if (card->priv->slot != NULL) { const char *card_name; card_name = PK11_GetTokenName (card->priv->slot); if ((card->priv->name == NULL) || ((card_name != NULL) && (strcmp (card_name, card->priv->name) != 0))) { csd_smartcard_set_name (card, card_name); } _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_INSERTED); } else { _csd_smartcard_set_state (card, CSD_SMARTCARD_STATE_REMOVED); } } g_object_notify (G_OBJECT (card), "slot-id"); } } static void csd_smartcard_set_slot_series (CsdSmartcard *card, int slot_series) { if (card->priv->slot_series != slot_series) { card->priv->slot_series = slot_series; g_object_notify (G_OBJECT (card), "slot-series"); } } static void csd_smartcard_set_module (CsdSmartcard *card, SECMODModule *module) { gboolean should_notify; if (card->priv->module != module) { should_notify = TRUE; } else { should_notify = FALSE; } if (card->priv->module != NULL) { SECMOD_DestroyModule (card->priv->module); card->priv->module = NULL; } if (module != NULL) { card->priv->module = SECMOD_ReferenceModule (module); } if (should_notify) { g_object_notify (G_OBJECT (card), "module"); } } int csd_smartcard_get_slot_series (CsdSmartcard *card) { return card->priv->slot_series; } static void csd_smartcard_init (CsdSmartcard *card) { g_debug ("initializing smartcard "); card->priv = G_TYPE_INSTANCE_GET_PRIVATE (card, CSD_TYPE_SMARTCARD, CsdSmartcardPrivate); } static void csd_smartcard_finalize (GObject *object) { CsdSmartcard *card; GObjectClass *gobject_class; card = CSD_SMARTCARD (object); g_free (card->priv->name); csd_smartcard_set_module (card, NULL); gobject_class = G_OBJECT_CLASS (csd_smartcard_parent_class); gobject_class->finalize (object); } GQuark csd_smartcard_error_quark (void) { static GQuark error_quark = 0; if (error_quark == 0) { error_quark = g_quark_from_static_string ("csd-smartcard-error-quark"); } return error_quark; } CsdSmartcard * _csd_smartcard_new (SECMODModule *module, CK_SLOT_ID slot_id, int slot_series) { CsdSmartcard *card; g_return_val_if_fail (module != NULL, NULL); g_return_val_if_fail (slot_id >= 1, NULL); g_return_val_if_fail (slot_series > 0, NULL); g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL); card = CSD_SMARTCARD (g_object_new (CSD_TYPE_SMARTCARD, "module", module, "slot-id", (gulong) slot_id, "slot-series", slot_series, NULL)); return card; } CsdSmartcard * _csd_smartcard_new_from_name (SECMODModule *module, const char *name) { CsdSmartcard *card; g_return_val_if_fail (module != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); card = CSD_SMARTCARD (g_object_new (CSD_TYPE_SMARTCARD, "module", module, "name", name, NULL)); return card; } void _csd_smartcard_set_state (CsdSmartcard *card, CsdSmartcardState state) { /* csd_smartcard_fetch_certificates (card); */ if (card->priv->state != state) { card->priv->state = state; if (state == CSD_SMARTCARD_STATE_INSERTED) { g_signal_emit (card, csd_smartcard_signals[INSERTED], 0); } else if (state == CSD_SMARTCARD_STATE_REMOVED) { g_signal_emit (card, csd_smartcard_signals[REMOVED], 0); } else { g_assert_not_reached (); } } } /* So we could conceivably make the closure data a pointer to the card * or something similar and then emit signals when we want passwords, * but it's probably easier to just get the password up front and use * it. So we just take the passed in g_malloc'd (well probably, who knows) * and strdup it using NSPR's memory allocation routines. */ static char * csd_smartcard_password_handler (PK11SlotInfo *slot, PRBool is_retrying, const char *password) { if (is_retrying) { return NULL; } return password != NULL? PL_strdup (password): NULL; } gboolean csd_smartcard_unlock (CsdSmartcard *card, const char *password) { SECStatus status; PK11_SetPasswordFunc ((PK11PasswordFunc) csd_smartcard_password_handler); /* we pass PR_TRUE to load certificates */ status = PK11_Authenticate (card->priv->slot, PR_TRUE, (gpointer) password); if (status != SECSuccess) { g_debug ("could not unlock card - %d", status); return FALSE; } return TRUE; } static PK11SlotInfo * csd_smartcard_find_slot_from_card_name (CsdSmartcard *card, const char *card_name) { int i; for (i = 0; i < card->priv->module->slotCount; i++) { const char *slot_card_name; slot_card_name = PK11_GetTokenName (card->priv->module->slots[i]); if ((slot_card_name != NULL) && (strcmp (slot_card_name, card_name) == 0)) { return card->priv->module->slots[i]; } } return NULL; } static PK11SlotInfo * csd_smartcard_find_slot_from_id (CsdSmartcard *card, int slot_id) { int i; for (i = 0; i < card->priv->module->slotCount; i++) { if (PK11_GetSlotID (card->priv->module->slots[i]) == slot_id) { return card->priv->module->slots[i]; } } return NULL; } cinnamon-settings-daemon-6.4.3/plugins/smartcard/csd-smartcard.h0000664000175000017500000000656514733247605023741 0ustar fabiofabio/* securitycard.h - api for reading and writing data to a security card * * Copyright (C) 2006 Ray Strode * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #ifndef CSD_SMARTCARD_H #define CSD_SMARTCARD_H #include #include #include G_BEGIN_DECLS #define CSD_TYPE_SMARTCARD (csd_smartcard_get_type ()) #define CSD_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CSD_TYPE_SMARTCARD, CsdSmartcard)) #define CSD_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CSD_TYPE_SMARTCARD, CsdSmartcardClass)) #define CSD_IS_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CSD_TYPE_SMARTCARD)) #define CSD_IS_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CSD_TYPE_SMARTCARD)) #define CSD_SMARTCARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CSD_TYPE_SMARTCARD, CsdSmartcardClass)) #define CSD_SMARTCARD_ERROR (csd_smartcard_error_quark ()) typedef struct _CsdSmartcardClass CsdSmartcardClass; typedef struct _CsdSmartcard CsdSmartcard; typedef struct _CsdSmartcardPrivate CsdSmartcardPrivate; typedef enum _CsdSmartcardError CsdSmartcardError; typedef enum _CsdSmartcardState CsdSmartcardState; typedef struct _CsdSmartcardRequest CsdSmartcardRequest; struct _CsdSmartcard { GObject parent; /*< private > */ CsdSmartcardPrivate *priv; }; struct _CsdSmartcardClass { GObjectClass parent_class; void (* inserted) (CsdSmartcard *card); void (* removed) (CsdSmartcard *card); }; enum _CsdSmartcardError { CSD_SMARTCARD_ERROR_GENERIC = 0, }; enum _CsdSmartcardState { CSD_SMARTCARD_STATE_INSERTED = 0, CSD_SMARTCARD_STATE_REMOVED, }; GType csd_smartcard_get_type (void) G_GNUC_CONST; GQuark csd_smartcard_error_quark (void) G_GNUC_CONST; CK_SLOT_ID csd_smartcard_get_slot_id (CsdSmartcard *card); gint csd_smartcard_get_slot_series (CsdSmartcard *card); CsdSmartcardState csd_smartcard_get_state (CsdSmartcard *card); char *csd_smartcard_get_name (CsdSmartcard *card); gboolean csd_smartcard_is_login_card (CsdSmartcard *card); gboolean csd_smartcard_unlock (CsdSmartcard *card, const char *password); /* don't under any circumstances call these functions */ #ifdef CSD_SMARTCARD_ENABLE_INTERNAL_API CsdSmartcard *_csd_smartcard_new (SECMODModule *module, CK_SLOT_ID slot_id, gint slot_series); CsdSmartcard *_csd_smartcard_new_from_name (SECMODModule *module, const char *name); void _csd_smartcard_set_state (CsdSmartcard *card, CsdSmartcardState state); #endif G_END_DECLS #endif /* CSD_SMARTCARD_H */ cinnamon-settings-daemon-6.4.3/plugins/settings-remap/0000775000175000017500000000000014733247605022007 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/settings-remap/meson.build0000664000175000017500000000162014733247605024150 0ustar fabiofabioplugin_name = 'settings-remap' settings_remap_sources = [ 'csd-settings-remap-manager.c', 'main.c', ] settings_remap_deps = [ common_dep, csd_dep, ] executable( 'csd-settings-remap', settings_remap_sources, include_directories: [include_dirs, common_inc], dependencies: settings_remap_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-settings-remap') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-settings-remap') endif configure_file( input: 'cinnamon-settings-daemon-settings-remap.desktop.in', output: 'cinnamon-settings-daemon-settings-remap.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/settings-remap/main.c0000664000175000017500000000117114733247605023077 0ustar fabiofabio#define NEW csd_settings_remap_manager_new #define START csd_settings_remap_manager_start #define STOP csd_settings_remap_manager_stop #define MANAGER CsdSettingsRemapManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY FALSE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-settings-remap-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/settings-remap/csd-settings-remap-manager.h0000664000175000017500000000273214733247605027305 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2023 Linux Mint * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #pragma once #include G_BEGIN_DECLS #define CSD_TYPE_SETTINGS_REMAP_MANAGER (csd_settings_remap_manager_get_type ()) G_DECLARE_FINAL_TYPE (CsdSettingsRemapManager, csd_settings_remap_manager, CSD, SETTINGS_REMAP_MANAGER, GObject) CsdSettingsRemapManager *csd_settings_remap_manager_new (void); gboolean csd_settings_remap_manager_start (CsdSettingsRemapManager *manager, GError **error); void csd_settings_remap_manager_stop (CsdSettingsRemapManager *manager); G_END_DECLS cinnamon-settings-daemon-6.4.3/plugins/settings-remap/csd-settings-remap-manager.c0000664000175000017500000002012714733247605027276 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-settings-remap-manager.h" typedef struct { GHashTable *settings_table; GSettingsSchemaSource *source; } CsdSettingsRemapManagerPrivate; struct _CsdSettingsRemapManager { GObject parent; CsdSettingsRemapManagerPrivate *priv; }; G_DEFINE_TYPE_WITH_PRIVATE (CsdSettingsRemapManager, csd_settings_remap_manager, G_TYPE_OBJECT) static void csd_settings_remap_manager_class_init (CsdSettingsRemapManagerClass *klass); static void csd_settings_remap_manager_init (CsdSettingsRemapManager *settings_remap_manager); static void csd_settings_remap_manager_finalize (GObject *object); static gpointer manager_object = NULL; typedef struct { const gchar *gnome_schema; const gchar *cinnamon_schema; } SchemaMap; static SchemaMap schemas[] = { { "org.gnome.desktop.interface", "org.cinnamon.desktop.interface" }, { "org.gnome.desktop.peripherals.mouse", "org.cinnamon.desktop.peripherals.mouse" }, { "org.gnome.desktop.sound", "org.cinnamon.desktop.sound" }, { "org.gnome.desktop.privacy", "org.cinnamon.desktop.privacy" }, { "org.gnome.desktop.wm.preferences", "org.cinnamon.desktop.wm.preferences" }, { "org.gnome.settings-daemon.plugins.xsettings", "org.cinnamon.settings-daemon.plugins.xsettings" }, { "org.gnome.desktop.a11y", "org.cinnamon.desktop.a11y.keyboard" }, { "org.gnome.desktop.input-sources", "org.cinnamon.desktop.input-sources" }, }; static gboolean was_handled_specially (CsdSettingsRemapManager *manager, GSettings *cinnamon_settings, GSettings *gnome_settings, const gchar *key) { // ... return FALSE; } static void on_settings_changed (GSettings *cinnamon_settings, const gchar *key, gpointer user_data) { CsdSettingsRemapManager *manager = CSD_SETTINGS_REMAP_MANAGER (user_data); GSettings *gnome_settings; GSettingsSchema *gnome_schema; gnome_settings = g_hash_table_lookup (manager->priv->settings_table, cinnamon_settings); gnome_schema = g_settings_schema_source_lookup (manager->priv->source, (gchar *) g_object_get_data (G_OBJECT (gnome_settings), "schema"), FALSE); if (gnome_schema == NULL) { g_debug ("Schema not found during settings change - '%s'", (gchar *) g_object_get_data (G_OBJECT (gnome_settings), "schema")); return; } if (!was_handled_specially (manager, cinnamon_settings, gnome_settings, key)) { if (g_settings_schema_has_key (gnome_schema, key)) { GVariant *value = g_settings_get_value (cinnamon_settings, key); g_settings_set_value (gnome_settings, key, value); g_variant_unref (value); } } g_settings_schema_unref (gnome_schema); } static void sync_to_gnome (CsdSettingsRemapManager *manager, GSettings *cinnamon_settings) { GSettingsSchema *cinnamon_schema; gchar **cinnamon_keys; gint i; cinnamon_schema = g_settings_schema_source_lookup (manager->priv->source, (gchar *) g_object_get_data (G_OBJECT (cinnamon_settings), "schema"), FALSE); if (cinnamon_schema == NULL) { return; } cinnamon_keys = g_settings_schema_list_keys (cinnamon_schema); for (i = 0; i < g_strv_length (cinnamon_keys); i++) { on_settings_changed (cinnamon_settings, cinnamon_keys[i], manager); } g_strfreev (cinnamon_keys); g_settings_schema_unref (cinnamon_schema); } static gboolean schema_exists (CsdSettingsRemapManager *manager, const gchar *schema_id) { GSettingsSchema *schema; schema = g_settings_schema_source_lookup (manager->priv->source, schema_id, FALSE); if (schema == NULL) { return FALSE; } g_settings_schema_unref (schema); return TRUE; } gboolean csd_settings_remap_manager_start (CsdSettingsRemapManager *manager, GError **error) { gint i; g_debug ("Starting settings_remap manager"); cinnamon_settings_profile_start (NULL); manager->priv->settings_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_object_unref); manager->priv->source = g_settings_schema_source_get_default (); for (i = 0; i < G_N_ELEMENTS (schemas); i++) { GSettings *gnome_settings; GSettings *cinnamon_settings; if (!schema_exists (manager, schemas[i].gnome_schema)) { g_debug ("Skipping schema '%s' - doesn't exist", schemas[i].gnome_schema); continue; } gnome_settings = g_settings_new (schemas[i].gnome_schema); g_object_set_data_full (G_OBJECT (gnome_settings), "schema", g_strdup (schemas[i].gnome_schema), g_free); cinnamon_settings = g_settings_new (schemas[i].cinnamon_schema); g_object_set_data_full (G_OBJECT (cinnamon_settings), "schema", g_strdup (schemas[i].cinnamon_schema), g_free); g_signal_connect (cinnamon_settings, "changed", G_CALLBACK (on_settings_changed), manager); g_hash_table_insert (manager->priv->settings_table, cinnamon_settings, gnome_settings); sync_to_gnome (manager, cinnamon_settings); } cinnamon_settings_profile_end (NULL); return TRUE; } void csd_settings_remap_manager_stop (CsdSettingsRemapManager *manager) { g_clear_pointer (&manager->priv->settings_table, g_hash_table_destroy); g_debug ("Stopping settings_remap manager"); } static void csd_settings_remap_manager_class_init (CsdSettingsRemapManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_settings_remap_manager_finalize; } static void csd_settings_remap_manager_init (CsdSettingsRemapManager *manager) { manager->priv = csd_settings_remap_manager_get_instance_private (manager); manager->priv->settings_table = NULL; } static void csd_settings_remap_manager_finalize (GObject *object) { CsdSettingsRemapManager *settings_remap_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_SETTINGS_REMAP_MANAGER (object)); settings_remap_manager = CSD_SETTINGS_REMAP_MANAGER (object); g_return_if_fail (settings_remap_manager->priv != NULL); G_OBJECT_CLASS (csd_settings_remap_manager_parent_class)->finalize (object); } CsdSettingsRemapManager * csd_settings_remap_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_SETTINGS_REMAP_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_SETTINGS_REMAP_MANAGER (manager_object); } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootcinnamon-settings-daemon-6.4.3/plugins/settings-remap/cinnamon-settings-daemon-settings-remap.desktop.incinnamon-settings-daemon-6.4.3/plugins/settings-remap/cinnamon-settings-daemon-settings-remap.deskto0000664000175000017500000000035414733247605033065 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - settings-remap Exec=csd-settings-remap OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/keyboard/0000775000175000017500000000000014733247605020645 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/keyboard/cinnamon-settings-daemon-keyboard.desktop.in0000664000175000017500000000034014733247605031341 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - keyboard Exec=csd-keyboard OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/keyboard/meson.build0000664000175000017500000000250314733247605023007 0ustar fabiofabioplugin_name = 'keyboard' keyboard_sources = [ 'csd-keyboard-manager.c', 'csd-keyboard-xkb.c', 'delayed-dialog.c', 'gkbd-configuration.c', 'main.c', ] keyboard_deps = [ common_dep, csd_dep, gnomekbd, gnomekbdui, libnotify, xklavier, ] executable( 'csd-keyboard', keyboard_sources, include_directories: [include_dirs, common_inc, include_enums], dependencies: keyboard_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), '-DDATADIR="@0@"'.format(datadir), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-keyboard') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-keyboard') endif configure_file( input: 'cinnamon-settings-daemon-keyboard.desktop.in', output: 'cinnamon-settings-daemon-keyboard.desktop', configuration: desktop_conf, install_dir: autostartdir, ) keyboard_icons = [ 'kbd-capslock-off.png', 'kbd-numlock-off.png', 'kbd-scrolllock-off.png', 'kbd-capslock-on.png', 'kbd-numlock-on.png', 'kbd-scrolllock-on.png', ] install_data( keyboard_icons, install_dir: join_paths(pkgdatadir, 'icons', 'hicolor', '64x64', 'devices') ) cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-capslock-off.png0000664000175000017500000000316214733247605024462 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsœœn›¡NtEXtSoftwarewww.inkscape.org›î<ïIDATxœå›MŒEÇÿ5‹|È.‰D‘ÁàM#HÀ„(ÊW<¨¬9p °šOz‘ˆGãA=iL< DÀ€»$‚ Q? +Á]I0a•Øýy蚥¦¦fvº»&;ÿd’éž÷Þÿ½šªêªW¯ Ð.i±¤Ù’f>’Ôøœ—ÔmŒ(ÚÇèî6ŸƒdÇ °x ¸ÿvÇUÀD`p Ît- ÇÀ·;Þ% ¸P@еpØ”òúor¿\ÒNI§PPåX—*ç„ö¶NKzÙ³?…N~3ƒ üSCÀ  xèhÀv‡•í²ºC ðfÞŠØ,úGqh?°˜oºµµÎ~`AŒë9ÓIýYý00¿@þù–£Î"ˆÛ€]uˆO+£×ög¥å¬…]@[,²6`w ¢Àv"ÌÆü*Yî5|Û¥êüó—%bÉëßëK°'ä5ÞYÃðY`N¤r˜c} !Ûœ@2Û‡&¼n`jär˜j}ó1HÚ§És>ô¨;ÛŒÁ—a!ÔúI³N ¼È¹ÜLݾìpÍ ‡5°, |ƒ&˜ðÉÄz:¬M±|PÜ~‹|’G¤SÔ{dëJ§ë*5)ìŸZ,m¨¥0è (D_ᑬäxŸ§ âñq‘P>Ø>Û)ËõQ€ë“‚¸B{‡!Á£ÁèànàÏ×_DØ=øæ¸ŽûBÓ©Þw’d^ 8TÆkqú[éalޱ<¹­v¾—ñiÎHZê|ÿ]Ò9çzyAœ~,FÒª‘+`¯×BCuÇ…ÀÏÀ{Îõ5`Q¼¡¾¯üãdàª÷ã‘ØNX®w¼F^ [Òóð‡bš]ÒÍã)½8ð”óý_I:×ïKºRC6z÷f„`Às% œÀ,I9·ŽcΔ/Œ1¿IrçE@¨gf†É?g 6@Ÿâc“$7p0 ãÞ›"ic~ø±ÍÕ „žØ¬$gzeôwdÚIÖéU“dD?z¼XÏÞH6Sóœ[=Ƙ¿}9{ î6þ#r+qPÕnÅ6÷9U®2÷Ö‘Ý-©üd(Iz¦(§FPä 9çs»õÔÉÕ“ìápäÿ¦Dô'8ª'†xØ$É-lè6Æ Õ6Æ Kêö|ÙÑŸªá>NÅ6€Ÿƒ› ¼>ŠŽŸu^!éíHþ4Ôí@GÞµ0WÒ£ÞíµL-æcNäô§CÕµ}¡! I³òY¬—4)‚I’ÖE°3+p¯oœ*÷ãe,—t*+“è–9·$ý”Ò̃º9–mõæÊ5œ/d; ¬õì}–ÁÆÇž,ÃǵÜ—Œ1ÿ¨r7&I È—ñ3¼¡¥ïhðwo«3ú"‹>øåH "I ŠLkq’ÁKÞ³|r;w¿:v.÷fô)ßféæ m¤aOïÙ,d’^”4͹,Œ1×U¹4žfmg JbvîÀWVJ¾öl¬Éètù`ÃÍåÍ`#”?Ü<œ’ì ຣÿ30.­ÓŽ=|çØ»<žÒFè`d[Hp

ÜðÑðÉájù“{¼áÙÜ™B7t4v˜XKaM@a¬ŽÖ.™±]îD@i¬ŸõÏ–ÇJDc'OŒÍ™Æc´z‘”5ÖºerŽÑ΀ÁrOhšá@…’ŽñÖ-•µ­],mÉZ·\Þ#î¤_˜ðœhÝWf§ší¥©ƒd|i*ïksK%½)in µ˜¯Í”ôŠ1æ‹:qA²ZCx+]zIÊz›g—J’OØB’Yj¤Û¦ÅI1çV ¨!Š à’W[÷PrOƒ«$%|/P@Ùž”sh$áÅJŠ±Ò¼>NÉajê„jüLÍj¹ÑL‹IEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-numlock-on.png0000664000175000017500000000306714733247605024201 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsRGB®ÎébKGDÿÿÿ ½§“ pHYsœœn›¡NtIMEÚPˆL·IDATxÚå›mh•UÀÏu9Ý –åÈm±ޖƒ¤–‹ l­†}Ó^VN˜¬iÑ—JòCôQ"(êKA˜¢Ó&R¹†Óˆ¦®Fâ\&Wr,Zlmmÿ>ܳ|8û?÷>÷î<×»ÝçÃó<çüßžsþoç<"n%@°(W:@\é#ÀqÆYlM`­@»À!IɰO Ø.P‘ëL¯è˜]ÓA}Và´ÀN¢\b<&Ð*p)¦ƒúe­±…Òï-ùf`P›Æ´qk¯cé„’4`^ñ 'Û½R 7ÄŸšèØ%°^ 4ìR3v—™;Ï1Êl1_/p%A=með•X=)p^¨šùÖZýkºñ×ɬFkˆ— ìM‚øœ@K·`‹ÁDÏ^e.™ß€è_nÚ8CëÓmhÐhÛïDIþü5Æ0Æu%¸ØóàaêòEª M­­™­PxÇVå 'ºÊЦ)ÆútU˜ºá\dÞÂp€‰¬LPoÀž¯&ǛٚN8ÀãÚ¾‘EÒŒbÔ¬ÃaLËÊÄîE’w+|œMj²ž prbމ+¨Ø$°A`uD~‚æ,m šP(0ªLhqDPÀKGÆýòÀ.•¬ñµPºHÜ©ùöŽÙ p*d¬?(ð¤C!h±ÃNmàwÊÀ:4üበL(߯\ ÁP6üÓZÈiÇÝ=¯8cÁ ¼.ð‰3*^è·Æ ÜáH=Šð+ü¶)Rj‹ Žx0`ìJÏ­ñ:@›Âßvÿ€ƒJ&§ÌÒ;oI}GˆsÑ7çOû%Uì~xîc±²û m¶`ž cNöXóÞr´ ú”¡$FâÐb…5þK8ï·žñ`6ļAëùaGÁæ©hˆUÊà#Úö<rÞ0ã{®qt ñ´.Æõã)u€p¹õ<rÞ5kìm(Î4›ÆS¹&€qþr€ÐføöóŠ­wëJŒái<ŒâŽöÜUë9ìÙ޽ʻ[ÑϦX«à™¯µ¶Iy·rÑ ÀKoŸð½ºxM’Ççë±l Êö0å{~øB;êxxÝWð¢"°ÀHå.¿T\÷à3&®»Õð‰å<ð«ÙßUÀ=>FGHTü¯˜‘4oµG*ÓvGk³ïï–'ÁsøèʆbÚ¾pɽS< t§,'Çß.o%¸:…Eq¾ü­D Ô‘/àÄ>`ŸÀFàQãà˜%ÿ‰ÿ}p§oêð•ƒX ”ùµª ‡ŸBéxp’D"ôVàn+†¸ìµ–[ˆÇ€ ʇfn\k·Ÿ~Gp5žF" ‡3\¦…¦jŽŽ WõAápd ‘ ‰|Ï¢ã #¸ZBäPª”Q›#äS%B<7­ÃØß%½â«tSbív*ÊyRÔÀî7ï <#‰ø¾Pà&*—•SÝ)ÝW––]k:QZü[ù˜ÀUiç´«4˜Á¯¥Å´QŒ(HÖG:ëí`¤K¸ÜàôhLày~ ¨ù›øÞ(ÀJÇÌkGc—Ä—õ¬ [€O-8C@mÈ„fREgœ¦†<8E‰‘€[c}zÁƒ’iã–ðñø`ÊÔ¼@Ó.h `)–Èô¦$¿‹¤ °ü-“óÍßBIðü-•5ò»XÚ'„ü,—WtBþ]˜P¬C~^™±ü„\º4Õ›i µÐksMÀ;„;ôœk.¯Í »=8z#Í'°% ”Žªš²Þ¹ÒL>¡Ãd–f"`zÆsvJ¢¾'§’5æjë€Jа}Âd¬·E•¥ö² Œb•hU¤w}þ‰ëóGIßÁñ8n. !IEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/keyboard/main.c0000664000175000017500000000114314733247605021734 0ustar fabiofabio#define NEW csd_keyboard_manager_new #define START csd_keyboard_manager_start #define STOP csd_keyboard_manager_stop #define MANAGER CsdKeyboardManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-keyboard-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-capslock-on.png0000664000175000017500000000272014733247605024323 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsRGB®ÎébKGDÿÿÿ ½§“ pHYsœœn›¡NtIMEÚ:=¨¾PIDATxÚå›KhE€¿{í#‰¡Å4Y””¸SZ¸|ä!±u!nJk¤±´»(iDtck] Ò…º(ŠÚE´4©Þ’¦B >j‹F%!M VÓúHŽ‹LÈdrþ{ïÿ™ëMî÷ÿï™óš3gÎ93“"ð#P Ü4›”0©´q`0Ó¬´G N`ŸÀiR`»!Ð/°_ ¾Ô…^+pHà¼À\¡£ÚœÀˆÀaõ¥$xZ Kàr¡£ÚÏ{ÒIùO%¾8Ü£Û´3×q|Bu \—€§S0PìQoÈä1R³Ã½w Ô仯Àöš¾³yÐ9+ÐP,á[®ä`h@ [`£z ®4¯´„¾+‡WÿD 9 ýfC#۪тp…À±,„/ tq všQü¨ð)|_¡z|xãWŸÃÆ[Ÿ%dùßZK`n5¼¨–àcÎkˆGšJ(i2²ÇˆÊ¥5¢¥œnÞ=hDžÍ’Ä<ˆæ€R^«‡E綃åŽîd ÿÔfýþ ³Þ;Ñ<©T¶Û:¥TrB˜ã=YtÞ8n½ÿ-poºš…÷/üY%pÝùs8)¾æ(¹SàA'hy=ía%G¨F`»2{0p³À/Äe>·¾ ¬ @¿W‘sGØ¢ÀŸ 0³4—L˜ßvœÞ<€¾&ScšÅí)û™ÀÀÃÖïà-ëý `*Öףɴ ŽYL0¿Í×,+0ýÖÿˆn™Iù˜rd=¡YÀdíïei!£ÀØßnºð1©Y€[@  ù§8q«SmâôeNÒ#Cn'¸˜dênëÓP ®±<2™f©ò·. VY@1ÒÜÇœ(óTØ>W†4ðh1òæ`SÀìóÙfým¶Z½É῱à‘yt ,w ~_½³öÏF§`txÙ둟eÓ½2°Ü\­À‹9úÔ*8^ ¥Ž*!bsÛ&0ãá0ÄŒ,u¢I¦£‹ûh:Âëoöú®ó€g°ÛM¦ÉJ'·óò‹ ´]´[Ÿ¦ïb¢¹ÃšíÙüGVk’ ìrð}PŽw»‚¤Ã! "ï;øž*‡»1ûžç‚Èi [qÝ«¸ê¬åUà¹IàG ÏUÛ äI“oŸ °ÁWQTà7ãJ0rÇ\Ï{,ŠÖ¹@Ÿú(‹ |æàØ™$pæ\8´²øy ð@Òþ±ú/P™@)¯œ¢é}1qh#‡¢jvãI¶Æ^1›« -q'ð’ƒóHL rå¹,°6ªÃÎ2ØíÊer_®âíñ 9S mèÈÁj<"“‰ƒ¤¼Idå{L.K<^>%-äå{Tv!·/ëÃÒ–Êó¸¼âÊ:”ç•'N(¥KS™B/M%½6×¼ l‹ÑÍçµ¹ À3)øèÿ\†R&‹/âÅÉ s¬·t²TSO8`*K³„ž5‡9†8Cä[ÌÕÖ•’{œvÝT¬Ÿ ql/±ÈSUÌ_ŸßB¼ëócÌo¦þ’¿ÿN|HƒÌ×0IEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/keyboard/delayed-dialog.c0000664000175000017500000000755414733247605023670 0ustar fabiofabio/* * Copyright © 2006 Novell, Inc. * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include #include #include "delayed-dialog.h" static gboolean delayed_show_timeout (gpointer data); static GdkFilterReturn message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data); static GSList *dialogs = NULL; /** * csd_delayed_show_dialog: * @dialog: the dialog * * Shows the dialog as with gtk_widget_show(), unless a window manager * hasn't been started yet, in which case it will wait up to 5 seconds * for that to happen before showing the dialog. **/ void csd_delayed_show_dialog (GtkWidget *dialog) { GdkDisplay *display = gtk_widget_get_display (dialog); Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); GdkScreen *screen = gtk_widget_get_screen (dialog); char selection_name[10]; Atom selection_atom; /* We can't use gdk_selection_owner_get() for this, because * it's an unknown out-of-process window. */ snprintf (selection_name, sizeof (selection_name), "WM_S%d", gdk_screen_get_number (screen)); selection_atom = XInternAtom (xdisplay, selection_name, True); if (selection_atom && XGetSelectionOwner (xdisplay, selection_atom) != None) { gtk_widget_show (dialog); return; } dialogs = g_slist_prepend (dialogs, dialog); gdk_window_add_filter (NULL, message_filter, NULL); g_timeout_add (5000, delayed_show_timeout, NULL); } static gboolean delayed_show_timeout (gpointer data) { GSList *l; for (l = dialogs; l; l = l->next) gtk_widget_show (l->data); g_slist_free (dialogs); dialogs = NULL; /* FIXME: There's no gdk_display_remove_client_message_filter */ return FALSE; } static GdkFilterReturn message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { XClientMessageEvent *evt; char *selection_name; int screen; GSList *l, *next; if (((XEvent *)xevent)->type != ClientMessage) return GDK_FILTER_CONTINUE; evt = (XClientMessageEvent *)xevent; if (evt->message_type != XInternAtom (evt->display, "MANAGER", FALSE)) return GDK_FILTER_CONTINUE; selection_name = XGetAtomName (evt->display, evt->data.l[1]); if (strncmp (selection_name, "WM_S", 4) != 0) { XFree (selection_name); return GDK_FILTER_CONTINUE; } screen = atoi (selection_name + 4); for (l = dialogs; l; l = next) { GtkWidget *dialog = l->data; next = l->next; if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) { gtk_widget_show (dialog); dialogs = g_slist_remove (dialogs, dialog); } } if (!dialogs) { gdk_window_remove_filter (NULL, message_filter, NULL); } XFree (selection_name); return GDK_FILTER_CONTINUE; } cinnamon-settings-daemon-6.4.3/plugins/keyboard/csd-keyboard-manager.h0000664000175000017500000000466514733247605025010 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_KEYBOARD_MANAGER_H #define __CSD_KEYBOARD_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_KEYBOARD_MANAGER (csd_keyboard_manager_get_type ()) #define CSD_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_KEYBOARD_MANAGER, CsdKeyboardManager)) #define CSD_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_KEYBOARD_MANAGER, CsdKeyboardManagerClass)) #define CSD_IS_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_KEYBOARD_MANAGER)) #define CSD_IS_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_KEYBOARD_MANAGER)) #define CSD_KEYBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_KEYBOARD_MANAGER, CsdKeyboardManagerClass)) typedef struct CsdKeyboardManagerPrivate CsdKeyboardManagerPrivate; typedef struct { GObject parent; CsdKeyboardManagerPrivate *priv; } CsdKeyboardManager; typedef struct { GObjectClass parent_class; } CsdKeyboardManagerClass; GType csd_keyboard_manager_get_type (void); CsdKeyboardManager * csd_keyboard_manager_new (void); gboolean csd_keyboard_manager_start (CsdKeyboardManager *manager, GError **error); void csd_keyboard_manager_stop (CsdKeyboardManager *manager); void csd_keyboard_manager_apply_settings (CsdKeyboardManager *manager); G_END_DECLS #endif /* __CSD_KEYBOARD_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-scrolllock-off.png0000664000175000017500000000267314733247605025040 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsœœn›¡NtEXtSoftwarewww.inkscape.org›î<8IDATxœí›ÏkUGÇ¿ó"F4"RЊJK6B„nºSˆMš?@hi¡u!Dbê? Ø¢….]»î"µj(i\¡(qcÁš]SlJÒüútqç™››s_ÞË›y/ôå ÷Î9ßsÎ;wæÌ§ÈZ$•ô¾¤ÃÆO’^¿IIœss±m àðpX`ëXî_ïÕÛ¯’ö—€q`µ §ó° <.{ëíï[ ˜Žàt^}@¡Zû]•ÎwIúNÒÉ Äæ´þ]—Ö -èšôsn¸™êFÊxR+À0´ûËн߷ô²+eðÜŽÔÂw§€™M ¾Zðµz]ÛpΧBøXʘ^Jê£@GDþÏ‘‡ 7qp£ñМ8ßžnÏ™‡@S(²&`(‡h Àh¼» ž{9Ƕ¡ A(ñägξTk_§·Åì Õ*ïÍQüh äCÕÚ¼M¶6&ŒöÖ€÷8؇ªð¶e±@¥_’ï¼õ©{±/ÂÁê 3T2OÀžäÌÆèöÀÁÀúÚ°Ç„ûå*øÈ^&€ž{ëíÄþ:|¼™`xb„40ÅwÇ댠{Àðã¥>ÙÀg†ÐDI¡­Ø“âxCøW¡€=YêËh¦ à3<`/ðk EàzžnßWXùà¢Ñx4´Qžë°”áZŽFà²Ö—­†Œ†Á6À ìj¸¯ÃàzœmÔÊÆuw”$É?ûô‹X*I®”Ë™]J¯âsŒÅÁ­'õ¿ˆ#ò¹¤Ó’vå4Y–TÝüÝFÖ'éÓ´a?g"´B€dFÀAàOÊK˜ž Ìmõð{Å›û€ùÌͱxž›^÷"ùKØb÷|T•¯4øÇ2< @KAɦEv&öS`òfIÓ’®JúAÒ#£Ù_’J—´()tz+ëS³¤³ú§Ð˜|€+çÃÈœígAkÛSiLÅ4FÒnãÚbdÎ)ãÚa+sι¿#Ól\û7&¡÷)»Ïhàµâ£æðÈú¶€Ô€ÔB=AQ©o½zÀ†Þ¾í`CZ(c»JÔ<Þ§líI:ÓÕgkcä’Õp70i4ޱ5v=„’m²à坨[cÓäíFç à›£$)ò7)Žžú=GÞæh~É É÷úwC(øö8I%(Àк½~k{üé¦8g/ ©. ©×ëÎ+°fƒ¦‚š”ÈxÂãuæ•ÈŒT¢¤±‹¤¼²Æ-“K)í5{Âÿ»P2¥¼qKe=AcK{²Æ-—Ï÷Òˆ&2F4î‘™”QÛíÐÔ[<4Uí±¹s’¾•ôab!Í=•tÅ9÷K2aA²€:½”Ž…)’²ÞzímnI>áIf©œn[)VHŠ9/’Ôm_äû€ÛlL¹W‚y’Œõ—ÎR´Í°OI%ÚªìøüK%Ççÿ‰ißv@é‹É?rIEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/keyboard/csd-input-sources-switcher.c0000664000175000017500000003762514733247605026243 0ustar fabiofabio/* * Copyright (C) 2012 Red Hat, Inc. * * Written by: Rui Matos * * 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 Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include "csd-enums.h" #include "csd-keygrab.h" #define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.cinnamon.desktop.input-sources" #define KEY_CURRENT_INPUT_SOURCE "current" #define KEY_INPUT_SOURCES "sources" #define CSD_KEYBOARD_DIR "org.cinnamon.settings-daemon.peripherals.keyboard" #define KEY_SWITCHER "input-sources-switcher" static GSettings *input_sources_settings; static Key *the_keys = NULL; static guint n_keys = 0; static guint master_keyboard_id = 0; static gboolean includes_caps = FALSE; static void do_switch (void) { GVariant *sources; gint i, n; /* FIXME: this is racy with the g-s-d media-keys plugin. Instead we should have a DBus API on g-s-d and poke it from here.*/ sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES); n = g_variant_n_children (sources); if (n < 2) goto out; i = g_settings_get_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE) + 1; if (i >= n) i = 0; g_settings_set_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE, i); out: g_variant_unref (sources); } static void init_keys (void) { GSettings *settings; settings = g_settings_new (CSD_KEYBOARD_DIR); switch (g_settings_get_enum (settings, KEY_SWITCHER)) { case CSD_INPUT_SOURCES_SWITCHER_SHIFT_L: n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_L: n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Alt_L; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_L: n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Control_L; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_SHIFT_R: n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_R; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_R: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Alt_R; the_keys[0].state = 0; the_keys[1].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[1].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_R: n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Control_R; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT_L: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Alt_L; the_keys[1].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT_R: n_keys = 4; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_R; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Alt_R; the_keys[1].state = GDK_SHIFT_MASK; the_keys[2].keysym = GDK_KEY_Shift_R; the_keys[2].state = GDK_MOD5_MASK; the_keys[3].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[3].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT_L: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = GDK_CONTROL_MASK; the_keys[1].keysym = GDK_KEY_Control_L; the_keys[1].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT_R: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_R; the_keys[0].state = GDK_CONTROL_MASK; the_keys[1].keysym = GDK_KEY_Control_R; the_keys[1].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_SHIFT_L_SHIFT_R: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = GDK_SHIFT_MASK; the_keys[1].keysym = GDK_KEY_Shift_R; the_keys[1].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_L_ALT_R: n_keys = 4; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Alt_L; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Alt_R; the_keys[1].state = GDK_MOD1_MASK; the_keys[2].keysym = GDK_KEY_Alt_L; the_keys[2].state = GDK_MOD5_MASK; the_keys[3].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[3].state = GDK_MOD1_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_L_CTRL_R: n_keys = 2; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Control_L; the_keys[0].state = GDK_CONTROL_MASK; the_keys[1].keysym = GDK_KEY_Control_R; the_keys[1].state = GDK_CONTROL_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT: n_keys = 7; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Shift_L; the_keys[1].state = GDK_MOD5_MASK; the_keys[2].keysym = GDK_KEY_Shift_R; the_keys[2].state = GDK_MOD1_MASK; the_keys[3].keysym = GDK_KEY_Shift_R; the_keys[3].state = GDK_MOD5_MASK; the_keys[4].keysym = GDK_KEY_Alt_L; the_keys[4].state = GDK_SHIFT_MASK; the_keys[5].keysym = GDK_KEY_Alt_R; the_keys[5].state = GDK_SHIFT_MASK; the_keys[6].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[6].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT: n_keys = 4; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Shift_L; the_keys[0].state = GDK_CONTROL_MASK; the_keys[1].keysym = GDK_KEY_Shift_R; the_keys[1].state = GDK_CONTROL_MASK; the_keys[2].keysym = GDK_KEY_Control_L; the_keys[2].state = GDK_SHIFT_MASK; the_keys[3].keysym = GDK_KEY_Control_R; the_keys[3].state = GDK_SHIFT_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_CTRL: n_keys = 7; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Control_L; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Control_L; the_keys[1].state = GDK_MOD5_MASK; the_keys[2].keysym = GDK_KEY_Control_R; the_keys[2].state = GDK_MOD1_MASK; the_keys[3].keysym = GDK_KEY_Control_R; the_keys[3].state = GDK_MOD5_MASK; the_keys[4].keysym = GDK_KEY_Alt_L; the_keys[4].state = GDK_CONTROL_MASK; the_keys[5].keysym = GDK_KEY_Alt_R; the_keys[5].state = GDK_CONTROL_MASK; the_keys[6].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[6].state = GDK_CONTROL_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CAPS: includes_caps = TRUE; n_keys = 1; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Caps_Lock; the_keys[0].state = 0; break; case CSD_INPUT_SOURCES_SWITCHER_SHIFT_CAPS: includes_caps = TRUE; n_keys = 3; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Caps_Lock; the_keys[0].state = GDK_SHIFT_MASK; the_keys[1].keysym = GDK_KEY_Shift_L; the_keys[1].state = GDK_LOCK_MASK; the_keys[2].keysym = GDK_KEY_Shift_R; the_keys[2].state = GDK_LOCK_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_ALT_CAPS: includes_caps = TRUE; n_keys = 5; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Caps_Lock; the_keys[0].state = GDK_MOD1_MASK; the_keys[1].keysym = GDK_KEY_Caps_Lock; the_keys[1].state = GDK_MOD5_MASK; the_keys[2].keysym = GDK_KEY_Alt_L; the_keys[2].state = GDK_LOCK_MASK; the_keys[3].keysym = GDK_KEY_Alt_R; the_keys[3].state = GDK_LOCK_MASK; the_keys[4].keysym = GDK_KEY_ISO_Level3_Shift; the_keys[4].state = GDK_LOCK_MASK; break; case CSD_INPUT_SOURCES_SWITCHER_CTRL_CAPS: includes_caps = TRUE; n_keys = 3; the_keys = g_new0 (Key, n_keys); the_keys[0].keysym = GDK_KEY_Caps_Lock; the_keys[0].state = GDK_CONTROL_MASK; the_keys[1].keysym = GDK_KEY_Control_L; the_keys[1].state = GDK_LOCK_MASK; the_keys[2].keysym = GDK_KEY_Control_R; the_keys[2].state = GDK_LOCK_MASK; break; } g_object_unref (settings); } static void free_keys (void) { gint i; for (i = 0; i < n_keys; ++i) g_free (the_keys[i].keycodes); g_free (the_keys); } static gboolean match_caps_locked (const Key *key, XIDeviceEvent *xev) { if (key->state & xev->mods.effective && key->keysym == XkbKeycodeToKeysym (xev->display, xev->detail, 0, 0)) return TRUE; return FALSE; } static gboolean match_modifier (const Key *key, XIEvent *xiev) { Key meta; /* When the grab is established with Caps Lock as the modifier (i.e. key->state == GDK_LOCK_MASK) we can't use match_xi2_key() as this modifier is black listed there, so we do the match ourselves. */ if (key->state == GDK_LOCK_MASK) return match_caps_locked (key, (XIDeviceEvent *) xiev); meta = *key; switch (key->keysym) { case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: if (xiev->evtype == XI_KeyRelease) meta.state |= GDK_SHIFT_MASK; break; case GDK_KEY_Control_L: case GDK_KEY_Control_R: if (xiev->evtype == XI_KeyRelease) meta.state |= GDK_CONTROL_MASK; break; case GDK_KEY_ISO_Level3_Shift: if (xiev->evtype == XI_KeyRelease) meta.state |= GDK_MOD5_MASK; break; case GDK_KEY_Alt_L: case GDK_KEY_Alt_R: if (key->state == GDK_SHIFT_MASK) meta.keysym = key->keysym == GDK_KEY_Alt_L ? GDK_KEY_Meta_L : GDK_KEY_Meta_R; if (xiev->evtype == XI_KeyRelease) meta.state |= GDK_MOD1_MASK; break; } return match_xi2_key (&meta, (XIDeviceEvent *) xiev); } static gboolean matches_key (XIEvent *xiev) { gint i; for (i = 0; i < n_keys; ++i) if (match_modifier (&the_keys[i], xiev)) return TRUE; return FALSE; } /* Owen magic, ported to XI2 */ static GdkFilterReturn filter (XEvent *xevent, GdkEvent *event, gpointer data) { XIEvent *xiev; XIDeviceEvent *xev; XIGrabModifiers mods; XIEventMask evmask; unsigned char mask[(XI_LASTEVENT + 7)/8] = { 0 }; if (xevent->type != GenericEvent) return GDK_FILTER_CONTINUE; xiev = (XIEvent *) xevent->xcookie.data; if (xiev->evtype != XI_ButtonPress && xiev->evtype != XI_KeyPress && xiev->evtype != XI_KeyRelease) return GDK_FILTER_CONTINUE; xev = (XIDeviceEvent *) xiev; mods.modifiers = XIAnyModifier; XISetMask (mask, XI_ButtonPress); evmask.deviceid = XIAllMasterDevices; evmask.mask_len = sizeof (mask); evmask.mask = mask; if (xiev->evtype != XI_ButtonPress && matches_key (xiev)) { if (xiev->evtype == XI_KeyPress) { if (includes_caps) { do_switch (); XIUngrabDevice (xev->display, master_keyboard_id, xev->time); XkbLockModifiers (xev->display, XkbUseCoreKbd, LockMask, 0); } else { XIAllowEvents (xev->display, xev->deviceid, XISyncDevice, xev->time); XIGrabButton (xev->display, XIAllMasterDevices, XIAnyButton, xev->root, None, GrabModeSync, GrabModeSync, False, &evmask, 1, &mods); } } else { do_switch (); XIUngrabDevice (xev->display, master_keyboard_id, xev->time); XIUngrabButton (xev->display, XIAllMasterDevices, XIAnyButton, xev->root, 1, &mods); } } else { XIAllowEvents (xev->display, xev->deviceid, XIReplayDevice, xev->time); XIUngrabDevice (xev->display, master_keyboard_id, xev->time); XIUngrabButton (xev->display, XIAllMasterDevices, XIAnyButton, xev->root, 1, &mods); } return GDK_FILTER_CONTINUE; } static void grab_key (Key *key, GdkDisplay *display, GSList *screens) { GdkKeymapKey *keys; gboolean has_entries; GArray *keycodes; gint n, i; has_entries = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), key->keysym, &keys, &n); if (!has_entries) return; keycodes = g_array_sized_new (TRUE, TRUE, sizeof (guint), n); for (i = 0; i < n; ++i) g_array_append_val (keycodes, keys[i].keycode); key->keycodes = (guint *) g_array_free (keycodes, FALSE); gdk_x11_display_error_trap_push (display); grab_key_unsafe (key, CSD_KEYGRAB_ALLOW_UNMODIFIED | CSD_KEYGRAB_SYNCHRONOUS, screens); gdk_x11_display_error_trap_pop_ignored (display); g_free (keys); } static guint get_master_keyboard_id (GdkDisplay *display) { XIDeviceInfo *info; guint id; int i, n; id = 0; info = XIQueryDevice (GDK_DISPLAY_XDISPLAY (display), XIAllMasterDevices, &n); for (i = 0; i < n; ++i) if (info[i].use == XIMasterKeyboard && info[i].enabled) { id = info[i].deviceid; break; } XIFreeDeviceInfo (info); return id; } static void set_input_sources_switcher (void) { GdkDisplay *display; gint n_screens; GSList *screens, *l; gint i; display = gdk_display_get_default (); n_screens = gdk_display_get_n_screens (display); screens = NULL; for (i = 0; i < n_screens; ++i) screens = g_slist_prepend (screens, gdk_display_get_screen (display, i)); for (i = 0; i < n_keys; ++i) grab_key (&the_keys[i], display, screens); for (l = screens; l; l = l->next) { GdkScreen *screen; screen = (GdkScreen *) l->data; gdk_window_add_filter (gdk_screen_get_root_window (screen), (GdkFilterFunc) filter, screen); } g_slist_free (screens); master_keyboard_id = get_master_keyboard_id (display); } int main (int argc, char *argv[]) { gtk_init (&argc, &argv); init_keys (); if (n_keys == 0) { g_warning ("No shortcut defined, exiting"); return -1; } input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); set_input_sources_switcher (); gtk_main (); g_object_unref (input_sources_settings); free_keys (); return 0; } cinnamon-settings-daemon-6.4.3/plugins/keyboard/csd-keyboard-xkb.c0000664000175000017500000003453114733247605024150 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2001 Udaltsoft * * Written by Sergey V. Oudaltsov * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "csd-keyboard-xkb.h" #include "delayed-dialog.h" #include "cinnamon-settings-profile.h" #define SETTINGS_KEYBOARD_DIR "org.cinnamon.settings-daemon.plugins.keyboard" static CsdKeyboardManager *manager = NULL; static XklEngine *xkl_engine; static XklConfigRegistry *xkl_registry = NULL; static GkbdDesktopConfig current_config; static GkbdKeyboardConfig current_kbd_config; /* never terminated */ static GkbdKeyboardConfig initial_sys_kbd_config; static gboolean inited_ok = FALSE; static GSettings *settings_desktop = NULL; static GSettings *settings_keyboard = NULL; static PostActivationCallback pa_callback = NULL; static void *pa_callback_user_data = NULL; static GHashTable *preview_dialogs = NULL; static void activation_error (void) { char const *vendor; GtkWidget *dialog; vendor = ServerVendor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); /* VNC viewers will not work, do not barrage them with warnings */ if (NULL != vendor && NULL != strstr (vendor, "VNC")) return; dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _ ("Error activating XKB configuration.\n" "There can be various reasons for that.\n\n" "If you report this situation as a bug, include the results of\n" " %s\n" " %s\n" " %s\n" " %s"), "xprop -root | grep XKB", "gsettings get org.gnome.libgnomekbd.keyboard model", "gsettings get org.gnome.libgnomekbd.keyboard layouts", "gsettings get org.gnome.libgnomekbd.keyboard options"); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); csd_delayed_show_dialog (dialog); } static gboolean ensure_xkl_registry (void) { if (!xkl_registry) { xkl_registry = xkl_config_registry_get_instance (xkl_engine); /* load all materials, unconditionally! */ if (!xkl_config_registry_load (xkl_registry, TRUE)) { g_object_unref (xkl_registry); xkl_registry = NULL; return FALSE; } } return TRUE; } static void apply_desktop_settings (void) { if (!inited_ok) return; csd_keyboard_manager_apply_settings (manager); gkbd_desktop_config_load (¤t_config); /* again, probably it would be nice to compare things before activating them */ gkbd_desktop_config_activate (¤t_config); } static void popup_menu_launch_capplet () { GAppInfo *info; GdkAppLaunchContext *ctx; GError *error = NULL; info = g_app_info_create_from_commandline ("cinnamon-settings region", NULL, 0, &error); if (info != NULL) { ctx = gdk_display_get_app_launch_context (gdk_display_get_default ()); if (g_app_info_launch (info, NULL, G_APP_LAUNCH_CONTEXT (ctx), &error) == FALSE) { g_warning ("Could not execute keyboard properties capplet: [%s]\n", error->message); g_error_free (error); } g_object_unref (info); g_object_unref (ctx); } } static void show_layout_destroy (GtkWidget * dialog, gint group) { g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); } static void popup_menu_show_layout () { GtkWidget *dialog; XklEngine *engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); XklState *xkl_state = xkl_engine_get_current_state (engine); gchar **group_names = gkbd_status_get_group_names (); gpointer p = g_hash_table_lookup (preview_dialogs, GINT_TO_POINTER (xkl_state->group)); if (xkl_state->group < 0 || xkl_state->group >= g_strv_length (group_names)) { return; } if (p != NULL) { /* existing window */ gtk_window_present (GTK_WINDOW (p)); return; } if (!ensure_xkl_registry ()) return; dialog = gkbd_keyboard_drawing_dialog_new (); gkbd_keyboard_drawing_dialog_set_group (dialog, xkl_registry, xkl_state->group); g_signal_connect (dialog, "destroy", G_CALLBACK (show_layout_destroy), GINT_TO_POINTER (xkl_state->group)); g_hash_table_insert (preview_dialogs, GINT_TO_POINTER (xkl_state->group), dialog); gtk_widget_show_all (dialog); } static void popup_menu_set_group (gint group_number, gboolean only_menu) { XklEngine *engine = gkbd_status_get_xkl_engine (); XklState *st = xkl_engine_get_current_state(engine); Window cur; st->group = group_number; xkl_engine_allow_one_switch_to_secondary_group (engine); cur = xkl_engine_get_current_window (engine); if (cur != (Window) NULL) { xkl_debug (150, "Enforcing the state %d for window %lx\n", st->group, cur); xkl_engine_save_state (engine, xkl_engine_get_current_window (engine), st); /* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ } else { xkl_debug (150, "??? Enforcing the state %d for unknown window\n", st->group); /* strange situation - bad things can happen */ } if (!only_menu) xkl_engine_lock_group (engine, st->group); } static void popup_menu_set_group_cb (GtkMenuItem * item, gpointer param) { gint group_number = GPOINTER_TO_INT (param); popup_menu_set_group(group_number, FALSE); } static GtkMenu * create_status_menu (void) { GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); int i = 0; GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); gchar **current_name = gkbd_status_get_group_names (); GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (groups_menu)); item = gtk_menu_item_new_with_mnemonic (_("Show _Keyboard Layout...")); gtk_widget_show (item); g_signal_connect (item, "activate", popup_menu_show_layout, NULL); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); /* translators note: * This is the name of the cinnamon-settings "region" panel */ item = gtk_menu_item_new_with_mnemonic (_("Region and Language Settings")); gtk_widget_show (item); g_signal_connect (item, "activate", popup_menu_launch_capplet, NULL); gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); for (i = 0; current_name && *current_name; i++, current_name++) { gchar *image_file = gkbd_status_get_image_filename (i); if (image_file == NULL) { item = gtk_menu_item_new_with_label (*current_name); } else { GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (image_file, 24, 24, NULL); GtkWidget *img = gtk_image_new_from_pixbuf (pixbuf); item = gtk_image_menu_item_new_with_label (*current_name); gtk_widget_show (img); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), img); gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE); g_free (image_file); } gtk_widget_show (item); gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); g_signal_connect (item, "activate", G_CALLBACK (popup_menu_set_group_cb), GINT_TO_POINTER (i)); } return popup_menu; } static void status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) { GtkMenu *popup_menu = create_status_menu (); gtk_menu_popup (popup_menu, NULL, NULL, gtk_status_icon_position_menu, (gpointer) icon, button, time); } static gboolean try_activating_xkb_config_if_new (GkbdKeyboardConfig * current_sys_kbd_config) { /* Activate - only if different! */ if (!gkbd_keyboard_config_equals (¤t_kbd_config, current_sys_kbd_config)) { if (gkbd_keyboard_config_activate (¤t_kbd_config)) { if (pa_callback != NULL) { (*pa_callback) (pa_callback_user_data); return TRUE; } } else { return FALSE; } } return TRUE; } static gboolean filter_xkb_config (void) { XklConfigItem *item; gchar *lname; gchar *vname; gchar **lv; gboolean any_change = FALSE; xkl_debug (100, "Filtering configuration against the registry\n"); if (!ensure_xkl_registry ()) return FALSE; lv = current_kbd_config.layouts_variants; item = xkl_config_item_new (); while (*lv) { xkl_debug (100, "Checking [%s]\n", *lv); if (gkbd_keyboard_config_split_items (*lv, &lname, &vname)) { gboolean should_be_dropped = FALSE; g_snprintf (item->name, sizeof (item->name), "%s", lname); if (!xkl_config_registry_find_layout (xkl_registry, item)) { xkl_debug (100, "Bad layout [%s]\n", lname); should_be_dropped = TRUE; } else if (vname) { g_snprintf (item->name, sizeof (item->name), "%s", vname); if (!xkl_config_registry_find_variant (xkl_registry, lname, item)) { xkl_debug (100, "Bad variant [%s(%s)]\n", lname, vname); should_be_dropped = TRUE; } } if (should_be_dropped) { gkbd_strv_behead (lv); any_change = TRUE; continue; } } lv++; } g_object_unref (item); return any_change; } static void apply_xkb_settings (void) { GkbdKeyboardConfig current_sys_kbd_config; if (!inited_ok) return; gkbd_keyboard_config_init (¤t_sys_kbd_config, xkl_engine); gkbd_keyboard_config_load (¤t_kbd_config, &initial_sys_kbd_config); gkbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, NULL); if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { if (filter_xkb_config ()) { if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { g_warning ("Could not activate the filtered XKB configuration"); activation_error (); } } else { g_warning ("Could not activate the XKB configuration"); activation_error (); } } else xkl_debug (100, "Actual KBD configuration was not changed: redundant notification\n"); gkbd_keyboard_config_term (¤t_sys_kbd_config); //show_hide_icon (); } static void csd_keyboard_xkb_analyze_sysconfig (void) { if (!inited_ok) return; gkbd_keyboard_config_init (&initial_sys_kbd_config, xkl_engine); gkbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, NULL); } void csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, void *user_data) { pa_callback = fun; pa_callback_user_data = user_data; } static GdkFilterReturn csd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) { XEvent *xevent = (XEvent *) xev; xkl_engine_filter_events (xkl_engine, xevent); return GDK_FILTER_CONTINUE; } /* When new Keyboard is plugged in - reload the settings */ static void csd_keyboard_new_device (XklEngine * engine) { apply_desktop_settings (); apply_xkb_settings (); } void csd_keyboard_xkb_init (CsdKeyboardManager * kbd_manager) { Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); cinnamon_settings_profile_start (NULL); gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), DATADIR G_DIR_SEPARATOR_S "icons"); manager = kbd_manager; cinnamon_settings_profile_start ("xkl_engine_get_instance"); xkl_engine = xkl_engine_get_instance (display); cinnamon_settings_profile_end ("xkl_engine_get_instance"); if (xkl_engine) { inited_ok = TRUE; gkbd_desktop_config_init (¤t_config, xkl_engine); gkbd_keyboard_config_init (¤t_kbd_config, xkl_engine); xkl_engine_backup_names_prop (xkl_engine); csd_keyboard_xkb_analyze_sysconfig (); settings_desktop = g_settings_new (GKBD_DESKTOP_SCHEMA); settings_keyboard = g_settings_new (GKBD_KEYBOARD_SCHEMA); g_signal_connect (settings_desktop, "changed", (GCallback) apply_desktop_settings, NULL); g_signal_connect (settings_keyboard, "changed", (GCallback) apply_xkb_settings, NULL); gdk_window_add_filter (NULL, (GdkFilterFunc) csd_keyboard_xkb_evt_filter, NULL); if (xkl_engine_get_features (xkl_engine) & XKLF_DEVICE_DISCOVERY) g_signal_connect (xkl_engine, "X-new-device", G_CALLBACK (csd_keyboard_new_device), NULL); cinnamon_settings_profile_start ("xkl_engine_start_listen"); xkl_engine_start_listen (xkl_engine, XKLL_MANAGE_LAYOUTS | XKLL_MANAGE_WINDOW_STATES); cinnamon_settings_profile_end ("xkl_engine_start_listen"); cinnamon_settings_profile_start ("apply_desktop_settings"); apply_desktop_settings (); cinnamon_settings_profile_end ("apply_desktop_settings"); cinnamon_settings_profile_start ("apply_xkb_settings"); apply_xkb_settings (); cinnamon_settings_profile_end ("apply_xkb_settings"); } preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); cinnamon_settings_profile_end (NULL); } void csd_keyboard_xkb_shutdown (void) { if (!inited_ok) return; pa_callback = NULL; pa_callback_user_data = NULL; manager = NULL; if (preview_dialogs != NULL) g_hash_table_destroy (preview_dialogs); if (!inited_ok) return; xkl_engine_stop_listen (xkl_engine, XKLL_MANAGE_LAYOUTS | XKLL_MANAGE_WINDOW_STATES); gdk_window_remove_filter (NULL, (GdkFilterFunc) csd_keyboard_xkb_evt_filter, NULL); g_object_unref (settings_desktop); settings_desktop = NULL; g_object_unref (settings_keyboard); settings_keyboard = NULL; if (xkl_registry) { g_object_unref (xkl_registry); } g_object_unref (xkl_engine); xkl_engine = NULL; inited_ok = FALSE; } cinnamon-settings-daemon-6.4.3/plugins/keyboard/csd-keyboard-xkb.h0000664000175000017500000000254114733247605024151 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * cinnamon-settings-keyboard-xkb.h * * Copyright (C) 2001 Udaltsoft * * Written by Sergey V. Oudaltsov * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #ifndef __CSD_KEYBOARD_XKB_H #define __CSD_KEYBOARD_XKB_H #include #include "csd-keyboard-manager.h" void csd_keyboard_xkb_init (CsdKeyboardManager *manager); void csd_keyboard_xkb_shutdown (void); typedef void (*PostActivationCallback) (void *userData); void csd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, void *userData); #endif cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-scrolllock-on.png0000664000175000017500000000247114733247605024676 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsRGB®ÎébKGDÿÿÿ ½§“ pHYsœœn›¡NtIMEÚ)øzè¹IDATxÚí›ÏkTWÇ?o#qD¤Pƒ––l„º ÄBlÚü…vÀZB$¦þ[´Ð¥k×.âÏ¡ŒØJã"EQ$CmÜi±)±“Œ§‹Üâã͹3o2÷¼<<¸›÷î;ßsν÷Ü{~ÜãG >( `IióÀ–yÛý_ Üx% l¯n |#p0ïBï8#0+𺠡}íµÀ}³Ýy¼ PX4Ú×þ8)Ph—ÿ¨MáG€€~[N¬u6¡Ø­ÇÀ·”³õ^JŠ‘ª ÌL ô ìNA{·ë;åþ­¥À¹-Л•ðCÏš0TøR '^£Un‚ùL`ÈZøR«þ«À !þ Ãh´k”,€· \lüX`4Ã%8ê0}ü\ØRøiКÀdk¼ÁÝgÒñ ñ6D Fþ…Àp¶áaÇ‹:B¬yðœ@_ŽÎ"}Ž'×ÒF‰y Þ=9<‰îq¼i†q¨Ub½ž­n.Â'”0çÙ"{[!Tñ¬ù>¦÷,Í&ÜNKàcµ6þ°À†QÛ>I³µ ìŒüT€Õ&]'"xxŒQò»×о,‚¢ –ÁªE$ÊájAÑýÉN¿e¿[ëIpÄO ‹ÏjOe‘8¤(`Uà¼Ñèk‰‘3ZÇó¥Æ.Ä”Psi²n-5¶èÍF |–ErÔ…È_Æ0Æ „÷%GKÍöëß³H»JP¸a4õµôøÃ¦ƒ)p"‹ W]þDà°ð¾‰‘´2)‘ }àq4}%2•Vˆtv‘”#Ö¹er1¢[(#Þ¹¥² ³‹¥cJèÌryÅ&tÞ… ewèÌ+3‰sBž.MU6ziªÝks'€ïZø-äµ¹‡À¹~ÞÌm(r^ä|†'\Yo¼<.žpÊE–jB×\1çiÑ+¹:–îsW[¯)!÷VÚŠ‹X:JĤTÆ.Ö+Ñ>¤µëóOY¿>ÿ%ÿ üë»-u"ÌIEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/keyboard/gkbd-configuration.c0000664000175000017500000002346114733247605024573 0ustar fabiofabio/* * Copyright (C) 2010 Canonical Ltd. * * Authors: Jan Arne Petersen * * Based on gkbd-status.c by Sergey V. Udaltsov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, * Boston, MA 02110-1335, USA. */ #include #include #include #include #include #include #include "gkbd-configuration.h" struct _GkbdConfigurationPrivate { XklEngine *engine; XklConfigRegistry *registry; GkbdDesktopConfig cfg; GkbdIndicatorConfig ind_cfg; GkbdKeyboardConfig kbd_cfg; gchar **full_group_names; gchar **short_group_names; gulong state_changed_handler; gulong config_changed_handler; }; enum { SIGNAL_CHANGED, SIGNAL_GROUP_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0, }; #define GKBD_CONFIGURATION_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GKBD_TYPE_CONFIGURATION, GkbdConfigurationPrivate)) G_DEFINE_TYPE (GkbdConfiguration, gkbd_configuration, G_TYPE_OBJECT) /* Should be called once for all widgets */ static void gkbd_configuration_cfg_changed (GSettings *settings, const char *key, GkbdConfiguration * configuration) { GkbdConfigurationPrivate *priv = configuration->priv; xkl_debug (100, "General configuration changed in GSettings - reiniting...\n"); gkbd_desktop_config_load (&priv->cfg); gkbd_desktop_config_activate (&priv->cfg); g_signal_emit (configuration, signals[SIGNAL_CHANGED], 0); } /* Should be called once for all widgets */ static void gkbd_configuration_ind_cfg_changed (GSettings *settings, const char *key, GkbdConfiguration * configuration) { GkbdConfigurationPrivate *priv = configuration->priv; xkl_debug (100, "Applet configuration changed in GSettings - reiniting...\n"); gkbd_indicator_config_load (&priv->ind_cfg); gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, &priv->kbd_cfg); gkbd_indicator_config_activate (&priv->ind_cfg); g_signal_emit (configuration, signals[SIGNAL_CHANGED], 0); } static void gkbd_configuration_load_group_names (GkbdConfiguration * configuration, XklConfigRec * xklrec) { GkbdConfigurationPrivate *priv = configuration->priv; if (!gkbd_desktop_config_load_group_descriptions (&priv->cfg, priv->registry, (const char **) xklrec->layouts, (const char **) xklrec->variants, &priv->short_group_names, &priv->full_group_names)) { /* We just populate no short names (remain NULL) - * full names are going to be used anyway */ gint i, total_groups = xkl_engine_get_num_groups (priv->engine); xkl_debug (150, "group descriptions loaded: %d!\n", total_groups); priv->full_group_names = g_new0 (char *, total_groups + 1); if (xkl_engine_get_features (priv->engine) & XKLF_MULTIPLE_LAYOUTS_SUPPORTED) { for (i = 0; priv->kbd_cfg.layouts_variants[i]; i++) { priv->full_group_names[i] = g_strdup ((char *) priv->kbd_cfg.layouts_variants[i]); } } else { for (i = total_groups; --i >= 0;) { priv->full_group_names[i] = g_strdup_printf ("Group %d", i); } } } } /* Should be called once for all widgets */ static void gkbd_configuration_kbd_cfg_callback (XklEngine *engine, GkbdConfiguration *configuration) { GkbdConfigurationPrivate *priv = configuration->priv; XklConfigRec *xklrec = xkl_config_rec_new (); xkl_debug (100, "XKB configuration changed on X Server - reiniting...\n"); gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, xklrec); gkbd_indicator_config_free_image_filenames (&priv->ind_cfg); gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, &priv->kbd_cfg); g_strfreev (priv->full_group_names); priv->full_group_names = NULL; g_strfreev (priv->short_group_names); priv->short_group_names = NULL; gkbd_configuration_load_group_names (configuration, xklrec); g_signal_emit (configuration, signals[SIGNAL_CHANGED], 0); g_object_unref (G_OBJECT (xklrec)); } /* Should be called once for all applets */ static void gkbd_configuration_state_callback (XklEngine * engine, XklEngineStateChange changeType, gint group, gboolean restore, GkbdConfiguration * configuration) { xkl_debug (150, "group is now %d, restore: %d\n", group, restore); if (changeType == GROUP_CHANGED) { g_signal_emit (configuration, signals[SIGNAL_GROUP_CHANGED], 0, group); } } static void gkbd_configuration_init (GkbdConfiguration *configuration) { GkbdConfigurationPrivate *priv; XklConfigRec *xklrec = xkl_config_rec_new (); priv = GKBD_CONFIGURATION_GET_PRIVATE (configuration); configuration->priv = priv; priv->engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); if (priv->engine == NULL) { xkl_debug (0, "Libxklavier initialization error"); return; } priv->state_changed_handler = g_signal_connect (priv->engine, "X-state-changed", G_CALLBACK (gkbd_configuration_state_callback), configuration); priv->config_changed_handler = g_signal_connect (priv->engine, "X-config-changed", G_CALLBACK (gkbd_configuration_kbd_cfg_callback), configuration); gkbd_desktop_config_init (&priv->cfg, priv->engine); gkbd_keyboard_config_init (&priv->kbd_cfg, priv->engine); gkbd_indicator_config_init (&priv->ind_cfg, priv->engine); gkbd_desktop_config_load (&priv->cfg); gkbd_desktop_config_activate (&priv->cfg); priv->registry = xkl_config_registry_get_instance (priv->engine); xkl_config_registry_load (priv->registry, priv->cfg.load_extra_items); gkbd_keyboard_config_load_from_x_current (&priv->kbd_cfg, xklrec); gkbd_indicator_config_load (&priv->ind_cfg); gkbd_indicator_config_load_image_filenames (&priv->ind_cfg, &priv->kbd_cfg); gkbd_indicator_config_activate (&priv->ind_cfg); gkbd_configuration_load_group_names (configuration, xklrec); g_object_unref (G_OBJECT (xklrec)); gkbd_desktop_config_start_listen (&priv->cfg, G_CALLBACK (gkbd_configuration_cfg_changed), configuration); gkbd_indicator_config_start_listen (&priv->ind_cfg, G_CALLBACK (gkbd_configuration_ind_cfg_changed), configuration); xkl_engine_start_listen (priv->engine, XKLL_TRACK_KEYBOARD_STATE); xkl_debug (100, "Initiating the widget startup process for %p\n", configuration); } static void gkbd_configuration_finalize (GObject * obj) { GkbdConfiguration *configuration = GKBD_CONFIGURATION (obj); GkbdConfigurationPrivate *priv = configuration->priv; xkl_debug (100, "Starting the gnome-kbd-configuration widget shutdown process for %p\n", configuration); xkl_engine_stop_listen (priv->engine, XKLL_TRACK_KEYBOARD_STATE); gkbd_desktop_config_stop_listen (&priv->cfg); gkbd_indicator_config_stop_listen (&priv->ind_cfg); gkbd_indicator_config_term (&priv->ind_cfg); gkbd_keyboard_config_term (&priv->kbd_cfg); gkbd_desktop_config_term (&priv->cfg); if (g_signal_handler_is_connected (priv->engine, priv->state_changed_handler)) { g_signal_handler_disconnect (priv->engine, priv->state_changed_handler); priv->state_changed_handler = 0; } if (g_signal_handler_is_connected (priv->engine, priv->config_changed_handler)) { g_signal_handler_disconnect (priv->engine, priv->config_changed_handler); priv->config_changed_handler = 0; } g_object_unref (priv->registry); priv->registry = NULL; g_object_unref (priv->engine); priv->engine = NULL; G_OBJECT_CLASS (gkbd_configuration_parent_class)->finalize (obj); } static void gkbd_configuration_class_init (GkbdConfigurationClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); /* Initing vtable */ object_class->finalize = gkbd_configuration_finalize; /* Signals */ signals[SIGNAL_CHANGED] = g_signal_new ("changed", GKBD_TYPE_CONFIGURATION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIGNAL_GROUP_CHANGED] = g_signal_new ("group-changed", GKBD_TYPE_CONFIGURATION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); g_type_class_add_private (klass, sizeof (GkbdConfigurationPrivate)); } GkbdConfiguration * gkbd_configuration_get (void) { static gpointer instance = NULL; if (!instance) { instance = g_object_new (GKBD_TYPE_CONFIGURATION, NULL); g_object_add_weak_pointer (instance, &instance); } else { g_object_ref (instance); } return instance; } XklEngine * gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration) { return configuration->priv->engine; } const char * const * gkbd_configuration_get_group_names (GkbdConfiguration *configuration) { return (const char * const *)configuration->priv->full_group_names; } const char * const * gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration) { return (const char * const *)configuration->priv->short_group_names; } cinnamon-settings-daemon-6.4.3/plugins/keyboard/gkbd-configuration.h0000664000175000017500000000464514733247605024603 0ustar fabiofabio/* * Copyright (C) 2010 Canonical Ltd. * * Authors: Jan Arne Petersen * * Based on gkbd-status.h by Sergey V. Udaltsov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street - Suite 500, * Boston, MA 02110-1335, USA. */ #ifndef __GKBD_CONFIGURATION_H__ #define __GKBD_CONFIGURATION_H__ #include #include G_BEGIN_DECLS typedef struct _GkbdConfiguration GkbdConfiguration; typedef struct _GkbdConfigurationPrivate GkbdConfigurationPrivate; typedef struct _GkbdConfigurationClass GkbdConfigurationClass; #define GKBD_TYPE_CONFIGURATION (gkbd_configuration_get_type ()) #define GKBD_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfiguration)) #define GKBD_INDCATOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) #define GKBD_IS_CONFIGURATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) #define GKBD_IS_CONFIGURATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GKBD_TYPE_CONFIGURATION)) #define GKBD_CONFIGURATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKBD_TYPE_CONFIGURATION, GkbdConfigurationClass)) struct _GkbdConfiguration { GObject parent; GkbdConfigurationPrivate *priv; }; struct _GkbdConfigurationClass { GObjectClass parent_class; }; extern GType gkbd_configuration_get_type (void); extern GkbdConfiguration *gkbd_configuration_get (void); extern XklEngine *gkbd_configuration_get_xkl_engine (GkbdConfiguration *configuration); extern const char * const *gkbd_configuration_get_group_names (GkbdConfiguration *configuration); extern const char * const *gkbd_configuration_get_short_group_names (GkbdConfiguration *configuration); G_END_DECLS #endif cinnamon-settings-daemon-6.4.3/plugins/keyboard/csd-keyboard-manager.c0000664000175000017500000003036614733247605025000 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright © 2001 Ximian, Inc. * Copyright (C) 2007 William Jon McCann * Written by Sergey V. Oudaltsov * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-keyboard-manager.h" #include "csd-enums.h" #include "csd-keyboard-xkb.h" #include "migrate-settings.h" #define CSD_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_KEYBOARD_MANAGER, CsdKeyboardManagerPrivate)) #ifndef HOST_NAME_MAX # define HOST_NAME_MAX 255 #endif #define CSD_KEYBOARD_DIR "org.cinnamon.settings-daemon.peripherals.keyboard" #define KEY_CLICK "click" #define KEY_CLICK_VOLUME "click-volume" #define KEY_NUMLOCK_STATE "numlock-state" #define KEY_BELL_VOLUME "bell-volume" #define KEY_BELL_PITCH "bell-pitch" #define KEY_BELL_DURATION "bell-duration" #define KEY_BELL_MODE "bell-mode" struct CsdKeyboardManagerPrivate { guint start_idle_id; GSettings *settings; gboolean have_xkb; gint xkb_event_base; CsdNumLockState old_state; }; static void csd_keyboard_manager_finalize (GObject *object); G_DEFINE_TYPE (CsdKeyboardManager, csd_keyboard_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static void numlock_xkb_init (CsdKeyboardManager *manager) { Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); gboolean have_xkb; int opcode, error_base, major, minor; have_xkb = XkbQueryExtension (dpy, &opcode, &manager->priv->xkb_event_base, &error_base, &major, &minor) && XkbUseExtension (dpy, &major, &minor); if (have_xkb) { XkbSelectEventDetails (dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbModifierLockMask, XkbModifierLockMask); } else { g_warning ("XKB extension not available"); } manager->priv->have_xkb = have_xkb; } static unsigned numlock_NumLock_modifier_mask (void) { Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); return XkbKeysymToModifiers (dpy, XK_Num_Lock); } static void numlock_set_xkb_state (CsdNumLockState new_state) { unsigned int num_mask; Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); if (new_state != CSD_NUM_LOCK_STATE_ON && new_state != CSD_NUM_LOCK_STATE_OFF) return; num_mask = numlock_NumLock_modifier_mask (); XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state == CSD_NUM_LOCK_STATE_ON ? num_mask : 0); } static GdkFilterReturn numlock_xkb_callback (GdkXEvent *xev_, GdkEvent *gdkev_, gpointer user_data) { XEvent *xev = (XEvent *) xev_; XkbEvent *xkbev = (XkbEvent *) xev; CsdKeyboardManager *manager = (CsdKeyboardManager *) user_data; if (xev->type != manager->priv->xkb_event_base) return GDK_FILTER_CONTINUE; if (xkbev->any.xkb_type != XkbStateNotify) return GDK_FILTER_CONTINUE; if (xkbev->state.changed & XkbModifierLockMask) { unsigned num_mask = numlock_NumLock_modifier_mask (); unsigned locked_mods = xkbev->state.locked_mods; CsdNumLockState numlock_state; numlock_state = (num_mask & locked_mods) ? CSD_NUM_LOCK_STATE_ON : CSD_NUM_LOCK_STATE_OFF; if (numlock_state != manager->priv->old_state) { g_settings_set_enum (manager->priv->settings, KEY_NUMLOCK_STATE, numlock_state); manager->priv->old_state = numlock_state; } } return GDK_FILTER_CONTINUE; } static void numlock_install_xkb_callback (CsdKeyboardManager *manager) { if (!manager->priv->have_xkb) return; gdk_window_add_filter (NULL, numlock_xkb_callback, manager); } static guint _csd_settings_get_uint (GSettings *settings, const char *key) { guint value; g_settings_get (settings, key, "u", &value); return value; } static void apply_settings (GSettings *settings, const char *key, CsdKeyboardManager *manager) { XKeyboardControl kbdcontrol; gboolean click; int click_volume; int bell_volume; int bell_pitch; int bell_duration; CsdBellMode bell_mode; gboolean rnumlock; if (g_strcmp0 (key, KEY_NUMLOCK_STATE) == 0) return; click = g_settings_get_boolean (settings, KEY_CLICK); click_volume = g_settings_get_int (settings, KEY_CLICK_VOLUME); bell_pitch = g_settings_get_int (settings, KEY_BELL_PITCH); bell_duration = g_settings_get_int (settings, KEY_BELL_DURATION); bell_mode = g_settings_get_enum (settings, KEY_BELL_MODE); bell_volume = (bell_mode == CSD_BELL_MODE_ON) ? 50 : 0; gdk_x11_display_error_trap_push (gdk_display_get_default ()); /* as percentage from 0..100 inclusive */ if (click_volume < 0) { click_volume = 0; } else if (click_volume > 100) { click_volume = 100; } kbdcontrol.key_click_percent = click ? click_volume : 0; kbdcontrol.bell_percent = bell_volume; kbdcontrol.bell_pitch = bell_pitch; kbdcontrol.bell_duration = bell_duration; XChangeKeyboardControl (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, &kbdcontrol); if (g_strcmp0 (key, "remember-numlock-state") == 0 || key == NULL) { rnumlock = g_settings_get_boolean (settings, "remember-numlock-state"); manager->priv->old_state = g_settings_get_enum (manager->priv->settings, KEY_NUMLOCK_STATE); if (manager->priv->have_xkb && rnumlock) numlock_set_xkb_state (manager->priv->old_state); } XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); } void csd_keyboard_manager_apply_settings (CsdKeyboardManager *manager) { apply_settings (manager->priv->settings, NULL, manager); } static gboolean start_keyboard_idle_cb (CsdKeyboardManager *manager) { cinnamon_settings_profile_start (NULL); g_debug ("Starting keyboard manager"); manager->priv->have_xkb = 0; manager->priv->settings = g_settings_new (CSD_KEYBOARD_DIR); /* Essential - xkb initialization should happen before */ csd_keyboard_xkb_init (manager); numlock_xkb_init (manager); /* apply current settings before we install the callback */ csd_keyboard_manager_apply_settings (manager); g_signal_connect (G_OBJECT (manager->priv->settings), "changed", G_CALLBACK (apply_settings), manager); numlock_install_xkb_callback (manager); cinnamon_settings_profile_end (NULL); manager->priv->start_idle_id = 0; return FALSE; } gboolean csd_keyboard_manager_start (CsdKeyboardManager *manager, GError **error) { cinnamon_settings_profile_start (NULL); manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_keyboard_manager_stop (CsdKeyboardManager *manager) { CsdKeyboardManagerPrivate *p = manager->priv; g_debug ("Stopping keyboard manager"); if (p->settings != NULL) { g_object_unref (p->settings); p->settings = NULL; } if (p->have_xkb) { gdk_window_remove_filter (NULL, numlock_xkb_callback, manager); } csd_keyboard_xkb_shutdown (); } static GObject * csd_keyboard_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CsdKeyboardManager *keyboard_manager; keyboard_manager = CSD_KEYBOARD_MANAGER (G_OBJECT_CLASS (csd_keyboard_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (keyboard_manager); } static void csd_keyboard_manager_class_init (CsdKeyboardManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = csd_keyboard_manager_constructor; object_class->finalize = csd_keyboard_manager_finalize; g_type_class_add_private (klass, sizeof (CsdKeyboardManagerPrivate)); } static void csd_keyboard_manager_init (CsdKeyboardManager *manager) { manager->priv = CSD_KEYBOARD_MANAGER_GET_PRIVATE (manager); } static void csd_keyboard_manager_finalize (GObject *object) { CsdKeyboardManager *keyboard_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_KEYBOARD_MANAGER (object)); keyboard_manager = CSD_KEYBOARD_MANAGER (object); g_return_if_fail (keyboard_manager->priv != NULL); if (keyboard_manager->priv->start_idle_id != 0) { g_source_remove (keyboard_manager->priv->start_idle_id); keyboard_manager->priv->start_idle_id = 0; } G_OBJECT_CLASS (csd_keyboard_manager_parent_class)->finalize (object); } static void migrate_keyboard_settings (void) { CsdSettingsMigrateEntry entries[] = { { "repeat", "repeat", NULL }, { "repeat-interval", "repeat-interval", NULL }, { "delay", "delay", NULL } }; csd_settings_migrate_check ("org.cinnamon.settings-daemon.peripherals.keyboard.deprecated", "/org/cinnamon/settings-daemon/peripherals/keyboard/", "org.cinnamon.desktop.peripherals.keyboard", "/org/cinnamon/desktop/peripherals/keyboard/", entries, G_N_ELEMENTS (entries)); } CsdKeyboardManager * csd_keyboard_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { migrate_keyboard_settings (); manager_object = g_object_new (CSD_TYPE_KEYBOARD_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_KEYBOARD_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/keyboard/delayed-dialog.h0000664000175000017500000000163414733247605023666 0ustar fabiofabio/* * Copyright © 2006 Novell, Inc. * * 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #ifndef __DELAYED_DIALOG_H #define __DELAYED_DIALOG_H #include G_BEGIN_DECLS void csd_delayed_show_dialog (GtkWidget *dialog); G_END_DECLS #endif cinnamon-settings-daemon-6.4.3/plugins/keyboard/kbd-numlock-off.png0000664000175000017500000000331614733247605024334 0ustar fabiofabio‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsœœn›¡NtEXtSoftwarewww.inkscape.org›î<KIDATxœå›[ˆVUÇÿûÓò6b7‡¼<ˆƒÝL!)Ó A³DˆÞ²Ë” ^ÀÀÔ$"¢—Jò!z”Šz)S¼¥ˆ¥‰—ˆFÇÅq2Éy˜"c&uæ×Ã>£gö¬óÍ÷}gãàüá{8笵þkíoŸ}Y{§*¨‘4GÒdIãŸ$µ¿&I{s—ªíctã€eÀ6 ƒÊÑl–nt\E V‡®Ag¡ 8 ¬FÞèx¯(õÀ¹*…óÀb ×—3øù’6Hš^†Ú%õ|×¥žcBM¶%½áœÛQ†N~Ý%üSÀ`0 ]‚íщìºD·³ž=ÀÄþˆ]ÀlàBí–µøj[;úà¼ÌŽc1gê)>ªïfV‘f‘… ¾ÄC€Eˆщ³ýYpfa#0$Ù`sÑU` Fã ü*$ÜW3|Û¥ŠüómÀܱäõonâ‹Ùò¯Ï0|˜)†Ü¦$>Y¨lLÀöÖ€·9†ÜÆ$¾…è ÜÙ?Ï[SÝÉ|7’F°zÂÊY'`/rÚR·ÏBò:XcžR cð*p0k&åõ!ñ#ÜJw‘Î1KVZ8ÜGœÉ|ȚׇÄö#¾åi­ÁÃNr&3ðƒÞé ÕWö¡38›Òùx0‰]«‡oï~8ŠÞïá¤ó›‡(a:6zïåõ%±{ °ÛÔä-†òßFà|(¸>åœë*A¯!¸~,‚/RIšSTgïŒ@Îç-¦To–Ô™ºžJœs+¦É]?žJ£9á­ÁuG‰zmì]’̳L4÷Æ[ pÉ9÷OÂ0à»KÔ{XÒ¨àÞ´¼Î$1…çŒf”ÚUûÂÅàºÔ³½Œ{·çô¥alUm€-êÙ ÂÑÂBãÞˆ8.õc8çš$íOݺMÒ[@æq~ñõ¤ñ¨ª PM|"érêú9Iß`uoJúP’åS®3Ìb*ß*÷¦îY³BEpÎ}̓Խ¬v’ž•48-éwù÷»NÒýºh“|AE7bIôêíUm€+åZÏëú¿›® ±SÒo’V§îU­ 2Þ‹Hd’$çÜeçÜ‹’VH:¢ž‹œ4ÎJz_~ 3DáŒR)2{@5ÀèHkkpÎm’´ ˜%é ùÎHIÉwù/œsÿIpOJµ]ÒwyùñGóaíÙ’4IÒñ¼¤œs‡$ÊzÜ)é¾Ô­Sιó¨'÷Z ’ÎæG ¬ËÔsás0’]+¦¦ªm‡+>1{4åG;‘ê ²¶ÃÝ£'D*tò£À­‘ìZ ‘mi+e”;%–ØžE‰ÀïÒó0öO œâ«bö­ø–¥Æ-¥ò Ÿìl>^¦â»ú-@ð:½Ou/ëcð'>XIÑq¡Ð~£•b¤Å0È[‹Àƒó ‘Ò` ¿•?l ®0÷Ep l€bhVåå ø­ƒ‘Õ–à­‰!r/Ÿ¿b×ü]~€Qký°ÆÎ×r .PX$éËÀÎ IÓKLhsÆÉ/p¦Jª•߈µJ:áœ;–Çv_AÒ±„/WœsŸe: ül´ÚÍr<Þ@_©y`ž¡x³H”¶Âåæ,‘Ù]Ž‘Á]$•¼er)£õ†Áîž0`^ªQ(™2>xKe‚Á], Þrù€¸žÁøÁDàÄàýd&åÔ@ûhj7n¤ò~67OÒê] R 1?›k´Þ9·« ¸Ào ao¥«…f|Yo¿Ï>™ÀçVà3K¥tÛrщ/æ\ »Ññ>ǸØ‚] Z*Úñë¥T)K]µcçn£ä+ÑêTÞçógä?Ÿÿ·šþý|wÙUú‘&IEND®B`‚cinnamon-settings-daemon-6.4.3/plugins/a11y-settings/0000775000175000017500000000000014733247605021456 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/a11y-settings/meson.build0000664000175000017500000000162414733247605023623 0ustar fabiofabioplugin_name = 'a11y-settings' a11y_settings_sources = [ 'csd-a11y-settings-manager.c', 'main.c', ] a11y_settings_deps = [ common_dep, csd_dep, libnotify, ] executable( 'csd-a11y-settings', a11y_settings_sources, include_directories: [include_dirs, common_inc], dependencies: a11y_settings_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-a11y-settings') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-a11y-settings') endif configure_file( input: 'cinnamon-settings-daemon-a11y-settings.desktop.in', output: 'cinnamon-settings-daemon-a11y-settings.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/a11y-settings/main.c0000664000175000017500000000116314733247605022547 0ustar fabiofabio#define NEW csd_a11y_settings_manager_new #define START csd_a11y_settings_manager_start #define STOP csd_a11y_settings_manager_stop #define MANAGER CsdA11ySettingsManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-a11y-settings-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/a11y-settings/csd-a11y-settings-manager.h0000664000175000017500000000474414733247605026430 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_A11Y_SETTINGS_MANAGER_H #define __CSD_A11Y_SETTINGS_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_A11Y_SETTINGS_MANAGER (csd_a11y_settings_manager_get_type ()) #define CSD_A11Y_SETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_A11Y_SETTINGS_MANAGER, CsdA11ySettingsManager)) #define CSD_A11Y_SETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_A11Y_SETTINGS_MANAGER, CsdA11ySettingsManagerClass)) #define CSD_IS_A11Y_SETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_A11Y_SETTINGS_MANAGER)) #define CSD_IS_A11Y_SETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_A11Y_SETTINGS_MANAGER)) #define CSD_A11Y_SETTINGS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_A11Y_SETTINGS_MANAGER, CsdA11ySettingsManagerClass)) typedef struct CsdA11ySettingsManagerPrivate CsdA11ySettingsManagerPrivate; typedef struct { GObject parent; CsdA11ySettingsManagerPrivate *priv; } CsdA11ySettingsManager; typedef struct { GObjectClass parent_class; } CsdA11ySettingsManagerClass; GType csd_a11y_settings_manager_get_type (void); CsdA11ySettingsManager *csd_a11y_settings_manager_new (void); gboolean csd_a11y_settings_manager_start (CsdA11ySettingsManager *manager, GError **error); void csd_a11y_settings_manager_stop (CsdA11ySettingsManager *manager); G_END_DECLS #endif /* __CSD_A11Y_SETTINGS_MANAGER_H */ ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootcinnamon-settings-daemon-6.4.3/plugins/a11y-settings/cinnamon-settings-daemon-a11y-settings.desktop.incinnamon-settings-daemon-6.4.3/plugins/a11y-settings/cinnamon-settings-daemon-a11y-settings.desktop.0000664000175000017500000000035214733247605032437 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - a11y-settings Exec=csd-a11y-settings OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/a11y-settings/csd-a11y-settings-manager.c0000664000175000017500000004105614733247605026420 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-a11y-settings-manager.h" #define CSD_A11Y_SETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_A11Y_SETTINGS_MANAGER, CsdA11ySettingsManagerPrivate)) struct CsdA11ySettingsManagerPrivate { GSettings *interface_settings; GSettings *a11y_apps_settings; GSettings *wm_settings; GSettings *sound_settings; GHashTable *bind_table; }; enum { PROP_0, }; static void csd_a11y_settings_manager_class_init (CsdA11ySettingsManagerClass *klass); static void csd_a11y_settings_manager_init (CsdA11ySettingsManager *a11y_settings_manager); static void csd_a11y_settings_manager_finalize (GObject *object); G_DEFINE_TYPE (CsdA11ySettingsManager, csd_a11y_settings_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; typedef struct { GSettings *settings; gchar *key; } SettingsData; static void settings_data_free (SettingsData *data) { g_object_unref (data->settings); g_free (data->key); } static void bound_key_changed (GSettings *settings, gchar *key, SettingsData *data) { g_signal_handlers_block_matched (G_SETTINGS (data->settings), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, bound_key_changed, NULL); g_settings_set_value (data->settings, data->key, g_settings_get_value (settings, key)); g_signal_handlers_unblock_matched (G_SETTINGS (data->settings), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, bound_key_changed, NULL); } static void bind_keys (CsdA11ySettingsManager *manager, const gchar *schema_id_a, const gchar *key_a, const gchar *schema_id_b, const gchar *key_b) { GSettingsSchemaSource *source = g_settings_schema_source_get_default (); /* We assume any schema_id_a will exist (since it's our's) */ GSettingsSchema *schema = g_settings_schema_source_lookup (source, schema_id_b, FALSE); if (!schema) return; if (!g_settings_schema_has_key (schema, key_b)) return; g_settings_schema_unref (schema); if (!manager->priv->bind_table) { manager->priv->bind_table = g_hash_table_new_full (g_direct_hash, g_str_equal, g_free, g_object_unref); } GSettings *a_settings = NULL; GSettings *b_settings = NULL; a_settings = g_hash_table_lookup (manager->priv->bind_table, schema_id_a); if (!a_settings) { a_settings = g_settings_new (schema_id_a); g_hash_table_insert (manager->priv->bind_table, g_strdup (schema_id_a), a_settings); } b_settings = g_hash_table_lookup (manager->priv->bind_table, schema_id_b); if (!b_settings) { b_settings = g_settings_new (schema_id_b); g_hash_table_insert (manager->priv->bind_table, g_strdup (schema_id_b), b_settings); } /* initial sync */ g_settings_set_value (b_settings, key_b, g_settings_get_value (a_settings, key_a)); gchar *detailed_signal_a = g_strdup_printf ("changed::%s", key_a); gchar *detailed_signal_b = g_strdup_printf ("changed::%s", key_b); SettingsData *data_a = g_slice_new(SettingsData); SettingsData *data_b = g_slice_new(SettingsData); data_a->settings = g_object_ref (a_settings); data_a->key = g_strdup (key_a); data_b->settings = g_object_ref (b_settings); data_b->key = g_strdup (key_b); g_signal_connect_data (a_settings, detailed_signal_a, G_CALLBACK (bound_key_changed), data_b, (GClosureNotify) settings_data_free, 0); g_signal_connect_data (b_settings, detailed_signal_b, G_CALLBACK (bound_key_changed), data_a, (GClosureNotify) settings_data_free, 0); g_free (detailed_signal_a); g_free (detailed_signal_b); } #define CINNAMON_A11Y_APP_SCHEMA "org.cinnamon.desktop.a11y.applications" #define CINNAMON_DESKTOP_SCHEMA "org.cinnamon.desktop.interface" #define CINNAMON_A11Y_MOUSE_SCHEMA "org.cinnamon.desktop.a11y.mouse" #define GNOME_A11Y_APP_SCHEMA "org.gnome.desktop.a11y.applications" #define GNOME_DESKTOP_SCHEMA "org.gnome.desktop.interface" #define GNOME_A11Y_MOUSE_SCHEMA "org.gnome.desktop.a11y.mouse" static void bind_cinnamon_gnome_a11y_settings (CsdA11ySettingsManager *manager) { bind_keys (manager, CINNAMON_A11Y_APP_SCHEMA, "screen-keyboard-enabled", GNOME_A11Y_APP_SCHEMA, "screen-keyboard-enabled"); bind_keys (manager, CINNAMON_A11Y_APP_SCHEMA, "screen-reader-enabled", GNOME_A11Y_APP_SCHEMA, "screen-reader-enabled"); bind_keys (manager, CINNAMON_DESKTOP_SCHEMA, "toolkit-accessibility", GNOME_DESKTOP_SCHEMA, "toolkit-accessibility"); bind_keys (manager, CINNAMON_A11Y_MOUSE_SCHEMA, "secondary-click-enabled", GNOME_A11Y_MOUSE_SCHEMA, "secondary-click-enabled"); bind_keys (manager, CINNAMON_A11Y_MOUSE_SCHEMA, "secondary-click-time", GNOME_A11Y_MOUSE_SCHEMA, "secondary-click-time"); bind_keys (manager, CINNAMON_A11Y_MOUSE_SCHEMA, "dwell-click-enabled", GNOME_A11Y_MOUSE_SCHEMA, "dwell-click-enabled"); bind_keys (manager, CINNAMON_A11Y_MOUSE_SCHEMA, "dwell-threshold", GNOME_A11Y_MOUSE_SCHEMA, "dwell-threshold"); bind_keys (manager, CINNAMON_A11Y_MOUSE_SCHEMA, "dwell-time", GNOME_A11Y_MOUSE_SCHEMA, "dwell-time"); } static void hash_table_foreach_disconnect (gpointer key, gpointer value, gpointer user_data) { g_signal_handlers_disconnect_matched (G_SETTINGS (value), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, bound_key_changed, NULL); } static void unbind_cinnamon_gnome_a11y_settings (CsdA11ySettingsManager *manager) { g_hash_table_foreach (manager->priv->bind_table, (GHFunc) hash_table_foreach_disconnect, manager); g_clear_pointer (&manager->priv->bind_table, g_hash_table_destroy); } static void on_notification_closed (NotifyNotification *notification, CsdA11ySettingsManager *manager) { g_object_unref (notification); } static void on_notification_action_clicked (NotifyNotification *notification, const char *action, CsdA11ySettingsManager *manager) { g_spawn_command_line_async ("cinnamon-settings universal-access", NULL); } static void apps_settings_changed (GSettings *settings, const char *key, CsdA11ySettingsManager *manager) { gboolean screen_reader, keyboard; if (g_str_equal (key, "screen-reader-enabled") == FALSE && g_str_equal (key, "screen-keyboard-enabled") == FALSE) return; g_debug ("screen reader or OSK enablement changed"); screen_reader = g_settings_get_boolean (manager->priv->a11y_apps_settings, "screen-reader-enabled"); keyboard = g_settings_get_boolean (manager->priv->a11y_apps_settings, "screen-keyboard-enabled"); if (screen_reader || keyboard) { g_debug ("Enabling toolkit-accessibility, screen reader or OSK enabled"); g_settings_set_boolean (manager->priv->interface_settings, "toolkit-accessibility", TRUE); } else if (screen_reader == FALSE && keyboard == FALSE) { g_debug ("Disabling toolkit-accessibility, screen reader and OSK disabled"); g_settings_set_boolean (manager->priv->interface_settings, "toolkit-accessibility", FALSE); } if (screen_reader) { gchar *orca_path = g_find_program_in_path ("orca"); if (orca_path == NULL) { NotifyNotification *notification = notify_notification_new (_("Screen reader not found."), _("Please install the 'orca' package."), "preferences-desktop-accessibility"); notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL); notify_notification_add_action (notification, "open-cinnamon-settings", _("Open accessibility settings"), (NotifyActionCallback) on_notification_action_clicked, manager, NULL); g_signal_connect (notification, "closed", G_CALLBACK (on_notification_closed), manager); GError *error = NULL; gboolean res = notify_notification_show (notification, &error); if (!res) { g_warning ("CsdA11ySettingsManager: unable to show notification: %s", error->message); g_error_free (error); notify_notification_close (notification, NULL); } } g_free (orca_path); } } static void bell_settings_changed (GSettings *settings, const char *key, CsdA11ySettingsManager *manager) { gboolean visual, audible; if (g_str_equal (key, "visual-bell") == FALSE && g_str_equal (key, "audible-bell") == FALSE) return; g_debug ("event feedback settings changed"); visual = g_settings_get_boolean (manager->priv->wm_settings, "visual-bell"); audible = g_settings_get_boolean (manager->priv->wm_settings, "audible-bell"); if (visual || audible) { g_debug ("Enabling event-sounds, visible or audible feedback enabled"); g_settings_set_boolean (manager->priv->sound_settings, "event-sounds", TRUE); } else if (visual == FALSE && audible == FALSE) { g_debug ("Disabling event-sounds, visible and audible feedback disabled"); g_settings_set_boolean (manager->priv->sound_settings, "event-sounds", FALSE); } } gboolean csd_a11y_settings_manager_start (CsdA11ySettingsManager *manager, GError **error) { g_debug ("Starting a11y_settings manager"); cinnamon_settings_profile_start (NULL); manager->priv->interface_settings = g_settings_new ("org.cinnamon.desktop.interface"); manager->priv->a11y_apps_settings = g_settings_new ("org.cinnamon.desktop.a11y.applications"); manager->priv->wm_settings = g_settings_new ("org.cinnamon.desktop.wm.preferences"); manager->priv->sound_settings = g_settings_new ("org.cinnamon.desktop.sound"); g_signal_connect (G_OBJECT (manager->priv->a11y_apps_settings), "changed", G_CALLBACK (apps_settings_changed), manager); g_signal_connect (G_OBJECT (manager->priv->wm_settings), "changed", G_CALLBACK (bell_settings_changed), manager); /* If any of the screen reader or on-screen keyboard are enabled, * make sure a11y is enabled for the toolkits. * We don't do the same thing for the reverse so it's possible to * enable AT-SPI for the toolkits without using an a11y app */ if (g_settings_get_boolean (manager->priv->a11y_apps_settings, "screen-keyboard-enabled") || g_settings_get_boolean (manager->priv->a11y_apps_settings, "screen-reader-enabled")) g_settings_set_boolean (manager->priv->interface_settings, "toolkit-accessibility", TRUE); if (g_settings_get_boolean (manager->priv->wm_settings, "audible-bell") || g_settings_get_boolean (manager->priv->wm_settings, "visual-bell")) g_settings_set_boolean (manager->priv->sound_settings, "event-sounds", TRUE); else g_settings_set_boolean (manager->priv->sound_settings, "event-sounds", FALSE); /* Some accessibility applications (like orca) are hardcoded to look at the gnome a11y applications schema - mirror them */ bind_cinnamon_gnome_a11y_settings (manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_a11y_settings_manager_stop (CsdA11ySettingsManager *manager) { unbind_cinnamon_gnome_a11y_settings (manager); g_clear_object (&manager->priv->interface_settings); g_clear_object (&manager->priv->a11y_apps_settings); g_clear_object (&manager->priv->wm_settings); g_clear_object (&manager->priv->sound_settings); g_debug ("Stopping a11y_settings manager"); } static GObject * csd_a11y_settings_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CsdA11ySettingsManager *a11y_settings_manager; a11y_settings_manager = CSD_A11Y_SETTINGS_MANAGER (G_OBJECT_CLASS (csd_a11y_settings_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (a11y_settings_manager); } static void csd_a11y_settings_manager_dispose (GObject *object) { G_OBJECT_CLASS (csd_a11y_settings_manager_parent_class)->dispose (object); } static void csd_a11y_settings_manager_class_init (CsdA11ySettingsManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = csd_a11y_settings_manager_constructor; object_class->dispose = csd_a11y_settings_manager_dispose; object_class->finalize = csd_a11y_settings_manager_finalize; g_type_class_add_private (klass, sizeof (CsdA11ySettingsManagerPrivate)); } static void csd_a11y_settings_manager_init (CsdA11ySettingsManager *manager) { manager->priv = CSD_A11Y_SETTINGS_MANAGER_GET_PRIVATE (manager); manager->priv->bind_table = NULL; } static void csd_a11y_settings_manager_finalize (GObject *object) { CsdA11ySettingsManager *a11y_settings_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_A11Y_SETTINGS_MANAGER (object)); a11y_settings_manager = CSD_A11Y_SETTINGS_MANAGER (object); g_return_if_fail (a11y_settings_manager->priv != NULL); G_OBJECT_CLASS (csd_a11y_settings_manager_parent_class)->finalize (object); } CsdA11ySettingsManager * csd_a11y_settings_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_A11Y_SETTINGS_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_A11Y_SETTINGS_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/media-keys/0000775000175000017500000000000014733247605021075 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/media-keys/csd-marshal.list0000664000175000017500000000002314733247605024163 0ustar fabiofabioVOID:STRING,STRING cinnamon-settings-daemon-6.4.3/plugins/media-keys/meson.build0000664000175000017500000000201114733247605023231 0ustar fabiofabioplugin_name = 'media-keys' media_keys_sources = [ 'csd-media-keys-manager.c', 'bus-watch-namespace.c', 'mpris-controller.c', 'main.c', ] media_keys_deps = [ canberra, cinnamon_desktop, common_dep, csd_dep, cvc, gio_unix, gudev, libnotify, math, ] executable( 'csd-media-keys', media_keys_sources, include_directories: [include_dirs, common_inc, include_enums], dependencies: media_keys_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-media-keys') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-media-keys') endif configure_file( input: 'cinnamon-settings-daemon-media-keys.desktop.in', output: 'cinnamon-settings-daemon-media-keys.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/media-keys/bus-watch-namespace.h0000664000175000017500000000261214733247605025076 0ustar fabiofabio/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Lars Uebernickel */ #ifndef __BUS_WATCH_NAMESPACE_H__ #define __BUS_WATCH_NAMESPACE_H__ #include guint bus_watch_namespace (GBusType bus_type, const gchar *name_space, GBusNameAppearedCallback appeared_handler, GBusNameVanishedCallback vanished_handler, gpointer user_data, GDestroyNotify user_data_destroy); void bus_unwatch_namespace (guint id); #endif cinnamon-settings-daemon-6.4.3/plugins/media-keys/mpris-controller.h0000664000175000017500000000365314733247605024570 0ustar fabiofabio/* * Copyright © 2013 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, * version 2.1, as published by the Free Software Foundation. * * This program is distributed in the hope 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 Lesser General Public License * along with this program; if not, see * * Author: Michael Wood */ #ifndef __MPRIS_CONTROLLER_H__ #define __MPRIS_CONTROLLER_H__ #include G_BEGIN_DECLS #define MPRIS_TYPE_CONTROLLER mpris_controller_get_type() #define MPRIS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MPRIS_TYPE_CONTROLLER, MprisController)) #define MPRIS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MPRIS_TYPE_CONTROLLER, MprisControllerClass)) #define MPRIS_IS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MPRIS_TYPE_CONTROLLER)) #define MPRIS_IS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MPRIS_TYPE_CONTROLLER)) #define MPRIS_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MPRIS_TYPE_CONTROLLER, MprisControllerClass)) typedef struct _MprisController MprisController; typedef struct _MprisControllerClass MprisControllerClass; typedef struct _MprisControllerPrivate MprisControllerPrivate; struct _MprisController { GObject parent; MprisControllerPrivate *priv; }; struct _MprisControllerClass { GObjectClass parent_class; }; GType mpris_controller_get_type (void) G_GNUC_CONST; MprisController *mpris_controller_new (void); gboolean mpris_controller_key (MprisController *self, const gchar *key); G_END_DECLS #endif /* __MPRIS_CONTROLLER_H__ */ cinnamon-settings-daemon-6.4.3/plugins/media-keys/main.c0000664000175000017500000000126314733247605022167 0ustar fabiofabio#define NEW csd_media_keys_manager_new #define START csd_media_keys_manager_start #define STOP csd_media_keys_manager_stop #define MANAGER CsdMediaKeysManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-media-keys-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/media-keys/csd-marshal.h0000664000175000017500000000130014733247605023436 0ustar fabiofabio #ifndef __csd_marshal_MARSHAL_H__ #define __csd_marshal_MARSHAL_H__ #include G_BEGIN_DECLS /* VOID:STRING,STRING (csd-marshal.list:1) */ G_GNUC_INTERNAL void csd_marshal_VOID__STRING_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); G_END_DECLS #endif /* __csd_marshal_MARSHAL_H__ */ cinnamon-settings-daemon-6.4.3/plugins/media-keys/mpris-controller.c0000664000175000017500000001570314733247605024562 0ustar fabiofabio/* * Copyright © 2013 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, * version 2.1, as published by the Free Software Foundation. * * This program is distributed in the hope 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 Lesser General Public License * along with this program; if not, see * * Author: Michael Wood */ #include "mpris-controller.h" #include "bus-watch-namespace.h" #include G_DEFINE_TYPE (MprisController, mpris_controller, G_TYPE_OBJECT) #define CONTROLLER_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MPRIS_TYPE_CONTROLLER, MprisControllerPrivate)) struct _MprisControllerPrivate { GCancellable *cancellable; GDBusProxy *mpris_client_proxy; guint namespace_watcher_id; GSList *other_players; gboolean connecting; }; static void mpris_player_try_connect (MprisController *self); static void mpris_controller_dispose (GObject *object) { MprisControllerPrivate *priv = MPRIS_CONTROLLER (object)->priv; g_clear_object (&priv->cancellable); g_clear_object (&priv->mpris_client_proxy); if (priv->namespace_watcher_id) { bus_unwatch_namespace (priv->namespace_watcher_id); priv->namespace_watcher_id = 0; } if (priv->other_players) { g_slist_free_full (priv->other_players, g_free); priv->other_players = NULL; } G_OBJECT_CLASS (mpris_controller_parent_class)->dispose (object); } static void mpris_proxy_call_done (GObject *object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *ret; if (!(ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error))) { g_warning ("Error calling method %s", error->message); g_clear_error (&error); return; } g_variant_unref (ret); } gboolean mpris_controller_key (MprisController *self, const gchar *key) { MprisControllerPrivate *priv = MPRIS_CONTROLLER (self)->priv; if (!priv->mpris_client_proxy) return FALSE; if (g_strcmp0 (key, "Play") == 0) key = "PlayPause"; g_debug ("calling %s over dbus to mpris client %s", key, g_dbus_proxy_get_name (priv->mpris_client_proxy)); g_dbus_proxy_call (priv->mpris_client_proxy, key, NULL, 0, -1, priv->cancellable, mpris_proxy_call_done, NULL); return TRUE; } static void mpris_client_notify_name_owner_cb (GDBusProxy *proxy, GParamSpec *pspec, MprisController *self) { g_autofree gchar *name_owner = NULL; /* Owner changed, but the proxy is still valid. */ name_owner = g_dbus_proxy_get_name_owner (proxy); if (name_owner) return; g_clear_object (&self->priv->mpris_client_proxy); mpris_player_try_connect (self); } static void mpris_proxy_ready_cb (GObject *object, GAsyncResult *res, gpointer user_data) { MprisControllerPrivate *priv = MPRIS_CONTROLLER (user_data)->priv; GError *error = NULL; priv->mpris_client_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (!priv->mpris_client_proxy) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_warning ("Error connecting to mpris interface %s", error->message); priv->connecting = FALSE; mpris_player_try_connect (MPRIS_CONTROLLER (user_data)); } g_clear_error (&error); return; } priv->connecting = FALSE; g_signal_connect (priv->mpris_client_proxy, "notify::g-name-owner", G_CALLBACK (mpris_client_notify_name_owner_cb), user_data); } static void start_mpris_proxy (MprisController *self, const gchar *name) { MprisControllerPrivate *priv = MPRIS_CONTROLLER (self)->priv; g_debug ("Creating proxy for for %s", name); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, 0, NULL, name, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", priv->cancellable, mpris_proxy_ready_cb, self); priv->connecting = TRUE; } static void mpris_player_try_connect (MprisController *self) { GSList *first; gchar *name; if (self->priv->connecting || self->priv->mpris_client_proxy) return; if (!self->priv->other_players) return; first = self->priv->other_players; name = first->data; start_mpris_proxy (self, name); self->priv->other_players = self->priv->other_players->next; g_free (name); g_slist_free_1 (first); } static void mpris_player_appeared (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { MprisController *self = user_data; MprisControllerPrivate *priv = MPRIS_CONTROLLER (self)->priv; self->priv->other_players = g_slist_prepend (self->priv->other_players, g_strdup (name)); mpris_player_try_connect (self); } static void mpris_player_vanished (GDBusConnection *connection, const gchar *name, gpointer user_data) { MprisController *self = user_data; MprisControllerPrivate *priv = MPRIS_CONTROLLER (self)->priv; GSList *elem; elem = g_slist_find_custom (priv->other_players, name, (GCompareFunc) g_strcmp0); if (elem) { priv->other_players = g_slist_remove_link (priv->other_players, elem); g_free (elem->data); g_slist_free_1 (elem); } } static void mpris_controller_constructed (GObject *object) { MprisControllerPrivate *priv = MPRIS_CONTROLLER (object)->priv; priv->namespace_watcher_id = bus_watch_namespace (G_BUS_TYPE_SESSION, "org.mpris.MediaPlayer2", mpris_player_appeared, mpris_player_vanished, MPRIS_CONTROLLER (object), NULL); } static void mpris_controller_class_init (MprisControllerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (MprisControllerPrivate)); object_class->constructed = mpris_controller_constructed; object_class->dispose = mpris_controller_dispose; } static void mpris_controller_init (MprisController *self) { self->priv = CONTROLLER_PRIVATE (self); } MprisController * mpris_controller_new (void) { return g_object_new (MPRIS_TYPE_CONTROLLER, NULL); } cinnamon-settings-daemon-6.4.3/plugins/media-keys/csd-marshal.c0000664000175000017500000001114114733247605023435 0ustar fabiofabio #ifndef __csd_marshal_MARSHAL_H__ #define __csd_marshal_MARSHAL_H__ #include G_BEGIN_DECLS #ifdef G_ENABLE_DEBUG #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) #define g_marshal_value_peek_char(v) g_value_get_schar (v) #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) #define g_marshal_value_peek_int(v) g_value_get_int (v) #define g_marshal_value_peek_uint(v) g_value_get_uint (v) #define g_marshal_value_peek_long(v) g_value_get_long (v) #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) #define g_marshal_value_peek_enum(v) g_value_get_enum (v) #define g_marshal_value_peek_flags(v) g_value_get_flags (v) #define g_marshal_value_peek_float(v) g_value_get_float (v) #define g_marshal_value_peek_double(v) g_value_get_double (v) #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) #define g_marshal_value_peek_param(v) g_value_get_param (v) #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) #define g_marshal_value_peek_variant(v) g_value_get_variant (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the * g_value_get_*() functions */ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int #define g_marshal_value_peek_char(v) (v)->data[0].v_int #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint #define g_marshal_value_peek_int(v) (v)->data[0].v_int #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint #define g_marshal_value_peek_long(v) (v)->data[0].v_long #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 #define g_marshal_value_peek_enum(v) (v)->data[0].v_long #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong #define g_marshal_value_peek_float(v) (v)->data[0].v_float #define g_marshal_value_peek_double(v) (v)->data[0].v_double #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ /* VOID:STRING,STRING (csd-marshal.list:1) */ G_GNUC_INTERNAL void csd_marshal_VOID__STRING_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); void csd_marshal_VOID__STRING_STRING (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer data2); GMarshalFunc_VOID__STRING_STRING callback; GCClosure *cc = (GCClosure*) closure; gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_string (param_values + 1), g_marshal_value_peek_string (param_values + 2), data2); } G_END_DECLS #endif /* __csd_marshal_MARSHAL_H__ */ cinnamon-settings-daemon-6.4.3/plugins/media-keys/README.media-keys-API0000664000175000017500000000347114733247605024420 0ustar fabiofabioThis is very simple documentation to cinnamon-settings-daemon's D-Bus API for media players. cinnamon-settings-daemon will send key press events from multimedia keys to applications that register their interest in those events. This allows the play/pause button to control an audio player that's not focused for example. The D-Bus API is described in csd-media-keys-manager.c (look for introspection_xml), but a small explanation follows here. 1. Create yourself a proxy object for the remote interface: Object path: /org/gnome/SettingsDaemon/MediaKeys D-Bus name: org.gnome.SettingsDaemon.MediaKeys Interface name: org.gnome.SettingsDaemon.MediaKeys 2. Register your application with cinnamon-settings-daemon GrabMediaPlayerKeys ("my-application", 0) with the second argument being the current time (usually 0, or the time passed to you from an event, such as a mouse click) 3. Listen to the MediaPlayerKeyPressed() signal 4. When receiving a MediaPlayerKeyPressed() signal, check whether the first argument (application) matches the value you passed to GrabMediaPlayerKeys() and apply the action depending on the key (2nd argument) Possible values of key are: - Play - Pause - Stop - Previous - Next - Rewind - FastForward - Repeat - Shuffle 5. Every time your application is focused, you should call GrabMediaPlayerKeys() again, so that cinnamon-settings-daemon knows which one was last used. This allows switching between a movie player and a music player, for example, and have the buttons control the last used application. 6. When your application wants to stop using the functionality it can call ReleaseMediaPlayerKeys(). If your application does not call ReleaseMediaPlayerKeys() and releases its D-Bus connection then the application will be automatically removed from the list of applications held by cinnamon-settings-daemon. cinnamon-settings-daemon-6.4.3/plugins/media-keys/csd-media-keys-manager.h0000664000175000017500000000522714733247605025463 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_MEDIA_KEYS_MANAGER_H #define __CSD_MEDIA_KEYS_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_MEDIA_KEYS_MANAGER (csd_media_keys_manager_get_type ()) #define CSD_MEDIA_KEYS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManager)) #define CSD_MEDIA_KEYS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerClass)) #define CSD_IS_MEDIA_KEYS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_MEDIA_KEYS_MANAGER)) #define CSD_IS_MEDIA_KEYS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_MEDIA_KEYS_MANAGER)) #define CSD_MEDIA_KEYS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerClass)) typedef struct CsdMediaKeysManagerPrivate CsdMediaKeysManagerPrivate; typedef struct { GObject parent; CsdMediaKeysManagerPrivate *priv; } CsdMediaKeysManager; typedef struct { GObjectClass parent_class; void (* media_player_key_pressed) (CsdMediaKeysManager *manager, const char *application, const char *key); } CsdMediaKeysManagerClass; GType csd_media_keys_manager_get_type (void); CsdMediaKeysManager * csd_media_keys_manager_new (void); gboolean csd_media_keys_manager_start (CsdMediaKeysManager *manager, GError **error); void csd_media_keys_manager_stop (CsdMediaKeysManager *manager); G_END_DECLS #endif /* __CSD_MEDIA_KEYS_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/media-keys/csd-media-keys-manager.c0000664000175000017500000025537214733247605025466 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2001-2003 Bastien Nocera * Copyright (C) 2006-2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GUDEV #include #endif #include "mpris-controller.h" #include "cinnamon-settings-profile.h" #include "csd-marshal.h" #include "csd-media-keys-manager.h" #include "csd-power-helper.h" #include "csd-input-helper.h" #include "csd-enums.h" #include #include #include #include /* For media keys, we need to keep using org.gnome because that's what apps are looking for */ #define GSD_DBUS_NAME "org.gnome.SettingsDaemon" #define CSD_MEDIA_KEYS_DBUS_PATH "/org/gnome/SettingsDaemon/MediaKeys" #define CSD_MEDIA_KEYS_DBUS_NAME "org.gnome.SettingsDaemon.MediaKeys" #define CINNAMON_KEYBINDINGS_PATH "/org/cinnamon/SettingsDaemon/KeybindingHandler" #define CINNAMON_KEYBINDINGS_NAME "org.cinnamon.SettingsDaemon.KeybindingHandler" #define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" #define GNOME_SESSION_DBUS_PATH "/org/gnome/SessionManager" #define GNOME_SESSION_DBUS_INTERFACE "org.gnome.SessionManager" #define GNOME_KEYRING_DBUS_NAME "org.gnome.keyring" #define GNOME_KEYRING_DBUS_PATH "/org/gnome/keyring/daemon" #define GNOME_KEYRING_DBUS_INTERFACE "org.gnome.keyring.Daemon" #define OSD_ALL_OUTPUTS_X -1 #define OSD_ALL_OUTPUTS_Y -1 static const gchar introspection_xml[] = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; static const gchar kb_introspection_xml[] = "" " " " " " " " " " " " " ""; #define SETTINGS_INTERFACE_DIR "org.cinnamon.desktop.interface" #define SETTINGS_POWER_DIR "org.cinnamon.settings-daemon.plugins.power" #define SETTINGS_XSETTINGS_DIR "org.cinnamon.settings-daemon.plugins.xsettings" #define SETTINGS_TOUCHPAD_DIR "org.cinnamon.desktop.peripherals.touchpad" #define TOUCHPAD_SEND_EVENTS_KEY "send-events" #define HIGH_CONTRAST "HighContrast" #define VOLUME_STEP 5 /* percents for one volume button press */ #define LOGIND_DBUS_NAME "org.freedesktop.login1" #define LOGIND_DBUS_PATH "/org/freedesktop/login1" #define LOGIND_DBUS_INTERFACE "org.freedesktop.login1.Manager" #define AUDIO_SELECTION_DBUS_NAME "org.Cinnamon.AudioDeviceSelection" #define AUDIO_SELECTION_DBUS_PATH "/org/Cinnamon/AudioDeviceSelection" #define AUDIO_SELECTION_DBUS_INTERFACE "org.Cinnamon.AudioDeviceSelection" #define CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_MEDIA_KEYS_MANAGER, CsdMediaKeysManagerPrivate)) typedef struct { char *application; char *name; guint32 time; guint watch_id; } MediaPlayer; struct CsdMediaKeysManagerPrivate { /* dbus owned names */ guint name_id; guint gnome_name_id; /* Volume bits */ GvcMixerControl *volume; GvcMixerStream *stream; GvcMixerStream *source_stream; /* Microphone */ ca_context *ca; #ifdef HAVE_GUDEV GHashTable *streams; /* key = X device ID, value = stream id */ GUdevClient *udev_client; #endif /* HAVE_GUDEV */ guint audio_selection_watch_id; guint audio_selection_signal_id; GDBusConnection *audio_selection_conn; gboolean audio_selection_requested; guint audio_selection_device_id; GtkWidget *dialog; /* HighContrast theme settings */ GSettings *interface_settings; char *icon_theme; char *gtk_theme; /* Power stuff */ GSettings *power_settings; GDBusProxy *upower_proxy; GDBusProxy *power_screen_proxy; GDBusProxy *power_keyboard_proxy; /* OSD stuff */ GDBusProxy *cinnamon_proxy; GCancellable *cinnamon_cancellable; /* logind stuff */ GDBusProxy *logind_proxy; gint inhibit_keys_fd; GSettings *desktop_session_settings; GSettings *cinnamon_session_settings; GSettings *sound_settings; /* Multihead stuff */ GdkScreen *current_screen; GSList *screens; int opcode; GList *media_players; GDBusNodeInfo *introspection_data; GDBusNodeInfo *kb_introspection_data; GDBusConnection *connection; GCancellable *bus_cancellable; GCancellable *cancellable; guint start_idle_id; MprisController *mpris_controller; /* Ubuntu notifications */ NotifyNotification *volume_notification; NotifyNotification *brightness_notification; NotifyNotification *kb_backlight_notification; }; static void csd_media_keys_manager_finalize (GObject *object); static void register_manager (CsdMediaKeysManager *manager); static gboolean do_action (CsdMediaKeysManager *manager, guint deviceid, CDesktopMediaKeyType type, gint64 timestamp); G_DEFINE_TYPE (CsdMediaKeysManager, csd_media_keys_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; #define NOTIFY_CAP_PRIVATE_SYNCHRONOUS "x-canonical-private-synchronous" #define NOTIFY_CAP_PRIVATE_ICON_ONLY "x-canonical-private-icon-only" #define NOTIFY_HINT_TRUE "true" typedef struct { CsdMediaKeysManager *manager; CDesktopMediaKeyType type; guint old_percentage; } CsdBrightnessActionData; static void init_screens (CsdMediaKeysManager *manager) { GdkDisplay *display; int i; display = gdk_display_get_default (); for (i = 0; i < gdk_display_get_n_screens (display); i++) { GdkScreen *screen; screen = gdk_display_get_screen (display, i); if (screen == NULL) { continue; } manager->priv->screens = g_slist_append (manager->priv->screens, screen); } manager->priv->current_screen = manager->priv->screens->data; } static char * get_term_command (CsdMediaKeysManager *manager) { char *cmd_term, *cmd_args;; char *cmd = NULL; GSettings *settings; settings = g_settings_new ("org.cinnamon.desktop.default-applications.terminal"); cmd_term = g_settings_get_string (settings, "exec"); if (cmd_term[0] == '\0') cmd_term = g_strdup ("gnome-terminal"); cmd_args = g_settings_get_string (settings, "exec-arg"); if (strcmp (cmd_term, "") != 0) { cmd = g_strdup_printf ("%s %s -e", cmd_term, cmd_args); } else { cmd = g_strdup_printf ("%s -e", cmd_term); } g_free (cmd_args); g_free (cmd_term); g_object_unref (settings); return cmd; } static char ** get_keyring_env (CsdMediaKeysManager *manager) { GError *error = NULL; GVariant *variant, *item; GVariantIter *iter; char **envp; variant = g_dbus_connection_call_sync (manager->priv->connection, GNOME_KEYRING_DBUS_NAME, GNOME_KEYRING_DBUS_PATH, GNOME_KEYRING_DBUS_INTERFACE, "GetEnvironment", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (variant == NULL) { g_warning ("Failed to call GetEnvironment on keyring daemon: %s", error->message); g_error_free (error); return NULL; } envp = g_get_environ (); g_variant_get (variant, "(a{ss})", &iter); while ((item = g_variant_iter_next_value (iter))) { char *key; char *value; g_variant_get (item, "{ss}", &key, &value); envp = g_environ_setenv (envp, key, value, TRUE); g_variant_unref (item); g_free (key); g_free (value); } g_variant_iter_free (iter); g_variant_unref (variant); return envp; } static void execute (CsdMediaKeysManager *manager, char *cmd, gboolean need_term) { gboolean retval; char **argv; int argc; char *exec; char *term = NULL; GError *error = NULL; retval = FALSE; if (need_term) { term = get_term_command (manager); } if (term) { exec = g_strdup_printf ("%s %s", term, cmd); g_free (term); } else { exec = g_strdup (cmd); } if (g_shell_parse_argv (exec, &argc, &argv, NULL)) { char **envp; envp = get_keyring_env (manager); retval = g_spawn_async (g_get_home_dir (), argv, envp, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); g_strfreev (argv); g_strfreev (envp); } if (retval == FALSE && error != NULL) { g_warning ("Couldn't execute command: %s: %s", exec, error->message); g_error_free (error); } g_free (exec); } static void ensure_cancellable (GCancellable **cancellable) { if (*cancellable == NULL) { *cancellable = g_cancellable_new (); g_object_add_weak_pointer (G_OBJECT (*cancellable), (gpointer *)cancellable); } else { g_object_ref (*cancellable); } } static void cinnamon_proxy_complete (GObject *source, GAsyncResult *result, gpointer data) { CsdMediaKeysManager *manager = data; g_object_unref (manager->priv->cinnamon_cancellable); } static void show_osd (CsdMediaKeysManager *manager, const char *icon, int level, int outx, int outy) { GVariantBuilder builder; if (manager->priv->connection == NULL || manager->priv->cinnamon_proxy == NULL) { g_warning ("No existing D-Bus connection trying to handle osd"); return; } g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); g_variant_builder_open (&builder, G_VARIANT_TYPE_VARDICT); if (icon) g_variant_builder_add (&builder, "{sv}", "icon", g_variant_new_string (icon)); if (level >= 0) g_variant_builder_add (&builder, "{sv}", "level", g_variant_new_int32 (level)); if (outx >= 0 && outy >= 0) { g_debug ("Calling showOSD with coordinates: %d, %d", outx, outy); g_variant_builder_add (&builder, "{sv}", "monitor_x", g_variant_new_int32 (outx)); g_variant_builder_add (&builder, "{sv}", "monitor_y", g_variant_new_int32 (outy)); } g_variant_builder_close (&builder); ensure_cancellable (&manager->priv->cinnamon_cancellable); g_dbus_proxy_call (manager->priv->cinnamon_proxy, "ShowOSD", g_variant_builder_end (&builder), G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, manager->priv->cinnamon_cancellable, cinnamon_proxy_complete, manager); } static const char * get_icon_name_for_volume (gboolean muted, int volume, gboolean is_mic) { static const char *icon_names[] = { "audio-volume-muted-symbolic", "audio-volume-low-symbolic", "audio-volume-medium-symbolic", "audio-volume-high-symbolic", "microphone-sensitivity-muted-symbolic", "microphone-sensitivity-low-symbolic", "microphone-sensitivity-medium-symbolic", "microphone-sensitivity-high-symbolic", NULL }; int n; if (muted) { n = 0; } else { n = 3 * volume / 100 + 1; if (n < 1) { n = 1; } else if (n > 3) { n = 3; } } if (is_mic) { n += 4; } return icon_names[n]; } static void launch_app (GAppInfo *app_info, gint64 timestamp) { GError *error = NULL; GdkAppLaunchContext *launch_context; /* setup the launch context so the startup notification is correct */ launch_context = gdk_display_get_app_launch_context (gdk_display_get_default ()); gdk_app_launch_context_set_timestamp (launch_context, timestamp); if (!g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (launch_context), &error)) { g_warning ("Could not launch '%s': %s", g_app_info_get_commandline (app_info), error->message); g_error_free (error); } g_object_unref (launch_context); } static void do_url_action (CsdMediaKeysManager *manager, const char *scheme, gint64 timestamp) { GAppInfo *app_info; app_info = g_app_info_get_default_for_uri_scheme (scheme); if (app_info != NULL) { launch_app (app_info, timestamp); g_object_unref (app_info); } else { g_warning ("Could not find default application for '%s' scheme", scheme); } } static void do_media_action (CsdMediaKeysManager *manager, gint64 timestamp) { GAppInfo *app_info; app_info = g_app_info_get_default_for_type ("audio/x-vorbis+ogg", FALSE); if (app_info != NULL) { launch_app (app_info, timestamp); g_object_unref (app_info); } else { g_warning ("Could not find default application for '%s' mime-type", "audio/x-vorbis+ogg"); } } static void do_terminal_action (CsdMediaKeysManager *manager) { GSettings *settings; char *term; settings = g_settings_new ("org.cinnamon.desktop.default-applications.terminal"); term = g_settings_get_string (settings, "exec"); if (term) execute (manager, term, FALSE); g_free (term); g_object_unref (settings); } static void do_calculator_action (CsdMediaKeysManager *manager) { GSettings *settings; char *calc; settings = g_settings_new ("org.cinnamon.desktop.default-applications.calculator"); calc = g_settings_get_string (settings, "exec"); if (calc) execute (manager, calc, FALSE); g_free (calc); g_object_unref (settings); } static void cinnamon_session_shutdown (CsdMediaKeysManager *manager) { GError *error = NULL; GVariant *variant; /* Shouldn't happen, but you never know */ if (manager->priv->connection == NULL) { execute (manager, "cinnamon-session-quit --logout", FALSE); return; } variant = g_dbus_connection_call_sync (manager->priv->connection, GNOME_SESSION_DBUS_NAME, GNOME_SESSION_DBUS_PATH, GNOME_SESSION_DBUS_INTERFACE, "Shutdown", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (variant == NULL) { g_warning ("Failed to call Shutdown on session manager: %s", error->message); g_error_free (error); return; } g_variant_unref (variant); } static void do_logout_action (CsdMediaKeysManager *manager) { execute (manager, "cinnamon-session-quit --logout", FALSE); } static void do_eject_action_cb (GDrive *drive, GAsyncResult *res, CsdMediaKeysManager *manager) { g_drive_eject_with_operation_finish (drive, res, NULL); } #define NO_SCORE 0 #define SCORE_CAN_EJECT 50 #define SCORE_HAS_MEDIA 100 static void do_eject_action (CsdMediaKeysManager *manager) { GList *drives, *l; GDrive *fav_drive; guint score; GVolumeMonitor *volume_monitor; volume_monitor = g_volume_monitor_get (); /* Find the best drive to eject */ fav_drive = NULL; score = NO_SCORE; drives = g_volume_monitor_get_connected_drives (volume_monitor); for (l = drives; l != NULL; l = l->next) { GDrive *drive = l->data; if (g_drive_can_eject (drive) == FALSE) continue; if (g_drive_is_media_removable (drive) == FALSE) continue; if (score < SCORE_CAN_EJECT) { fav_drive = drive; score = SCORE_CAN_EJECT; } if (g_drive_has_media (drive) == FALSE) continue; if (score < SCORE_HAS_MEDIA) { fav_drive = drive; score = SCORE_HAS_MEDIA; break; } } /* Show the dialogue */ show_osd (manager, "media-eject-symbolic", -1, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); /* Clean up the drive selection and exit if no suitable * drives are found */ if (fav_drive != NULL) fav_drive = g_object_ref (fav_drive); g_list_foreach (drives, (GFunc) g_object_unref, NULL); if (fav_drive == NULL) return; /* Eject! */ g_drive_eject_with_operation (fav_drive, G_MOUNT_UNMOUNT_FORCE, NULL, NULL, (GAsyncReadyCallback) do_eject_action_cb, manager); g_object_unref (fav_drive); g_object_unref (volume_monitor); } static void do_home_key_action (CsdMediaKeysManager *manager, gint64 timestamp) { gchar *path; path = g_strdup_printf ("xdg-open %s", g_get_home_dir ()); execute (manager, path, FALSE); g_free (path); } static void do_execute_desktop (CsdMediaKeysManager *manager, const char *desktop, gint64 timestamp) { GDesktopAppInfo *app_info; app_info = g_desktop_app_info_new (desktop); if (app_info != NULL) { launch_app (G_APP_INFO (app_info), timestamp); g_object_unref (app_info); } else { g_warning ("Could not find application '%s'", desktop); } } static void do_touchpad_osd_action (CsdMediaKeysManager *manager, gboolean state) { show_osd (manager, state ? "input-touchpad-symbolic" : "touchpad-disabled-symbolic", -1, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); } static void do_touchpad_action (CsdMediaKeysManager *manager) { GSettings *settings; gboolean state; if (!touchpad_is_present ()) { do_touchpad_osd_action (manager, FALSE); return; } settings = g_settings_new (SETTINGS_TOUCHPAD_DIR); state = g_settings_get_enum (settings, TOUCHPAD_SEND_EVENTS_KEY) == C_DESKTOP_DEVICE_SEND_EVENTS_ENABLED || (C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE && !mouse_is_present ()); do_touchpad_osd_action (manager, !state); g_settings_set_enum (settings, TOUCHPAD_SEND_EVENTS_KEY, (state) ? C_DESKTOP_DEVICE_SEND_EVENTS_DISABLED : C_DESKTOP_DEVICE_SEND_EVENTS_ENABLED); g_object_unref (settings); } static void show_sound_osd (CsdMediaKeysManager *manager, GvcMixerStream *stream, gboolean is_mic, gint vol, gint max_vol, gboolean muted, gboolean sound_changed, gboolean quiet) { const char *icon; icon = get_icon_name_for_volume (muted, vol, is_mic); show_osd (manager, icon, vol, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); if (quiet == FALSE && sound_changed != FALSE && muted == FALSE) { gboolean enabled = g_settings_get_boolean (manager->priv->sound_settings, "volume-sound-enabled"); char *sound = g_settings_get_string (manager->priv->sound_settings, "volume-sound-file"); if (enabled) { ca_context_change_device (manager->priv->ca, gvc_mixer_stream_get_name (stream)); ca_context_play (manager->priv->ca, 1, CA_PROP_MEDIA_FILENAME, sound, NULL); } g_free(sound); } } #ifdef HAVE_GUDEV /* PulseAudio gives us /devices/... paths, when udev * expects /sys/devices/... paths. */ static GUdevDevice * get_udev_device_for_sysfs_path (CsdMediaKeysManager *manager, const char *sysfs_path) { char *path; GUdevDevice *dev; path = g_strdup_printf ("/sys%s", sysfs_path); dev = g_udev_client_query_by_sysfs_path (manager->priv->udev_client, path); g_free (path); return dev; } static GvcMixerStream * get_stream_for_device_id (CsdMediaKeysManager *manager, guint deviceid, gboolean is_source_stream) { char *devnode; gpointer id_ptr; GvcMixerStream *res; GUdevDevice *dev, *parent; GSList *streams, *l; id_ptr = g_hash_table_lookup (manager->priv->streams, GUINT_TO_POINTER (deviceid)); if (id_ptr != NULL) { if (GPOINTER_TO_UINT (id_ptr) == (guint) -1) return NULL; else return gvc_mixer_control_lookup_stream_id (manager->priv->volume, GPOINTER_TO_UINT (id_ptr)); } devnode = xdevice_get_device_node (deviceid); if (devnode == NULL) { g_debug ("Could not find device node for XInput device %d", deviceid); return NULL; } dev = g_udev_client_query_by_device_file (manager->priv->udev_client, devnode); if (dev == NULL) { g_debug ("Could not find udev device for device path '%s'", devnode); g_free (devnode); return NULL; } g_free (devnode); if (g_strcmp0 (g_udev_device_get_property (dev, "ID_BUS"), "usb") != 0) { g_debug ("Not handling XInput device %d, not USB", deviceid); g_hash_table_insert (manager->priv->streams, GUINT_TO_POINTER (deviceid), GUINT_TO_POINTER ((guint) -1)); g_object_unref (dev); return NULL; } parent = g_udev_device_get_parent_with_subsystem (dev, "usb", "usb_device"); if (parent == NULL) { g_warning ("No USB device parent for XInput device %d even though it's USB", deviceid); g_object_unref (dev); return NULL; } res = NULL; if (is_source_stream) { streams = gvc_mixer_control_get_sinks (manager->priv->volume); } else { streams = gvc_mixer_control_get_sources (manager->priv->volume); } for (l = streams; l; l = l->next) { GvcMixerStream *stream = l->data; const char *sysfs_path; GUdevDevice *stream_dev, *stream_parent; sysfs_path = gvc_mixer_stream_get_sysfs_path (stream); stream_dev = get_udev_device_for_sysfs_path (manager, sysfs_path); if (stream_dev == NULL) continue; stream_parent = g_udev_device_get_parent_with_subsystem (stream_dev, "usb", "usb_device"); g_object_unref (stream_dev); if (stream_parent == NULL) continue; if (g_strcmp0 (g_udev_device_get_sysfs_path (stream_parent), g_udev_device_get_sysfs_path (parent)) == 0) { res = stream; } g_object_unref (stream_parent); if (res != NULL) break; } if (res) g_hash_table_insert (manager->priv->streams, GUINT_TO_POINTER (deviceid), GUINT_TO_POINTER (gvc_mixer_stream_get_id (res))); else g_hash_table_insert (manager->priv->streams, GUINT_TO_POINTER (deviceid), GUINT_TO_POINTER ((guint) -1)); return res; } #endif /* HAVE_GUDEV */ static void do_sound_action (CsdMediaKeysManager *manager, guint deviceid, int type, gboolean quiet) { GvcMixerStream *stream; gboolean old_muted, new_muted; guint old_vol_pa, new_vol_pa, max_vol_pa; gint vol_step_pa; gint osd_vol, osd_max_vol; gboolean sound_changed; /* Find the stream that corresponds to the device, if any */ gboolean is_source_stream = type == C_DESKTOP_MEDIA_KEY_MIC_MUTE ? TRUE : FALSE; #ifdef HAVE_GUDEV stream = get_stream_for_device_id (manager, deviceid, is_source_stream); if (stream == NULL) #endif /* HAVE_GUDEV */ { if (is_source_stream) { stream = manager->priv->source_stream; } else { stream = manager->priv->stream; } } if (stream == NULL) return; if (g_settings_get_boolean (manager->priv->sound_settings, "allow-amplified-volume")) { osd_max_vol = 150; max_vol_pa = MIN ((guint) PA_VOLUME_NORM * 1.5, PA_VOLUME_MAX); } else { osd_max_vol = 100; max_vol_pa = MIN ((guint) PA_VOLUME_NORM, PA_VOLUME_MAX); } vol_step_pa = (max_vol_pa * ((double) VOLUME_STEP) / 100); // Make the max volume divisible by our 5% step. max_vol_pa = (max_vol_pa / vol_step_pa) * vol_step_pa; // The volume snaps to PA_VALUE_NORM when adjusting - this is done outside our control here, // And this messes up the 5% step: Below we try to always end up with a percent divisible by // VOLUME_STEP. We round up or down to the next closest, but have to give it an extra bump at the PA_VOLUME_NORM // threshold or else it gets stuck. #define CROSSING_PA_NORM(val,step)(val >= PA_VOLUME_NORM && val - step < PA_VOLUME_NORM || \ val <= PA_VOLUME_NORM && val + step > PA_VOLUME_NORM) /* FIXME: this is racy */ new_vol_pa = old_vol_pa = gvc_mixer_stream_get_volume (stream); new_muted = old_muted = gvc_mixer_stream_get_is_muted (stream); sound_changed = FALSE; switch (type) { case C_DESKTOP_MEDIA_KEY_MUTE: case C_DESKTOP_MEDIA_KEY_MIC_MUTE: new_muted = !old_muted; break; case C_DESKTOP_MEDIA_KEY_VOLUME_DOWN: if (old_vol_pa <= vol_step_pa) { new_vol_pa = 0; new_muted = TRUE; } else { if (old_vol_pa % vol_step_pa > 0 && !CROSSING_PA_NORM (old_vol_pa, vol_step_pa)) { new_vol_pa = (old_vol_pa / vol_step_pa * vol_step_pa); } else { new_vol_pa = (old_vol_pa / vol_step_pa * vol_step_pa) - vol_step_pa; } } break; case C_DESKTOP_MEDIA_KEY_VOLUME_UP: new_muted = FALSE; /* When coming out of mute only increase the volume if it was 0 */ if (!old_muted || old_vol_pa == 0) { if (old_vol_pa % vol_step_pa > 0 && !CROSSING_PA_NORM (old_vol_pa, vol_step_pa)) { new_vol_pa = MIN (old_vol_pa / vol_step_pa * vol_step_pa + vol_step_pa, max_vol_pa); } else { new_vol_pa = MIN (old_vol_pa / vol_step_pa * vol_step_pa + vol_step_pa, max_vol_pa); } } break; } if (old_muted != new_muted) { gvc_mixer_stream_change_is_muted (stream, new_muted); sound_changed = TRUE; } if (old_vol_pa != new_vol_pa) { if (gvc_mixer_stream_set_volume (stream, new_vol_pa) != FALSE) { gvc_mixer_stream_push_volume (stream); sound_changed = TRUE; } } if (type == C_DESKTOP_MEDIA_KEY_VOLUME_DOWN && old_vol_pa == 0 && old_muted) // This should bottom out at 0. At -1 (old value), the OSD doesn't show a bar. osd_vol = 0; else if (type == C_DESKTOP_MEDIA_KEY_VOLUME_UP && (old_vol_pa == max_vol_pa) && !old_muted) osd_vol = 100; else if (!new_muted) osd_vol = CLAMP ((int) (100 * ((double) new_vol_pa / max_vol_pa)), 0, 100); else osd_vol = 0; show_sound_osd (manager, stream, is_source_stream, osd_vol, osd_max_vol, new_muted, sound_changed, quiet); } static void update_default_sink (CsdMediaKeysManager *manager) { GvcMixerStream *stream; stream = gvc_mixer_control_get_default_sink (manager->priv->volume); if (stream == manager->priv->stream) return; if (manager->priv->stream != NULL) { g_object_unref (manager->priv->stream); manager->priv->stream = NULL; } if (stream != NULL) { manager->priv->stream = g_object_ref (stream); } else { g_warning ("Unable to get default sink"); } } static void update_default_source (CsdMediaKeysManager *manager) { GvcMixerStream *stream; stream = gvc_mixer_control_get_default_source (manager->priv->volume); if (stream == manager->priv->source_stream) return; if (manager->priv->source_stream != NULL) { g_object_unref (manager->priv->source_stream); manager->priv->source_stream = NULL; } if (stream != NULL) { manager->priv->source_stream = g_object_ref (stream); } else { g_warning ("Unable to get default source"); } } static void on_control_state_changed (GvcMixerControl *control, GvcMixerControlState new_state, CsdMediaKeysManager *manager) { update_default_sink (manager); update_default_source (manager); } static void on_control_default_sink_changed (GvcMixerControl *control, guint id, CsdMediaKeysManager *manager) { update_default_sink (manager); } static void on_control_default_source_changed (GvcMixerControl *control, guint id, CsdMediaKeysManager *manager) { update_default_source (manager); } #ifdef HAVE_GUDEV static gboolean remove_stream (gpointer key, gpointer value, gpointer id) { if (GPOINTER_TO_UINT (value) == GPOINTER_TO_UINT (id)) return TRUE; return FALSE; } #endif /* HAVE_GUDEV */ static void on_control_stream_removed (GvcMixerControl *control, guint id, CsdMediaKeysManager *manager) { if (manager->priv->stream != NULL) { if (gvc_mixer_stream_get_id (manager->priv->stream) == id) { g_object_unref (manager->priv->stream); manager->priv->stream = NULL; } } if (manager->priv->source_stream != NULL) { if (gvc_mixer_stream_get_id (manager->priv->source_stream) == id) { g_object_unref (manager->priv->source_stream); manager->priv->source_stream = NULL; } } #ifdef HAVE_GUDEV g_hash_table_foreach_remove (manager->priv->streams, (GHRFunc) remove_stream, GUINT_TO_POINTER (id)); #endif } static void free_media_player (MediaPlayer *player) { if (player->watch_id > 0) { g_bus_unwatch_name (player->watch_id); player->watch_id = 0; } g_free (player->application); g_free (player->name); g_free (player); } static gint find_by_application (gconstpointer a, gconstpointer b) { return strcmp (((MediaPlayer *)a)->application, b); } static gint find_by_name (gconstpointer a, gconstpointer b) { return strcmp (((MediaPlayer *)a)->name, b); } static gint find_by_time (gconstpointer a, gconstpointer b) { return ((MediaPlayer *)a)->time < ((MediaPlayer *)b)->time; } static void name_vanished_handler (GDBusConnection *connection, const gchar *name, CsdMediaKeysManager *manager) { GList *iter; iter = g_list_find_custom (manager->priv->media_players, name, find_by_name); if (iter != NULL) { MediaPlayer *player; player = iter->data; g_debug ("Deregistering vanished %s (name: %s)", player->application, player->name); free_media_player (player); manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); } } /* * Register a new media player. Most applications will want to call * this with time = GDK_CURRENT_TIME. This way, the last registered * player will receive media events. In some cases, applications * may want to register with a lower priority (usually 1), to grab * events only nobody is interested. */ static void csd_media_keys_manager_grab_media_player_keys (CsdMediaKeysManager *manager, const char *application, const char *name, guint32 time) { GList *iter; MediaPlayer *media_player; guint watch_id; if (time == GDK_CURRENT_TIME) { GTimeVal tv; g_get_current_time (&tv); time = tv.tv_sec * 1000 + tv.tv_usec / 1000; } iter = g_list_find_custom (manager->priv->media_players, application, find_by_application); if (iter != NULL) { if (((MediaPlayer *)iter->data)->time < time) { MediaPlayer *player = iter->data; free_media_player (player); manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); } else { return; } } watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, name, G_BUS_NAME_WATCHER_FLAGS_NONE, NULL, (GBusNameVanishedCallback) name_vanished_handler, manager, NULL); g_debug ("Registering %s at %u", application, time); media_player = g_new0 (MediaPlayer, 1); media_player->application = g_strdup (application); media_player->name = g_strdup (name); media_player->time = time; media_player->watch_id = watch_id; manager->priv->media_players = g_list_insert_sorted (manager->priv->media_players, media_player, find_by_time); } static void csd_media_keys_manager_release_media_player_keys (CsdMediaKeysManager *manager, const char *application, const char *name) { GList *iter = NULL; g_return_if_fail (application != NULL || name != NULL); if (application != NULL) { iter = g_list_find_custom (manager->priv->media_players, application, find_by_application); } if (iter == NULL && name != NULL) { iter = g_list_find_custom (manager->priv->media_players, name, find_by_name); } if (iter != NULL) { MediaPlayer *player; player = iter->data; g_debug ("Deregistering %s (name: %s)", application, player->name); free_media_player (player); manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); } } static gboolean csd_media_player_key_pressed (CsdMediaKeysManager *manager, const char *key) { const char *application; gboolean have_listeners; GError *error = NULL; MediaPlayer *player; g_return_val_if_fail (key != NULL, FALSE); g_debug ("Media key '%s' pressed", key); have_listeners = (manager->priv->media_players != NULL); if (!have_listeners) { if (!mpris_controller_key (manager->priv->mpris_controller, key)) { /* Popup a dialog with an (/) icon */ show_osd (manager, "action-unavailable-symbolic", -1, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); } return TRUE; } player = manager->priv->media_players->data; application = player->application; if (g_dbus_connection_emit_signal (manager->priv->connection, player->name, CSD_MEDIA_KEYS_DBUS_PATH, CSD_MEDIA_KEYS_DBUS_NAME, "MediaPlayerKeyPressed", g_variant_new ("(ss)", application ? application : "", key), &error) == FALSE) { g_debug ("Error emitting signal: %s", error->message); g_error_free (error); } return !have_listeners; } static void csd_media_keys_manager_handle_cinnamon_keybinding (CsdMediaKeysManager *manager, guint deviceid, CDesktopMediaKeyType type, gint64 timestamp) { do_action (manager, deviceid, type, timestamp); } static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { CsdMediaKeysManager *manager = (CsdMediaKeysManager *) user_data; g_debug ("Calling method '%s' for media-keys", method_name); if (g_strcmp0 (method_name, "ReleaseMediaPlayerKeys") == 0) { const char *app_name; g_variant_get (parameters, "(&s)", &app_name); csd_media_keys_manager_release_media_player_keys (manager, app_name, sender); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "GrabMediaPlayerKeys") == 0) { const char *app_name; guint32 time; g_variant_get (parameters, "(&su)", &app_name, &time); csd_media_keys_manager_grab_media_player_keys (manager, app_name, sender, time); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "HandleKeybinding") == 0) { CDesktopMediaKeyType action; g_variant_get (parameters, "(u)", &action); csd_media_keys_manager_handle_cinnamon_keybinding (manager, 0, action, CurrentTime); g_dbus_method_invocation_return_value (invocation, NULL); } } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, /* Get Property */ NULL, /* Set Property */ }; static gboolean do_multimedia_player_action (CsdMediaKeysManager *manager, const char *icon, const char *key) { return csd_media_player_key_pressed (manager, key); } static void do_video_rotate_lock_action (CsdMediaKeysManager *manager, gint64 timestamp) { GSettings *settings; gboolean locked; settings = g_settings_new ("org.cinnamon.settings-daemon.peripherals.touchscreen"); locked = !g_settings_get_boolean (settings, "orientation-lock"); g_settings_set_boolean (settings, "orientation-lock", locked); g_object_unref (settings); show_osd (manager, locked ? "rotation-locked-symbolic" : "rotation-allowed-symbolic", -1, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); } static void do_toggle_accessibility_key (const char *key) { GSettings *settings; gboolean state; settings = g_settings_new ("org.cinnamon.desktop.a11y.applications"); state = g_settings_get_boolean (settings, key); g_settings_set_boolean (settings, key, !state); g_object_unref (settings); } static void do_screenreader_action (CsdMediaKeysManager *manager) { do_toggle_accessibility_key ("screen-reader-enabled"); } static void do_on_screen_keyboard_action (CsdMediaKeysManager *manager) { if (manager->priv->connection == NULL || manager->priv->cinnamon_proxy == NULL) { g_warning ("No existing D-Bus connection trying to handle osd"); do_toggle_accessibility_key ("screen-keyboard-enabled"); return; } ensure_cancellable (&manager->priv->cinnamon_cancellable); g_dbus_proxy_call (manager->priv->cinnamon_proxy, "ToggleKeyboard", NULL, G_DBUS_CALL_FLAGS_NONE, -1, manager->priv->cinnamon_cancellable, cinnamon_proxy_complete, manager); } static void do_text_size_action (CsdMediaKeysManager *manager, CDesktopMediaKeyType type) { gdouble factor, best, distance; guint i; /* Same values used in the Seeing tab of the Universal Access panel */ static gdouble factors[] = { 0.75, 1.0, 1.25, 1.5 }; /* Figure out the current DPI scaling factor */ factor = g_settings_get_double (manager->priv->interface_settings, "text-scaling-factor"); factor += (type == C_DESKTOP_MEDIA_KEY_INCREASE_TEXT ? 0.25 : -0.25); /* Try to find a matching value */ distance = 1e6; best = 1.0; for (i = 0; i < G_N_ELEMENTS(factors); i++) { gdouble d; d = fabs (factor - factors[i]); if (d < distance) { best = factors[i]; distance = d; } } if (best == 1.0) g_settings_reset (manager->priv->interface_settings, "text-scaling-factor"); else g_settings_set_double (manager->priv->interface_settings, "text-scaling-factor", best); } static void do_toggle_contrast_action (CsdMediaKeysManager *manager) { gboolean high_contrast; char *theme; /* Are we using HighContrast now? */ theme = g_settings_get_string (manager->priv->interface_settings, "gtk-theme"); high_contrast = g_str_equal (theme, HIGH_CONTRAST); g_free (theme); if (high_contrast != FALSE) { if (manager->priv->gtk_theme == NULL) g_settings_reset (manager->priv->interface_settings, "gtk-theme"); else g_settings_set (manager->priv->interface_settings, "gtk-theme", manager->priv->gtk_theme); g_settings_set (manager->priv->interface_settings, "icon-theme", manager->priv->icon_theme); } else { g_settings_set (manager->priv->interface_settings, "gtk-theme", HIGH_CONTRAST); g_settings_set (manager->priv->interface_settings, "icon-theme", HIGH_CONTRAST); } } static void do_config_power_action (CsdMediaKeysManager *manager, const gchar *config_key) { CsdPowerActionType action_type; action_type = g_settings_get_enum (manager->priv->power_settings, config_key); switch (action_type) { case CSD_POWER_ACTION_SUSPEND: ; gboolean hybrid = g_settings_get_boolean (manager->priv->cinnamon_session_settings, "prefer-hybrid-sleep"); gboolean suspend_then_hibernate = g_settings_get_boolean (manager->priv->cinnamon_session_settings, "suspend-then-hibernate"); csd_power_suspend (hybrid, suspend_then_hibernate); break; case CSD_POWER_ACTION_INTERACTIVE: cinnamon_session_shutdown (manager); break; case CSD_POWER_ACTION_SHUTDOWN: csd_power_poweroff (); break; case CSD_POWER_ACTION_HIBERNATE: csd_power_hibernate (); break; case CSD_POWER_ACTION_BLANK: execute (manager, "cinnamon-screensaver-command --lock", FALSE); break; case CSD_POWER_ACTION_NOTHING: /* these actions cannot be handled by media-keys and * are not used in this context */ break; } } static void update_screen_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; guint percentage; int outx, outy; GVariant *variant; CsdMediaKeysManager *manager = CSD_MEDIA_KEYS_MANAGER (user_data); variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (variant == NULL) { g_warning ("Failed to set new screen percentage: %s", error->message); g_error_free (error); return; } /* update the dialog with the new value */ g_variant_get (variant, "(uii)", &percentage, &outx, &outy); show_osd (manager, "display-brightness-symbolic", percentage, outx, outy); g_variant_unref (variant); } static void do_screen_brightness_action_real (GObject *source_object, GAsyncResult *res, gpointer user_data) { CsdBrightnessActionData *data = (CsdBrightnessActionData *) user_data; CsdMediaKeysManager *manager = data->manager; GError *error = NULL; GVariant *old_percentage = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (old_percentage == NULL) { g_warning ("Failed to get old screen percentage: %s", error->message); g_error_free (error); g_free (data); return; } g_variant_get (old_percentage, "(u)", &data->old_percentage); /* call into the power plugin */ g_dbus_proxy_call (manager->priv->power_screen_proxy, data->type == C_DESKTOP_MEDIA_KEY_SCREEN_BRIGHTNESS_UP ? "StepUp" : "StepDown", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, update_screen_cb, manager); g_variant_unref (old_percentage); } static void do_screen_brightness_action (CsdMediaKeysManager *manager, CDesktopMediaKeyType type) { if (manager->priv->connection == NULL || manager->priv->power_screen_proxy == NULL) { g_warning ("No existing D-Bus connection trying to handle power keys"); return; } CsdBrightnessActionData *data = g_new0 (CsdBrightnessActionData, 1); data->manager = manager; data->type = type; g_dbus_proxy_call (manager->priv->power_screen_proxy, "GetPercentage", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, do_screen_brightness_action_real, data); } static void update_keyboard_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; guint percentage; GVariant *new_percentage; CsdMediaKeysManager *manager = CSD_MEDIA_KEYS_MANAGER (user_data); new_percentage = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (new_percentage == NULL) { g_warning ("Failed to set new keyboard percentage: %s", error->message); g_error_free (error); return; } /* update the dialog with the new value */ g_variant_get (new_percentage, "(u)", &percentage); show_osd (manager, "keyboard-brightness-symbolic", percentage, OSD_ALL_OUTPUTS_X, OSD_ALL_OUTPUTS_Y); g_variant_unref (new_percentage); } static void do_keyboard_brightness_action (CsdMediaKeysManager *manager, CDesktopMediaKeyType type) { const char *cmd; if (manager->priv->connection == NULL || manager->priv->power_keyboard_proxy == NULL) { g_warning ("No existing D-Bus connection trying to handle power keys"); return; } switch (type) { case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_UP: cmd = "StepUp"; break; case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_DOWN: cmd = "StepDown"; break; case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_TOGGLE: cmd = "Toggle"; break; default: g_assert_not_reached (); } /* call into the power plugin */ g_dbus_proxy_call (manager->priv->power_keyboard_proxy, cmd, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, update_keyboard_cb, manager); } static gboolean do_action (CsdMediaKeysManager *manager, guint deviceid, CDesktopMediaKeyType type, gint64 timestamp) { char *cmd; g_debug ("Launching action for key type '%d' (on device id %d)", type, deviceid); switch (type) { case C_DESKTOP_MEDIA_KEY_TOUCHPAD: do_touchpad_action (manager); break; case C_DESKTOP_MEDIA_KEY_TOUCHPAD_ON: do_touchpad_osd_action (manager, TRUE); break; case C_DESKTOP_MEDIA_KEY_TOUCHPAD_OFF: do_touchpad_osd_action (manager, FALSE); break; case C_DESKTOP_MEDIA_KEY_MUTE: case C_DESKTOP_MEDIA_KEY_VOLUME_DOWN: case C_DESKTOP_MEDIA_KEY_VOLUME_UP: case C_DESKTOP_MEDIA_KEY_MIC_MUTE: do_sound_action (manager, deviceid, type, FALSE); break; case C_DESKTOP_MEDIA_KEY_MUTE_QUIET: do_sound_action (manager, deviceid, C_DESKTOP_MEDIA_KEY_MUTE, TRUE); break; case C_DESKTOP_MEDIA_KEY_VOLUME_DOWN_QUIET: do_sound_action (manager, deviceid, C_DESKTOP_MEDIA_KEY_VOLUME_DOWN, TRUE); break; case C_DESKTOP_MEDIA_KEY_VOLUME_UP_QUIET: do_sound_action (manager, deviceid, C_DESKTOP_MEDIA_KEY_VOLUME_UP, TRUE); break; case C_DESKTOP_MEDIA_KEY_LOGOUT: do_logout_action (manager); break; case C_DESKTOP_MEDIA_KEY_EJECT: do_eject_action (manager); break; case C_DESKTOP_MEDIA_KEY_HOME: do_home_key_action (manager, timestamp); break; case C_DESKTOP_MEDIA_KEY_SEARCH: cmd = NULL; if ((cmd = g_find_program_in_path ("tracker-search-tool"))) do_execute_desktop (manager, "tracker-needle.desktop", timestamp); else do_execute_desktop (manager, "gnome-search-tool.desktop", timestamp); g_free (cmd); break; case C_DESKTOP_MEDIA_KEY_EMAIL: do_url_action (manager, "mailto", timestamp); break; case C_DESKTOP_MEDIA_KEY_SCREENSAVER: execute (manager, "cinnamon-screensaver-command --lock", FALSE); break; case C_DESKTOP_MEDIA_KEY_HELP: do_url_action (manager, "ghelp", timestamp); break; case C_DESKTOP_MEDIA_KEY_SCREENSHOT: execute (manager, "gnome-screenshot", FALSE); break; case C_DESKTOP_MEDIA_KEY_WINDOW_SCREENSHOT: execute (manager, "gnome-screenshot --window", FALSE); break; case C_DESKTOP_MEDIA_KEY_AREA_SCREENSHOT: execute (manager, "gnome-screenshot --area", FALSE); break; case C_DESKTOP_MEDIA_KEY_SCREENSHOT_CLIP: execute (manager, "gnome-screenshot --clipboard", FALSE); break; case C_DESKTOP_MEDIA_KEY_WINDOW_SCREENSHOT_CLIP: execute (manager, "gnome-screenshot --window --clipboard", FALSE); break; case C_DESKTOP_MEDIA_KEY_AREA_SCREENSHOT_CLIP: execute (manager, "gnome-screenshot --area --clipboard", FALSE); break; case C_DESKTOP_MEDIA_KEY_TERMINAL: do_terminal_action (manager); break; case C_DESKTOP_MEDIA_KEY_WWW: do_url_action (manager, "http", timestamp); break; case C_DESKTOP_MEDIA_KEY_MEDIA: do_media_action (manager, timestamp); break; case C_DESKTOP_MEDIA_KEY_CALCULATOR: do_calculator_action (manager); break; case C_DESKTOP_MEDIA_KEY_PLAY: return do_multimedia_player_action (manager, NULL, "Play"); case C_DESKTOP_MEDIA_KEY_PAUSE: return do_multimedia_player_action (manager, NULL, "Pause"); case C_DESKTOP_MEDIA_KEY_STOP: return do_multimedia_player_action (manager, NULL, "Stop"); case C_DESKTOP_MEDIA_KEY_PREVIOUS: return do_multimedia_player_action (manager, NULL, "Previous"); case C_DESKTOP_MEDIA_KEY_NEXT: return do_multimedia_player_action (manager, NULL, "Next"); case C_DESKTOP_MEDIA_KEY_REWIND: return do_multimedia_player_action (manager, NULL, "Rewind"); case C_DESKTOP_MEDIA_KEY_FORWARD: return do_multimedia_player_action (manager, NULL, "FastForward"); case C_DESKTOP_MEDIA_KEY_REPEAT: return do_multimedia_player_action (manager, NULL, "Repeat"); case C_DESKTOP_MEDIA_KEY_RANDOM: return do_multimedia_player_action (manager, NULL, "Shuffle"); case C_DESKTOP_MEDIA_KEY_ROTATE_VIDEO_LOCK: do_video_rotate_lock_action (manager, timestamp); break; case C_DESKTOP_MEDIA_KEY_SCREENREADER: do_screenreader_action (manager); break; case C_DESKTOP_MEDIA_KEY_ON_SCREEN_KEYBOARD: do_on_screen_keyboard_action (manager); break; case C_DESKTOP_MEDIA_KEY_INCREASE_TEXT: case C_DESKTOP_MEDIA_KEY_DECREASE_TEXT: do_text_size_action (manager, type); break; case C_DESKTOP_MEDIA_KEY_TOGGLE_CONTRAST: do_toggle_contrast_action (manager); break; case C_DESKTOP_MEDIA_KEY_SHUTDOWN: do_config_power_action (manager, "button-power"); break; case C_DESKTOP_MEDIA_KEY_SUSPEND: do_config_power_action (manager, "button-suspend"); break; case C_DESKTOP_MEDIA_KEY_HIBERNATE: do_config_power_action (manager, "button-hibernate"); break; case C_DESKTOP_MEDIA_KEY_SCREEN_BRIGHTNESS_UP: case C_DESKTOP_MEDIA_KEY_SCREEN_BRIGHTNESS_DOWN: do_screen_brightness_action (manager, type); break; case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_UP: case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_DOWN: case C_DESKTOP_MEDIA_KEY_KEYBOARD_BRIGHTNESS_TOGGLE: do_keyboard_brightness_action (manager, type); break; case C_DESKTOP_MEDIA_KEY_BATTERY: do_execute_desktop (manager, "org.gnome.PowerStats.desktop", timestamp); break; /* Note, no default so compiler catches missing keys */ case C_DESKTOP_MEDIA_KEY_SEPARATOR: g_assert_not_reached (); } return FALSE; } static void update_theme_settings (GSettings *settings, const char *key, CsdMediaKeysManager *manager) { char *theme; theme = g_settings_get_string (manager->priv->interface_settings, key); if (g_str_equal (theme, HIGH_CONTRAST)) { g_free (theme); } else { if (g_str_equal (key, "gtk-theme")) { g_free (manager->priv->gtk_theme); manager->priv->gtk_theme = theme; } else { g_free (manager->priv->icon_theme); manager->priv->icon_theme = theme; } } } typedef struct { GvcHeadsetPortChoice choice; gchar *name; } AudioSelectionChoice; static AudioSelectionChoice audio_selection_choices[] = { { GVC_HEADSET_PORT_CHOICE_HEADPHONES, "headphones" }, { GVC_HEADSET_PORT_CHOICE_HEADSET, "headset" }, { GVC_HEADSET_PORT_CHOICE_MIC, "microphone" }, }; static void audio_selection_done (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer data) { CsdMediaKeysManagerPrivate *priv = CSD_MEDIA_KEYS_MANAGER (data)->priv; const gchar *choice; guint i; if (!priv->audio_selection_requested) return; choice = NULL; g_variant_get_child (parameters, 0, "&s", &choice); if (!choice) return; for (i = 0; i < G_N_ELEMENTS (audio_selection_choices); ++i) { if (g_str_equal (choice, audio_selection_choices[i].name)) { gvc_mixer_control_set_headset_port (priv->volume, priv->audio_selection_device_id, audio_selection_choices[i].choice); break; } } priv->audio_selection_requested = FALSE; } static void audio_selection_needed (GvcMixerControl *control, guint id, gboolean show_dialog, GvcHeadsetPortChoice choices, CsdMediaKeysManager *manager) { CsdMediaKeysManagerPrivate *priv = manager->priv; gchar *args[G_N_ELEMENTS (audio_selection_choices) + 1]; guint i, n; if (!priv->audio_selection_conn) return; if (priv->audio_selection_requested) { g_dbus_connection_call (priv->audio_selection_conn, AUDIO_SELECTION_DBUS_NAME, AUDIO_SELECTION_DBUS_PATH, AUDIO_SELECTION_DBUS_INTERFACE, "Close", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); priv->audio_selection_requested = FALSE; } if (!show_dialog) return; n = 0; for (i = 0; i < G_N_ELEMENTS (audio_selection_choices); ++i) { if (choices & audio_selection_choices[i].choice) args[n++] = audio_selection_choices[i].name; } args[n] = NULL; priv->audio_selection_requested = TRUE; priv->audio_selection_device_id = id; g_dbus_connection_call (priv->audio_selection_conn, AUDIO_SELECTION_DBUS_NAME, AUDIO_SELECTION_DBUS_PATH, AUDIO_SELECTION_DBUS_INTERFACE, "Open", g_variant_new ("(^as)", args), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } static void audio_selection_appeared (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer data) { CsdMediaKeysManager *manager = data; manager->priv->audio_selection_conn = connection; manager->priv->audio_selection_signal_id = g_dbus_connection_signal_subscribe (connection, AUDIO_SELECTION_DBUS_NAME, AUDIO_SELECTION_DBUS_INTERFACE, "DeviceSelected", AUDIO_SELECTION_DBUS_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, audio_selection_done, manager, NULL); } static void clear_audio_selection (CsdMediaKeysManager *manager) { CsdMediaKeysManagerPrivate *priv = manager->priv; if (priv->audio_selection_signal_id) g_dbus_connection_signal_unsubscribe (priv->audio_selection_conn, priv->audio_selection_signal_id); priv->audio_selection_signal_id = 0; priv->audio_selection_conn = NULL; } static void audio_selection_vanished (GDBusConnection *connection, const gchar *name, gpointer data) { if (connection) clear_audio_selection (data); } static gboolean start_media_keys_idle_cb (CsdMediaKeysManager *manager) { g_debug ("Starting media_keys manager"); cinnamon_settings_profile_start (NULL); gvc_mixer_control_open (manager->priv->volume); /* Sound events */ ca_context_create (&manager->priv->ca); ca_context_set_driver (manager->priv->ca, "pulse"); ca_context_change_props (manager->priv->ca, 0, CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl", NULL); manager->priv->desktop_session_settings = g_settings_new("org.cinnamon.desktop.session"); manager->priv->cinnamon_session_settings = g_settings_new("org.cinnamon.SessionManager"); /* for the power plugin interface code */ manager->priv->power_settings = g_settings_new (SETTINGS_POWER_DIR); manager->priv->sound_settings = g_settings_new ("org.cinnamon.desktop.sound"); /* Logic from http://git.gnome.org/browse/gnome-shell/tree/js/ui/status/accessibility.js#n163 */ manager->priv->interface_settings = g_settings_new (SETTINGS_INTERFACE_DIR); g_signal_connect (G_OBJECT (manager->priv->interface_settings), "changed::gtk-theme", G_CALLBACK (update_theme_settings), manager); g_signal_connect (G_OBJECT (manager->priv->interface_settings), "changed::icon-theme", G_CALLBACK (update_theme_settings), manager); manager->priv->gtk_theme = g_settings_get_string (manager->priv->interface_settings, "gtk-theme"); if (g_str_equal (manager->priv->gtk_theme, HIGH_CONTRAST)) { g_free (manager->priv->gtk_theme); manager->priv->gtk_theme = NULL; } manager->priv->icon_theme = g_settings_get_string (manager->priv->interface_settings, "icon-theme"); init_screens (manager); g_debug ("Starting mpris controller"); manager->priv->mpris_controller = mpris_controller_new (); cinnamon_settings_profile_end (NULL); manager->priv->start_idle_id = 0; return FALSE; } gboolean csd_media_keys_manager_start (CsdMediaKeysManager *manager, GError **error) { const char * const subsystems[] = { "input", "usb", "sound", NULL }; cinnamon_settings_profile_start (NULL); #ifdef HAVE_GUDEV manager->priv->streams = g_hash_table_new (g_direct_hash, g_direct_equal); manager->priv->udev_client = g_udev_client_new (subsystems); #endif /* initialise Volume handler * * We do this one here to force checking gstreamer cache, etc. * The rest (grabbing and setting the keys) can happen in an * idle. */ cinnamon_settings_profile_start ("gvc_mixer_control_new"); manager->priv->volume = gvc_mixer_control_new ("Cinnamon Volume Control Media Keys"); g_signal_connect (manager->priv->volume, "state-changed", G_CALLBACK (on_control_state_changed), manager); g_signal_connect (manager->priv->volume, "default-sink-changed", G_CALLBACK (on_control_default_sink_changed), manager); g_signal_connect (manager->priv->volume, "default-source-changed", G_CALLBACK (on_control_default_source_changed), manager); g_signal_connect (manager->priv->volume, "stream-removed", G_CALLBACK (on_control_stream_removed), manager); g_signal_connect (manager->priv->volume, "audio-device-selection-needed", G_CALLBACK (audio_selection_needed), manager); manager->priv->audio_selection_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, AUDIO_SELECTION_DBUS_NAME, G_BUS_NAME_WATCHER_FLAGS_NONE, audio_selection_appeared, audio_selection_vanished, manager, NULL); cinnamon_settings_profile_end ("gvc_mixer_control_new"); manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); register_manager (manager_object); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_media_keys_manager_stop (CsdMediaKeysManager *manager) { CsdMediaKeysManagerPrivate *priv = manager->priv; GList *l; g_debug ("Stopping media_keys manager"); if (priv->bus_cancellable != NULL) { g_cancellable_cancel (priv->bus_cancellable); g_object_unref (priv->bus_cancellable); priv->bus_cancellable = NULL; } if (manager->priv->ca) { ca_context_destroy (manager->priv->ca); manager->priv->ca = NULL; } #ifdef HAVE_GUDEV if (priv->streams) { g_hash_table_destroy (priv->streams); priv->streams = NULL; } if (priv->udev_client) { g_object_unref (priv->udev_client); priv->udev_client = NULL; } #endif /* HAVE_GUDEV */ if (priv->logind_proxy) { g_object_unref (priv->logind_proxy); priv->logind_proxy = NULL; } if (priv->power_settings) { g_object_unref (priv->power_settings); priv->power_settings = NULL; } if (priv->desktop_session_settings) { g_object_unref (priv->desktop_session_settings); priv->desktop_session_settings = NULL; } if (priv->cinnamon_session_settings) { g_object_unref (priv->cinnamon_session_settings); priv->cinnamon_session_settings = NULL; } if (priv->interface_settings) { g_object_unref (priv->interface_settings); priv->interface_settings = NULL; } g_clear_object (&priv->sound_settings); if (priv->power_screen_proxy) { g_object_unref (priv->power_screen_proxy); priv->power_screen_proxy = NULL; } if (priv->power_keyboard_proxy) { g_object_unref (priv->power_keyboard_proxy); priv->power_keyboard_proxy = NULL; } if (priv->mpris_controller) { g_object_unref (priv->mpris_controller); priv->mpris_controller = NULL; } if (priv->upower_proxy) { g_object_unref (priv->upower_proxy); priv->upower_proxy = NULL; } if (priv->cinnamon_proxy) { g_object_unref (priv->cinnamon_proxy); priv->cinnamon_proxy = NULL; } if (priv->cancellable != NULL) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->name_id != 0) g_bus_unown_name (priv->name_id); if (priv->gnome_name_id != 0) g_bus_unown_name (priv->gnome_name_id); if (priv->introspection_data) { g_dbus_node_info_unref (priv->introspection_data); priv->introspection_data = NULL; } if (priv->kb_introspection_data) { g_dbus_node_info_unref (priv->kb_introspection_data); priv->kb_introspection_data = NULL; } if (priv->connection != NULL) { g_object_unref (priv->connection); priv->connection = NULL; } if (priv->volume_notification != NULL) { notify_notification_close (priv->volume_notification, NULL); g_object_unref (priv->volume_notification); priv->volume_notification = NULL; } if (priv->brightness_notification != NULL) { notify_notification_close (priv->brightness_notification, NULL); g_object_unref (priv->brightness_notification); priv->brightness_notification = NULL; } if (priv->kb_backlight_notification != NULL) { notify_notification_close (priv->kb_backlight_notification, NULL); g_object_unref (priv->kb_backlight_notification); priv->kb_backlight_notification = NULL; } if (priv->cinnamon_cancellable != NULL) { g_cancellable_cancel (priv->cinnamon_cancellable); g_object_unref (priv->cinnamon_cancellable); priv->cinnamon_cancellable = NULL; } if (priv->screens != NULL) { g_slist_free (priv->screens); priv->screens = NULL; } if (priv->stream) { g_object_unref (priv->stream); priv->stream = NULL; } if (priv->volume) { g_object_unref (priv->volume); priv->volume = NULL; } if (priv->dialog != NULL) { gtk_widget_destroy (priv->dialog); priv->dialog = NULL; } if (priv->media_players != NULL) { for (l = priv->media_players; l; l = l->next) { MediaPlayer *mp = l->data; g_free (mp->application); g_free (mp); } g_list_free (priv->media_players); priv->media_players = NULL; } if (priv->audio_selection_watch_id) g_bus_unwatch_name (priv->audio_selection_watch_id); priv->audio_selection_watch_id = 0; clear_audio_selection (manager); } static GObject * csd_media_keys_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CsdMediaKeysManager *media_keys_manager; media_keys_manager = CSD_MEDIA_KEYS_MANAGER (G_OBJECT_CLASS (csd_media_keys_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (media_keys_manager); } static void csd_media_keys_manager_class_init (CsdMediaKeysManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = csd_media_keys_manager_constructor; object_class->finalize = csd_media_keys_manager_finalize; g_type_class_add_private (klass, sizeof (CsdMediaKeysManagerPrivate)); } static void inhibit_done (GObject *source, GAsyncResult *result, gpointer user_data) { GDBusProxy *proxy = G_DBUS_PROXY (source); CsdMediaKeysManager *manager = CSD_MEDIA_KEYS_MANAGER (user_data); GError *error = NULL; GVariant *res; GUnixFDList *fd_list = NULL; gint idx; res = g_dbus_proxy_call_with_unix_fd_list_finish (proxy, &fd_list, result, &error); if (res == NULL) { g_warning ("Unable to inhibit keypresses: %s", error->message); g_error_free (error); } else { g_variant_get (res, "(h)", &idx); manager->priv->inhibit_keys_fd = g_unix_fd_list_get (fd_list, idx, &error); if (manager->priv->inhibit_keys_fd == -1) { g_warning ("Failed to receive system inhibitor fd: %s", error->message); g_error_free (error); } g_debug ("System inhibitor fd is %d", manager->priv->inhibit_keys_fd); g_object_unref (fd_list); g_variant_unref (res); } } static void csd_media_keys_manager_init (CsdMediaKeysManager *manager) { GError *error; GDBusConnection *bus; error = NULL; manager->priv = CSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager); bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (bus == NULL) { g_warning ("Failed to connect to system bus: %s", error->message); g_error_free (error); return; } manager->priv->logind_proxy = g_dbus_proxy_new_sync (bus, 0, NULL, LOGIND_DBUS_NAME, LOGIND_DBUS_PATH, LOGIND_DBUS_INTERFACE, NULL, &error); if (manager->priv->logind_proxy == NULL) { g_warning ("Failed to connect to logind: %s", error->message); g_error_free (error); } g_object_unref (bus); g_debug ("Adding system inhibitors for power keys"); manager->priv->inhibit_keys_fd = -1; g_dbus_proxy_call_with_unix_fd_list (manager->priv->logind_proxy, "Inhibit", g_variant_new ("(ssss)", "handle-power-key:handle-suspend-key:handle-hibernate-key", g_get_user_name (), "Cinnamon handling keypresses", "block"), 0, G_MAXINT, NULL, NULL, inhibit_done, manager); } static void csd_media_keys_manager_finalize (GObject *object) { CsdMediaKeysManager *media_keys_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_MEDIA_KEYS_MANAGER (object)); media_keys_manager = CSD_MEDIA_KEYS_MANAGER (object); g_return_if_fail (media_keys_manager->priv != NULL); if (media_keys_manager->priv->start_idle_id != 0) { g_source_remove (media_keys_manager->priv->start_idle_id); media_keys_manager->priv->start_idle_id = 0; } if (media_keys_manager->priv->inhibit_keys_fd != -1) close (media_keys_manager->priv->inhibit_keys_fd); G_OBJECT_CLASS (csd_media_keys_manager_parent_class)->finalize (object); } static void upower_ready_cb (GObject *source_object, GAsyncResult *res, CsdMediaKeysManager *manager) { GError *error = NULL; manager->priv->upower_proxy = g_dbus_proxy_new_finish (res, &error); if (manager->priv->upower_proxy == NULL) { g_warning ("Failed to get proxy for upower: %s", error->message); g_error_free (error); } } static void power_screen_ready_cb (GObject *source_object, GAsyncResult *res, CsdMediaKeysManager *manager) { GError *error = NULL; manager->priv->power_screen_proxy = g_dbus_proxy_new_finish (res, &error); if (manager->priv->power_screen_proxy == NULL) { g_warning ("Failed to get proxy for power (screen): %s", error->message); g_error_free (error); } } static void power_keyboard_ready_cb (GObject *source_object, GAsyncResult *res, CsdMediaKeysManager *manager) { GError *error = NULL; manager->priv->power_keyboard_proxy = g_dbus_proxy_new_finish (res, &error); if (manager->priv->power_keyboard_proxy == NULL) { g_warning ("Failed to get proxy for power (keyboard): %s", error->message); g_error_free (error); } } static void osd_ready_cb (GObject *source_object, GAsyncResult *res, CsdMediaKeysManager *manager) { GError *error = NULL; manager->priv->cinnamon_proxy = g_dbus_proxy_new_finish (res, &error); if (manager->priv->cinnamon_proxy == NULL) { g_warning ("Failed to get proxy for OSD operations: %s", error->message); g_error_free (error); } } static void on_bus_gotten (GObject *source_object, GAsyncResult *res, CsdMediaKeysManager *manager) { GDBusConnection *connection; GError *error = NULL; if (manager->priv->bus_cancellable == NULL || g_cancellable_is_cancelled (manager->priv->bus_cancellable)) { g_warning ("Operation has been cancelled, so not retrieving session bus"); return; } connection = g_bus_get_finish (res, &error); if (connection == NULL) { g_warning ("Could not get session bus: %s", error->message); g_error_free (error); return; } manager->priv->connection = connection; g_dbus_connection_register_object (connection, CSD_MEDIA_KEYS_DBUS_PATH, manager->priv->introspection_data->interfaces[0], &interface_vtable, manager, NULL, NULL); manager->priv->gnome_name_id = g_bus_own_name_on_connection (connection, GSD_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); g_dbus_connection_register_object (connection, CINNAMON_KEYBINDINGS_PATH, manager->priv->kb_introspection_data->interfaces[0], &interface_vtable, manager, NULL, NULL); manager->priv->name_id = g_bus_own_name_on_connection (connection, CINNAMON_KEYBINDINGS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); g_dbus_proxy_new (manager->priv->connection, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.cinnamon.SettingsDaemon.Power", "/org/cinnamon/SettingsDaemon/Power", "org.cinnamon.SettingsDaemon.Power.Screen", NULL, (GAsyncReadyCallback) power_screen_ready_cb, manager); g_dbus_proxy_new (manager->priv->connection, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.cinnamon.SettingsDaemon.Power", "/org/cinnamon/SettingsDaemon/Power", "org.cinnamon.SettingsDaemon.Power.Keyboard", NULL, (GAsyncReadyCallback) power_keyboard_ready_cb, manager); g_dbus_proxy_new (manager->priv->connection, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, "org.Cinnamon", "/org/Cinnamon", "org.Cinnamon", NULL, (GAsyncReadyCallback) osd_ready_cb, manager); } static void register_manager (CsdMediaKeysManager *manager) { manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); manager->priv->kb_introspection_data = g_dbus_node_info_new_for_xml (kb_introspection_xml, NULL); manager->priv->bus_cancellable = g_cancellable_new (); g_assert (manager->priv->introspection_data != NULL); g_assert (manager->priv->kb_introspection_data != NULL); g_bus_get (G_BUS_TYPE_SESSION, manager->priv->bus_cancellable, (GAsyncReadyCallback) on_bus_gotten, manager); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", NULL, (GAsyncReadyCallback) upower_ready_cb, manager); } CsdMediaKeysManager * csd_media_keys_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_MEDIA_KEYS_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_MEDIA_KEYS_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/media-keys/bus-watch-namespace.c0000664000175000017500000002516214733247605025076 0ustar fabiofabio/* * Copyright 2013 Canonical Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Author: Lars Uebernickel */ #include "config.h" #include #include #include "bus-watch-namespace.h" typedef struct { guint id; gchar *name_space; GBusNameAppearedCallback appeared_handler; GBusNameVanishedCallback vanished_handler; gpointer user_data; GDestroyNotify user_data_destroy; GDBusConnection *connection; GCancellable *cancellable; GHashTable *names; guint subscription_id; } NamespaceWatcher; typedef struct { NamespaceWatcher *watcher; gchar *name; } GetNameOwnerData; static guint namespace_watcher_next_id; static GHashTable *namespace_watcher_watchers; static void namespace_watcher_stop (gpointer data) { NamespaceWatcher *watcher = data; g_cancellable_cancel (watcher->cancellable); g_object_unref (watcher->cancellable); if (watcher->subscription_id) g_dbus_connection_signal_unsubscribe (watcher->connection, watcher->subscription_id); if (watcher->vanished_handler) { GHashTableIter it; const gchar *name; g_hash_table_iter_init (&it, watcher->names); while (g_hash_table_iter_next (&it, (gpointer *) &name, NULL)) watcher->vanished_handler (watcher->connection, name, watcher->user_data); } if (watcher->user_data_destroy) watcher->user_data_destroy (watcher->user_data); if (watcher->connection) { g_signal_handlers_disconnect_by_func (watcher->connection, namespace_watcher_stop, watcher); g_object_unref (watcher->connection); } g_hash_table_unref (watcher->names); g_hash_table_remove (namespace_watcher_watchers, GUINT_TO_POINTER (watcher->id)); if (g_hash_table_size (namespace_watcher_watchers) == 0) g_clear_pointer (&namespace_watcher_watchers, g_hash_table_destroy); g_free (watcher); } static void namespace_watcher_name_appeared (NamespaceWatcher *watcher, const gchar *name, const gchar *owner) { /* There's a race between NameOwnerChanged signals arriving and the * ListNames/GetNameOwner sequence returning, so this function might * be called more than once for the same name. To ensure that * appeared_handler is only called once for each name, it is only * called when inserting the name into watcher->names (each name is * only inserted once there). */ if (g_hash_table_contains (watcher->names, name)) return; g_hash_table_add (watcher->names, g_strdup (name)); if (watcher->appeared_handler) watcher->appeared_handler (watcher->connection, name, owner, watcher->user_data); } static void namespace_watcher_name_vanished (NamespaceWatcher *watcher, const gchar *name) { if (g_hash_table_remove (watcher->names, name) && watcher->vanished_handler) watcher->vanished_handler (watcher->connection, name, watcher->user_data); } static gboolean dbus_name_has_namespace (const gchar *name, const gchar *name_space) { gint len_name; gint len_namespace; len_name = strlen (name); len_namespace = strlen (name_space); if (len_name < len_namespace) return FALSE; if (memcmp (name_space, name, len_namespace) != 0) return FALSE; return len_namespace == len_name || name[len_namespace] == '.'; } static void name_owner_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { NamespaceWatcher *watcher = user_data; const gchar *name; const gchar *old_owner; const gchar *new_owner; g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner); if (old_owner[0] != '\0') namespace_watcher_name_vanished (watcher, name); if (new_owner[0] != '\0') namespace_watcher_name_appeared (watcher, name, new_owner); } static void got_name_owner (GObject *object, GAsyncResult *result, gpointer user_data) { GetNameOwnerData *data = user_data; GError *error = NULL; GVariant *reply; const gchar *owner; reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); goto out; } if (reply == NULL) { if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER)) g_warning ("bus_watch_namespace: error calling org.freedesktop.DBus.GetNameOwner: %s", error->message); g_error_free (error); goto out; } g_variant_get (reply, "(&s)", &owner); namespace_watcher_name_appeared (data->watcher, data->name, owner); g_variant_unref (reply); out: g_free (data->name); g_slice_free (GetNameOwnerData, data); } static void names_listed (GObject *object, GAsyncResult *result, gpointer user_data) { NamespaceWatcher *watcher; GError *error = NULL; GVariant *reply; GVariantIter *iter; const gchar *name; reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); return; } watcher = user_data; if (reply == NULL) { g_warning ("bus_watch_namespace: error calling org.freedesktop.DBus.ListNames: %s", error->message); g_error_free (error); return; } g_variant_get (reply, "(as)", &iter); while (g_variant_iter_next (iter, "&s", &name)) { if (dbus_name_has_namespace (name, watcher->name_space)) { GetNameOwnerData *data = g_slice_new (GetNameOwnerData); data->watcher = watcher; data->name = g_strdup (name); g_dbus_connection_call (watcher->connection, "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetNameOwner", g_variant_new ("(s)", name), G_VARIANT_TYPE ("(s)"), G_DBUS_CALL_FLAGS_NONE, -1, watcher->cancellable, got_name_owner, data); } } g_variant_iter_free (iter); g_variant_unref (reply); } static void connection_closed (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data) { NamespaceWatcher *watcher = user_data; namespace_watcher_stop (watcher); } static void got_bus (GObject *object, GAsyncResult *result, gpointer user_data) { GDBusConnection *connection; NamespaceWatcher *watcher; GError *error = NULL; connection = g_bus_get_finish (result, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); return; } watcher = user_data; if (connection == NULL) { namespace_watcher_stop (watcher); return; } watcher->connection = connection; g_signal_connect (watcher->connection, "closed", G_CALLBACK (connection_closed), watcher); watcher->subscription_id = g_dbus_connection_signal_subscribe (watcher->connection, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus", watcher->name_space, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, name_owner_changed, watcher, NULL); g_dbus_connection_call (watcher->connection, "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames", NULL, G_VARIANT_TYPE ("(as)"), G_DBUS_CALL_FLAGS_NONE, -1, watcher->cancellable, names_listed, watcher); } guint bus_watch_namespace (GBusType bus_type, const gchar *name_space, GBusNameAppearedCallback appeared_handler, GBusNameVanishedCallback vanished_handler, gpointer user_data, GDestroyNotify user_data_destroy) { NamespaceWatcher *watcher; /* same rules for interfaces and well-known names */ g_return_val_if_fail (name_space != NULL && g_dbus_is_interface_name (name_space), 0); g_return_val_if_fail (appeared_handler || vanished_handler, 0); watcher = g_new0 (NamespaceWatcher, 1); watcher->id = namespace_watcher_next_id++; watcher->name_space = g_strdup (name_space); watcher->appeared_handler = appeared_handler; watcher->vanished_handler = vanished_handler; watcher->user_data = user_data; watcher->user_data_destroy = user_data_destroy; watcher->cancellable = g_cancellable_new ();; watcher->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (namespace_watcher_watchers == NULL) namespace_watcher_watchers = g_hash_table_new (g_direct_hash, g_direct_equal); g_hash_table_insert (namespace_watcher_watchers, GUINT_TO_POINTER (watcher->id), watcher); g_bus_get (bus_type, watcher->cancellable, got_bus, watcher); return watcher->id; } void bus_unwatch_namespace (guint id) { /* namespace_watcher_stop() might have already removed the watcher * with @id in the case of a connection error. Thus, this function * doesn't warn when @id is absent from the hash table. */ if (namespace_watcher_watchers) { NamespaceWatcher *watcher; watcher = g_hash_table_lookup (namespace_watcher_watchers, GUINT_TO_POINTER (id)); if (watcher) { /* make sure vanished() is not called as a result of this function */ g_hash_table_remove_all (watcher->names); namespace_watcher_stop (watcher); } } } cinnamon-settings-daemon-6.4.3/plugins/media-keys/cinnamon-settings-daemon-media-keys.desktop.in0000664000175000017500000000034414733247605032025 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - media-keys Exec=csd-media-keys OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/dummy/0000775000175000017500000000000014733247605020200 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/dummy/meson.build0000664000175000017500000000076114733247605022346 0ustar fabiofabioplugin_name = 'dummy' dummy_sources = [ 'csd-dummy-manager.h', 'csd-dummy-manager.c', 'main.c', ] dummy_deps = [ common_dep, csd_dep, libnotify, ] executable( 'csd-dummy', dummy_sources, include_directories: [include_dirs, common_inc], dependencies: dummy_deps, c_args: [ '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-dummy') cinnamon-settings-daemon-6.4.3/plugins/dummy/csd-dummy-manager.h0000664000175000017500000000437314733247605023672 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_DUMMY_MANAGER_H #define __CSD_DUMMY_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_DUMMY_MANAGER (csd_dummy_manager_get_type ()) #define CSD_DUMMY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_DUMMY_MANAGER, CsdDummyManager)) #define CSD_DUMMY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_DUMMY_MANAGER, CsdDummyManagerClass)) #define CSD_IS_DUMMY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_DUMMY_MANAGER)) #define CSD_IS_DUMMY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_DUMMY_MANAGER)) #define CSD_DUMMY_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_DUMMY_MANAGER, CsdDummyManagerClass)) typedef struct CsdDummyManagerPrivate CsdDummyManagerPrivate; typedef struct { GObject parent; CsdDummyManagerPrivate *priv; } CsdDummyManager; typedef struct { GObjectClass parent_class; } CsdDummyManagerClass; GType csd_dummy_manager_get_type (void); CsdDummyManager * csd_dummy_manager_new (void); gboolean csd_dummy_manager_start (CsdDummyManager *manager, GError **error); void csd_dummy_manager_stop (CsdDummyManager *manager); G_END_DECLS #endif /* __CSD_DUMMY_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/dummy/main.c0000664000175000017500000000111414733247605021265 0ustar fabiofabio#define NEW csd_dummy_manager_new #define START csd_dummy_manager_start #define STOP csd_dummy_manager_stop #define MANAGER CsdDummyManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-dummy-manager.h" #include "daemon-skeleton.h" cinnamon-settings-daemon-6.4.3/plugins/dummy/csd-dummy-manager.c0000664000175000017500000001176514733247605023670 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" #include "csd-dummy-manager.h" #define CSD_DUMMY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_DUMMY_MANAGER, CsdDummyManagerPrivate)) struct CsdDummyManagerPrivate { gboolean padding; }; enum { PROP_0, }; static void csd_dummy_manager_finalize (GObject *object); G_DEFINE_TYPE (CsdDummyManager, csd_dummy_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; gboolean csd_dummy_manager_start (CsdDummyManager *manager, GError **error) { g_debug ("Starting dummy manager"); cinnamon_settings_profile_start (NULL); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_dummy_manager_stop (CsdDummyManager *manager) { g_debug ("Stopping dummy manager"); } static void csd_dummy_manager_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_dummy_manager_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GObject * csd_dummy_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CsdDummyManager *dummy_manager; dummy_manager = CSD_DUMMY_MANAGER (G_OBJECT_CLASS (csd_dummy_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (dummy_manager); } static void csd_dummy_manager_dispose (GObject *object) { G_OBJECT_CLASS (csd_dummy_manager_parent_class)->dispose (object); } static void csd_dummy_manager_class_init (CsdDummyManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = csd_dummy_manager_get_property; object_class->set_property = csd_dummy_manager_set_property; object_class->constructor = csd_dummy_manager_constructor; object_class->dispose = csd_dummy_manager_dispose; object_class->finalize = csd_dummy_manager_finalize; g_type_class_add_private (klass, sizeof (CsdDummyManagerPrivate)); } static void csd_dummy_manager_init (CsdDummyManager *manager) { manager->priv = CSD_DUMMY_MANAGER_GET_PRIVATE (manager); } static void csd_dummy_manager_finalize (GObject *object) { CsdDummyManager *dummy_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_DUMMY_MANAGER (object)); dummy_manager = CSD_DUMMY_MANAGER (object); g_return_if_fail (dummy_manager->priv != NULL); G_OBJECT_CLASS (csd_dummy_manager_parent_class)->finalize (object); } CsdDummyManager * csd_dummy_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_DUMMY_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_DUMMY_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/0000775000175000017500000000000014733247605021533 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-ldsm-dialog.h0000664000175000017500000000510214733247605024645 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * csd-ldsm-dialog.c * Copyright (C) Chris Coulson 2009 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef _CSD_LDSM_DIALOG_H_ #define _CSD_LDSM_DIALOG_H_ #include #include G_BEGIN_DECLS #define CSD_TYPE_LDSM_DIALOG (csd_ldsm_dialog_get_type ()) #define CSD_LDSM_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CSD_TYPE_LDSM_DIALOG, CsdLdsmDialog)) #define CSD_LDSM_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CSD_TYPE_LDSM_DIALOG, CsdLdsmDialogClass)) #define CSD_IS_LDSM_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CSD_TYPE_LDSM_DIALOG)) #define CSD_IS_LDSM_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CSD_TYPE_LDSM_DIALOG)) #define CSD_LDSM_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CSD_TYPE_LDSM_DIALOG, CsdLdsmDialogClass)) enum { CSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH = -20, CSD_LDSM_DIALOG_RESPONSE_ANALYZE = -21 }; typedef struct CsdLdsmDialogPrivate CsdLdsmDialogPrivate; typedef struct _CsdLdsmDialogClass CsdLdsmDialogClass; typedef struct _CsdLdsmDialog CsdLdsmDialog; struct _CsdLdsmDialogClass { GtkDialogClass parent_class; }; struct _CsdLdsmDialog { GtkDialog parent_instance; CsdLdsmDialogPrivate *priv; }; GType csd_ldsm_dialog_get_type (void) G_GNUC_CONST; CsdLdsmDialog * csd_ldsm_dialog_new (gboolean other_usable_partitions, gboolean other_partitions, gboolean display_baobab, gboolean display_empty_trash, gint64 space_remaining, const gchar *partition_name, const gchar *mount_path); G_END_DECLS #endif /* _CSD_LDSM_DIALOG_H_ */ cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-disk-space.c0000664000175000017500000007041414733247605024477 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2008, Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "csd-disk-space.h" #include "csd-ldsm-dialog.h" #include "csd-disk-space-helper.h" #define GIGABYTE 1024 * 1024 * 1024 #define CHECK_EVERY_X_SECONDS 60 #define DISK_SPACE_ANALYZER "baobab" #define SETTINGS_HOUSEKEEPING_DIR "org.cinnamon.settings-daemon.plugins.housekeeping" #define SETTINGS_FREE_PC_NOTIFY_KEY "free-percent-notify" #define SETTINGS_FREE_PC_NOTIFY_AGAIN_KEY "free-percent-notify-again" #define SETTINGS_FREE_SIZE_NO_NOTIFY "free-size-gb-no-notify" #define SETTINGS_MIN_NOTIFY_PERIOD "min-notify-period" #define SETTINGS_IGNORE_PATHS "ignore-paths" typedef struct { GUnixMountEntry *mount; struct statvfs buf; time_t notify_time; } LdsmMountInfo; static GHashTable *ldsm_notified_hash = NULL; static unsigned int ldsm_timeout_id = 0; static GUnixMountMonitor *ldsm_monitor = NULL; static double free_percent_notify = 0.05; static double free_percent_notify_again = 0.01; static unsigned int free_size_gb_no_notify = 2; static unsigned int min_notify_period = 10; static GSList *ignore_paths = NULL; static GSettings *settings = NULL; static CsdLdsmDialog *dialog = NULL; static NotifyNotification *notification = NULL; static guint64 *time_read; static gchar* ldsm_get_fs_id_for_path (const gchar *path) { GFile *file; GFileInfo *fileinfo; gchar *attr_id_fs; file = g_file_new_for_path (path); fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); if (fileinfo) { attr_id_fs = g_strdup (g_file_info_get_attribute_string (fileinfo, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); g_object_unref (fileinfo); } else { attr_id_fs = NULL; } g_object_unref (file); return attr_id_fs; } static gboolean ldsm_mount_has_trash (LdsmMountInfo *mount) { const gchar *user_data_dir; gchar *user_data_attr_id_fs; gchar *path_attr_id_fs; gboolean mount_uses_user_trash = FALSE; gchar *trash_files_dir; gboolean has_trash = FALSE; GDir *dir; const gchar *path; user_data_dir = g_get_user_data_dir (); user_data_attr_id_fs = ldsm_get_fs_id_for_path (user_data_dir); path = g_unix_mount_get_mount_path (mount->mount); path_attr_id_fs = ldsm_get_fs_id_for_path (path); if (g_strcmp0 (user_data_attr_id_fs, path_attr_id_fs) == 0) { /* The volume that is low on space is on the same volume as our home * directory. This means the trash is at $XDG_DATA_HOME/Trash, * not at the root of the volume which is full. */ mount_uses_user_trash = TRUE; } g_free (user_data_attr_id_fs); g_free (path_attr_id_fs); /* I can't think of a better way to find out if a volume has any trash. Any suggestions? */ if (mount_uses_user_trash) { trash_files_dir = g_build_filename (g_get_user_data_dir (), "Trash", "files", NULL); } else { gchar *uid; uid = g_strdup_printf ("%d", getuid ()); trash_files_dir = g_build_filename (path, ".Trash", uid, "files", NULL); if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { gchar *trash_dir; g_free (trash_files_dir); trash_dir = g_strdup_printf (".Trash-%s", uid); trash_files_dir = g_build_filename (path, trash_dir, "files", NULL); g_free (trash_dir); if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { g_free (trash_files_dir); g_free (uid); return has_trash; } } g_free (uid); } dir = g_dir_open (trash_files_dir, 0, NULL); if (dir) { if (g_dir_read_name (dir)) has_trash = TRUE; g_dir_close (dir); } g_free (trash_files_dir); return has_trash; } static void ldsm_analyze_path (const gchar *path) { const gchar *argv[] = { DISK_SPACE_ANALYZER, path, NULL }; g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); } static gboolean server_has_actions (void) { gboolean has; GList *caps; GList *l; caps = notify_get_server_caps (); if (caps == NULL) { fprintf (stderr, "Failed to receive server caps.\n"); return FALSE; } l = g_list_find_custom (caps, "actions", (GCompareFunc)strcmp); has = l != NULL; g_list_foreach (caps, (GFunc) g_free, NULL); g_list_free (caps); return has; } static void ignore_callback (NotifyNotification *n, const char *action) { g_assert (action != NULL); g_assert (strcmp (action, "ignore") == 0); /* Do nothing */ notify_notification_close (n, NULL); } static void examine_callback (NotifyNotification *n, const char *action, const char *path) { g_assert (action != NULL); g_assert (strcmp (action, "examine") == 0); ldsm_analyze_path (path); notify_notification_close (n, NULL); } static void nemo_empty_trash_cb (GObject *object, GAsyncResult *res, gpointer _unused) { GDBusProxy *proxy = G_DBUS_PROXY (object); GError *error = NULL; g_dbus_proxy_call_finish (proxy, res, &error); if (error != NULL) { g_warning ("Unable to call EmptyTrash() on the Nemo DBus interface: %s", error->message); g_error_free (error); } /* clean up the proxy object */ g_object_unref (proxy); } static void nemo_proxy_ready_cb (GObject *object, GAsyncResult *res, gpointer _unused) { GDBusProxy *proxy = NULL; GError *error = NULL; proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (proxy == NULL) { g_warning ("Unable to create a proxy object for the Nemo DBus interface: %s", error->message); g_error_free (error); return; } g_dbus_proxy_call (proxy, "EmptyTrash", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, nemo_empty_trash_cb, NULL); } void csd_ldsm_show_empty_trash (void) { /* prepare the Nemo proxy object */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.Nemo", "/org/Nemo", "org.Nemo.FileOperations", NULL, nemo_proxy_ready_cb, NULL); } static void empty_trash_callback (NotifyNotification *n, const char *action) { g_assert (action != NULL); g_assert (strcmp (action, "empty-trash") == 0); csd_ldsm_show_empty_trash (); notify_notification_close (n, NULL); } static void on_notification_closed (NotifyNotification *n) { g_object_unref (notification); notification = NULL; } static gboolean ldsm_notify_for_mount (LdsmMountInfo *mount, gboolean multiple_volumes, gboolean other_usable_volumes) { gchar *name, *program; gint64 free_space; gint response; gboolean has_trash; gboolean has_disk_analyzer; gboolean retval = TRUE; gchar *path; /* Don't show a notice if one is already displayed */ if (dialog != NULL || notification != NULL) return retval; name = g_unix_mount_guess_name (mount->mount); free_space = (gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail; has_trash = ldsm_mount_has_trash (mount); path = g_strdup (g_unix_mount_get_mount_path (mount->mount)); program = g_find_program_in_path (DISK_SPACE_ANALYZER); has_disk_analyzer = (program != NULL); g_free (program); if (server_has_actions ()) { char *free_space_str; char *summary; char *body; free_space_str = g_format_size (free_space); if (multiple_volumes) { summary = g_strdup_printf (_("Low Disk Space on \"%s\""), name); if (has_trash) { body = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining. You may free up some space by emptying the trash."), name, free_space_str); } else { body = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining."), name, free_space_str); } } else { summary = g_strdup (_("Low Disk Space")); if (has_trash) { body = g_strdup_printf (_("This computer has only %s disk space remaining. You may free up some space by emptying the trash."), free_space_str); } else { body = g_strdup_printf (_("This computer has only %s disk space remaining."), free_space_str); } } g_free (free_space_str); notification = notify_notification_new (summary, body, "drive-harddisk-symbolic"); g_free (summary); g_free (body); g_signal_connect (notification, "closed", G_CALLBACK (on_notification_closed), NULL); notify_notification_set_app_name (notification, _("Disk space")); notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE)); notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL); notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT); if (has_disk_analyzer) { notify_notification_add_action (notification, "examine", _("Examine"), (NotifyActionCallback) examine_callback, g_strdup (path), g_free); } if (has_trash) { notify_notification_add_action (notification, "empty-trash", _("Empty Trash"), (NotifyActionCallback) empty_trash_callback, NULL, NULL); } notify_notification_add_action (notification, "ignore", _("Ignore"), (NotifyActionCallback) ignore_callback, NULL, NULL); notify_notification_set_category (notification, "device"); if (!notify_notification_show (notification, NULL)) { g_warning ("failed to send disk space notification\n"); } } else { dialog = csd_ldsm_dialog_new (other_usable_volumes, multiple_volumes, has_disk_analyzer, has_trash, free_space, name, path); g_object_ref (G_OBJECT (dialog)); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); dialog = NULL; switch (response) { case GTK_RESPONSE_CANCEL: retval = FALSE; break; case CSD_LDSM_DIALOG_RESPONSE_ANALYZE: retval = FALSE; ldsm_analyze_path (path); break; case CSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH: retval = TRUE; csd_ldsm_show_empty_trash (); break; case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: retval = TRUE; break; default: g_assert_not_reached (); } } g_free (name); g_free (path); return retval; } static gboolean ldsm_mount_has_space (LdsmMountInfo *mount) { gdouble free_space; free_space = (double) mount->buf.f_bavail / (double) mount->buf.f_blocks; /* enough free space, nothing to do */ if (free_space > free_percent_notify) return TRUE; if (((gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail) > ((gint64) free_size_gb_no_notify * GIGABYTE)) return TRUE; /* If we got here, then this volume is low on space */ return FALSE; } static gboolean ldsm_mount_is_virtual (LdsmMountInfo *mount) { if (mount->buf.f_blocks == 0) { /* Filesystems with zero blocks are virtual */ return TRUE; } return FALSE; } static gint ldsm_ignore_path_compare (gconstpointer a, gconstpointer b) { return g_strcmp0 ((const gchar *)a, (const gchar *)b); } static gboolean ldsm_mount_is_user_ignore (const gchar *path) { if (g_slist_find_custom (ignore_paths, path, (GCompareFunc) ldsm_ignore_path_compare) != NULL) return TRUE; else return FALSE; } static void ldsm_free_mount_info (gpointer data) { LdsmMountInfo *mount = data; g_return_if_fail (mount != NULL); g_unix_mount_free (mount->mount); g_free (mount); } static void ldsm_maybe_warn_mounts (GList *mounts, gboolean multiple_volumes, gboolean other_usable_volumes) { GList *l; gboolean done = FALSE; for (l = mounts; l != NULL; l = l->next) { LdsmMountInfo *mount_info = l->data; LdsmMountInfo *previous_mount_info; gdouble free_space; gdouble previous_free_space; time_t curr_time; const gchar *path; gboolean show_notify; if (done) { /* Don't show any more dialogs if the user took action with the last one. The user action * might free up space on multiple volumes, making the next dialog redundant. */ ldsm_free_mount_info (mount_info); continue; } path = g_unix_mount_get_mount_path (mount_info->mount); previous_mount_info = g_hash_table_lookup (ldsm_notified_hash, path); if (previous_mount_info != NULL) previous_free_space = (gdouble) previous_mount_info->buf.f_bavail / (gdouble) previous_mount_info->buf.f_blocks; free_space = (gdouble) mount_info->buf.f_bavail / (gdouble) mount_info->buf.f_blocks; if (previous_mount_info == NULL) { /* We haven't notified for this mount yet */ show_notify = TRUE; mount_info->notify_time = time (NULL); g_hash_table_replace (ldsm_notified_hash, g_strdup (path), mount_info); } else if ((previous_free_space - free_space) > free_percent_notify_again) { /* We've notified for this mount before and free space has decreased sufficiently since last time to notify again */ curr_time = time (NULL); if (difftime (curr_time, previous_mount_info->notify_time) > (gdouble)(min_notify_period * 60)) { show_notify = TRUE; mount_info->notify_time = curr_time; } else { /* It's too soon to show the dialog again. However, we still replace the LdsmMountInfo * struct in the hash table, but give it the notfiy time from the previous dialog. * This will stop the notification from reappearing unnecessarily as soon as the timeout expires. */ show_notify = FALSE; mount_info->notify_time = previous_mount_info->notify_time; } g_hash_table_replace (ldsm_notified_hash, g_strdup (path), mount_info); } else { /* We've notified for this mount before, but the free space hasn't decreased sufficiently to notify again */ ldsm_free_mount_info (mount_info); show_notify = FALSE; } if (show_notify) { if (ldsm_notify_for_mount (mount_info, multiple_volumes, other_usable_volumes)) done = TRUE; } } } static gboolean ldsm_check_all_mounts (gpointer data) { GList *mounts; GList *l; GList *check_mounts = NULL; GList *full_mounts = NULL; guint number_of_mounts; guint number_of_full_mounts; gboolean multiple_volumes = FALSE; gboolean other_usable_volumes = FALSE; /* We iterate through the static mounts in /etc/fstab first, seeing if * they're mounted by checking if the GUnixMountPoint has a corresponding GUnixMountEntry. * Iterating through the static mounts means we automatically ignore dynamically mounted media. */ mounts = g_unix_mount_points_get (time_read); for (l = mounts; l != NULL; l = l->next) { GUnixMountPoint *mount_point = l->data; GUnixMountEntry *mount; LdsmMountInfo *mount_info; const gchar *path; path = g_unix_mount_point_get_mount_path (mount_point); mount = g_unix_mount_at (path, time_read); g_unix_mount_point_free (mount_point); if (mount == NULL) { /* The GUnixMountPoint is not mounted */ continue; } mount_info = g_new0 (LdsmMountInfo, 1); mount_info->mount = mount; path = g_unix_mount_get_mount_path (mount); if (g_unix_mount_is_readonly (mount)) { ldsm_free_mount_info (mount_info); continue; } if (ldsm_mount_is_user_ignore (path)) { ldsm_free_mount_info (mount_info); continue; } if (csd_should_ignore_unix_mount (mount)) { ldsm_free_mount_info (mount_info); continue; } if (statvfs (path, &mount_info->buf) != 0) { ldsm_free_mount_info (mount_info); continue; } if (ldsm_mount_is_virtual (mount_info)) { ldsm_free_mount_info (mount_info); continue; } check_mounts = g_list_prepend (check_mounts, mount_info); } g_list_free (mounts); number_of_mounts = g_list_length (check_mounts); if (number_of_mounts > 1) multiple_volumes = TRUE; for (l = check_mounts; l != NULL; l = l->next) { LdsmMountInfo *mount_info = l->data; if (!ldsm_mount_has_space (mount_info)) { full_mounts = g_list_prepend (full_mounts, mount_info); } else { g_hash_table_remove (ldsm_notified_hash, g_unix_mount_get_mount_path (mount_info->mount)); ldsm_free_mount_info (mount_info); } } number_of_full_mounts = g_list_length (full_mounts); if (number_of_mounts > number_of_full_mounts) other_usable_volumes = TRUE; ldsm_maybe_warn_mounts (full_mounts, multiple_volumes, other_usable_volumes); g_list_free (check_mounts); g_list_free (full_mounts); return TRUE; } static gboolean ldsm_is_hash_item_not_in_mounts (gpointer key, gpointer value, gpointer user_data) { GList *l; for (l = (GList *) user_data; l != NULL; l = l->next) { GUnixMountEntry *mount = l->data; const char *path; path = g_unix_mount_get_mount_path (mount); if (strcmp (path, key) == 0) return FALSE; } return TRUE; } static void ldsm_mounts_changed (GObject *monitor, gpointer data) { GList *mounts; /* remove the saved data for mounts that got removed */ mounts = g_unix_mounts_get (time_read); g_hash_table_foreach_remove (ldsm_notified_hash, ldsm_is_hash_item_not_in_mounts, mounts); g_list_free_full (mounts, (GDestroyNotify) g_unix_mount_free); /* check the status now, for the new mounts */ ldsm_check_all_mounts (NULL); /* and reset the timeout */ if (ldsm_timeout_id) { g_source_remove (ldsm_timeout_id); ldsm_timeout_id = 0; } ldsm_timeout_id = g_timeout_add_seconds (CHECK_EVERY_X_SECONDS, ldsm_check_all_mounts, NULL); } static gboolean ldsm_is_hash_item_in_ignore_paths (gpointer key, gpointer value, gpointer user_data) { return ldsm_mount_is_user_ignore (key); } static void csd_ldsm_get_config (void) { gchar **settings_list; free_percent_notify = g_settings_get_double (settings, SETTINGS_FREE_PC_NOTIFY_KEY); if (free_percent_notify >= 1 || free_percent_notify < 0) { g_warning ("Invalid configuration of free_percent_notify: %f\n" \ "Using sensible default", free_percent_notify); free_percent_notify = 0.05; } free_percent_notify_again = g_settings_get_double (settings, SETTINGS_FREE_PC_NOTIFY_AGAIN_KEY); if (free_percent_notify_again >= 1 || free_percent_notify_again < 0) { g_warning ("Invalid configuration of free_percent_notify_again: %f\n" \ "Using sensible default\n", free_percent_notify_again); free_percent_notify_again = 0.01; } free_size_gb_no_notify = g_settings_get_int (settings, SETTINGS_FREE_SIZE_NO_NOTIFY); min_notify_period = g_settings_get_int (settings, SETTINGS_MIN_NOTIFY_PERIOD); if (ignore_paths != NULL) { g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); g_clear_pointer (&ignore_paths, g_slist_free); } settings_list = g_settings_get_strv (settings, SETTINGS_IGNORE_PATHS); if (settings_list != NULL) { guint i; for (i = 0; settings_list[i] != NULL; i++) ignore_paths = g_slist_prepend (ignore_paths, g_strdup (settings_list[i])); /* Make sure we don't leave stale entries in ldsm_notified_hash */ g_hash_table_foreach_remove (ldsm_notified_hash, ldsm_is_hash_item_in_ignore_paths, NULL); g_strfreev (settings_list); } } static void csd_ldsm_update_config (GSettings *settings, const gchar *key, gpointer user_data) { csd_ldsm_get_config (); } void csd_ldsm_setup (gboolean check_now) { if (ldsm_notified_hash || ldsm_timeout_id || ldsm_monitor) { g_warning ("Low disk space monitor already initialized."); return; } ldsm_notified_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, ldsm_free_mount_info); settings = g_settings_new (SETTINGS_HOUSEKEEPING_DIR); csd_ldsm_get_config (); g_signal_connect (G_OBJECT (settings), "changed", G_CALLBACK (csd_ldsm_update_config), NULL); ldsm_monitor = g_unix_mount_monitor_get (); g_signal_connect (ldsm_monitor, "mounts-changed", G_CALLBACK (ldsm_mounts_changed), NULL); if (check_now) ldsm_check_all_mounts (NULL); ldsm_timeout_id = g_timeout_add_seconds (CHECK_EVERY_X_SECONDS, ldsm_check_all_mounts, NULL); } void csd_ldsm_clean (void) { if (ldsm_timeout_id) { g_source_remove (ldsm_timeout_id); ldsm_timeout_id = 0; } g_clear_pointer (&ldsm_notified_hash, g_hash_table_destroy); g_clear_object (&ldsm_monitor); g_clear_object (&settings); g_clear_object (&dialog); if (notification != NULL) notify_notification_close (notification, NULL); g_slist_free_full (ignore_paths, g_free); ignore_paths = NULL; } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/meson.build0000664000175000017500000000274114733247605023701 0ustar fabiofabioplugin_name = 'housekeeping' housekeeping_common_sources = [ 'csd-disk-space.c', 'csd-ldsm-dialog.c', 'csd-disk-space-helper.c', ] housekeeping_sources = [ 'csd-housekeeping-manager.c', 'main.c', housekeeping_common_sources, ] housekeeping_deps = [ common_dep, csd_dep, gio_unix, libnotify, ] executable( 'csd-housekeeping', housekeeping_sources, include_directories: [include_dirs, common_inc], dependencies: housekeeping_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-housekeeping') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-housekeeping') endif test_disk_space_sources = [ 'csd-disk-space-test.c', housekeeping_common_sources, ] executable( 'test-disk-space', test_disk_space_sources, dependencies: housekeeping_deps, install: false, ) test_empty_trash_sources = [ 'csd-empty-trash-test.c', housekeeping_common_sources, ] executable( 'test-empty-trash', test_empty_trash_sources, dependencies: housekeeping_deps, install: false, ) configure_file( input: 'cinnamon-settings-daemon-housekeeping.desktop.in', output: 'cinnamon-settings-daemon-housekeeping.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-disk-space-test.c0000664000175000017500000000251614733247605025452 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2008, Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include "csd-disk-space.h" int main (int argc, char **argv) { GMainLoop *loop; gtk_init (&argc, &argv); notify_init ("csd-disk-space-test"); loop = g_main_loop_new (NULL, FALSE); csd_ldsm_setup (TRUE); g_main_loop_run (loop); csd_ldsm_clean (); g_main_loop_unref (loop); return 0; } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-disk-space-helper.h0000664000175000017500000000242614733247605025757 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2008, Novell, Inc. * Copyright (c) 2012, Red Hat, Inc. * * Authors: Vincent Untz * Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_DISK_SPACE_HELPER_H #define __CSD_DISK_SPACE_HELPER_H #include #include G_BEGIN_DECLS gboolean csd_should_ignore_unix_mount (GUnixMountEntry *mount); gboolean csd_is_removable_mount (GUnixMountEntry *mount); G_END_DECLS #endif /* __CSD_DISK_SPACE_HELPER_H */ cinnamon-settings-daemon-6.4.3/plugins/housekeeping/main.c0000664000175000017500000000116314733247605022624 0ustar fabiofabio#define NEW csd_housekeeping_manager_new #define START csd_housekeeping_manager_start #define STOP csd_housekeeping_manager_stop #define MANAGER CsdHousekeepingManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // TRUE if the plugin sends notifications #define INIT_LIBNOTIFY TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE #include "csd-housekeeping-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-housekeeping-manager.h0000664000175000017500000000471014733247605026553 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2008 Michael J. Chudobiak * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_HOUSEKEEPING_MANAGER_H #define __CSD_HOUSEKEEPING_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_HOUSEKEEPING_MANAGER (csd_housekeeping_manager_get_type ()) #define CSD_HOUSEKEEPING_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_HOUSEKEEPING_MANAGER, CsdHousekeepingManager)) #define CSD_HOUSEKEEPING_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_HOUSEKEEPING_MANAGER, CsdHousekeepingManagerClass)) #define CSD_IS_HOUSEKEEPING_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_HOUSEKEEPING_MANAGER)) #define CSD_IS_HOUSEKEEPING_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_HOUSEKEEPING_MANAGER)) #define CSD_HOUSEKEEPING_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_HOUSEKEEPING_MANAGER, CsdHousekeepingManagerClass)) typedef struct CsdHousekeepingManagerPrivate CsdHousekeepingManagerPrivate; typedef struct { GObject parent; CsdHousekeepingManagerPrivate *priv; } CsdHousekeepingManager; typedef struct { GObjectClass parent_class; } CsdHousekeepingManagerClass; GType csd_housekeeping_manager_get_type (void); CsdHousekeepingManager * csd_housekeeping_manager_new (void); gboolean csd_housekeeping_manager_start (CsdHousekeepingManager *manager, GError **error); void csd_housekeeping_manager_stop (CsdHousekeepingManager *manager); G_END_DECLS #endif /* __CSD_HOUSEKEEPING_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-disk-space-helper.c0000664000175000017500000000667514733247605025764 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2008, Novell, Inc. * Copyright (c) 2012, Red Hat, Inc. * * Authors: Vincent Untz * Bastien Nocera * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include "csd-disk-space-helper.h" gboolean csd_should_ignore_unix_mount (GUnixMountEntry *mount) { const char *fs, *device; guint i; /* This is borrowed from GLib and used as a way to determine * which mounts we should ignore by default. GLib doesn't * expose this in a way that allows it to be used for this * purpose */ /* We also ignore network filesystems */ const gchar *ignore_fs[] = { "adfs", "afs", "auto", "autofs", "autofs4", "cifs", "cxfs", "devfs", "devpts", "ecryptfs", "fdescfs", "gfs", "gfs2", "kernfs", "linprocfs", "linsysfs", "lustre", "lustre_lite", "ncpfs", "nfs", "nfs4", "nfsd", "ocfs2", "proc", "procfs", "ptyfs", "rpc_pipefs", "selinuxfs", "smbfs", "sysfs", "tmpfs", "usbfs", "zfs", NULL }; const gchar *ignore_devices[] = { "none", "sunrpc", "devpts", "nfsd", "/dev/loop", "/dev/vn", NULL }; fs = g_unix_mount_get_fs_type (mount); device = g_unix_mount_get_device_path (mount); for (i = 0; ignore_fs[i] != NULL; i++) if (g_str_equal (ignore_fs[i], fs)) return TRUE; for (i = 0; ignore_devices[i] != NULL; i++) if (g_str_equal (ignore_devices[i], device)) return TRUE; return FALSE; } gboolean csd_is_removable_mount (GUnixMountEntry *mount) { const char *mount_path; char *path; mount_path = g_unix_mount_get_mount_path (mount); if (mount_path == NULL) return FALSE; path = g_strdup_printf ("/run/media/%s", g_get_user_name ()); if (g_str_has_prefix (mount_path, path)) { g_free (path); return TRUE; } g_free (path); return FALSE; } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-housekeeping-manager.c0000664000175000017500000002605114733247605026550 0ustar fabiofabio/* * Copyright (C) 2008 Michael J. Chudobiak * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include "cinnamon-settings-profile.h" #include "csd-housekeeping-manager.h" #include "csd-disk-space.h" /* General */ #define INTERVAL_ONCE_A_DAY 24*60*60 #define INTERVAL_TWO_MINUTES 2*60 /* Thumbnail cleaner */ #define THUMB_PREFIX "org.cinnamon.desktop.thumbnail-cache" #define THUMB_AGE_KEY "maximum-age" #define THUMB_SIZE_KEY "maximum-size" struct CsdHousekeepingManagerPrivate { GSettings *settings; guint long_term_cb; guint short_term_cb; }; #define CSD_HOUSEKEEPING_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_HOUSEKEEPING_MANAGER, CsdHousekeepingManagerPrivate)) G_DEFINE_TYPE (CsdHousekeepingManager, csd_housekeeping_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; typedef struct { glong now; glong max_age; goffset total_size; goffset max_size; } PurgeData; typedef struct { time_t mtime; char *path; glong size; } ThumbData; static void thumb_data_free (gpointer data) { ThumbData *info = data; if (info) { g_free (info->path); g_free (info); } } static GList * read_dir_for_purge (const char *path, GList *files) { GFile *read_path; GFileEnumerator *enum_dir; read_path = g_file_new_for_path (path); enum_dir = g_file_enumerate_children (read_path, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (enum_dir != NULL) { GFileInfo *info; while ((info = g_file_enumerator_next_file (enum_dir, NULL, NULL)) != NULL) { const char *name; name = g_file_info_get_name (info); if (strlen (name) == 36 && strcmp (name + 32, ".png") == 0) { ThumbData *td; GFile *entry; char *entry_path; GTimeVal mod_time; entry = g_file_get_child (read_path, name); entry_path = g_file_get_path (entry); g_object_unref (entry); g_file_info_get_modification_time (info, &mod_time); td = g_new0 (ThumbData, 1); td->path = entry_path; td->mtime = mod_time.tv_sec; td->size = g_file_info_get_size (info); files = g_list_prepend (files, td); } g_object_unref (info); } g_object_unref (enum_dir); } g_object_unref (read_path); return files; } static void purge_old_thumbnails (ThumbData *info, PurgeData *purge_data) { if ((purge_data->now - info->mtime) > purge_data->max_age) { g_unlink (info->path); info->size = 0; } else { purge_data->total_size += info->size; } } static int sort_file_mtime (ThumbData *file1, ThumbData *file2) { return file1->mtime - file2->mtime; } static char ** get_thumbnail_dirs (void) { GPtrArray *array; char *path; array = g_ptr_array_new (); /* check new XDG cache */ path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "normal", NULL); g_ptr_array_add (array, path); path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "large", NULL); g_ptr_array_add (array, path); path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "fail", "gnome-thumbnail-factory", NULL); g_ptr_array_add (array, path); /* cleanup obsolete locations too */ path = g_build_filename (g_get_home_dir (), ".thumbnails", "normal", NULL); g_ptr_array_add (array, path); path = g_build_filename (g_get_home_dir (), ".thumbnails", "large", NULL); g_ptr_array_add (array, path); path = g_build_filename (g_get_home_dir (), ".thumbnails", "fail", "gnome-thumbnail-factory", NULL); g_ptr_array_add (array, path); g_ptr_array_add (array, NULL); return (char **) g_ptr_array_free (array, FALSE); } static void purge_thumbnail_cache (CsdHousekeepingManager *manager) { char **paths; GList *files; PurgeData purge_data; GTimeVal current_time; guint i; g_debug ("housekeeping: checking thumbnail cache size and freshness"); paths = get_thumbnail_dirs (); files = NULL; for (i = 0; paths[i] != NULL; i++) files = read_dir_for_purge (paths[i], files); g_strfreev (paths); g_get_current_time (¤t_time); purge_data.now = current_time.tv_sec; purge_data.max_age = g_settings_get_int (manager->priv->settings, THUMB_AGE_KEY) * 24 * 60 * 60; purge_data.max_size = g_settings_get_int (manager->priv->settings, THUMB_SIZE_KEY) * 1024 * 1024; purge_data.total_size = 0; if (purge_data.max_age >= 0) g_list_foreach (files, (GFunc) purge_old_thumbnails, &purge_data); if ((purge_data.total_size > purge_data.max_size) && (purge_data.max_size >= 0)) { GList *scan; files = g_list_sort (files, (GCompareFunc) sort_file_mtime); for (scan = files; scan && (purge_data.total_size > purge_data.max_size); scan = scan->next) { ThumbData *info = scan->data; g_unlink (info->path); purge_data.total_size -= info->size; } } g_list_foreach (files, (GFunc) thumb_data_free, NULL); g_list_free (files); } static gboolean do_cleanup (CsdHousekeepingManager *manager) { purge_thumbnail_cache (manager); return TRUE; } static gboolean do_cleanup_once (CsdHousekeepingManager *manager) { do_cleanup (manager); manager->priv->short_term_cb = 0; return FALSE; } static void do_cleanup_soon (CsdHousekeepingManager *manager) { if (manager->priv->short_term_cb == 0) { g_debug ("housekeeping: will tidy up in 2 minutes"); manager->priv->short_term_cb = g_timeout_add_seconds (INTERVAL_TWO_MINUTES, (GSourceFunc) do_cleanup_once, manager); } } static void settings_changed_callback (GSettings *settings, const char *key, CsdHousekeepingManager *manager) { do_cleanup_soon (manager); } gboolean csd_housekeeping_manager_start (CsdHousekeepingManager *manager, GError **error) { g_debug ("Starting housekeeping manager"); cinnamon_settings_profile_start (NULL); csd_ldsm_setup (FALSE); manager->priv->settings = g_settings_new (THUMB_PREFIX); g_signal_connect (G_OBJECT (manager->priv->settings), "changed", G_CALLBACK (settings_changed_callback), manager); /* Clean once, a few minutes after start-up */ do_cleanup_soon (manager); /* Clean periodically, on a daily basis. */ manager->priv->long_term_cb = g_timeout_add_seconds (INTERVAL_ONCE_A_DAY, (GSourceFunc) do_cleanup, manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_housekeeping_manager_stop (CsdHousekeepingManager *manager) { CsdHousekeepingManagerPrivate *p = manager->priv; g_debug ("Stopping housekeeping manager"); if (p->short_term_cb) { g_source_remove (p->short_term_cb); p->short_term_cb = 0; } if (p->long_term_cb) { g_source_remove (p->long_term_cb); p->long_term_cb = 0; /* Do a clean-up on shutdown if and only if the size or age limits have been set to paranoid levels (zero) */ if ((g_settings_get_int (p->settings, THUMB_AGE_KEY) == 0) || (g_settings_get_int (p->settings, THUMB_SIZE_KEY) == 0)) { do_cleanup (manager); } g_clear_object (&p->settings); } csd_ldsm_clean (); } static void csd_housekeeping_manager_class_init (CsdHousekeepingManagerClass *klass) { g_type_class_add_private (klass, sizeof (CsdHousekeepingManagerPrivate)); } static void csd_housekeeping_manager_init (CsdHousekeepingManager *manager) { manager->priv = CSD_HOUSEKEEPING_MANAGER_GET_PRIVATE (manager); } CsdHousekeepingManager * csd_housekeeping_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_HOUSEKEEPING_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_HOUSEKEEPING_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-empty-trash-test.c0000664000175000017500000000236314733247605025704 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2011, Red Hat, Inc. * * Authors: Cosimo Cecchi * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include "csd-disk-space.h" int main (int argc, char **argv) { GMainLoop *loop; gtk_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); csd_ldsm_show_empty_trash (); g_main_loop_run (loop); g_main_loop_unref (loop); return 0; } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/cinnamon-settings-daemon-housekeeping.desktop.in0000664000175000017500000000035014733247605033116 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - housekeeping Exec=csd-housekeeping OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-ldsm-dialog.c0000664000175000017500000004726214733247605024655 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * csd-ldsm-dialog.c * Copyright (C) Chris Coulson 2009 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #include "config.h" #include #include #include "csd-ldsm-dialog.h" #define SETTINGS_HOUSEKEEPING_DIR "org.cinnamon.settings-daemon.plugins.housekeeping" enum { PROP_0, PROP_OTHER_USABLE_PARTITIONS, PROP_OTHER_PARTITIONS, PROP_HAS_TRASH, PROP_SPACE_REMAINING, PROP_PARTITION_NAME, PROP_MOUNT_PATH }; struct CsdLdsmDialogPrivate { GtkWidget *primary_label; GtkWidget *secondary_label; GtkWidget *ignore_check_button; gboolean other_usable_partitions; gboolean other_partitions; gboolean has_trash; gint64 space_remaining; gchar *partition_name; gchar *mount_path; }; #define CSD_LDSM_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_LDSM_DIALOG, CsdLdsmDialogPrivate)) G_DEFINE_TYPE (CsdLdsmDialog, csd_ldsm_dialog, GTK_TYPE_DIALOG); static const gchar* csd_ldsm_dialog_get_checkbutton_text (CsdLdsmDialog *dialog) { g_return_val_if_fail (CSD_IS_LDSM_DIALOG (dialog), NULL); if (dialog->priv->other_partitions) return _("Don't show any warnings again for this file system"); else return _("Don't show any warnings again"); } static gchar* csd_ldsm_dialog_get_primary_text (CsdLdsmDialog *dialog) { gchar *primary_text, *free_space; g_return_val_if_fail (CSD_IS_LDSM_DIALOG (dialog), NULL); free_space = g_format_size (dialog->priv->space_remaining); if (dialog->priv->other_partitions) { primary_text = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining."), dialog->priv->partition_name, free_space); } else { primary_text = g_strdup_printf (_("This computer has only %s disk space remaining."), free_space); } g_free (free_space); return primary_text; } static const gchar* csd_ldsm_dialog_get_secondary_text (CsdLdsmDialog *dialog) { g_return_val_if_fail (CSD_IS_LDSM_DIALOG (dialog), NULL); if (dialog->priv->other_usable_partitions) { if (dialog->priv->has_trash) { return _("You can free up disk space by emptying the Trash, removing " \ "unused programs or files, or moving files to another disk or partition."); } else { return _("You can free up disk space by removing unused programs or files, " \ "or by moving files to another disk or partition."); } } else { if (dialog->priv->has_trash) { return _("You can free up disk space by emptying the Trash, removing unused " \ "programs or files, or moving files to an external disk."); } else { return _("You can free up disk space by removing unused programs or files, " \ "or by moving files to an external disk."); } } } static gint ignore_path_compare (gconstpointer a, gconstpointer b) { return g_strcmp0 ((const gchar *)a, (const gchar *)b); } static gboolean update_ignore_paths (GSList **ignore_paths, const gchar *mount_path, gboolean ignore) { GSList *found; gchar *path_to_remove; found = g_slist_find_custom (*ignore_paths, mount_path, (GCompareFunc) ignore_path_compare); if (ignore && (found == NULL)) { *ignore_paths = g_slist_prepend (*ignore_paths, g_strdup (mount_path)); return TRUE; } if (!ignore && (found != NULL)) { path_to_remove = found->data; *ignore_paths = g_slist_remove (*ignore_paths, path_to_remove); g_free (path_to_remove); return TRUE; } return FALSE; } static void ignore_check_button_toggled_cb (GtkToggleButton *button, gpointer user_data) { CsdLdsmDialog *dialog = (CsdLdsmDialog *)user_data; GSettings *settings; gchar **settings_list; gboolean ignore, updated; gint i; GSList *ignore_paths = NULL; settings = g_settings_new (SETTINGS_HOUSEKEEPING_DIR); settings_list = g_settings_get_strv (settings, "ignore-paths"); for (i = 0; i < G_N_ELEMENTS (settings_list); i++) { if (settings_list[i] != NULL) ignore_paths = g_slist_append (ignore_paths, g_strdup (settings_list[i])); } ignore = gtk_toggle_button_get_active (button); updated = update_ignore_paths (&ignore_paths, dialog->priv->mount_path, ignore); g_strfreev (settings_list); if (updated) { GSList *l; GPtrArray *array = g_ptr_array_new (); for (l = ignore_paths; l != NULL; l = l->next) g_ptr_array_add (array, l->data); g_ptr_array_add (array, NULL); if (!g_settings_set_strv (settings, "ignore-paths", (const gchar **) array->pdata)) { g_warning ("Cannot change ignore preference - failed to commit changes"); } g_ptr_array_free (array, FALSE); } g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); g_slist_free (ignore_paths); g_object_unref (settings); } static void csd_ldsm_dialog_init (CsdLdsmDialog *dialog) { GtkWidget *main_vbox, *text_vbox, *hbox; GtkWidget *image; dialog->priv = CSD_LDSM_DIALOG_GET_PRIVATE (dialog); main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); /* Set up all the window stuff here */ gtk_window_set_title (GTK_WINDOW (dialog), _("Low Disk Space")); gtk_window_set_icon_name (GTK_WINDOW (dialog), "dialog-warning"); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE); gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); /* Create the image */ image = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); /* Create the labels */ dialog->priv->primary_label = gtk_label_new (NULL); gtk_label_set_line_wrap (GTK_LABEL (dialog->priv->primary_label), TRUE); gtk_label_set_single_line_mode (GTK_LABEL (dialog->priv->primary_label), FALSE); gtk_misc_set_alignment (GTK_MISC (dialog->priv->primary_label), 0.0, 0.0); dialog->priv->secondary_label = gtk_label_new (NULL); gtk_label_set_line_wrap (GTK_LABEL (dialog->priv->secondary_label), TRUE); gtk_label_set_single_line_mode (GTK_LABEL (dialog->priv->secondary_label), FALSE); gtk_misc_set_alignment (GTK_MISC (dialog->priv->secondary_label), 0.0, 0.0); /* Create the check button to ignore future warnings */ dialog->priv->ignore_check_button = gtk_check_button_new (); /* The button should be inactive if the dialog was just called. * I suppose it could be possible for the user to manually edit the GSettings key between * the mount being checked and the dialog appearing, but I don't think it matters * too much */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->ignore_check_button), FALSE); g_signal_connect (dialog->priv->ignore_check_button, "toggled", G_CALLBACK (ignore_check_button_toggled_cb), dialog); /* Now set up the dialog's GtkBox's' */ gtk_box_set_spacing (GTK_BOX (main_vbox), 14); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); text_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->primary_label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->secondary_label, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->ignore_check_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), text_vbox, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); /* Set up the action area */ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), 6); gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), 5); gtk_widget_show_all (hbox); } static void csd_ldsm_dialog_finalize (GObject *object) { CsdLdsmDialog *self; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_LDSM_DIALOG (object)); self = CSD_LDSM_DIALOG (object); if (self->priv->partition_name) g_free (self->priv->partition_name); if (self->priv->mount_path) g_free (self->priv->mount_path); G_OBJECT_CLASS (csd_ldsm_dialog_parent_class)->finalize (object); } static void csd_ldsm_dialog_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CsdLdsmDialog *self; g_return_if_fail (CSD_IS_LDSM_DIALOG (object)); self = CSD_LDSM_DIALOG (object); switch (prop_id) { case PROP_OTHER_USABLE_PARTITIONS: self->priv->other_usable_partitions = g_value_get_boolean (value); break; case PROP_OTHER_PARTITIONS: self->priv->other_partitions = g_value_get_boolean (value); break; case PROP_HAS_TRASH: self->priv->has_trash = g_value_get_boolean (value); break; case PROP_SPACE_REMAINING: self->priv->space_remaining = g_value_get_int64 (value); break; case PROP_PARTITION_NAME: self->priv->partition_name = g_value_dup_string (value); break; case PROP_MOUNT_PATH: self->priv->mount_path = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_ldsm_dialog_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdLdsmDialog *self; g_return_if_fail (CSD_IS_LDSM_DIALOG (object)); self = CSD_LDSM_DIALOG (object); switch (prop_id) { case PROP_OTHER_USABLE_PARTITIONS: g_value_set_boolean (value, self->priv->other_usable_partitions); break; case PROP_OTHER_PARTITIONS: g_value_set_boolean (value, self->priv->other_partitions); break; case PROP_HAS_TRASH: g_value_set_boolean (value, self->priv->has_trash); break; case PROP_SPACE_REMAINING: g_value_set_int64 (value, self->priv->space_remaining); break; case PROP_PARTITION_NAME: g_value_set_string (value, self->priv->partition_name); break; case PROP_MOUNT_PATH: g_value_set_string (value, self->priv->mount_path); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_ldsm_dialog_class_init (CsdLdsmDialogClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_ldsm_dialog_finalize; object_class->set_property = csd_ldsm_dialog_set_property; object_class->get_property = csd_ldsm_dialog_get_property; g_object_class_install_property (object_class, PROP_OTHER_USABLE_PARTITIONS, g_param_spec_boolean ("other-usable-partitions", "other-usable-partitions", "Set to TRUE if there are other usable partitions on the system", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_OTHER_PARTITIONS, g_param_spec_boolean ("other-partitions", "other-partitions", "Set to TRUE if there are other partitions on the system", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_HAS_TRASH, g_param_spec_boolean ("has-trash", "has-trash", "Set to TRUE if the partition has files in it's trash folder that can be deleted", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_SPACE_REMAINING, g_param_spec_int64 ("space-remaining", "space-remaining", "Specify how much space is remaining in bytes", G_MININT64, G_MAXINT64, 0, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_PARTITION_NAME, g_param_spec_string ("partition-name", "partition-name", "Specify the name of the partition", "Unknown", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_MOUNT_PATH, g_param_spec_string ("mount-path", "mount-path", "Specify the mount path for the partition", "Unknown", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_type_class_add_private (klass, sizeof (CsdLdsmDialogPrivate)); } CsdLdsmDialog* csd_ldsm_dialog_new (gboolean other_usable_partitions, gboolean other_partitions, gboolean display_baobab, gboolean display_empty_trash, gint64 space_remaining, const gchar *partition_name, const gchar *mount_path) { CsdLdsmDialog *dialog; GtkWidget *button_empty_trash, *button_ignore, *button_analyze; GtkWidget *empty_trash_image, *analyze_image, *ignore_image; gchar *primary_text, *primary_text_markup; const gchar *secondary_text, *checkbutton_text; dialog = CSD_LDSM_DIALOG (g_object_new (CSD_TYPE_LDSM_DIALOG, "other-usable-partitions", other_usable_partitions, "other-partitions", other_partitions, "has-trash", display_empty_trash, "space-remaining", space_remaining, "partition-name", partition_name, "mount-path", mount_path, NULL)); /* Add some buttons */ if (dialog->priv->has_trash) { button_empty_trash = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Empty Trash"), CSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH); empty_trash_image = gtk_image_new_from_icon_name ("edit-clear", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button_empty_trash), empty_trash_image); } if (display_baobab) { button_analyze = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Examine..."), CSD_LDSM_DIALOG_RESPONSE_ANALYZE); analyze_image = gtk_image_new_from_icon_name ("baobab", GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button_analyze), analyze_image); } button_ignore = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Ignore"), GTK_RESPONSE_CANCEL); ignore_image = gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); gtk_button_set_image (GTK_BUTTON (button_ignore), ignore_image); gtk_widget_grab_default (button_ignore); /* Set the label text */ primary_text = csd_ldsm_dialog_get_primary_text (dialog); primary_text_markup = g_markup_printf_escaped ("%s", primary_text); gtk_label_set_markup (GTK_LABEL (dialog->priv->primary_label), primary_text_markup); secondary_text = csd_ldsm_dialog_get_secondary_text (dialog); gtk_label_set_text (GTK_LABEL (dialog->priv->secondary_label), secondary_text); checkbutton_text = csd_ldsm_dialog_get_checkbutton_text (dialog); gtk_button_set_label (GTK_BUTTON (dialog->priv->ignore_check_button), checkbutton_text); g_free (primary_text); g_free (primary_text_markup); return dialog; } cinnamon-settings-daemon-6.4.3/plugins/housekeeping/csd-disk-space.h0000664000175000017500000000223214733247605024475 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * vim: set et sw=8 ts=8: * * Copyright (c) 2008, Novell, Inc. * * Authors: Vincent Untz * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_DISK_SPACE_H #define __CSD_DISK_SPACE_H #include G_BEGIN_DECLS void csd_ldsm_setup (gboolean check_now); void csd_ldsm_clean (void); /* for the test */ void csd_ldsm_show_empty_trash (void); G_END_DECLS #endif /* __CSD_DISK_SPACE_H */ cinnamon-settings-daemon-6.4.3/plugins/background/0000775000175000017500000000000014733247605021164 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/background/meson.build0000664000175000017500000000164514733247605023334 0ustar fabiofabioplugin_name = 'background' background_sources = [ 'csd-background-manager.c', 'monitor-background.c', 'main.c', ] background_deps = [ cinnamon_desktop, common_dep, csd_dep, libnotify, ] executable( 'csd-background', background_sources, include_directories: [include_dirs, common_inc], dependencies: background_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-background') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-background') endif configure_file( input: 'cinnamon-settings-daemon-background.desktop.in', output: 'cinnamon-settings-daemon-background.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/background/main.c0000664000175000017500000000115514733247605022256 0ustar fabiofabio#define NEW csd_background_manager_new #define START csd_background_manager_start #define STOP csd_background_manager_stop #define MANAGER CsdBackgroundManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-background-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/background/cinnamon-settings-daemon-background.desktop.in0000664000175000017500000000034414733247605032203 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - background Exec=csd-background OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/background/monitor-background.h0000664000175000017500000000135114733247605025141 0ustar fabiofabio#pragma once #include #include G_BEGIN_DECLS #define MONITOR_TYPE_BACKGROUND (monitor_background_get_type ()) G_DECLARE_FINAL_TYPE (MonitorBackground, monitor_background, MONITOR, BACKGROUND, GObject) struct _MonitorBackground { GObject parent_instance; GdkMonitor *monitor; GtkWidget *window; GtkWidget *stack; GtkWidget *current; GtkWidget *pending; gboolean valid; gint monitor_index; gint width; gint height; }; MonitorBackground *monitor_background_new (gint index, GdkMonitor *monitor); GtkImage *monitor_background_get_pending_image (MonitorBackground *mb); void monitor_background_show_next_image (MonitorBackground *mb); G_END_DECLS cinnamon-settings-daemon-6.4.3/plugins/background/csd-background-manager.h0000664000175000017500000000462614733247605025643 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_BACKGROUND_MANAGER_H #define __CSD_BACKGROUND_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_BACKGROUND_MANAGER (csd_background_manager_get_type ()) #define CSD_BACKGROUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_BACKGROUND_MANAGER, CsdBackgroundManager)) #define CSD_BACKGROUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_BACKGROUND_MANAGER, CsdBackgroundManagerClass)) #define CSD_IS_BACKGROUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_BACKGROUND_MANAGER)) #define CSD_IS_BACKGROUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_BACKGROUND_MANAGER)) #define CSD_BACKGROUND_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_BACKGROUND_MANAGER, CsdBackgroundManagerClass)) typedef struct CsdBackgroundManagerPrivate CsdBackgroundManagerPrivate; typedef struct { GObject parent; CsdBackgroundManagerPrivate *priv; } CsdBackgroundManager; typedef struct { GObjectClass parent_class; } CsdBackgroundManagerClass; GType csd_background_manager_get_type (void); CsdBackgroundManager * csd_background_manager_new (void); gboolean csd_background_manager_start (CsdBackgroundManager *manager, GError **error); void csd_background_manager_stop (CsdBackgroundManager *manager); G_END_DECLS #endif /* __CSD_BACKGROUND_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/background/csd-background-manager.c0000664000175000017500000003456614733247605025644 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright © 2001 Ximian, Inc. * Copyright (C) 2007 William Jon McCann * Copyright 2007 Red Hat, Inc. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define GNOME_DESKTOP_USE_UNSTABLE_API #include #include #include "cinnamon-settings-profile.h" #include "csd-background-manager.h" #include "monitor-background.h" #define CSD_BACKGROUND_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_BACKGROUND_MANAGER, CsdBackgroundManagerPrivate)) struct CsdBackgroundManagerPrivate { GSettings *settings; GnomeBG *bg; GnomeBGCrossfade *fade; GDBusProxy *proxy; guint proxy_signal_id; GPtrArray *mbs; }; static void csd_background_manager_finalize (GObject *object); static void setup_bg (CsdBackgroundManager *manager); static void connect_screen_signals (CsdBackgroundManager *manager); G_DEFINE_TYPE (CsdBackgroundManager, csd_background_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; static void draw_background_wayland_session (CsdBackgroundManager *manager) { gint i; cinnamon_settings_profile_start (NULL); for (i = 0; i < manager->priv->mbs->len; i++) { GtkImage *image; MonitorBackground *mb = g_ptr_array_index (manager->priv->mbs, i); image = monitor_background_get_pending_image (mb); gnome_bg_create_and_set_gtk_image (manager->priv->bg, image, mb->width, mb->height); g_object_unref (image); monitor_background_show_next_image (mb); } cinnamon_settings_profile_end (NULL); } static void draw_background_x11_session (CsdBackgroundManager *manager) { GdkDisplay *display; cinnamon_settings_profile_start (NULL); display = gdk_display_get_default (); if (display) { GdkScreen *screen; GdkWindow *root_window; cairo_surface_t *surface; screen = gdk_display_get_screen (display, 0); root_window = gdk_screen_get_root_window (screen); surface = gnome_bg_create_surface (manager->priv->bg, root_window, gdk_screen_get_width (screen), gdk_screen_get_height (screen), TRUE); gnome_bg_set_surface_as_root (screen, surface); cairo_surface_destroy (surface); } cinnamon_settings_profile_end (NULL); } static gboolean session_is_wayland (void) { static gboolean session_is_wayland = FALSE; static gsize once_init = 0; if (g_once_init_enter (&once_init)) { const gchar *env = g_getenv ("XDG_SESSION_TYPE"); if (env && g_strcmp0 (env, "wayland") == 0) { session_is_wayland = TRUE; } g_debug ("Session is Wayland? %d", session_is_wayland); g_once_init_leave (&once_init, 1); } return session_is_wayland; } static void draw_background (CsdBackgroundManager *manager) { if (session_is_wayland ()) { draw_background_wayland_session (manager); } else { draw_background_x11_session (manager); } } static void on_bg_transitioned (GnomeBG *bg, CsdBackgroundManager *manager) { draw_background (manager); } static gboolean settings_change_event_cb (GSettings *settings, gpointer keys, gint n_keys, CsdBackgroundManager *manager) { gnome_bg_load_from_preferences (manager->priv->bg, manager->priv->settings); gnome_bg_set_accountsservice_background (gnome_bg_get_filename (manager->priv->bg)); return FALSE; } static void on_screen_size_changed (GdkScreen *screen, CsdBackgroundManager *manager) { draw_background (manager); } static void setup_monitors (CsdBackgroundManager *manager) { GdkDisplay *display; gint i; display = gdk_display_get_default (); g_clear_pointer (&manager->priv->mbs, g_ptr_array_unref); manager->priv->mbs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); for (i = 0; i < gdk_display_get_n_monitors (display); i++) { GdkMonitor *monitor = gdk_display_get_monitor (display, i); MonitorBackground *mb = monitor_background_new (i, monitor); g_ptr_array_add (manager->priv->mbs, mb); } } static void watch_bg_preferences (CsdBackgroundManager *manager) { g_signal_connect (manager->priv->settings, "change-event", G_CALLBACK (settings_change_event_cb), manager); } static void on_bg_changed (GnomeBG *bg, CsdBackgroundManager *manager) { draw_background (manager); } static void setup_bg (CsdBackgroundManager *manager) { if (manager->priv->bg != NULL) return; manager->priv->bg = gnome_bg_new (); g_signal_connect (manager->priv->bg, "changed", G_CALLBACK (on_bg_changed), manager); g_signal_connect (manager->priv->bg, "transitioned", G_CALLBACK (on_bg_transitioned), manager); connect_screen_signals (manager); watch_bg_preferences (manager); gnome_bg_load_from_preferences (manager->priv->bg, manager->priv->settings); gnome_bg_set_accountsservice_background (gnome_bg_get_filename (manager->priv->bg)); } static void setup_bg_and_draw_background (CsdBackgroundManager *manager) { setup_bg (manager); if (session_is_wayland ()) { setup_monitors (manager); } draw_background (manager); } static void disconnect_session_manager_listener (CsdBackgroundManager *manager) { if (manager->priv->proxy && manager->priv->proxy_signal_id) { g_signal_handler_disconnect (manager->priv->proxy, manager->priv->proxy_signal_id); manager->priv->proxy_signal_id = 0; } } static void on_session_manager_signal (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { CsdBackgroundManager *manager = CSD_BACKGROUND_MANAGER (user_data); if (g_strcmp0 (signal_name, "SessionRunning") == 0) { setup_bg_and_draw_background (manager); disconnect_session_manager_listener (manager); } } static void draw_background_after_session_loads (CsdBackgroundManager *manager) { GError *error = NULL; GDBusProxyFlags flags; GVariant *var = NULL; gboolean running = FALSE; flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START; manager->priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, flags, NULL, /* GDBusInterfaceInfo */ "org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", NULL, /* GCancellable */ &error); if (manager->priv->proxy == NULL) { g_warning ("Could not listen to session manager: %s", error->message); g_error_free (error); return; } var = g_dbus_proxy_call_sync (manager->priv->proxy, "IsSessionRunning", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); if (var != NULL) { g_variant_get (var, "(b)", &running); g_variant_unref (var); } if (running) { setup_bg_and_draw_background (manager); } else { manager->priv->proxy_signal_id = g_signal_connect (manager->priv->proxy, "g-signal", G_CALLBACK (on_session_manager_signal), manager); } } static void disconnect_screen_signals (CsdBackgroundManager *manager) { GdkDisplay *display; display = gdk_display_get_default (); if (display) { GdkScreen *screen; screen = gdk_display_get_screen (display, 0); g_signal_handlers_disconnect_by_func (screen, G_CALLBACK (on_screen_size_changed), manager); } } static void connect_screen_signals (CsdBackgroundManager *manager) { GdkDisplay *display; display = gdk_display_get_default (); if (display) { GdkScreen *screen; screen = gdk_display_get_screen (display, 0); g_signal_connect (screen, "monitors-changed", G_CALLBACK (on_screen_size_changed), manager); g_signal_connect (screen, "size-changed", G_CALLBACK (on_screen_size_changed), manager); } } gboolean csd_background_manager_start (CsdBackgroundManager *manager, GError **error) { g_debug ("Starting background manager"); cinnamon_settings_profile_start (NULL); manager->priv->settings = g_settings_new ("org.cinnamon.desktop.background"); draw_background_after_session_loads (manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_background_manager_stop (CsdBackgroundManager *manager) { CsdBackgroundManagerPrivate *p = manager->priv; g_debug ("Stopping background manager"); disconnect_screen_signals (manager); if (manager->priv->proxy) { disconnect_session_manager_listener (manager); g_object_unref (manager->priv->proxy); } g_signal_handlers_disconnect_by_func (manager->priv->settings, settings_change_event_cb, manager); g_clear_pointer (&manager->priv->mbs, g_ptr_array_unref); g_clear_object (&p->settings); g_clear_object (&p->bg); } static GObject * csd_background_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) { CsdBackgroundManager *background_manager; background_manager = CSD_BACKGROUND_MANAGER (G_OBJECT_CLASS (csd_background_manager_parent_class)->constructor (type, n_construct_properties, construct_properties)); return G_OBJECT (background_manager); } static void csd_background_manager_class_init (CsdBackgroundManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructor = csd_background_manager_constructor; object_class->finalize = csd_background_manager_finalize; g_type_class_add_private (klass, sizeof (CsdBackgroundManagerPrivate)); } static void csd_background_manager_init (CsdBackgroundManager *manager) { manager->priv = CSD_BACKGROUND_MANAGER_GET_PRIVATE (manager); } static void csd_background_manager_finalize (GObject *object) { CsdBackgroundManager *background_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_BACKGROUND_MANAGER (object)); background_manager = CSD_BACKGROUND_MANAGER (object); g_return_if_fail (background_manager->priv != NULL); G_OBJECT_CLASS (csd_background_manager_parent_class)->finalize (object); } CsdBackgroundManager * csd_background_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_BACKGROUND_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_BACKGROUND_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/background/monitor-background.c0000664000175000017500000001103314733247605025132 0ustar fabiofabio #include #include #include #include #include #include #include #include #include "monitor-background.h" G_DEFINE_TYPE (MonitorBackground, monitor_background, G_TYPE_OBJECT) enum { INVALIDATED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0 }; static void invalidate_mb (MonitorBackground *mb) { mb->valid = FALSE; g_signal_emit (mb, signals[INVALIDATED], 0); } static void on_gdk_monitor_dispose (gpointer data, GObject *monitor) { MonitorBackground *mb = MONITOR_BACKGROUND (data); invalidate_mb (mb); } static void on_gdk_monitor_invalidate (gpointer data) { MonitorBackground *mb = MONITOR_BACKGROUND (data); invalidate_mb (mb); } static void on_window_realized (GtkWidget *widget, gpointer user_data) { MonitorBackground *mb = MONITOR_BACKGROUND (user_data); GdkRectangle geometry; gdk_monitor_get_geometry (mb->monitor, &geometry); gdk_window_move (gtk_widget_get_window (widget), geometry.x, geometry.y); } static void build_monitor_background (MonitorBackground *mb) { GdkRectangle geometry; mb->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint (GTK_WINDOW (mb->window), GDK_WINDOW_TYPE_HINT_DESKTOP); // Set keep below so muffin recognizes the backgrounds and keeps them // at the bottom of the bottom window layer (under file managers, etc..) gtk_window_set_keep_below (GTK_WINDOW (mb->window), TRUE); mb->stack = gtk_stack_new (); g_object_set (mb->stack, "transition-duration", 500, "transition-type", GTK_STACK_TRANSITION_TYPE_CROSSFADE, NULL); gtk_container_add (GTK_CONTAINER (mb->window), mb->stack); gdk_monitor_get_geometry (mb->monitor, &geometry); mb->width = geometry.width; mb->height = geometry.height; gtk_window_set_default_size (GTK_WINDOW (mb->window), geometry.width, geometry.height); g_signal_connect (mb->window, "realize", G_CALLBACK (on_window_realized), mb); gtk_widget_show_all (mb->window); } static void monitor_background_init (MonitorBackground *mb) { mb->valid = TRUE; } static void monitor_background_dispose (GObject *object) { g_debug ("MonitorBackground dispose (%p)", object); G_OBJECT_CLASS (monitor_background_parent_class)->dispose (object); } static void monitor_background_finalize (GObject *object) { g_debug ("MonitorBackground finalize (%p)", object); // MonitorBackground *mb = MONITOR_BACKGROUND (object); G_OBJECT_CLASS (monitor_background_parent_class)->finalize (object); } static void monitor_background_class_init (MonitorBackgroundClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = monitor_background_dispose; gobject_class->finalize = monitor_background_finalize; signals[INVALIDATED] = g_signal_new ("invalidated", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); } MonitorBackground * monitor_background_new (gint index, GdkMonitor *monitor) { MonitorBackground *mb = g_object_new (monitor_background_get_type (), NULL); mb->monitor_index = index; mb->monitor = monitor; g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) on_gdk_monitor_dispose, mb); g_signal_connect_swapped (monitor, "invalidate", G_CALLBACK (on_gdk_monitor_invalidate), mb); build_monitor_background (mb); return mb; } GtkImage * monitor_background_get_pending_image (MonitorBackground *mb) { if (!mb->valid) { g_warning ("Asked for pending image when monitor is no longer valid"); return NULL; } if (!mb->pending) { mb->pending = gtk_image_new (); gtk_container_add (GTK_CONTAINER (mb->stack), mb->pending); gtk_widget_show (mb->pending); } return GTK_IMAGE (g_object_ref (mb->pending)); } void monitor_background_show_next_image (MonitorBackground *mb) { g_return_if_fail (mb->pending != NULL); if (!mb->valid) { g_warning ("Asked for pending image when monitor is no longer valid"); return; } GtkWidget *tmp; tmp = mb->current; mb->current = mb->pending; mb->pending = tmp; gtk_stack_set_visible_child (GTK_STACK (mb->stack), mb->current); } cinnamon-settings-daemon-6.4.3/plugins/clipboard/0000775000175000017500000000000014733247605021004 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/plugins/clipboard/cinnamon-settings-daemon-clipboard.desktop.in0000664000175000017500000000034214733247605031641 0ustar fabiofabio[Desktop Entry] Type=Application Name=Cinnamon Settings Daemon - clipboard Exec=csd-clipboard OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Phase=Initialization X-GNOME-Autostart-Notify=true X-GNOME-AutoRestart=true cinnamon-settings-daemon-6.4.3/plugins/clipboard/meson.build0000664000175000017500000000160614733247605023151 0ustar fabiofabioplugin_name = 'clipboard' clipboard_sources = [ 'csd-clipboard-manager.c', 'list.c', 'xutils.c', 'main.c', ] clipboard_deps = [ common_dep, csd_dep, libnotify, ] executable( 'csd-clipboard', clipboard_sources, include_directories: [include_dirs, common_inc], dependencies: clipboard_deps, c_args: [ '-DG_LOG_DOMAIN="csd-@0@"'.format(plugin_name), '-DPLUGIN_NAME="@0@"'.format(plugin_name), ], install: true, install_dir: libexecdir, ) meson.add_install_script(ln_script, libexecdir, bindir, 'csd-clipboard') if libexecdir != pkglibdir meson.add_install_script(ln_script, libexecdir, pkglibdir, 'csd-clipboard') endif configure_file( input: 'cinnamon-settings-daemon-clipboard.desktop.in', output: 'cinnamon-settings-daemon-clipboard.desktop', configuration: desktop_conf, install_dir: autostartdir, ) cinnamon-settings-daemon-6.4.3/plugins/clipboard/main.c0000664000175000017500000000115014733247605022071 0ustar fabiofabio#define NEW csd_clipboard_manager_new #define START csd_clipboard_manager_start #define STOP csd_clipboard_manager_stop #define MANAGER CsdClipboardManager // Setting this to TRUE makes the plugin register // with CSM before starting. // Setting this to FALSE makes CSM wait for the plugin to be started // before initializing the next phase. #define REGISTER_BEFORE_STARTING TRUE // Setting this to TRUE makes the plugin force GDK_SCALE=1 #define FORCE_GDK_SCALE TRUE // This plugin must run under x11/xwayland #define FORCE_X11_BACKEND TRUE #include "csd-clipboard-manager.h" #include "daemon-skeleton-gtk.h" cinnamon-settings-daemon-6.4.3/plugins/clipboard/xutils.c0000664000175000017500000000675614733247605022516 0ustar fabiofabio/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #include #include "xutils.h" Atom XA_ATOM_PAIR; Atom XA_CLIPBOARD_MANAGER; Atom XA_CLIPBOARD; Atom XA_DELETE; Atom XA_INCR; Atom XA_INSERT_PROPERTY; Atom XA_INSERT_SELECTION; Atom XA_MANAGER; Atom XA_MULTIPLE; Atom XA_NULL; Atom XA_SAVE_TARGETS; Atom XA_TARGETS; Atom XA_TIMESTAMP; unsigned long SELECTION_MAX_SIZE = 0; void init_atoms (Display *display) { unsigned long max_request_size; if (SELECTION_MAX_SIZE > 0) return; XA_ATOM_PAIR = XInternAtom (display, "ATOM_PAIR", False); XA_CLIPBOARD_MANAGER = XInternAtom (display, "CLIPBOARD_MANAGER", False); XA_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); XA_DELETE = XInternAtom (display, "DELETE", False); XA_INCR = XInternAtom (display, "INCR", False); XA_INSERT_PROPERTY = XInternAtom (display, "INSERT_PROPERTY", False); XA_INSERT_SELECTION = XInternAtom (display, "INSERT_SELECTION", False); XA_MANAGER = XInternAtom (display, "MANAGER", False); XA_MULTIPLE = XInternAtom (display, "MULTIPLE", False); XA_NULL = XInternAtom (display, "NULL", False); XA_SAVE_TARGETS = XInternAtom (display, "SAVE_TARGETS", False); XA_TARGETS = XInternAtom (display, "TARGETS", False); XA_TIMESTAMP = XInternAtom (display, "TIMESTAMP", False); max_request_size = XExtendedMaxRequestSize (display); if (max_request_size == 0) max_request_size = XMaxRequestSize (display); SELECTION_MAX_SIZE = max_request_size - 100; if (SELECTION_MAX_SIZE > 262144) SELECTION_MAX_SIZE = 262144; } typedef struct { Window window; Atom timestamp_prop_atom; } TimeStampInfo; static Bool timestamp_predicate (Display *display, XEvent *xevent, XPointer arg) { TimeStampInfo *info = (TimeStampInfo *)arg; if (xevent->type == PropertyNotify && xevent->xproperty.window == info->window && xevent->xproperty.atom == info->timestamp_prop_atom) return True; return False; } Time get_server_time (Display *display, Window window) { unsigned char c = 'a'; XEvent xevent; TimeStampInfo info; info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); info.window = window; XChangeProperty (display, window, info.timestamp_prop_atom, info.timestamp_prop_atom, 8, PropModeReplace, &c, 1); XIfEvent (display, &xevent, timestamp_predicate, (XPointer)&info); return xevent.xproperty.time; } cinnamon-settings-daemon-6.4.3/plugins/clipboard/list.h0000664000175000017500000000356614733247605022142 0ustar fabiofabio/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #ifndef LIST_H #define LIST_H typedef struct _List List; typedef void (*Callback) (void *data, void *user_data); struct _List { void *data; List *next; }; typedef int (*ListFindFunc) (void *data, void *user_data); void list_foreach (List *list, Callback func, void *user_data); List *list_prepend (List *list, void *data); void list_free (List *list); List *list_find (List *list, ListFindFunc func, void *user_data); List *list_remove (List *list, void *data); int list_length (List *list); List *list_copy (List *list); #endif /* LIST_H */ cinnamon-settings-daemon-6.4.3/plugins/clipboard/list.c0000664000175000017500000000550414733247605022127 0ustar fabiofabio/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #include #include void list_foreach (List *list, Callback func, void *user_data) { while (list) { func (list->data, user_data); list = list->next; } } List * list_prepend (List *list, void *data) { List *link; link = (List *) malloc (sizeof (List)); link->next = list; link->data = data; return link; } void list_free (List *list) { while (list) { List *next = list->next; free (list); list = next; } } List * list_find (List *list, ListFindFunc func, void *user_data) { List *tmp; for (tmp = list; tmp; tmp = tmp->next) { if ((*func) (tmp->data, user_data)) break; } return tmp; } List * list_remove (List *list, void *data) { List *tmp, *prev; prev = NULL; for (tmp = list; tmp; tmp = tmp->next) { if (tmp->data == data) { if (prev) prev->next = tmp->next; else list = tmp->next; free (tmp); break; } prev = tmp; } return list; } int list_length (List *list) { List *tmp; int length; length = 0; for (tmp = list; tmp; tmp = tmp->next) length++; return length; } List * list_copy (List *list) { List *new_list = NULL; if (list) { List *last; new_list = (List *) malloc (sizeof (List)); new_list->data = list->data; new_list->next = NULL; last = new_list; list = list->next; while (list) { last->next = (List *) malloc (sizeof (List)); last = last->next; last->data = list->data; list = list->next; } last->next = NULL; } return new_list; } cinnamon-settings-daemon-6.4.3/plugins/clipboard/csd-clipboard-manager.c0000664000175000017500000011533614733247605025277 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 Matthias Clasen * Copyright (C) 2007 Anders Carlsson * Copyright (C) 2007 Rodrigo Moya * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xutils.h" #include "list.h" #include "cinnamon-settings-profile.h" #include "csd-clipboard-manager.h" #define CSD_CLIPBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CSD_TYPE_CLIPBOARD_MANAGER, CsdClipboardManagerPrivate)) struct CsdClipboardManagerPrivate { guint start_idle_id; Display *display; Window window; Time timestamp; List *contents; List *conversions; Window requestor; Atom property; Time time; }; typedef struct { unsigned char *data; unsigned long length; Atom target; Atom type; int format; int refcount; } TargetData; typedef struct { Atom target; TargetData *data; Atom property; Window requestor; int offset; } IncrConversion; static void csd_clipboard_manager_finalize (GObject *object); static void clipboard_manager_watch_cb (CsdClipboardManager *manager, Window window, Bool is_start, long mask, void *cb_data); G_DEFINE_TYPE (CsdClipboardManager, csd_clipboard_manager, G_TYPE_OBJECT) static gpointer manager_object = NULL; /* We need to use reference counting for the target data, since we may * need to keep the data around after losing the CLIPBOARD ownership * to complete incremental transfers. */ static TargetData * target_data_ref (TargetData *data) { data->refcount++; return data; } static void target_data_unref (TargetData *data) { data->refcount--; if (data->refcount == 0) { free (data->data); free (data); } } static void conversion_free (IncrConversion *rdata) { if (rdata->data) { target_data_unref (rdata->data); } free (rdata); } static void send_selection_notify (CsdClipboardManager *manager, Bool success) { XSelectionEvent notify; notify.type = SelectionNotify; notify.serial = 0; notify.send_event = True; notify.display = manager->priv->display; notify.requestor = manager->priv->requestor; notify.selection = XA_CLIPBOARD_MANAGER; notify.target = XA_SAVE_TARGETS; notify.property = success ? manager->priv->property : None; notify.time = manager->priv->time; gdk_x11_display_error_trap_push (gdk_display_get_default ()); XSendEvent (manager->priv->display, manager->priv->requestor, False, NoEventMask, (XEvent *)¬ify); XSync (manager->priv->display, False); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); } static void finish_selection_request (CsdClipboardManager *manager, XEvent *xev, Bool success) { XSelectionEvent notify; notify.type = SelectionNotify; notify.serial = 0; notify.send_event = True; notify.display = xev->xselectionrequest.display; notify.requestor = xev->xselectionrequest.requestor; notify.selection = xev->xselectionrequest.selection; notify.target = xev->xselectionrequest.target; notify.property = success ? xev->xselectionrequest.property : None; notify.time = xev->xselectionrequest.time; gdk_x11_display_error_trap_push (gdk_display_get_default ()); XSendEvent (xev->xselectionrequest.display, xev->xselectionrequest.requestor, False, NoEventMask, (XEvent *) ¬ify); XSync (manager->priv->display, False); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); } static gsize clipboard_bytes_per_item (int format) { switch (format) { case 8: return sizeof (char); case 16: return sizeof (short); case 32: return sizeof (long); default: ; } return 0; } static void free_contents (CsdClipboardManager *manager) { list_foreach (manager->priv->contents, (Callback)target_data_unref, NULL); list_free (manager->priv->contents); manager->priv->contents = NULL; } static void save_targets (CsdClipboardManager *manager, Atom *save_targets, int nitems) { int nout, i; Atom *multiple; TargetData *tdata; multiple = (Atom *) malloc (2 * nitems * sizeof (Atom)); nout = 0; for (i = 0; i < nitems; i++) { if (save_targets[i] != XA_TARGETS && save_targets[i] != XA_MULTIPLE && save_targets[i] != XA_DELETE && save_targets[i] != XA_INSERT_PROPERTY && save_targets[i] != XA_INSERT_SELECTION && save_targets[i] != XA_PIXMAP) { tdata = (TargetData *) malloc (sizeof (TargetData)); tdata->data = NULL; tdata->length = 0; tdata->target = save_targets[i]; tdata->type = None; tdata->format = 0; tdata->refcount = 1; manager->priv->contents = list_prepend (manager->priv->contents, tdata); multiple[nout++] = save_targets[i]; multiple[nout++] = save_targets[i]; } } XFree (save_targets); XChangeProperty (manager->priv->display, manager->priv->window, XA_MULTIPLE, XA_ATOM_PAIR, 32, PropModeReplace, (const unsigned char *) multiple, nout); free (multiple); XConvertSelection (manager->priv->display, XA_CLIPBOARD, XA_MULTIPLE, XA_MULTIPLE, manager->priv->window, manager->priv->time); } static int find_content_target (TargetData *tdata, Atom target) { return tdata->target == target; } static int find_content_type (TargetData *tdata, Atom type) { return tdata->type == type; } static int find_conversion_requestor (IncrConversion *rdata, XEvent *xev) { return (rdata->requestor == xev->xproperty.window && rdata->property == xev->xproperty.atom); } static void get_property (TargetData *tdata, CsdClipboardManager *manager) { Atom type; int format; unsigned long length; unsigned long remaining; unsigned char *data; XGetWindowProperty (manager->priv->display, manager->priv->window, tdata->target, 0, 0x1FFFFFFF, True, AnyPropertyType, &type, &format, &length, &remaining, &data); if (type == None) { manager->priv->contents = list_remove (manager->priv->contents, tdata); free (tdata); } else if (type == XA_INCR) { tdata->type = type; tdata->length = 0; XFree (data); } else { tdata->type = type; tdata->data = data; tdata->length = length * clipboard_bytes_per_item (format); tdata->format = format; } } static Bool receive_incrementally (CsdClipboardManager *manager, XEvent *xev) { List *list; TargetData *tdata; Atom type; int format; unsigned long length, nitems, remaining; unsigned char *data; if (xev->xproperty.window != manager->priv->window) return False; list = list_find (manager->priv->contents, (ListFindFunc) find_content_target, (void *) xev->xproperty.atom); if (!list) return False; tdata = (TargetData *) list->data; if (tdata->type != XA_INCR) return False; XGetWindowProperty (xev->xproperty.display, xev->xproperty.window, xev->xproperty.atom, 0, 0x1FFFFFFF, True, AnyPropertyType, &type, &format, &nitems, &remaining, &data); length = nitems * clipboard_bytes_per_item (format); if (length == 0) { tdata->type = type; tdata->format = format; if (!list_find (manager->priv->contents, (ListFindFunc) find_content_type, (void *)XA_INCR)) { /* all incremental transfers done */ send_selection_notify (manager, True); manager->priv->requestor = None; } XFree (data); } else { if (!tdata->data) { tdata->data = data; tdata->length = length; } else { tdata->data = realloc (tdata->data, tdata->length + length + 1); memcpy (tdata->data + tdata->length, data, length + 1); tdata->length += length; XFree (data); } } return True; } static Bool send_incrementally (CsdClipboardManager *manager, XEvent *xev) { List *list; IncrConversion *rdata; unsigned long length; unsigned long items; unsigned char *data; gsize bytes_per_item; list = list_find (manager->priv->conversions, (ListFindFunc) find_conversion_requestor, xev); if (list == NULL) return False; rdata = (IncrConversion *) list->data; bytes_per_item = clipboard_bytes_per_item (rdata->data->format); if (bytes_per_item == 0) return False; data = rdata->data->data + rdata->offset; length = rdata->data->length - rdata->offset; if (length > SELECTION_MAX_SIZE) length = SELECTION_MAX_SIZE; rdata->offset += length; items = length / bytes_per_item; XChangeProperty (manager->priv->display, rdata->requestor, rdata->property, rdata->data->type, rdata->data->format, PropModeAppend, data, items); if (length == 0) { clipboard_manager_watch_cb (manager, rdata->requestor, False, PropertyChangeMask, NULL); manager->priv->conversions = list_remove (manager->priv->conversions, rdata); conversion_free (rdata); } return True; } static void convert_clipboard_manager (CsdClipboardManager *manager, XEvent *xev) { Atom type = None; int format; unsigned long nitems; unsigned long remaining; Atom *targets = NULL; if (xev->xselectionrequest.target == XA_SAVE_TARGETS) { if (manager->priv->requestor != None || manager->priv->contents != NULL) { /* We're in the middle of a conversion request, or own * the CLIPBOARD already */ finish_selection_request (manager, xev, False); } else { gdk_x11_display_error_trap_push (gdk_display_get_default ()); clipboard_manager_watch_cb (manager, xev->xselectionrequest.requestor, True, StructureNotifyMask, NULL); XSelectInput (manager->priv->display, xev->xselectionrequest.requestor, StructureNotifyMask); XSync (manager->priv->display, False); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ()) != Success) return; gdk_x11_display_error_trap_push (gdk_display_get_default ()); if (xev->xselectionrequest.property != None) { XGetWindowProperty (manager->priv->display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, 0, 0x1FFFFFFF, False, XA_ATOM, &type, &format, &nitems, &remaining, (unsigned char **) &targets); if (gdk_x11_display_error_trap_pop (gdk_display_get_default ()) != Success) { if (targets) XFree (targets); return; } } manager->priv->requestor = xev->xselectionrequest.requestor; manager->priv->property = xev->xselectionrequest.property; manager->priv->time = xev->xselectionrequest.time; if (type == None) XConvertSelection (manager->priv->display, XA_CLIPBOARD, XA_TARGETS, XA_TARGETS, manager->priv->window, manager->priv->time); else save_targets (manager, targets, nitems); } } else if (xev->xselectionrequest.target == XA_TIMESTAMP) { XChangeProperty (manager->priv->display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_INTEGER, 32, PropModeReplace, (unsigned char *) &manager->priv->timestamp, 1); finish_selection_request (manager, xev, True); } else if (xev->xselectionrequest.target == XA_TARGETS) { int n_targets = 0; Atom tgets[3]; tgets[n_targets++] = XA_TARGETS; tgets[n_targets++] = XA_TIMESTAMP; tgets[n_targets++] = XA_SAVE_TARGETS; XChangeProperty (manager->priv->display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_ATOM, 32, PropModeReplace, (unsigned char *) tgets, n_targets); finish_selection_request (manager, xev, True); } else finish_selection_request (manager, xev, False); } static void convert_clipboard_target (IncrConversion *rdata, CsdClipboardManager *manager) { TargetData *tdata; Atom *targets; int n_targets; List *list; unsigned long items; XWindowAttributes atts; if (rdata->target == XA_TARGETS) { n_targets = list_length (manager->priv->contents) + 2; targets = (Atom *) malloc (n_targets * sizeof (Atom)); n_targets = 0; targets[n_targets++] = XA_TARGETS; targets[n_targets++] = XA_MULTIPLE; for (list = manager->priv->contents; list; list = list->next) { tdata = (TargetData *) list->data; targets[n_targets++] = tdata->target; } XChangeProperty (manager->priv->display, rdata->requestor, rdata->property, XA_ATOM, 32, PropModeReplace, (unsigned char *) targets, n_targets); free (targets); } else { gsize bytes_per_item; /* Convert from stored CLIPBOARD data */ list = list_find (manager->priv->contents, (ListFindFunc) find_content_target, (void *) rdata->target); /* We got a target that we don't support */ if (!list) return; tdata = (TargetData *)list->data; if (tdata->type == XA_INCR) { /* we haven't completely received this target yet */ rdata->property = None; return; } bytes_per_item = clipboard_bytes_per_item (tdata->format); if (bytes_per_item == 0) return; rdata->data = target_data_ref (tdata); items = tdata->length / bytes_per_item; if (tdata->length <= SELECTION_MAX_SIZE) XChangeProperty (manager->priv->display, rdata->requestor, rdata->property, tdata->type, tdata->format, PropModeReplace, tdata->data, items); else { /* start incremental transfer */ rdata->offset = 0; gdk_x11_display_error_trap_push (gdk_display_get_default ()); XGetWindowAttributes (manager->priv->display, rdata->requestor, &atts); clipboard_manager_watch_cb (manager, rdata->requestor, True, PropertyChangeMask, NULL); XSelectInput (manager->priv->display, rdata->requestor, atts.your_event_mask | PropertyChangeMask); XChangeProperty (manager->priv->display, rdata->requestor, rdata->property, XA_INCR, 32, PropModeReplace, (unsigned char *) &items, 1); XSync (manager->priv->display, False); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); } } } static void collect_incremental (IncrConversion *rdata, CsdClipboardManager *manager) { if (rdata->offset >= 0) manager->priv->conversions = list_prepend (manager->priv->conversions, rdata); else { if (rdata->data) { target_data_unref (rdata->data); rdata->data = NULL; } free (rdata); } } static void convert_clipboard (CsdClipboardManager *manager, XEvent *xev) { List *list; List *conversions; IncrConversion *rdata; Atom type; int format; unsigned long i, nitems; unsigned long remaining; Atom *multiple; conversions = NULL; type = None; if (xev->xselectionrequest.target == XA_MULTIPLE) { XGetWindowProperty (xev->xselectionrequest.display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, 0, 0x1FFFFFFF, False, XA_ATOM_PAIR, &type, &format, &nitems, &remaining, (unsigned char **) &multiple); if (type != XA_ATOM_PAIR || nitems == 0) { if (multiple) free (multiple); return; } for (i = 0; i < nitems; i += 2) { rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); rdata->requestor = xev->xselectionrequest.requestor; rdata->target = multiple[i]; rdata->property = multiple[i+1]; rdata->data = NULL; rdata->offset = -1; conversions = list_prepend (conversions, rdata); } } else { multiple = NULL; rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); rdata->requestor = xev->xselectionrequest.requestor; rdata->target = xev->xselectionrequest.target; rdata->property = xev->xselectionrequest.property; rdata->data = NULL; rdata->offset = -1; conversions = list_prepend (conversions, rdata); } list_foreach (conversions, (Callback) convert_clipboard_target, manager); if (conversions->next == NULL && ((IncrConversion *) conversions->data)->property == None) { finish_selection_request (manager, xev, False); } else { if (multiple) { i = 0; for (list = conversions; list; list = list->next) { rdata = (IncrConversion *)list->data; multiple[i++] = rdata->target; multiple[i++] = rdata->property; } XChangeProperty (xev->xselectionrequest.display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_ATOM_PAIR, 32, PropModeReplace, (unsigned char *) multiple, nitems); } finish_selection_request (manager, xev, True); } list_foreach (conversions, (Callback) collect_incremental, manager); list_free (conversions); if (multiple) free (multiple); } static Bool clipboard_manager_process_event (CsdClipboardManager *manager, XEvent *xev) { Atom type; int format; unsigned long nitems; unsigned long remaining; Atom *targets; targets = NULL; switch (xev->xany.type) { case DestroyNotify: if (xev->xdestroywindow.window == manager->priv->requestor) { free_contents (manager); clipboard_manager_watch_cb (manager, manager->priv->requestor, False, 0, NULL); manager->priv->requestor = None; } break; case PropertyNotify: if (xev->xproperty.state == PropertyNewValue) { return receive_incrementally (manager, xev); } else { return send_incrementally (manager, xev); } case SelectionClear: if (xev->xany.window != manager->priv->window) return False; if (xev->xselectionclear.selection == XA_CLIPBOARD_MANAGER) { /* We lost the manager selection */ if (manager->priv->contents) { free_contents(manager); XSetSelectionOwner (manager->priv->display, XA_CLIPBOARD, None, manager->priv->time); } return True; } if (xev->xselectionclear.selection == XA_CLIPBOARD) { /* We lost the clipboard selection */ free_contents(manager); clipboard_manager_watch_cb (manager, manager->priv->requestor, False, 0, NULL); manager->priv->requestor = None; return True; } break; case SelectionNotify: if (xev->xany.window != manager->priv->window) return False; if (xev->xselection.selection == XA_CLIPBOARD) { /* a CLIPBOARD conversion is done */ if (xev->xselection.property == XA_TARGETS) { XGetWindowProperty (xev->xselection.display, xev->xselection.requestor, xev->xselection.property, 0, 0x1FFFFFFF, True, XA_ATOM, &type, &format, &nitems, &remaining, (unsigned char **) &targets); save_targets (manager, targets, nitems); } else if (xev->xselection.property == XA_MULTIPLE) { List *tmp; tmp = list_copy (manager->priv->contents); list_foreach (tmp, (Callback) get_property, manager); list_free (tmp); manager->priv->time = xev->xselection.time; XSetSelectionOwner (manager->priv->display, XA_CLIPBOARD, manager->priv->window, manager->priv->time); if (manager->priv->property != None) XChangeProperty (manager->priv->display, manager->priv->requestor, manager->priv->property, XA_ATOM, 32, PropModeReplace, (unsigned char *)&XA_NULL, 1); if (!list_find (manager->priv->contents, (ListFindFunc)find_content_type, (void *)XA_INCR)) { /* all transfers done */ send_selection_notify (manager, True); clipboard_manager_watch_cb (manager, manager->priv->requestor, False, 0, NULL); manager->priv->requestor = None; } } else if (xev->xselection.property == None) { send_selection_notify (manager, False); free_contents (manager); clipboard_manager_watch_cb (manager, manager->priv->requestor, False, 0, NULL); manager->priv->requestor = None; } return True; } break; case SelectionRequest: if (xev->xany.window != manager->priv->window) { return False; } if (xev->xselectionrequest.selection == XA_CLIPBOARD_MANAGER) { convert_clipboard_manager (manager, xev); return True; } else if (xev->xselectionrequest.selection == XA_CLIPBOARD) { convert_clipboard (manager, xev); return True; } break; default: ; } return False; } static GdkFilterReturn clipboard_manager_event_filter (GdkXEvent *xevent, GdkEvent *event, CsdClipboardManager *manager) { if (clipboard_manager_process_event (manager, (XEvent *)xevent)) { return GDK_FILTER_REMOVE; } else { return GDK_FILTER_CONTINUE; } } static void clipboard_manager_watch_cb (CsdClipboardManager *manager, Window window, Bool is_start, long mask, void *cb_data) { GdkWindow *gdkwin; GdkDisplay *display; display = gdk_display_get_default (); gdkwin = gdk_x11_window_lookup_for_display (display, window); if (is_start) { if (gdkwin == NULL) { gdkwin = gdk_x11_window_foreign_new_for_display (display, window); } else { g_object_ref (gdkwin); } gdk_window_add_filter (gdkwin, (GdkFilterFunc)clipboard_manager_event_filter, manager); } else { if (gdkwin == NULL) { return; } gdk_window_remove_filter (gdkwin, (GdkFilterFunc)clipboard_manager_event_filter, manager); g_object_unref (gdkwin); } } static gboolean start_clipboard_idle_cb (CsdClipboardManager *manager) { XClientMessageEvent xev; cinnamon_settings_profile_start (NULL); init_atoms (manager->priv->display); /* check if there is a clipboard manager running */ if (XGetSelectionOwner (manager->priv->display, XA_CLIPBOARD_MANAGER)) { g_warning ("Clipboard manager is already running."); return FALSE; } manager->priv->contents = NULL; manager->priv->conversions = NULL; manager->priv->requestor = None; manager->priv->window = XCreateSimpleWindow (manager->priv->display, DefaultRootWindow (manager->priv->display), 0, 0, 10, 10, 0, WhitePixel (manager->priv->display, DefaultScreen (manager->priv->display)), WhitePixel (manager->priv->display, DefaultScreen (manager->priv->display))); clipboard_manager_watch_cb (manager, manager->priv->window, True, PropertyChangeMask, NULL); XSelectInput (manager->priv->display, manager->priv->window, PropertyChangeMask); manager->priv->timestamp = get_server_time (manager->priv->display, manager->priv->window); XSetSelectionOwner (manager->priv->display, XA_CLIPBOARD_MANAGER, manager->priv->window, manager->priv->timestamp); /* Check to see if we managed to claim the selection. If not, * we treat it as if we got it then immediately lost it */ if (XGetSelectionOwner (manager->priv->display, XA_CLIPBOARD_MANAGER) == manager->priv->window) { xev.type = ClientMessage; xev.window = DefaultRootWindow (manager->priv->display); xev.message_type = XA_MANAGER; xev.format = 32; xev.data.l[0] = manager->priv->timestamp; xev.data.l[1] = XA_CLIPBOARD_MANAGER; xev.data.l[2] = manager->priv->window; xev.data.l[3] = 0; /* manager specific data */ xev.data.l[4] = 0; /* manager specific data */ XSendEvent (manager->priv->display, DefaultRootWindow (manager->priv->display), False, StructureNotifyMask, (XEvent *)&xev); } else { clipboard_manager_watch_cb (manager, manager->priv->window, False, 0, NULL); /* FIXME: manager->priv->terminate (manager->priv->cb_data); */ } cinnamon_settings_profile_end (NULL); manager->priv->start_idle_id = 0; return FALSE; } gboolean csd_clipboard_manager_start (CsdClipboardManager *manager, GError **error) { cinnamon_settings_profile_start (NULL); manager->priv->start_idle_id = g_idle_add ((GSourceFunc) start_clipboard_idle_cb, manager); cinnamon_settings_profile_end (NULL); return TRUE; } void csd_clipboard_manager_stop (CsdClipboardManager *manager) { g_debug ("Stopping clipboard manager"); if (manager->priv->window != None) { clipboard_manager_watch_cb (manager, manager->priv->window, FALSE, 0, NULL); XDestroyWindow (manager->priv->display, manager->priv->window); manager->priv->window = None; } if (manager->priv->conversions != NULL) { list_foreach (manager->priv->conversions, (Callback) conversion_free, NULL); list_free (manager->priv->conversions); manager->priv->conversions = NULL; } if (manager->priv->contents != NULL) { free_contents (manager); } } static void csd_clipboard_manager_class_init (CsdClipboardManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_clipboard_manager_finalize; g_type_class_add_private (klass, sizeof (CsdClipboardManagerPrivate)); } static void csd_clipboard_manager_init (CsdClipboardManager *manager) { manager->priv = CSD_CLIPBOARD_MANAGER_GET_PRIVATE (manager); manager->priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); } static void csd_clipboard_manager_finalize (GObject *object) { CsdClipboardManager *clipboard_manager; g_return_if_fail (object != NULL); g_return_if_fail (CSD_IS_CLIPBOARD_MANAGER (object)); clipboard_manager = CSD_CLIPBOARD_MANAGER (object); g_return_if_fail (clipboard_manager->priv != NULL); csd_clipboard_manager_stop(clipboard_manager); if (clipboard_manager->priv->start_idle_id !=0) { g_source_remove (clipboard_manager->priv->start_idle_id); clipboard_manager->priv->start_idle_id = 0; } G_OBJECT_CLASS (csd_clipboard_manager_parent_class)->finalize (object); } CsdClipboardManager * csd_clipboard_manager_new (void) { if (manager_object != NULL) { g_object_ref (manager_object); } else { manager_object = g_object_new (CSD_TYPE_CLIPBOARD_MANAGER, NULL); g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); } return CSD_CLIPBOARD_MANAGER (manager_object); } cinnamon-settings-daemon-6.4.3/plugins/clipboard/csd-clipboard-manager.h0000664000175000017500000000456314733247605025303 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2007 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CSD_CLIPBOARD_MANAGER_H #define __CSD_CLIPBOARD_MANAGER_H #include G_BEGIN_DECLS #define CSD_TYPE_CLIPBOARD_MANAGER (csd_clipboard_manager_get_type ()) #define CSD_CLIPBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSD_TYPE_CLIPBOARD_MANAGER, CsdClipboardManager)) #define CSD_CLIPBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSD_TYPE_CLIPBOARD_MANAGER, CsdClipboardManagerClass)) #define CSD_IS_CLIPBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSD_TYPE_CLIPBOARD_MANAGER)) #define CSD_IS_CLIPBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSD_TYPE_CLIPBOARD_MANAGER)) #define CSD_CLIPBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CSD_TYPE_CLIPBOARD_MANAGER, CsdClipboardManagerClass)) typedef struct CsdClipboardManagerPrivate CsdClipboardManagerPrivate; typedef struct { GObject parent; CsdClipboardManagerPrivate *priv; } CsdClipboardManager; typedef struct { GObjectClass parent_class; } CsdClipboardManagerClass; GType csd_clipboard_manager_get_type (void); CsdClipboardManager * csd_clipboard_manager_new (void); gboolean csd_clipboard_manager_start (CsdClipboardManager *manager, GError **error); void csd_clipboard_manager_stop (CsdClipboardManager *manager); G_END_DECLS #endif /* __CSD_CLIPBOARD_MANAGER_H */ cinnamon-settings-daemon-6.4.3/plugins/clipboard/xutils.h0000664000175000017500000000334014733247605022505 0ustar fabiofabio/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #ifndef X_UTILS_H #define X_UTILS_H #include extern Atom XA_ATOM_PAIR; extern Atom XA_CLIPBOARD_MANAGER; extern Atom XA_CLIPBOARD; extern Atom XA_DELETE; extern Atom XA_INCR; extern Atom XA_INSERT_PROPERTY; extern Atom XA_INSERT_SELECTION; extern Atom XA_MANAGER; extern Atom XA_MULTIPLE; extern Atom XA_NULL; extern Atom XA_SAVE_TARGETS; extern Atom XA_TARGETS; extern Atom XA_TIMESTAMP; extern unsigned long SELECTION_MAX_SIZE; void init_atoms (Display *display); Time get_server_time (Display *display, Window window); #endif /* X_UTILS_H */ cinnamon-settings-daemon-6.4.3/debian/0000775000175000017500000000000014733247605016606 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/meson.build0000664000175000017500000001225014733247605017526 0ustar fabiofabioproject('cinnamon-settings-daemon', 'c', version : '6.4.3', meson_version : '>=0.56.0') gnome = import('gnome') i18n = import('i18n') pkg = import('pkgconfig') version = meson.project_version() pkgname = meson.project_name().to_lower() api_version = '3.0' cc = meson.get_compiler('c') cargs = [] # directories prefix = get_option('prefix') bindir = get_option('bindir') datadir = get_option('datadir') libdir = get_option('libdir') libexecdir = get_option('libexecdir') includedir = get_option('includedir') desktopdir = join_paths(datadir, 'applications') schemadir = join_paths(datadir, 'glib-2.0', 'schemas') pkglibdir = join_paths(libdir, pkgname) apilibdir = join_paths(libdir, '@0@-@1@'.format(pkgname, api_version)) pkgdatadir = join_paths(datadir, pkgname) gtkbuilderdir = join_paths(prefix, datadir, pkgname) pkgincludedir = join_paths(includedir, pkgname) localedir = join_paths(prefix, datadir, 'locale') polkitdir = join_paths(datadir, 'polkit-1', 'actions') sysconfdir = get_option('sysconfdir') autostartdir = join_paths(sysconfdir, 'xdg', 'autostart') dbusservicedir = get_option('dbus_service_dir') if dbusservicedir == '' dbusservicedir = join_paths(datadir, 'dbus-1', 'system-services') endif dbussystemdir = get_option('dbus_system_dir') if dbussystemdir == '' dbussystemdir = join_paths(datadir, 'dbus-1', 'system.d') endif # dependencies cinnamon_desktop_required = '>= 4.8.0' canberra = dependency('libcanberra-gtk3') cinnamon_desktop = dependency('cinnamon-desktop', version: cinnamon_desktop_required) colord = dependency('colord', version: '>= 0.1.27', required: get_option('use_color')) cups = dependency('cups', version: '>= 1.4', required: get_option('use_cups')) cvc = dependency('cvc', version: cinnamon_desktop_required) fontconfig = dependency('fontconfig') gio = dependency('gio-2.0', version: '>= 2.40.0') gio_unix = dependency('gio-unix-2.0', version: '>= 2.40.0') glib = dependency('glib-2.0', version: '>= 2.40.0') gnomekbd_required = '>= 3.6.0' gnomekbd = dependency('libgnomekbd', version: gnomekbd_required) gnomekbdui = dependency('libgnomekbdui', version: gnomekbd_required) gtk = dependency('gtk+-3.0', version: '>= 3.14.0') gudev = dependency('gudev-1.0', required: get_option('use_gudev')) libnotify = dependency('libnotify', version: '>= 0.7.3') kbproto = dependency('kbproto') nss = dependency('nss', version: '>= 3.11.2', required: get_option('use_smartcard')) pango = dependency('pango', version: '>= 1.20.0') polkit = dependency('polkit-gobject-1', version: '>= 0.97', required: get_option('use_polkit')) pulse_required = '>= 0.9.16' pulse = dependency('libpulse', version: pulse_required) upower_glib = dependency('upower-glib', version: '>= 0.9.11') wacom = dependency('libwacom', version: '>= 0.7', required: get_option('use_wacom')) x11 = dependency('x11') xext = dependency('xext') xfixes = dependency('xfixes') xi = dependency('xi') xklavier = dependency('libxklavier', version: '>= 5.0') # currently only used for the wacom plugin librsvg = dependency('librsvg-2.0', version: '>= 2.36.2', required: wacom.found()) lcms = dependency('lcms2', required: colord.found()) if lcms.version().version_compare('>=2.2') cargs += '-DHAVE_NEW_LCMS' endif using_logind = false if not get_option('use_logind').disabled() logind = dependency('libsystemd-logind', required: false) if not logind.found() logind = dependency('libsystemd', required: false) endif if not logind.found() # if logind is explicitly enabled, we want to make sure it gives an error if we don't find anything logind = dependency('libelogind', required: get_option('use_logind')) endif if logind.found() cargs += '-DHAVE_LOGIND' using_logind = true endif endif cc = meson.get_compiler('c') math = cc.find_library('m', required: false) has_timerfd_create = cc.has_function('timerfd_create') csd_conf = configuration_data() csd_conf.set_quoted('GTKBUILDERDIR', gtkbuilderdir) csd_conf.set_quoted('CINNAMON_SETTINGS_LOCALEDIR', localedir) csd_conf.set_quoted('PACKAGE', meson.project_name()) csd_conf.set_quoted('PACKAGE_NAME', meson.project_name()) csd_conf.set_quoted('PACKAGE_VERSION', meson.project_version()) csd_conf.set_quoted('GETTEXT_PACKAGE', meson.project_name()) csd_conf.set_quoted('LIBEXECDIR', join_paths(prefix, libexecdir)) csd_conf.set_quoted('SYSCONFDIR', sysconfdir) csd_conf.set_quoted('LIBDIR', libdir) csd_conf.set10('HAVE_TIMERFD', has_timerfd_create) if gudev.found() cargs += '-DHAVE_GUDEV' endif if wacom.found() cargs += '-DHAVE_WACOM' endif if not get_option('enable_debug') cargs += [ '-Wno-deprecated-declarations', '-Wno-deprecated', '-Wno-declaration-after-statement', '-DGLIB_DISABLE_DEPRECATION_WARNINGS', ] endif add_global_arguments( cargs, language: 'c' ) # generate config.h config_h_file = configure_file( output : 'config.h', configuration : csd_conf ) config_h = declare_dependency( sources: config_h_file ) include_dirs = include_directories('.', 'cinnamon-settings-daemon') subdir('data') subdir('cinnamon-settings-daemon') subdir('plugins') install_subdir( 'files/usr', install_dir: prefix, strip_directory: true, ) subdir('install-scripts') cinnamon-settings-daemon-6.4.3/files/0000775000175000017500000000000014733247605016466 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/0000775000175000017500000000000014733247605017277 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/0000775000175000017500000000000014733247605020401 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/0000775000175000017500000000000014733247605021514 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/0000775000175000017500000000000014733247605023153 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/0000775000175000017500000000000014733247605024721 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/0000775000175000017500000000000014733247605025664 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-housekeeping.svg0000664000175000017500000010612714733247605031651 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-datetime.svg0000664000175000017500000012776014733247605030765 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-color.svg0000664000175000017500000030762514733247605030307 0ustar fabiofabio image/svg+xml Lapo Calamandrei keyboard keys configure cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-wacom.svg0000664000175000017500000022137514733247605030274 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-clipboard.svg0000664000175000017500000004073414733247605031123 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-mouse.svg0000664000175000017500000002777014733247605030321 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-xrandr.svg0000664000175000017500000002436014733247605030457 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-media-keys.svg0000664000175000017500000012210314733247605031203 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-a11y-settings.svg0000664000175000017500000002475114733247605031576 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-keyboard.svg0000664000175000017500000011030514733247605030754 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-sound.svg0000664000175000017500000003535514733247605030317 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-orientation.svg0000664000175000017500000002436014733247605031514 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-cursor.svg0000664000175000017500000004073414733247605030501 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-xsettings.svg0000664000175000017500000003471714733247605031220 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-a11y-keyboard.svg0000664000175000017500000002475114733247605031536 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-screensaver-proxy.svg0000664000175000017500000006605314733247605032665 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-background.svg0000664000175000017500000012055014733247605031276 0ustar fabiofabio image/svg+xml ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootcinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-print-notifications.svgcinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-print-notifications.s0000664000175000017500000021537514733247605032637 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-automount.svg0000664000175000017500000005116714733247605031221 0ustar fabiofabio image/svg+xml cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-power.svg0000664000175000017500000003045114733247605030313 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/scalable/apps/csd-printer.svg0000664000175000017500000065744714733247605030666 0ustar fabiofabio cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/0000775000175000017500000000000014733247605023736 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/0000775000175000017500000000000014733247605024701 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-screensaver-proxy.png0000664000175000017500000000243514733247605031661 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<šIDATH‰µ•Ý•ÕÆkíý¾œ3ƒÌ(#™`!±ˆdŠÑ¦A 7Ú´·½hŒ‘peœ´^xcâ`ƒzݤá¢ü $ƒ%´ã’ah‚L†af„r3{ïµ·ï9Æñ¢Mt%o²÷›ìçYk=ë~f€C‡µ;öV]×ý !„ËSSS>uêÔmüÉ“'ÿ¶oß¾?™ÙZv‘5÷º®ñÞ¯,¥¬ûwæÌ™¿>|øˆêãC!fffùúìD…[Ö=üq+”%žüõ~&'÷RÚÔ£äœùòËó¼}ìTU…sŠª®ñ^yýõ—×—R(¥ÐéÞáôéÏÙ³g71FÄÄé§§ª*ªÊ㜃{R4::Ìþý{@À••p/¹Rj0ÌŒcã@ÎYJ)8çîz.‚““sôèøÕ½8§8çð¾âêÕy¦§Ï±p}™Ò‹"ƈsŽœ39gP@RJäœQ@u¨8ž~úqÞüëkì}l7)EVWWév»˜%¶nã¹ç²mÛý„U#†LXÍxïÉ9“RH)afxï©ëµo11±•¿¼úªBsçf™zå ¦^yƒ‹/c¤”ÂÁ§ÐÚP7$1ã]MJ©OÐD`f’sFÅS¹!êªÅï~ÿ Þ{B„8ýɼtäyŽù#}8MJ‰#"°ë‘í¤XH¡à]™Ý¹Ÿ"çuµ§ÊÞ½¿$„FÈ……E¾ýÏÓÿ:‹—/_gaa‘‘‘6ã޲ºjdkt4³A „€™áÔá}ˆ02²i@ðÁûÿdvf™Ù™%DÇÇ~Ƴ¿ý ­V“"²àœÇÌo}¯¬š9OUµR¸uëÃÃí^*[›UDUáæÍÛº.%Tç‚^ФÈÌPQ¼«Q.ÌÎñؾ]ƒ:jÕ8UT§BXYaee€K—®P‹…Ú»5"÷ ¤¯×šª®9óéyv?º€_ìxûÚc Š ¨#cŽN§ƒª2óÕEZUK‰Ê4DpO8¼sÔ•²tÝ8ýÉç<þÄ$ÛǘØÎ:ëv»\ü÷Öñ m¼êjÈâ !ˆ™!Î ^•ªÞÈô§W¸Ó½Ã'&ñÞ­·dœýâ8Sh¶‘Ÿµ>èÅ#ž!1*C´Ö  ªÄœ3fŠK¦i÷ñ 1ï*(½†'+‰¢f¨UrΈÖMȪJ)òÜó/\¹§lFEÁOt§á˜à¾5M÷ò>}Zî9|øð›ÝnwûíHzõêÕ_:ôêÉ“'׈sssïLOO¿âî·#?!Ξ=ûî¾}ûF ãî;ʲäĉ/™ŸŸ‡|‹™œ˜`ï{q÷ûN$¥$îÎü… |òÑ1Dä–òçœyæ¹ìy|)%$”e‰™!"×Å–-[nxû7af”eYÑR ¶ÕlÚ´‰}ÈÐÐÐMu¡ª¸;)¥Ðˆ™áî„Ú÷xš‰‰ žÚÿ$!(ªŠj¬"(!„¤2„€»cfÌ 3k;FFG8ÿÓyFGG‰«ö‘ZÿLΙœœ3žfUµÍ×v°‘" U¥sŸgê¡)>;þ9EQcA, Š"cA ŠØ©Þµ ƈHø;EU)%*€Š‚¨‘Tý~+3wŽŒ !–?VW(Ë’Ò¤”êªK2¹ 03bT¢*#åÔ©ï¸Ü» ƒrÀ (Ë+t»w°¶¶†»Wô˜ažHõ$šÙõf&M¡î ÆÈ™ÎÐë÷Ú‘´¦§¨“;&‚X¥OÔØˆ,Z‘U#ÉŒÕõUÎýxKV‹€dˆE‡"v07\ ±ê[Î׋ʲlE^[ûÏÎÎv²²²Z™-–[®€B+уÌCõž kÅ‚»S–ehZxv’%:EŠÒï]!Æ*¢è u•ÝN—á{†yt×4ã;îãÈ{°°°€{$ÖS´Ñ’R3«JU¥ˆ4(C#Cܽu3““<2ý03»fkuyþ…gyéÅ—9}ê{4ÆFdiÇÔÝÅÝ Z9´ ex¸KÔHÊâÂ2¿^:ÍW_|ƒy"„ÌÌc3lß¾#ïϲ²¼J×|àî×DÎ9‹»U‚—~¾Tª6S¬V„Jå äëßV|§¡^t @ÎY'“s®}P\³»2äLµ{›ý“!C@&W«£ÎkŠrÎ퉻«»355Éëo¼†»#‘€  4Vn€½.†ú4059IÿJw×F_ZZZvwÖ{ëlÝvï òfÎzoaqqñwÀ#Л}k0ŒŒoVU©ƒB{WU‘z?眳™åÚPÙÝÛ»™å‹/.=zôm ×쯸 þOåohXÊ¿ŽÅ:Õ‡ô'vIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-orientation.png0000664000175000017500000000213514733247605030512 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ÚIDATH‰µ”Ík^UÆsæÜ÷µ$$fSµ¶ÅÔ×$é®ÖUQKñ ]õ/((‚ ¡{‚XãG»RÔŠZ¨ÕÒ•ÝXšUµ4Ƽ}Û÷ž™ãâ~4µ.l­ç^æ™yžyþç#»wï>|øð›ÝnwûíHzõêÕ_:ôêÉ“'׈sssïLOO¿âî·#?!Ξ=ûî¾}ûF ãî;ʲäĉ/™ŸŸ‡|‹™œ˜`ï{q÷ûN$¥$îÎü… |òÑ1Dä–òçœyæ¹ìy|)%$”e‰™!"×Å–-[nxû7af”eYÑR ¶ÕlÚ´‰}ÈÐÐÐMu¡ª¸;)¥Ðˆ™áî„Ú÷xš‰‰ žÚÿ$!(ªŠj¬"(!„¤2„€»cfÌ 3k;FFG8ÿÓyFGG‰«ö‘ZÿLΙœœ3žfUµÍ×v°‘" U¥sŸgê¡)>;þ9EQcA, Š"cA ŠØ©Þµ ƈHø;EU)%*€Š‚¨‘Tý~+3wŽŒ !–?VW(Ë’Ò¤”êªK2¹ 03bT¢*#åÔ©ï¸Ü» ƒrÀ (Ë+t»w°¶¶†»Wô˜ažHõ$šÙõf&M¡î ÆÈ™ÎÐë÷Ú‘´¦§¨“;&‚X¥OÔØˆ,Z‘U#ÉŒÕõUÎýxKV‹€dˆE‡"v07\ ±ê[Î׋ʲlE^[ûÏÎÎv²²²Z™-–[®€B+уÌCõž kÅ‚»S–ehZxv’%:EŠÒï]!Æ*¢è u•ÝN—á{†yt×4ã;îãÈ{°°°€{$ÖS´Ñ’R3«JU¥ˆ4(C#Cܽu3““<2ý03»fkuyþ…gyéÅ—9}ê{4ÆFdiÇÔÝÅÝ Z9´ ex¸KÔHÊâÂ2¿^:ÍW_|ƒy"„ÌÌc3lß¾#ïϲ²¼J×|àî×DÎ9‹»U‚—~¾Tª6S¬V„Jå äëßV|§¡^t @ÎY'“s®}P\³»2äLµ{›ý“!C@&W«£ÎkŠrÎ퉻«»355Éëo¼†»#‘€  4Vn€½.†ú4059IÿJw×F_ZZZvwÖ{ëlÝvï òfÎzoaqqñwÀ#Л}k0ŒŒoVU©ƒB{WU‘z?眳™åÚPÙÝÛ»™å‹/.=zôm ×쯸 þOåohXÊ¿ŽÅ:Õ‡ô'vIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-a11y-keyboard.png0000664000175000017500000000225014733247605030526 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<%IDATH‰µ•]ˆUUÇkŸs㌣ãhNˆS”†’HêC_¾(TøAÑôâC…O}ÐKA`R¾hS f‘b™†eÖC~æèÌ8&MÎ9{­ÕÃ>sïÜ 2¨ ›s¹g¯ÿ¯õÿ¯uà^°nÝCí[^zñ™­­½ÿèõZmàÕ¶=qèPÿoä;vöáªË7Fõ«üKT/æ™pìø‰ŸÞt令f![\¨ñÆž#\›$ˆ "7Æâ¹ÓÕ^eóë ![Ts@ 5qwF®Õ˜Ñ6›,Bø+{™áßüojÆÈè5ÜBMÉÜÜKGÄ©' íyÁÖM+h›ÑÊ+aðzÖD"’bÝ=a™4ª8Ž›ãn˜•[{Yw ¯w=s;YÓ׎Em¼/Ï»[ÂÀѨân%«áª8¦Wâ»ÓÃŒ×&¨VrŽœ<ƒùܺª^ ìj¸•XnÔK¤E”$’¢ªXQã™õ}ŒŽM2puœ‹¿N2pe6<ÿ™€Ì¾‰Eó ;+,êl¥»c&;>=…JsÅ=aÖ3ˆnI(UÔ‘ÝûsÏÊ[ylý]ôtw¡j\Án^0<Ͻ6Æ'¿¦ÿ·LÄ9Hžaª¸;±)M¨F4*Y¨0$=ì:z•ûw±¸CØòøîXÚÀ¹ ƒ¼öîGü0t–޲Ê|$Õ˜4ФA°²nª†j:¤j ­ ¢›ó—®Ôõ830Ì©ñZæôB¨”q±ŒMXfÆT‰0M%R3Ô"^štJdwCB“óQWÄ|šÈŽYÂHåžFP¨Š{*QŒJ¤©™Üjž×ƒ³,£–Þo4›ZÂHÖ°)îZg5SÄ› Ä V-¿½¾Äܹïî•H<Š…J•ith=1+ ÌШøŸ2XÖÓBG{ïí;†šñàkY:¿…fó²áK,ɦÑê.Šªd>}Ö8ë–-áÀáo8;šîôùWÇY{û"Ž_ü‰éc·^"œÓ,*]ä‚;jŠÆdUÓ´µ¨qÿêå¼½ç $T±³ÿ ë×܉µÆ¹XÆ–sÍ̸9# –Æ5BWUùñÔ9NdÕtüÄÅg¾Ä¬`ŒFÅ)Çu‰áÖ?‰ŒaîD5,d!Ô '"›_ï§:kcŠÊ*<µý}ò™í„Lê:5 Ýq6W î°°«‘Q „is?«Rÿ¦•·099 L&×” Ñ;¿#õ…Z˜Ù._úE oÛ““-ëþ䯖7=`hpà `dYÖ²áÑg·n_ÜwKwÈ‚äAY&éË$„@žB™’¹{l|<•F=šcj~þÌéË»Þ|ù9Õ‰½Sw¬=À¬¼ó?­1`(þw…邆œùIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-xsettings.png0000664000175000017500000000201714733247605030206 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<ŒIDATH‰µ•OK3WÆw&ŽRƒ¤¦š@Z¯È*ˆ~¿@Wý Å•ô´ÐÅû]›…; ˆ;Á˜i ‰wî½ÝxÇ[xßB{á03—¹ç9çyÎ9þç%¶·· ûûû¿ÌÍÍÕþ §“ÉävooïçÓÓÓgä~o6›?*¥Þ‘…øWN1É»ëº\\\|ÞÝÝý)xRÊï___ÇN‡J¥Âòò2J)Éår_Ç1Q¡”úðr€ˆãX(¥B „àúúšb±ˆÖšÉd‚ÖšÑhÄËË ½^Z-Ëäíí-¥R‰|>çyŒÇcâ8€p´ÖcÐZ3 ØÙÙaii‰§§'Œ1(¥0Ɔ!ívcLÆÚí6a&>ìÀR:J)´ÖA€RŠççgÂ0$Žc´Öï'ù¶æ86P¥q#¥t,E¤)ÒZãº.RÊŒ£4@z¥Ò €È¤\×emmñxÌÍÍÍß2°¤—­8KMÇ ÉÀ±AÐétR2QJaéû§ úý>[[[äóyz½¥RÉfà$"K)GÅb‘ÃÃC.//Y__OœÌÀZÄqÌp8$‚„")å»ÈÖ¹RŠZ­†ïû¬®®ây^BÑG¾Óôh­B$šYÊÓ"•"áÓZ¿ßgaaV«Å`0Hö­fFƒétšœSJ «AFdcLò´Õ ”¢ÛíR.—x||Ä÷}€Œf£Ñ(8-2i‘?X“R"„H±´•ËeŽ©×ëlnn¦Ëô½¬ÈÖ±å9 0Ni4äóyÎÎ΀F£Áýý=+++xž— ÈöAf¥5°?ÚYtuu…çy„aHµZ͈o‰t£e†]¥RÁuÝ„­5œŸŸÓíviµZ™Êr]7éä”vï"€™™™ŒZkfggi6›ÌÏÏS¯×3écÏñv™96=ël2™`þøÌŸ77™*RJáy¾ïg´QJáû~¿í{eF@.—£ðí'D¥Â4ŽBE¥R)i´ôÍg÷lFQYz«~xxxJ§ml€Ö 5žçEÝn—/-c žçQ(ˆ¢¨èðrttôët:ý¦Z­–ÇÁqayuG¼í%¼&ÕåÆ^°ÿב¿Ïœ®"¨‚ˆÚ^¬-¡îŽ;˜Á­³fuΛ· ûî;¾ ¬Ë¬V­–Àywã[Gêµá¡,WrÉÈr%E5CriÇÁ7#DÇ1bˆä“§t}ðÑg‹«¡Þd9 Ñ ªµj(‰XäY¢)Ï•ÆJA †QrÇ‚"â„`H¦ŒW«Q<€än©£LAD!Ï!!R$o!ÈÈð „Ü äJ†j¡ŸE 9G¢™K¡¤ŠðäSkg?ûÂk«4K¦j13‘¢ƒ×j`׎-?ýpÓïY,ÞD€§j* (soŸß=é†ÎòÕ)¯Œ2“'wp[Oï4UMª EÎvŠT™h”+bÿÞ~×·uïµþeš‰ˆ"–ÌZyÓÍÚ´f{ôûíÏá‘¡±êh¥62<4ÖìÐÀð塱{î[¹ ±F5-š¤0qAQ4kR;€Fé7ßÒµ»oËácöœWÁŽºðôs¯¯hoBD&d°ØB€aÎu¢T*—¦Ní.×ëc1ל)]Ý“ÊW‰¨’4ÌSÎT „ëj98ðÇ?sæÎ¿iÖìW».]¡ÉFÎ4î×EлðÞ¹û~þþÐØèÈø‹îŸÏ;Ü=y¥øîEÁ$rôæAeÖ¾h¢M--:¾F;'18*’æ AÃ8zäà…¥«×\¤”çÚ9åÆÎ׆FÚ{ÑÙ©ã‡Ï[Ñ ãXÊY ZS@Œo¶}yúÛ¾­[JYÆâåMãí÷Ÿˆ1Ư>ÿø§í_|r"-u<Áœ‰¤‰ƒ”7;`î4@Z0‚(N¤RÝüΛ»÷ýòùöíÁ Žy ˜cf¸7ŠVÌš2G‚KŠºqfpplÃ+Ïl8UQKnŽ˜1€»a±1b¤Jù8y®±^Ë 3!ãÔÉ㣹 ’©¨i‹Kšy4‚AŒ†™AÖ¡^PØ( µzÝݵë^º} ÿÄ*频”0k;cLj·ìHtKÝ™ÓÓ3Œz­Þy|ç×»N.[¾bÉÊÕÏXõÀš"Ò¼‰%±©@ómÉ ›£Ý©ŽŽoÛÙwÒ¶yÏœ>­K5¥Î²âÖ–¬ª©³–O­PÓ ã3Ξ½8T©T¶ÇÛç¨|¥&ÿ!PøjÝ“òî]¶IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-housekeeping.png0000664000175000017500000000174314733247605030651 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<`IDATH‰µ•MhœeÇ3ûîÆ|˜¤µFi4&‚ˆ­b©ÅS/^õ`/âÑ“(žz¼x¨x¶=© (-±” Ò‚V„Ô i‰­iØ&ÙìGvßgæñ°ßi%¤Ä—çåùÏÌÿ?3üÏ&/=¹èÓãÇ?ìK²ìh-¤×Þ=9·°ZJ€äƒÃÏ|òÔúµ·©VöúyÿÐáÁ¹…Ùw G©ô¸%Õ½Ø,‘ 6 ä@ÒŠ‰ßVÙœùÜ}¼X[e(É´ÏÓ €Ç$î<d„ùdŒcå› „€ºšî¾‚`ü80Êtñ&ý"˜u0BêÚ –,³û}Õy³RÀs½ X EQj&f»£¨dÎl2Äê“j˜IÏÿ´yÒT-«;‚F`%D†.zŽ«DN¤d²±‡hS$M ’,8iÃä5b¢ Ä-ž÷ &·'5Dv‹;RT~¥P¨³¦ŠHd8ùÊûx5ÖÈk/En±M!5BøoŠÊÙ÷Ú1>>:ÍÌ·WøüŸÔEY3á¬d™J+Í ‰­0!5:"o÷zˆ¬çrìã&ž} Þzý9¾þèed¨ÕjäT ºQI½}·[d, b!Ûθæ™gäéƒL™"É%cC噜ÈóÝ©Ìÿ²ÄÕ…¿IÎýC5‚hDUȈ`ièt‘™K÷Ô-òè+G{(ßá)Æ_Û¬pè‰ ç%xd+÷$JD1"f.€( !xE9à·o.ã6á›UX06+)õÍ-®_^DòªôGÁ›!t`Å‚ÓrÎàï7˜ÿbž•¥U̬§Š•[e†û9wæ<3*<¬Jb‘n kv‘ÄMt»º3py‘+§ç°º5º"B±¼Eu+å§³?óÀ¥Eö!l¿kæÄæcÖš,ÜyF–×ùþ½3胣ŒÍ`­¨Ü(2þÇõÆ‚ó;ßóæ\5Dv×n‘·Û¸KX*ZÒo_ÝfÞY¾â-s¿»Gç6Se9xð(Ÿ.OÕáÞɾ¾qQE3UDT%“$ˆ*ª}àî1ºc!@ó;ºãf1ºóW¥ºòeqó3 Üšì,p?0´7%PV€ô_»ÉŸ€ IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-sound.png0000664000175000017500000000262614733247605027314 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<IDATH‰µ•ÍoTׯçÜO{ìÆx<ŽqÓ4îŠäŠRE¡´°Hý"›ÐM‘ˆ²ÊE–]E RXd…*«êׂ,AXªJ«ײÓ‚#+Ä™±‡áÎܯsÎíÆwb’MUµG:Ò«{î}Þû¼Ïû>þÏK8p`ìܹsïØ¶ý,€â¿Ëó¥ÔúåË—ß ‚ ´ûÔ©S¿B¼EBˆáþO’ yž·ëºœõÞnpc Q‘¦éàڀȲLc†I)‘RA'''™™™aß¾}lll°±±A»ÝÆó<¤”O±0Æe™„½û (‰”’$IáĉŒ±½½Í;w8|ø0Fƒ^¯ÇÍ›7‰¢Ïó0ÆðU< Ë2Y0Èóœ0 ©Õj,,,Ðl6i6›LLLP«Õˆã˜k×®Ñëõ8}ú4Geii‰N§ƒëº»È"ÐZcŒ)BpðàA.]º„ÖšZ­ÆÞ²Í³{`ã2IðIÂââ"+++œ={–ëׯ“eÙGkͰDY– ­5B¶¶¶8~ü87nÜ Iác~þ£Ø÷äwXª‚ï}«Æü‚K‹åÖ­[ÌÎÎ2??O³Ù¤\.£µ.4@î0;q`XÛŸýøyf;àéV9žú‚çzðë_ÆÃÕ«WB`Û6J)´Öh­% ä”RÄqŒçy3†­Û¿¿7ÁZ¯Î'Û{¹ú·*Þž)JnJã…:Žãžç†!Zk”RbØE»N’¥½^¨!XXþËËËüäÈ$n¥„‰ƒ°(0’$awà (¥„1Çqèt:ÌÎÎr÷î]ÖÖ«¼úg ýŒ³?´˜œžÂrK¼þÚs8r‹'b+÷?#MSfffxôè¶mcŒ2Zk¡µFJI§ÓÁqÒ4åÆíðOï§ %%kÀ¯ øÕq‡Q«‹’ ý2ßþ;###ضÍöö6RÊBä/»(Ë2¡”`0Ðív9tèƒÁ€ ÞduôMRYE'OPý/ wÌñÞoÿHÇ,,,Ðív ! ‘‡V! B¦¦¦X]]eÿþý4 VVVx÷Ÿ9öÊwùöóSi±r“æÇEFƒééi‚  R©pæ6NP/ˆBd±3yX–…뺬­­1??O½^gii‰¿|t‹vf$Ë2|ßçØ±cLOO³ººŠã8”J%F²*{Æê<6ÿzª‹„RjhRår™N§C«ÕbnnŽ3gÎÇ1›››ÔëõaK¶Z-Ç¡R©°¹¹‰Ü¬’xƘ/äyŽÖzhT–eQ­V‰ã˜V«…ïûŒ3>>Àúú:aEµZ ß÷éõzœ?€‹/>å¦C«(:©(—”’z½Nš¦„aH»ÝÀ÷}|ß§\.$ ¥R‰+W® „ T* ­ÂL†[h!öW¯Êt÷*n¸"ö<€8Žé÷ûÀØ@ÿÞ½{ïçy>^©T¦vLK·š”RX–5Œw4Ë K.âáÊó<§Ûí~¾¼¼|è¿éu`ŒÿÍ Ïìßùpëåà|±IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-automount.png0000664000175000017500000000162714733247605030217 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<IDATH‰µ•½oUÅwæ/ò‡X,vNXÉÉtôX²HÅß@„å JzÊ4é¨ Uìɲ¥àʉ]8Ùq¼ +Ïî¼/ŠÝ7ÌØãucŽ4ÒÌ›¹çÜóÞÀÿ XYY___ÿ˜àœ#Š"ïœÃ{OXÀø>ò5Á{O–eÏWWW×677;¨ûÍfó‹ëÌ|kkëÇååå/0b­}ÇsüXkßF ƘÈZ{­Y–E€¨W ˆq‡ì(ô¾¡# À9'ÃZ$"$IÂÁÁÞ{æçç1Æ  +@´ÖrY"‚RŠÃÃCZ­V¾Þh4ÐZ_*¢µB‹ŠŠUä­V‹½½=”꾿¿RŠéééKÛe­ŠDU-J’„ÓÓSvvvˆ¢ˆ^¯öÛÛÛ,--199IU¬µö¿ ¼÷*ˆ¢¥ÇÇÇ4œ¸ˆ““êõ:Y–áœ+½+ ¹è¢@ve»Ý&$QçÖÚ á¹ä") 8çØÝÝ-‘ŸZ\\¬´¹1&ŸAiPA$´maa¡D|^Àƒ1æBE›""qØH¡k-išÒl6ñÞçç‰:N¥K.ŠúÈÉà |îœ+]aàUƒÐZÃÀER¯×ç‚@ ™zï‡^!æít·î|ÄÑ«)‘ CÑž‰šâõËl=~<–ùݹ[úþƒŸÐcÛ˜¤ŽM¦ð7ÞÂ×nצˆ’„(‰‰¢`Ó§5ö¬œ#Ý#bÝFé—$é|úɇzsã‘(ÀMNŒ¿X[½÷æ³?Ï8íÆXB[½ï\QAÌ"2KŒf\õøøƒ·ùí×GÏ'ý~öÍwß~ߘ»}óÕë3º™6iÚ3iÚ5Ý^wèŸe$I¤V«©ÑÑDÝH’xjbLÚ'}}ï«5k{?'06ÃH<>«6÷•ÈúÉdöHÿô¿Ù.¿ênªIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-clipboard.png0000664000175000017500000000274114733247605030121 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<^IDATH‰µ•MˆeWÇçã~¼××™qzÌ|ÙŒfc«pˆ %D"ŠAÁ¸’àÖ¥ÙŠà¸VÜ&‚f!!Á•8³Ðé‘V3cwòd¦¿¦_¿{ß}÷œªs\ôLO4[­]-ªêœÿÿGüŸÃ¬­}zñÙo}û;ÎåsÖ.k­1Ö`Ð#9¥wW¬óXg°6gÈ9¥LÒdóGßûîsëë¯5ð_|ö?ˆõé¯ÎIïk¬18ï‰Ú£ßÕßZ‡ËeY’²!ç„HÖ'žxæ«Åús¯}Óeíjô¸XBGY•dÍ8cœ çÿú€Å’I9a2ÄÈYéû@R¥›ë% ´€™ÏgÙXƒ1‡=~MNr$º)£¼Ï()Æ‚³“3d¡ïçH ˆ*} 0 Äæ]GU”8ç06#1D0ÑB† ÌøÚ—žàùÅ-UsL† „Ð#"¨&Rʈȑ”I‚U Ìà QÁZG–ž‹ >~>q‚=.­œEUQU^9ɼÃ峑 Õ.ÍdŸ{’ ª‚hD%ZM ŤLLs¤‡•aËç?û)¬µ<ú‘žñxÌÆÆ>0à+ŸûÄ‘Á)1ûÅ+ü}R–”ª2÷%Š"¨ÆZÈ–¤[Ííl†Š°³³Ã©S§pΠªlnn²¼¼ŒóžÛÛ;ˆyç ¬±Þa\éîIdB×b@’ *¤œ™ô†#ÛÛÛ,//“sæÚõ Ö¯osfyy™ÝÝ]BLæGHû¢ÂZDâ;MžÍÚÜ6‡Ì½%ÇÀc/°²¶J Ñh„ªòâK¯påæ!Þx>ºqƒ§Ÿú ‹‹‹¨O~r­ñ6WßîqE¦DÃ;LNÙ¤œÉšéš†Õ‹çX{ä1FœsN§¬NŸû'ϼõM™N§8çÖ>x‰Õ÷ŸcÖN½«Â]Š<€ñÞ¾Ä[K,J$ ªŠ÷¡ðž‡Q…$ʉª¤( Dk-ªJ •DAS"h¼? «qXÖPÕ5Ï¿ô:Ïü™gž~жm±ÖòøåU®\ß$»ÌÇ]Ńª²°°ÀO~úsþ±µ‹,œa6ï0ÆC4Çú®¡’“bÈd{’k7wÙÛÛgiiDß÷\\9ÏÅ•óÇ«"¥DY–ìííó·qC|¥¥ÆêºÆ{ܼ( ƒÖZ––F\þÐÊ¢Ä:GÒD”@#€±€‰1!ÆHÊ™ªråú7nn26üñOWQ꺦®kbþðƦӆ7oü“ß¾±ŽDÅZKUð¾DEïcª¢&‰PÕ ÔÕA½€8Ïö*K¿Žyüæ˜/á ^øå˼zu“GÎý…Ã>!ÕYºæ²`ŒÇGY ü}ŠŒ±U5Ä%EQ¤§ï,œeÜ5 G7ÞºÍË¿þ )eÞܺÅpôÆsÏ`0b8p89`2¹CQ”eMÊzß䲪óE]Òõ=±ï CʉnÞ0nKÞúý¡ŸáоT¢*Ö´ÍTƒú>0m¬íÐ(ùxÙy[xç ú®gÞÍ0€1ÐÎäÈ,êzˆs4£´wi:`8\D5Q „hg-m3É÷öea×"V J1Hb­P¾‚}éûy)%’$‘{{{¿`'×çá`0è)¥@DâʵãiCôÒâ <óô‘©vu󧈈„R RÊG] §” ˆèhµZÅýûÛžµx]þö»¿Ÿ„À÷}†a ”òˆh;MÓÏh ïS€g)ÿ—°Br‘ÿt$¢PÑïU3IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-keyboard.png0000664000175000017500000000204414733247605027756 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<¡IDATH‰µ•ÏkÛHÇ?M,Û8`Ç$i¡$°ÉÅ…‚Cÿ€†¹ôÔž{éiï=-=…ý² Ùs IÉ5àKHr.-…œ $©‹ÓÖòoÉ–43{‰i -»›} „>~zßÑ{ßÃÿÀêêjissó×|>¿pEÇãñùóçÏ9<<Z€ÜÛÛû£^¯?UJÝD}lÛæÍ›7>~üøg ä‚ ø) Ã) µ&Š¢% 'K)ei­ét:¼{÷.“¬”BeYßeår™z½žÎ±KDQ„֚ׯ_óèÑ#Úí6Æòù<<|øð‡¬Ñh µN¢(@„a(´Ö(¥èõz8ŽC³Ù$—Ë1èõzh­ùðáC†¹®K»Ý&—Ë1ÑZ'W†"°Œ1Ä—”’ÓÓS¾~ýŠã8h­‘R†!•J%Ãúý>“É$aé:Æ’)¥2 q/s¹J)Œ1ÌÍÍQ(( »ÿ>ƒÁ aéÅŽ”€E‘ÐZ3??ÏË—/q!Æ...ØÝÝŶíï²f³ÉÑÑ÷îÝ£\.E‘øfȵZz½Îññ1ëëëø¾ÖšjµÊþþ>kkk?d;;;€••677‰¢€~¿O­VãÁƒì•uvv­5Î9Ò4 pÎiï=A ”b8¢µÎ;°Ö²´´D¯×Ã{OEôz=¬µy"‚RŠ ðÞãœÓ#åœCDò£(¢Ûí¢”ÂC©TâÕ«W>|€V«EE8çr‚r¹Œ÷­u.q.ÑèÅèrff†jµš·þüùs”R ¢(Â{ÏÒÒÒ>Ò4Í%I*MS=ê@DØÙÙáÔ©S4›M¶··òN¼÷t»ÝјžžÎ1Ò4Õy_JÔív‡œ8qçAP(xøð!¥R‰óçÏS¯×¹yó&Fƒ©©)._¾ü5‰ÐY–áœÃƒsŽJ¥‚÷ž ^¿~Í‹/˜œœd0011Áµk×8~ü8wîÜ!Iz½Þ>Œ,Ë>§h4J)D„r¹ÌÖÖišÇ1a2JY†T*ÆÇÇ™œœ R©P.—Ù‹±;0Ù9G§ÓáãÇôû}J¥"B¥RÉï_¾|ɹsç¸qãgÏžennŽ“'O²¹¹ùU“±Öæ&|øðùùyZ­½^¹¹9ƒÅb‘B¡Àõë×s€f³™'ëÈ‘#¹ÖÚÏs "¹É#ö8޹zõ*ƒÁ€§OŸrïÞ=Ž;F,,,H÷kmN°[€ e­U{ ²Öâ½çÛ·™Cþ\_gll çƒÁ€……:‹‹‹Äq @†´Ûí½ Pz׃Üdçãããh­Y{öŒ¿ž<Áƒ1!IÞ¾}KµZeee…jµJ½^Ï ™,"*©÷^í´0 ™ššbbb‚NpôèQŠÅ""BE,//“$ —.]Â9G³Ùäýû÷ìÅðÞN‘÷ž,Ë0Æ`­ÍãV,ù»X¤ßïçZk­i6›(¥¨V«´Z-”R|úô k-Ʋ,Ë'}d²êõ:.\Ø÷ þž¥µ¦^¯“$ "bF&K»ÝÞ:³³³ßü£ùryïét:(¥ØÚÚÚ$’ÕÕÕ_­µcµZmÚ£v7ZëülŒQj—Ù{ïsÞ9‡s΋H~vÎù8ŽÛwïÞý HF¥€ úW¥\=  ¤ÿ³¤a2·êIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-media-keys.png0000664000175000017500000000203114733247605030202 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<–IDATH‰µ•ÍK$GÆUý1ã̈"¨èb„ä".$ƒ‘PPÿ„•ՓלrßSð²â_@½ ñèm‚'ëIAqÃ:‚ÑiVǞœªLÇ !`^(zºŸª÷y?ž·þgKKK•Íb±øÕs8㸾¾¾þÓÞÞÞü_«ÕêJ©çðçyþ¶ººú£„I’|¦é³8ÐZ“eÙ7@èB)%´Öloo322ÂÝÝÆŒ1H)éëë#ÚßçÛJ…8ŽŸà…Bhaï_½B)%ádY†%fyy™(Šœ!¥R €³ùns³'^þðßëuôì,Y– Ò4•Zk´Ö´Z-¢( X,òðð@¡P Ñh$‰Ã›Í&———ØÞÝ6›cÐZ“¦©´¦iA!¾ïszzÊþþ>¾ï†!J)Œ1/—Ëœœœ`Œ! Ct· @)…ÍÀÖÓó<ŽŽŽÐZsyyIdY–ã(bzzš¡¡!‚ pçµÖ.+ ˆ,Ë\‰”RH)BP­VY[[#Š"‚ pH)ñ}ŸóósW2‹[‚,ËdÏ&ch·ÛŒQ«Õ˜ŸŸxTVbee%'Ï8ŽÑ¾o ð­n-AES¯×]4ÆÒ4åúúšB½O»¯ï7Œ!S }v†xù2çÏfàæ ÿüœb³É}«õ˜Q'+€AcÐÅ"õOŸ¿C_©ÄÑ—/ô×jÈZ™jÕf zf0S,2óî]Nç]ªÈý.  Þ¾eda!7ɹ ’$‘öC»ÝÎÍAš¦Aà·Z-Êå²{¿½½%i·CkI’HK º­Î=Ïcww—ññqJ¥qcŒ¡Õj177ç¥iêzÕmw!麋´ÖèŽÎ™¥R©àyRJ7vI)]IºWî.ÒZ [W:a200ÀÁÁ“““!åááß÷]¤žçåúÒ•Á_M6Æ8i­ÎÝ©©)zÙÍÍMwIœcrnÃÝ?è¼W”ð8\÷=šl÷Úÿ§"ýú5ûŸ??î¢gÔ9 Cß¼yB ”rW…¾ººº±¾˜˜àÅÄÄ¿;þ›u!h4Úî·¶¶~N’¤rrr´£ÑQÌ“gÇ™é¨%÷TJ¥ííí_€{[ƒ*ÿ9ôÞv\éŸÏ®­ü½uìIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-a11y-settings.png0000664000175000017500000000225014733247605030566 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<%IDATH‰µ•]ˆUUÇkŸs㌣ãhNˆS”†’HêC_¾(TøAÑôâC…O}ÐKA`R¾hS f‘b™†eÖC~æèÌ8&MÎ9{­ÕÃ>sïÜ 2¨ ›s¹g¯ÿ¯õÿ¯uà^°nÝCí[^zñ™­­½ÿèõZmàÕ¶=qèPÿoä;vöáªË7Fõ«üKT/æ™pìø‰ŸÞt令f![\¨ñÆž#\›$ˆ "7Æâ¹ÓÕ^eóë ![Ts@ 5qwF®Õ˜Ñ6›,Bø+{™áßüojÆÈè5ÜBMÉÜÜKGÄ©' íyÁÖM+h›ÑÊ+aðzÖD"’bÝ=a™4ª8Ž›ãn˜•[{Yw ¯w=s;YÓ׎Em¼/Ï»[ÂÀѨân%«áª8¦Wâ»ÓÃŒ×&¨VrŽœ<ƒùܺª^ ìj¸•XnÔK¤E”$’¢ªXQã™õ}ŒŽM2puœ‹¿N2pe6<ÿ™€Ì¾‰Eó ;+,êl¥»c&;>=…JsÅ=aÖ3ˆnI(UÔ‘ÝûsÏÊ[ylý]ôtw¡j\Án^0<Ͻ6Æ'¿¦ÿ·LÄ9Hžaª¸;±)M¨F4*Y¨0$=ì:z•ûw±¸CØòøîXÚÀ¹ ƒ¼öîGü0t–޲Ê|$Õ˜4ФA°²nª†j:¤j ­ ¢›ó—®Ôõ830Ì©ñZæôB¨”q±ŒMXfÆT‰0M%R3Ô"^štJdwCB“óQWÄ|šÈŽYÂHåžFP¨Š{*QŒJ¤©™Üjž×ƒ³,£–Þo4›ZÂHÖ°)îZg5SÄ› Ä V-¿½¾Äܹïî•H<Š…J•ith=1+ ÌШøŸ2XÖÓBG{ïí;†šñàkY:¿…fó²áK,ɦÑê.Šªd>}Ö8ë–-áÀáo8;šîôùWÇY{û"Ž_ü‰éc·^"œÓ,*]ä‚;jŠÆdUÓ´µ¨qÿêå¼½ç $T±³ÿ ë×܉µÆ¹XÆ–sÍ̸9# –Æ5BWUùñÔ9NdÕtüÄÅg¾Ä¬`ŒFÅ)Çu‰áÖ?‰ŒaîD5,d!Ô '"›_ï§:kcŠÊ*<µý}ò™í„Lê:5 Ýq6W î°°«‘Q „is?«Rÿ¦•·099 L&×” Ñ;¿#õ…Z˜Ù._úE oÛ““-ëþ䯖7=`hpà `dYÖ²áÑg·n_ÜwKwÈ‚äAY&éË$„@žB™’¹{l|<•F=šcj~þÌéË»Þ|ù9Õ‰½Sw¬=À¬¼ó?­1`(þw…邆œùIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-cursor.png0000664000175000017500000000274114733247605027477 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<^IDATH‰µ•MˆeWÇçã~¼××™qzÌ|ÙŒfc«pˆ %D"ŠAÁ¸’àÖ¥ÙŠà¸VÜ&‚f!!Á•8³Ðé‘V3cwòd¦¿¦_¿{ß}÷œªs\ôLO4[­]-ªêœÿÿGüŸÃ¬­}zñÙo}û;ÎåsÖ.k­1Ö`Ð#9¥wW¬óXg°6gÈ9¥LÒdóGßûîsëë¯5ð_|ö?ˆõé¯ÎIïk¬18ï‰Ú£ßÕßZ‡ËeY’²!ç„HÖ'žxæ«Åús¯}Óeíjô¸XBGY•dÍ8cœ çÿú€Å’I9a2ÄÈYéû@R¥›ë% ´€™ÏgÙXƒ1‡=~MNr$º)£¼Ï()Æ‚³“3d¡ïçH ˆ*} 0 Äæ]GU”8ç06#1D0ÑB† ÌøÚ—žàùÅ-UsL† „Ð#"¨&Rʈȑ”I‚U Ìà QÁZG–ž‹ >~>q‚=.­œEUQU^9ɼÃ峑 Õ.ÍdŸ{’ ª‚hD%ZM ŤLLs¤‡•aËç?û)¬µ<ú‘žñxÌÆÆ>0à+ŸûÄ‘Á)1ûÅ+ü}R–”ª2÷%Š"¨ÆZÈ–¤[Ííl†Š°³³Ã©S§pΠªlnn²¼¼ŒóžÛÛ;ˆyç ¬±Þa\éîIdB×b@’ *¤œ™ô†#ÛÛÛ,//“sæÚõ Ö¯osfyy™ÝÝ]BLæGHû¢ÂZDâ;MžÍÚÜ6‡Ì½%ÇÀc/°²¶J Ñh„ªòâK¯påæ!Þx>ºqƒ§Ÿú ‹‹‹¨O~r­ñ6WßîqE¦DÃ;LNÙ¤œÉšéš†Õ‹çX{ä1FœsN§¬NŸû'ϼõM™N§8çÖ>x‰Õ÷ŸcÖN½«Â]Š<€ñÞ¾Ä[K,J$ ªŠ÷¡ðž‡Q…$ʉª¤( Dk-ªJ •DAS"h¼? «qXÖPÕ5Ï¿ô:Ïü™gž~жm±ÖòøåU®\ß$»ÌÇ]Ńª²°°ÀO~úsþ±µ‹,œa6ï0ÆC4Çú®¡’“bÈd{’k7wÙÛÛgiiDß÷\\9ÏÅ•óÇ«"¥DY–ìííó·qC|¥¥ÆêºÆ{ܼ( ƒÖZ––F\þÐÊ¢Ä:GÒD”@#€±€‰1!ÆHÊ™ªråú7nn26üñOWQ꺦®kbþðƦӆ7oü“ß¾±ŽDÅZKUð¾DEïcª¢&‰PÕ ÔÕA½€8Ïö*K¿Žyüæ˜/á ^øå˼zu“GÎý…Ã>!ÕYºæ²`ŒÇGY ü}ŠŒ±U5Ä%EQ¤§ï,œeÜ5 G7ÞºÍË¿þ )eÞܺÅpôÆsÏ`0b8p89`2¹CQ”eMÊzß䲪óE]Òõ=±ï CʉnÞ0nKÞúý¡ŸáоT¢*Ö´ÍTƒú>0m¬íÐ(ùxÙy[xç ú®gÞÍ0€1ÐÎäÈ,êzˆs4£´wi:`8\D5Q „hg-m3É÷<ûïàæªªÁýû÷¿}òäÉ\ýøñãnÞ¼ù•sî?¨”R<þüÇ»wï~­Ì9÷qÛ¶°½½íÿ>Å›qýúuéõz8çpέ™¤m[99dkkËonnú$Id<Ël6“ÃÃCÇ2ŸÏe:Êh4’Åb!ãñX&“‰h­åÁƒ~kkˇ›ÍâÏõõu)Š"^ÖZ#"ÌçsBœµ–¦ibŒRŠÉd‹òà"I’Ä,—ËxñêÕ«²»»‹÷žýý}†Ã!³ÙŒ·½¶išrïÞ=&“ I’ µ&I‘øö;ç¸rå —/_æÙ³g,—K‹UU1N8wîçÏŸçÒ¥Kôû}nܸAžç8çâhCN 0“^¯+òÞ#"ܺu €$Iâ óëMðÞS–e ¶··§£Ñ¨oŒ¡®ëWüüO¡”BkM–eTUÅ`0˜)Ër¶ººêG£‘G’wAHžç9NÇ—e9ãDWUÕ8t÷NYÿUUN‹ïŒ1E§ÓYsÎù0[¥”ˆI’ ”’Ó„¸“Î1îèè¨ÜÙÙùX÷¤@(ÎVò/1€æ‡Ccr̃ûIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-color.png0000664000175000017500000000276714733247605027310 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsrr3À™tEXtSoftwarewww.inkscape.org›î<tEXtAuthorLapo Calamandreiß‘*QIDATH‰TilTUþî»ofÞ¬ƒí°(´UÖX ¥A  5‘b+P$Ѝ1QУ€„þ4‚ÊL —¶lÑ¢–R[°­]PÛB[œ™®Ó™nÓ™Îò¦ïÍ»þ(bQ(Åï×ÍÍ÷s¾sî¹À#Àãñ$¶¶¶Æ>ŠfÌèééI¼Jo_o //O«Ž+‘Rú­¯}á"—ô«²²ü¿2¸Ým³cüÈ»öövKÀߦôÔ¹nŒg­m­ý÷pìv{ŒÓykê¨ÜîÎ-­óû¼§ÓYn·Û€F£Ùî?J(§…†D¬a06=##™1F:;Û_ííímµÆ™¬Mpìß¿ÆÈ˜÷T¡(Ä%¶T‚®åT¶§éÖ|VuûvÓŽcœªOÍ  ¯"sÙ’7»»»³´>áº÷ t#ÓP‚²_˸&°Ùl—„%²B(oî-¾É‚qÖÖ,}Öø÷]¿²x nx«Ô³ 08 2Á|Ó`÷´:ú\}"{ýþqÞk ‚Ga¼yÞ‚­àøXp¼„…3àª'¼© <Õ‚=R-»qáâ¥O+++ýL:A÷Ÿ±S Ò˜a‚`‚ÙשÅ€‚€Gë†Á¬Gx0jÿ<´ß’Ïœ<jÔ!3Æ8I M—¢¨TçžB„•„ú&X”¢GVƒ‹ €#xjÄ_Åñ£Ã庲wïŽÿì§Ói6™ŒÇT”®–jjÕCÕÕP:;Al± B LÔhbà›ªBc’ 0GeCð÷Ç` ¬‡¤D¯KÁlK&ŸvÀíqéêèú0'''JÜn÷ ½F}1ðÅaùùŒFp‚P b6ÂqÈL€™T¨{:½áþ ;¡( "Ë>€ƒÑ^ðÖ'Äe~ðØÑãSøP(4M rre%t[ú$¿5öDôY'ÀW— e|ï&³;í½sŽÐÔõ]DRÂR£­-‰@áéÂìää”/ÔÂ1?¬¹èïl6”˜Ñ 3ƒ€.ª‚nN*­aQ„Êú#"ºbˆJ~2¦Ò0×ø+¿VUuú̹]ÕîÎëÿœ—Çíá¢óR’“Ö'%¦¬›>uFâñ}_'<0Ô›^«CòŒI ` Pq ¶.OÀÙΔØ[n_½V\~¶K– %%»C‰¼¼SÈÎ~ö£¦j{\È+ Â9‚u¸ÉŒÀ yÑ?8)ª€¨k baúÊÕìÙ±ða{@âââ·_)øbP„ qzlÙµ=¾0¼ƒ"¼ƒ"úüxyÙDD$ rtØEa¥³ž˜{pÔç/¥}!“¢DÆÒµéH[“Úý{}­3FKÁ„8*ÊŠÊrçk†&YÔˆH \ÞÒ-NŸŸ™óÀÖËJÊ«ðú¾W°q÷º@Õ­ŠÏ·¿¿sßßwlšÍ„P$Š€8„¹Iñ8wá§½™„Ž+'ßY#oH·Áh²Ò$«íñ‘1ïùM+*jðªß47êkkË«~ILLì®*-zr×¼™½¯èF)x% B!{ƒ½±¦¦°ç“öLšié“‹Ÿ¡ñ Îæ‘1ï·W÷EiYqë¡ï[–Ì™¥ÿSß}¿±¦¦F«þ¡8tø“åÍövæp8äå«W¥ŽUÇ?œ2Œwß~¯8·56µ xõcÕý¥ÉXhŒîÏIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-wacom.png0000664000175000017500000000164714733247605027274 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<$IDATH‰­•½KkYÅûÜ›5¾$EÄBœŠ BÒ¨££ ‚`§(BlL?µÅtƒZ<Aìý¢XD”d?´‰F2(!3Ìx?Κ˜yÏ÷Œ¾·ÊË9k­½÷Úç ÏP€ð}àš'BY^^þ1ÿâ÷ûC"‚ˆ µÃ0ÐZKù€Ö­5"¢]×¥Ldšf Zk÷ææfffægà/ôööþÚÒÒÒóÜÓØØøÃÜÜ\j}}ý£ Ôû|¾ZkÚÛÛßMª”¶mÎÏÏ9==åêêê'`ÃÄu] à ¿‹\keY¤ÓišššÈçó´µµÝRx/lÛ¦T*q||L(b{{¿ßã8÷ð˜\×­õ»œ‹E²Ù,‡ :::FžR¡ÊßSE¡Pàä䥛››ŒŽŽ222ÂSúŒ²€‘7 X–ÅÁÁ–e±µµÅÔÔˆ–e¡”2Ìêrß‚ÙÙYúúúÈd2ÌÏÏÓÙÙI©T¢X,bY"b–Dk­ÞBžH$H¥Rœ±¶¶F8&—ËáóùpÁ0ŒJ‹*Ûù\×eqq‘ÝÝ]b±;;;444Ëå°m¯×K0Äï÷—Ä”RêÕh­I$¤ÓiÆÆÆ˜žž&“Éàõzimm¥¹¹™@ Àíí-"ò<­õWcjÛ6KKKìïï399Iww7D£Q¢Ñ(>Ÿï33J)Uàq/’;ŽC2™$N3>>N$!‰ÐÓÓC}}ý‹••˜¼òD¯¬¬pttÄÐÐýýýÄãq‚Áà×®”+x½E«««ìíí‘L&|Ññ§(?íÕ3x\œ|>ÿ¿Ã]]]LLL ”¢P(Ô”´ûû{´Ö˜¦ù<Ã0$ qyyYqaš&@€ëëëš\W£*¦˜¦I]]Ý«Dµ ,æñx*ˆ×ëý,jµ} O-ø7—Ëý‹Å"_Z¶êr-xxx°S©Ôï€#€]XX˜ƒjfùwww–e9€><<ü#›Íþ\–m@U¯ë7âào€ÿxLhZñ1{IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/24x24/apps/csd-power.png0000664000175000017500000000246114733247605027315 0ustar fabiofabio‰PNG  IHDRàw=øsBIT|dˆ pHYsvv}Õ‚ÌtEXtSoftwarewww.inkscape.org›î<®IDATH‰­•ËGÆUÕ÷ÎŒ§3cg˜L ¹fa&‘,B ‰ D öH^±`˱ó?À†]KXdk¯9–[ ";aʈÇã¹îûèû¨ÛÝõ8Åâ><Ê’ŽN©ûèûê;çTÅÿ^=zôÙ˜ÍfXkFXk±Ö2Ng·oßþ=Pþ7°···yëÖ­_\»víÍN§“omm±½½MUUmkíÏz½ãñxe³ÙŒªªhµZlllüIkÝÌ€vUUûÆêºÆZK–ecÐZ3N©ªŠº®išf®k¼÷„V>„€s­õ[@[mà‡ƒÁà§Î9gŒy ˆ)¥D)­µŸ‹HŸR "bŒ!Ïó¯ŠHH)Å^¯÷8„œs¾Óé|m¿>Éô.]ºä€faqaÔ@À/ür?[ì¿wõêÕM º‹øà²3EO ÐxÆ¿´9NüÿðÅ âÎ2pI Oœ?K Nì—J¿¼~BÁ óeK'ýÙµŒ_äàé§ þüàö¯[ú"¯¬½JL‘ˆ¤È´ñåð_ÄÑ#)’H4¡"_»HŒo¿þ>Gƒ/(ÇeÙÅ…#€÷N0iÀ¨ù¡ƒ"BL´Êz~Ì瞤¨Ô!½pPܧ?|N¨±öl­½z*E)%$ (AA#d)ÑÞI`dQQìn¿Á¸âUä+pøü ýAAÐÅ»£s5PJ³NJPJÈ”°¶>^l¶^aÿâ·øûÑ_IJxðåÇ †Cœ ø‰'_{¹"0d:¡€Ò‚ÄèÄÚºBPdI‘’æ›»o“´×)%ÞûÆxÖ;¢è¦KS½„À€Ö‚6BÒ ¥h¡%‰öúéþ½ö•·ÙnïñÖÎwøè³ßòãö'TcO3ólšó tf@›¹‚d"¨F0"¬©Å…˜'’ƒãysë4¡&[Þýú9Î)Š‚®êRÙó5ÐÚ€Ê@eóÜ«lžª ¡mæáqÕ “Eþmµ…OŸ0îÕØ‘gf=ŠsJ…Ò ¥ç¤ôœDT¢f¡ Bñ\þIÌFd-á»oü„b½à¸]pºÌìù Ô¼‹Pó“+#(1Zh)P­U¯h&îÓLKxXü…q/0x¬õ¬¿¸d )­@âü’¡_XPB%óô-•`6ƒ&@5f¾q"¤y\ Рؾyóæ®\¹òóN§ÃåË—ÙÙÙagg­5£Ñˆ¢( ”e‰µvõÝ{Ê–ÃÆ{Ïp8üèîÝ»¿Êyüøqss“<ÏÉóœ .àœãä”›L&”eÉd2!Ë2úýþ©é¶^ú§OŸöÉ{ïÞ½ûÀ«Æ˜Ý‚)ËR ´Öj<S–¥L§S¦Ó©ªëZctÓ4¡išäœK ÐT×uòÞ§n·Ûøðá}À.ßö°äüÖ”ù\ðÿÚ £N¼¼IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/0000775000175000017500000000000014733247605023740 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/0000775000175000017500000000000014733247605024703 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-screensaver-proxy.png0000664000175000017500000000136014733247605031657 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<mIDAT8•“ÍoLaÅÏó¾÷ÞéLgÚj©L›iB”……ØH,­üþ¡!¾þi‘P6ãcúA¤¡&zgzï{ïk1¦ aᬟsrΓs„,`ø?d€ ·^¯×ûûûGþ¼PU¬µeonn®ŽŽŽNX`°X,ŽÌÎ>`a¡Žª²#pð`•<ÏÑ<ÆñcÓ¸,ëòɽgyé3Î9³#`ŒbŒ"ªœž™äÚõ+T«#A@»½Íüü>¼_!÷Dv<ÏQئ§ŽpãÆUú¸sû>wg†33S”Ë%Ú­ %èÆ4MS¢0¢§Pâòå $iB»Ý¦ù½ÅׯÄqL’$LNM°Ýʰ6 MSµ€dY†µÖ¨î¦Õjqëæ#^Î5BpñÒ9*•í8£\.t#ˆí:L@!(²¾¾A¥ÒË÷õ„ÐîÆaey8ŽÙÚŠñ™'´!I’üé ¤•y>÷–™3“Œ ³w·`Dééƒf³ÉÛWRˆô7’¦)¢†( xñl…‘}®ýVœÆÇ%Vê«”¢>¢ÀtˆHÓÁŠ™Oï½æÀx‘µ= Âê§5\Sê"4…ÚÀÚmZêÆQØËÚ'eãË7Bk(zËx#®$'딫óçã‡ö8ï§VÁˆ`TTðžÊPÙ:çl7Bkqqq³V«õŸ85aUUED~U¼÷xßÙAžçxïi4À–ЙñI`üï«ý'>s?‹|ý‰cûIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-background.png0000664000175000017500000000131114733247605030273 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<FIDAT8•“Áo7‡¿7žÝeÉfC2mB+ÔæÂ©—^Ú¿ºÿ@¥Jrà‚¡P)d³“ÝÙ™ñxl¿‚TõÂ;=Yö§ïýl ©rÀð}/Àìâº,÷ólüß"‚1ÿÏÎÅáQbÛñßÿ,ù²ëÃó«`˜ˆÛ;éÆÓ½‚Æoüà¾;‰d£ìøôñ(rÀ8çx»¬yc'ñ·ós°™GûøÇr|oþkY¨ »C®–78çL˜a¨»ž«W»\°³^cSâ²WØé(Ú00Ý.Ôw–aîâœc×9¾Tªî`Ý¥[úÍ᱉€ÕSûÕ@r ‹1b=¬¶=¾,p¡×‘MýʽáÑÃf§x!d9 ªŠ pÓ¥ªnsîâ4¬¨Ês¯g€¢ëf÷öˆ1~3ðÞ£ªøÞ½O—ìƒæCê›íg»ã´^Õp4ùšA2èûã{ò¾a§šLÓä)VLU^2ÎgÔ›5~6‡¾¿3k-8é;in°b¤ënV¤Z )7HѺ–è:hël›f£‚©ëdS7˜jcq”Ëk¹¿XÚH ³Ö²ˆ+~Ïßç½x€Ïdöé]`d6Ü$ØŸÙ.?Óš'É eж-GEÁ/?Ÿñ°OÉG#:ßO6›(Úg 0·ûEA› $º‹«µx0ÍŸ"rL–eˆˆIÏw¢jT•#ª*%^^{ Ò7þø‰ï«ÀË'c]«dºIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-xrandr.png0000664000175000017500000000121414733247605027454 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î< IDAT8•“ÍN“A†Ÿ9sfZ) ¦‰CcX€q¡à5ˆz ê=á¯Å1²#®ˆ QÉ$!J bi¿ùù\”£‘w3³˜óÎ3ï9cHËÅ”€h€‰ÍÍÍíV«ÕºHõááá—……… L7›ÍÖÚÚS>}øø_Åóí6Ÿ<š¦°1F¶Þoñæõ:Þ{ʲü;{ÎĬ ¬Dpÿá*«îý“ÀZ;b`RJX–—ï°rwç<ÞÕð®†SªbÌàŒ!¥`!SÏÆÆ[Äj¾ŽÁP‘É9%SÀˆ DcÜè=£!“ ºÝ.V•oßeIKb Ć¿¨â´ÆçÝ]z§=ööƒsŠˆE1ˆTÝ(AJ µÊÉÉzÝ)ÊhLMÑ?í36>†9b H çÜH&„@L‘\eÀPsu._j ªÌÌ^eúJ“›·ÙÛûÊóg/P«„Î ˆ1¢bQ«LLL’ÎB©ÄHEˆ}bŒt:ÇTUF­Ÿ€’sÆ:‹ˆ°SìP«Õ©ù:^=[ï ÊÐãÕËuʲO¿ìc­’síÂÒâãõqÄ**Q‹5–ª‚”#)%R5XÛíù‘.œEq<77ט½6ƒ1Áƒ1gsPUTUEÎù|_ÅðÓ0øÆ·ëÿœß?µ lüçÞö*ºõIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-orientation.png0000664000175000017500000000121414733247605030511 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î< IDAT8•“ÍN“A†Ÿ9sfZ) ¦‰CcX€q¡à5ˆz ê=á¯Å1²#®ˆ QÉ$!J bi¿ùù\”£‘w3³˜óÎ3ï9cHËÅ”€h€‰ÍÍÍíV«ÕºHõááá—……… L7›ÍÖÚÚS>}øø_Åóí6Ÿ<š¦°1F¶Þoñæõ:Þ{ʲü;{ÎĬ ¬Dpÿá*«îý“ÀZ;b`RJX–—ï°rwç<ÞÕð®†SªbÌàŒ!¥`!SÏÆÆ[Äj¾ŽÁP‘É9%SÀˆ DcÜè=£!“ ºÝ.V•oßeIKb Ć¿¨â´ÆçÝ]z§=ööƒsŠˆE1ˆTÝ(AJ µÊÉÉzÝ)ÊhLMÑ?í36>†9b H çÜH&„@L‘\eÀPsu._j ªÌÌ^eúJ“›·ÙÛûÊóg/P«„Î ˆ1¢bQ«LLL’ÎB©ÄHEˆ}bŒt:ÇTUF­Ÿ€’sÆ:‹ˆ°SìP«Õ©ù:^=[ï ÊÐãÕËuʲO¿ìc­’síÂÒâãõqÄ**Q‹5–ª‚”#)%R5XÛíù‘.œEq<77ט½6ƒ1Áƒ1gsPUTUEÎù|_ÅðÓ0øÆ·ëÿœß?µ lüçÞö*ºõIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-a11y-keyboard.png0000664000175000017500000000127114733247605030532 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<6IDAT8•“?kTAÅwÞÛMv7#*! b³ ¥(Q+ÁÆR,ì+K»|ñX ZXØÑhåLŒXˆE.F]RAɺîæÍ¹7) âif˜¹sæpGHÈŒÿCT€¡ù·­åÑáZ@þñÊÖ×ï«öñƒã906T¬_¾õœ®7œÈ4fD3*%áÒ™#u`,²ŒvW©ÔjdN’ 3Ží+S-ç<\ü"¢ÑîtˆÁ²ÈÌ"1*•h‚¿Æ¹““T«ƒ†ª¢k=N4¶±Òö,ÿȘº:Í@ÉQ.0> Û+9ÏšmTKnH¸"A…* ï›=0Á…S‡¨×ªÉîx0ÿй7Ÿñ~˜ "€K ¢ÔBβmcúõ*3/ïqûòyÎN]£íF©c$¨Çâ&Á §ŠHò` Ë7ÜÏʨ†¾>(Ál“^=Nó#°sG‰K- ­å¬|óD3¼zŒÐW 1A_(Î%‚ÉÆ×ïÌ!"L6Æyûd)Ä4»£¸?‡¾ðx_à}AQtiìÙÅì‡o<~·BcïnŠ¢Û¿÷…'&ȇE ¯˜+*N¹qwŽ^tܼÿ§=zVJxÛ”B4c¨œñãç/œzÀìâZ¿ÞuÖ÷éç‘ÚÑ6Rè~úÚê]¹xz0Õ ¥ H¿f`X?3h~iõ€Žj|Øÿ÷m‰&ðâ7‹´@ù)çèIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-xsettings.png0000664000175000017500000000121014733247605030202 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<IDAT8•“MK#A†Ÿî"¨ ñã2®H<( ›Óðgú<ºäàÉ=-¨»`ò1š 3Ó]Õ³‡qŽX·¦»ªž÷­.Ã:b âs¡€ sww÷£Ûí&ŸÉβì÷p8<~»ÝNŠ¢àöö–““öööè÷ûXkÿßZ•V«•} DÞ{ò<çðð¡ª*D„ÇÇGÒ4¥( Š¢ MSŠ¢ˆ,©*ÏÏÏlmm1NQUBTUE–e¨*ªJ–e8çšó¦€ʲäèèˆíím¼÷ˆu]cŒiŒ1Ôuªâ½0°Î9¼÷¤iÊýý="‚ª¾+0N ,—KT•ªªlC$ Þ{ÎÎ΂õ KÅb1†Õj…ˆlî×Þûwˆ‚<Ï9>>f6›Q–%———ôz½%¼l:†‚år‰µ–ù|ÎÎÎ××׌Çãfã1†Î9D„^¯ÇÅÅeYÒív9==e45£L "ch·Ûï$ŒÇcnnn¸ººú0… q¼ñÀZ «¡Óif=X,ìît:Œ1ˆι7¼÷8çøòçuž£ª¼¼¼Ç1ûûûÍ?888 Š"^__ !4Ч§§E’$½ÉùW¬µ´€ÉdÒ`ÔuݘE³Ùlä†õŸÙFà'ðý/ÄA{CD#ãIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-print-notifications.png0000664000175000017500000000137514733247605032171 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<zIDAT8}“Ah”G†Ÿï›“†Õ15¸ —` *iê)P‰HJ½Õ‹Þ¤7¢‚'/âMRìÁ¼ÕCk*¨H‚VÄE+ŠbšèÖ$MÜÍþÿ|Ÿ‡7»Héf†aæç}¿¸zå‡Ýk»KŸC@¥Õ¬ÑǘÏçÿyóÛÁCGî'@ÏÀÎ]?NO¿J—2AT‘–€;˜;nΚR)Ù98T† GÜ c§ŽMJ¬-BBAÑ$DibÄh˜1:‹. ô$ŽWj±#ÁUAU)¨’„œÆÍÉ€hà©ÖW¢7È 8ލ2²ÿ›£§Ïîømpøþâ¹ÛãW.Ï5B Dèíííìèü¤³y¬òvö]Lëi_ys_Sfý§ºB$à€$€ºÓðÚÊýÞäG•Ù™…z½–ön(ÿ5<òõ @ADÏ TsÎÜQ;pÿgåׯŸßúùêËþ­åæºmßÛ h(x›ÀÂ|eùðw'¿X©UëÕåk«I˜µBM>º¸E°eûæjõ}Õ,³b±T\=•g‰åƒ$€¸nðǃ»•ûS7Ÿ‹k:¶íêçùÓG¯qÃ7çÁÔí¿Ý ÷vòWöìÉ㥱Gï ì,Ž_wþÌñë¯^ü¹äfdn¤Y$M#ѽ«[ÒŒÞ͈fd™03ýºzâè·?--.¦ÍÂdfÄÔˆ1òU§š4­|u`ÓÂ|e9  „ÀF‘\ÞÀÝ1 Ëœîîžbþ;ò—XùuâúïÃ{ö–%„µAQѼÈîàŽ™»»cdbâ—‡@EUèÖýW5þ§Ís;0#£IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-housekeeping.png0000664000175000017500000000117614733247605030653 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<ûIDAT8•“½kTQÅsß[×1².˜Ã’Dí$ÁB ë`¡• ……€ƒB°¶³°‘NTÐ"¨‚øHˆW³Ù÷ÞÜ{Çâ­k„$’Ósfæž;B‰HØàè_¼<órд¹õ’T¾œ½{$û[+Mí´ÿ+ʃ±+hÔö4†_x¼Æmk- \«Ž²–u¹…HR ñ¹b¶íþ Ö°Ö14D´g ªÓ¸¥¸ˆÆ¼ëç¬.ã+%O$H 8_„M ¼Á£P!7è$G¥À«”WNP(æÿ]Á€ûÕ>nüÒ4åë,¦0ìJž˜ˆœf_Ä^E¤=r€ WÏpåä9/²À\îhw¹šmœ@=Ĉ7°‘Ç'Ÿš@D¸xnŠÓ§sóöï>²ûGšXoñyjdpfŠæô$"f¾½U.Í£þ+Ãk$zÃç¾g€j@5€¼¾õå¯+X,ÅÁÖ;ž§w3℃ð‡OyN½•Ý€Úb‹ç×ç=‚¡‰a¾ÊÛ…÷ =ûÌn Ý´Dþ¾×Ø3èke,ÍÞãMTDpüƘJIÎ;õ«ci¥."$ˆsàõ’„™a1b1B˜ŸT¿m¡<ãi`|˯¸9>O~ø!uoˆÄQIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-sound.png0000664000175000017500000000136214733247605027312 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<oIDAT8•“AkAų;IìnHÖz¨%!•J1‡"Hñ¢½ˆ÷úüÅ/R/âUЛG±Ð⡇ŠJS›ªT(›¶É&3™Éއ˜@ßõÏÿñÞã=Áðù?Œ+€üÖÖÖQ.—«!BüóË9‡s¥ÔÍÍͺnYk+Zk|ßÇó<Œ1A@’$d³YÒ4ÅZ‹”²Ü’€oŒ™ø’ÑhD¹\fmmããcªÕ*ûûûœžž’ÉdpÎñçÇ—€?ñ<$IX]]eooíím´Ö ‡C”RÔëuÖ××988@JIš¦3a­ P(°³³Ã`ÐçAuDµpÎqÜ+ñnç J)jµ½^o‰ðÏCÇ”J%NNN¸WJ¸ãÁeƒppÀƒüGž®/²»»K¥R!Žã©Oƒ֚f³Ép8¤V¼Â$ŽW­'8çxþø„za`³Ùd4M „œ*ÐZ£µ¦ßï#D€—•üúõOøäo¯pÙ PJ¡”bnnîºk-ù|ž~¿O«[áѼNjg9nÌß!(†5=„„aˆ1æš¡µ&Z­KKK¼~ÿ·ñ˜z8Æç8:ôyõæËËË´Z-®Gv`­%“É ”¢\.#„àåÛÆµ®¬¬°¸¸Èùù9rUa¾«IwÏZ‹sŽ(Šèt:„aÈÆÆDQD»Ý¦ÓéËå¸ërxyx=c ¾ïÏ<6 |²¯v»ME³ÛÙÙÙô&$0ìv»Ýb±xs*WJÉÂÂÂlXÎ9Ò4¶««+â8ŽD0™ñPûç ÿÆ7àóo„Ï5¬á/ŠIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-automount.png0000664000175000017500000000105014733247605030207 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<¥IDAT8•“1‹SA…¿;ï>Ø]ÃK±‚ 6A0Ä>`“Ôþ ñ_XXù‹,m¬,–z% #±HÈîêÜ™±È{Ï<7AöÂÀ0sçÜsν#ìCŒ‡EL€Öl6»n·Û!¥@J ©³ïÖëõ·~¿?Pà²ÕjuÌìAå‹¢x \*yïèU8çˆ1žÂÉÈÌì^’sŽår‰ˆÐívOd ˆ™Bh<^­VÌçsÌŒN§Ó)‹Î{_ˆ›Í†ÉdRK˜N§¨*EQü+Õ) !¼÷uuUe04’³,ãˆÔ&ƒªmWWW,‹@¯×c8gPQBŒÇcF£Q×”»Ýîoé}1Q@T3#¥DJ‰ívKŒ‘Â=Šå!ιúqµBõ¾Ò}¨¿4xïÁêû.ŠÇø‰Q0ƒ¥d@yf¤T¶/ìnSzçîÝûXñ‚ßòˆ„ÊÚ'yÜrvóòÜ)Þß¼}óÚÿüu‘onq'G×9‡8Wϳ'¯üçO·d¨¾DΟ“¹ÿ~ê„»Hº½Æì˪û&ÝA&šIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-clipboard.png0000664000175000017500000000142414733247605030120 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<‘IDAT8•“Í‹UÅ÷½WÝÕ‰JkHfÇ q“Š0AqwB–Š{÷þ.Ý nÁàN"‚ A† †¸°Õ8‘I§«'3Õ]ェz.FÚuÎúr¸÷ÜóÎdÍÓ©:&Ÿ|ñãoèô’Ö­ ¾s›IQ‚Ö b ô}ßáªåáÇï¿õЦŽÑ%[µøÞ“D1ZZW3 ýÙzQLRëÖY"¥v€©´µ-"ŠHkºÎÒu-]Src7âÆnDW•€Ç;‹w ζXï´´·-0JF®`ïú"^½ö"§ë_ÙÞ2Ü>˜áúsô}Oèec ÎyB Ör5ؽ¼Í8‰899ADxùJNžçÌþ:äÑß ˆAâ@  êfM¦åñ¢`’0Ò!C˹l„ˆ0_@š¦låÎz` !¶ó)³²Æ9O]לuDã1“ìYnß}ÈÑ|Ƀóчïðég_óÂNÎÝÙ1!}cÒ(Ý0 Ò$%M2:ßãsçÏš¶†Ï¿ú–~èypsW39¿Eµ^Qž®HGãÿ3ˆã1Î9œkV«¸·PÔU "ØrÅ€"NRúªa¹\nNhž,–&ÍÎk%ض…¡#Š J@K C ©Ö ¡g2™P.ž•ü‡ñkÀÕ§ÄyÜùØÇ9SÞPÖIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-mouse.png0000664000175000017500000000130114733247605027303 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<>IDAT8•’ÍNSQ…¿s{¹­b j…àOCâÔp‚`¢S'à ‘;ò)ˆÆ8ð„h%AÚP­ ÞÞöüŸëZKdâJvr²×Úûœuöœ¡pÿx̬¯¯¬T®Înl<™.—“‘b÷Ó.•ÊU®×jãªÁph67Y–eÝF£q/æ”R+Z—:qA$ZK¾òüÅK QÄÆ³'¬Üº @\‰sÖJ)Wù(h­ !Bß´½óµµgçí–Wn޹Zk€B DƬu"x?E…½^€érÌ$g­Æ€(„1&h­âþЦ’"¿¾P©,1Éi­b­uDh)¥é÷³bžçc+õ;ušÍ&Íf“Õz}œÏóœ4í—”RÐ10HÓ4B̵Û'jqq¾°t£ÊãG©\«P«UÇ/èüèÊÓÓÓ+išvAô³,û9Å«×o³<òðÎR]œ§º0‡w–Q~këÍ`8Š,˺@?¬”ò¸T*ÝÝûrLz]^ªùÿŸ÷ö)%RÊ#ÀÆ@®µn)¥èt:³Y&m¹\œ:Ø…ÕKûÛívg•R(¥Z@8ç~k­QJ‰ýýo&xÏeqxx¤•RBk÷¾xï3k-ÖZZ­¶ÁsY´['a¤óÞk€x4vï=Î9”16rÊœsø³¥š70Æl'Iâ¼÷qp^L~Ú$‚óÂ{OÁcÞˆs®Ü.­üà ÿÏ1–˜­jç“IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-keyboard.png0000664000175000017500000000125214733247605027760 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<'IDAT8•“?K+QÅ{ïÍ*I„l‚`p%J´XX½Ê&•ÄÏæ°±±òÁðŠðX‹€äíÉ&aïÜûа We``šsfΙ™€u@³Y` ùôôô«ÕjÅ› Ó4œ Щ×ëñb±Ø¨}£ÑˆŽ´ˆp{{K¯‡˜Ïçt:V«Æf³Fk-“É„ápXòhhk-"B¿ß§ÙlE½^­­-‰¢­5ÇÇÇEˆ`­­¡( êõ:q£µÆC»Ý®êƒƒ¢(ªD 0€Úí6×××Ôj5ò??999áããƒÝÝ]’$¡ÕjÑl6¹¹¹)% PÎ9œsˆÞ{¾¿¿ Ã¥___(¥ð!"8çTåAžçL§S²,C)ÅÃﯯìììðüüÌh4Â{Ït:­š•ÖZÆã1WWW¤iŠÖš‹‹ Â0äþþžËËK²,#MSÎÏÏ+ ¦IDX.—$I‚s޽½=ö÷÷ÑZã½çýýÁCQÕAU[pΑç9ƒÁ¥J)JoŠ¢ Žcf³ãñ˜0 Küz Î9ŽŽŽx||Ä{ÿßÙv»]îîî¨ÕjˆATI’¤½^/êv»AðOxïÿË···?À<`ýÆ?€þFß¿ŸÔ€!Q1' “IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-datetime.png0000664000175000017500000000124414733247605027755 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<!IDAT8•“ÏJQÆçÜÑqâ˜V†8‹j„µdá² >‡OãÂ7éÎgºAHâH B¹soa‚Ò"ôÛ^¾ïÎï~ÂL`ø?U€ ¾¼¼ì'I’þ{<ÿêv»ß i6›éÉÉ ÃáADþiòÞã½gccƒÃÃÃ/@ÆZËÝÝggg¼¾¾""looS–% ôz=œs„aHUUXkÌ<ÀCQ¼¼¼ ªt:â8àââ‚<ÏñÞ#"cÞˆs!I’úÓÓS(Š‚4MçÛˆÎ9Q@­µˆY–Ñét0Ɔ!Y–1i·Û<==Ç1£Ñ©©b­EU1ÆÐh4ØÝÝeee…V«Åúú:iš²··ÇÁÁyž£ªu€õªÊÒÒçççXkY^^Æ9G’$4›M1ÆEÑÛ ©ªªfKEÜßß³¶¶†ªòðð€µ–~¿Ïd2¡ÑhÌ~ÑÌ# HY–ˆÏÏÏDQÄñÑq3N ‚€ëëkT•~¿OžçˆHX`Î[U ü8>f†¬®®2™LØßß§Ýn“ç9½^·žPçªJ†c(½çsQU­V‹ÑhÄÕÕaR;;;5ÆÙ ¬µt»Ý9ãä½gkkë…üöö6ÛÜÜüTNUßu¢î€sçÞ{nnn~SaVãïÀ×Gÿ­ðó-$î‹×¨8IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-media-keys.png0000664000175000017500000000123414733247605030210 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<IDAT8•“ÏJ[Q‡¿¹¸× !ÅzckD¤P¸«>€Oà½kßÇ•/á+見"b%(XÅVP#¹ÔÐÆ›{æœ.b®ZêÂf7ó›3¿9#ŒŸ×¡€`²ÕjujµZã5ÕY–ýLÓ´Ó•J¥‘e'''8çÊ$çn8ÄS}V<»¸Èû¹¹0¾ªÒétX[[ãææ}(H’„Ë’4åþþœcrjŠ/»»Ô·¶|ð1¨*Ýn—(Џºº¢R©p}}Mw8¤XYá2Iø13Ci 5cL) ªŠª""äyÎáá!yž#"¨*QQI’àû>ㆀx€§ªXkŠ¢`ssc žç¡ªÄqŒµ¶Ì±Ö޼c ÖZŽi6›ÜÝÝEívÿö–_{{|ò<Üé)½^£:AÀ³Ö¢yÎ|»Í÷££‘ûÎQ±7;Ë·ƒáÁê*ï66°Ö>¾@U¡(xÛlRMS¬µxž@Q„aˆˆp´½MããÇÑ/zðàÙªÊÅÅÎ9úý>q#",//öÁì'H0VSU|ß§V«‘eqS­VÂ0$ CôѼ’àé²,£^¯S¯×K¬µ ƒ§ë3òÀZËÌü<íý}¼V Çÿù31Q ˆH9Âàìì,[XXx#ëëˆÈ³(oâŸ8??ï¿…Ñ>¼Ðø%N¯ÉÖ:‰‹>bùIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-a11y-settings.png0000664000175000017500000000127114733247605030572 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<6IDAT8•“?kTAÅwÞÛMv7#*! b³ ¥(Q+ÁÆR,ì+K»|ñX ZXØÑhåLŒXˆE.F]RAɺîæÍ¹7) âif˜¹sæpGHÈŒÿCT€¡ù·­åÑáZ@þñÊÖ×ï«öñƒã906T¬_¾õœ®7œÈ4fD3*%áÒ™#u`,²ŒvW©ÔjdN’ 3Ží+S-ç<\ü"¢ÑîtˆÁ²ÈÌ"1*•h‚¿Æ¹““T«ƒ†ª¢k=N4¶±Òö,ÿȘº:Í@ÉQ.0> Û+9ÏšmTKnH¸"A…* ï›=0Á…S‡¨×ªÉîx0ÿй7Ÿñ~˜ "€K ¢ÔBβmcúõ*3/ïqûòyÎN]£íF©c$¨Çâ&Á §ŠHò` Ë7ÜÏʨ†¾>(Ál“^=Nó#°sG‰K- ­å¬|óD3¼zŒÐW 1A_(Î%‚ÉÆ×ïÌ!"L6Æyûd)Ä4»£¸?‡¾ðx_à}AQtiìÙÅì‡o<~·BcïnŠ¢Û¿÷…'&ȇE ¯˜+*N¹qwŽ^tܼÿ§=zVJxÛ”B4c¨œñãç/œzÀìâZ¿ÞuÖ÷éç‘ÚÑ6Rè~úÚê]¹xz0Õ ¥ H¿f`X?3h~iõ€Žj|Øÿ÷m‰&ðâ7‹´@ù)çèIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-cursor.png0000664000175000017500000000142414733247605027476 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<‘IDAT8•“Í‹UÅ÷½WÝÕ‰JkHfÇ q“Š0AqwB–Š{÷þ.Ý nÁàN"‚ A† †¸°Õ8‘I§«'3Õ]ェz.FÚuÎúr¸÷ÜóÎdÍÓ©:&Ÿ|ñãoèô’Ö­ ¾s›IQ‚Ö b ô}ßáªåáÇï¿õЦŽÑ%[µøÞ“D1ZZW3 ýÙzQLRëÖY"¥v€©´µ-"ŠHkºÎÒu-]Src7âÆnDW•€Ç;‹w ζXï´´·-0JF®`ïú"^½ö"§ë_ÙÞ2Ü>˜áúsô}Oèec ÎyB Ör5ؽ¼Í8‰899ADxùJNžçÌþ:äÑß ˆAâ@  êfM¦åñ¢`’0Ò!C˹l„ˆ0_@š¦låÎz` !¶ó)³²Æ9O]לuDã1“ìYnß}ÈÑ|Ƀóчïðég_óÂNÎÝÙ1!}cÒ(Ý0 Ò$%M2:ßãsçÏš¶†Ï¿ú–~èypsW39¿Eµ^Qž®HGãÿ3ˆã1Î9œkV«¸·PÔU "ØrÅ€"NRúªa¹\nNhž,–&ÍÎk%ض…¡#Š J@K C ©Ö ¡g2™P.ž•ü‡ñkÀÕ§ÄyÜùØÇ9SÞPÖIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-printer.png0000664000175000017500000000126314733247605027645 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<0IDAT8•“½NA…¿™ÙÝÁØf³¦pE¤ÐXH–@(…˼/x ž"BÊ#DÔ TŽ( iø`v½»ìzæ¦pìEBât#Ý9sî}Š©Àð>9`¢€ÖÅÅÅy’$ëï¹ýððpÓëõz°ÚjµÖëºæàà@´Ö(¥æƒ"2?‹Þ{ö÷÷U»Ý^VÀTyŠ —8>>–££#ýøøHQ8爢ˆº®év»ìîîú½½=%"&Leøt:eYbŒÁ9‡ˆ†!EQ`­%I¼÷xïçêûø'äŠ8Ž©ëš<Ï&“ aEI’ÐétXYYÁ973P ¿¬ÐZómô•“““WXk±ÖÒh4‡2 t¨Ë›_,Ù%D„ÃÃC¿h°(ADpÎÍú™&¨Z[[[j8ŠÖ€4M@»Ýï=ÛÛÛªª*þÎLtÝG´Ö4›çE1_Á#yžÏ4›M²,{Õº»»Ã9Gš¦j0¨(Š(Ë’²,Ǽ¼¼PyžsÏÕÕƘ¹eYâœcss“ÓÓS.//¹¾¾f4Ç1kkklll°³³3ÿf˜2 ooo‰ã˜ªªè÷ûôû}´ÖAÀd2™E¦,K¼÷ïÅO¿óa7BAIììá¯.‡Y¯×±Áhb§žPD½] o( †mXŒ~1Ò„)@BàòawÉÍ&Ëf Õ×gg¦$W&*øbÎ'&¼iû†báåä`·ä@©TÀ à@~¶ÛظÉÞ®ëÔ=nyÕ2N-?Нz}_k]G®L*‡4R‚þ¨ 0´õÖLB!°‰ô6–)+[µ….½nçh·1W€@(€¼C»1ï'˜^$Ðn‰†/(@EZAéÙ³'bWä Wiÿî@f^:¶gBâœ;$„ôù0iüêNlY–ê½'MSàuÖ[[[\__c­e:Rι¹2˲™XU¥^¯óðð0/Øßß'I’¥ °¶¶&€ZÀ„a¸°ïóœïþÅŒ·Db£(ŠÇFc}Ùmyž—ι–e0ü2 ð¨­Ì¼È/ ùê"×ÿ<_ IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/16x16/apps/csd-power.png0000664000175000017500000000140614733247605027315 0ustar fabiofabio‰PNG  IHDRóÿasBIT|dˆ pHYsOO÷‘8tEXtSoftwarewww.inkscape.org›î<ƒIDAT8•“ÏnWÆwî±™ÄA„ÄÄ€D«dêÙ õ ²íKtÙ<›Ÿ3N™Íf ‡Ã·ÇÇÇÏ×ÌÀ >::zuppðdww—n·K–eœŸŸ3Çh­ÙÜܤª*úý>ZkœsïNNNž)`Ë“i­ß/‹¨Õjù4Mm’$£,Ë|š¦¾,KÇq§ª*Ò4MµÖH)%°%€v¿ßÿuooï.°ÖHË€wÀ¨š¼t¿€Ñééi|xxøFÞ4Þ쵸‚h²m€e]×ë€W×Üw$|Gb€^S®ú àåÅó_îe?=j©6ÆÊ*ããô•Yb½¡2š8êp;ÚažŒ™Ï.™$ƒ1ð@,—µÃ8‹Ç¢½£À(°N©…1´*CVx’,ÊÕ:ƒ+ B:Td‘-Ktï Ö:‚ÎFÀã÷i¯&Ë—ù€´œñ 2‚0r¡%ï±_™Þ·yzÿgl3Œ.èp“/vÄ,IP€ˆ"¡GE¤a‰ÕêÌ,_yÿÏK´œ "GH R^W tHeAY„²Ä€ ÔbDR Paz„lÌ7 HÒ#BƒR–¶®òå¨mן˜,*²RÛ½zó×ÛÁöÃûnÝ»+vzwȧ©ÿ|ya¦Ó¯>Ïò /K_–…³y)ohÜ*µ¬K³„=ÈÉßiý Ëêö:âε‹;+ÑIÎkòE@QŠÂ“ç†,ËþÁêï»ü?|~ÿyMxt†´IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/0000775000175000017500000000000014733247605023734 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/0000775000175000017500000000000014733247605024677 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-screensaver-proxy.png0000664000175000017500000000334214733247605031655 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<_IDATX…Å–]lg†ŸsÎ7³³»ö:‰ÛiˆÖ€°@D¨ªD"Ñ J¹¨ÄRn*q ¹z åç‚@À=7 RT )*¥B !MòG~›ÆÅöÚû33ßÇÅÌŽw;¢ˆŠOú¬‘wvÏ{Þ÷=?ð>2ôl@è»Ó] P;þüósss'¢(ªÿ§¿¤úαöûýî¥K—¾äÈ‘S@OJÎÏÏ_ !4¶ú’ˆlõo’$ù¯@t:ξ}û>üÝQP¿Û9×è÷û,..òæ›Wé÷SD„Ø[ƒØþ„âo€µZÌÁƒ˜™™!Žã:°¸íÊ·cï=Þ{._¾Æ³Ï~Ó3CU¶eÀ9ÇñãO³Ú^Ûƒï=ׯß@D8vl ï=@ 0À@šf˜ÆÄqmÀv ¦§§˜ý@sËàP2à >Ðï§Uœ* nu𙢪˜Yõ̦à"pèÐG™}SÓ»h6,,ÜÛD„Èò3 € ï=!Tµ¼R„oM48yò>D«5N…ÎFƒn·Ç­›w¹ðÚ_èõÒ! |îQ ÃÈ©ªnN>qðÜ:u‚;ZôûýêÓ~¿sÆc³ïå‘}Sœý͸»øöÀ‡x ¦®bd`PC’ç9Þ{D¤” Â,"²˜¹¹÷óÜs_dl¬A–edYF¯×cyy™ååe:yž“ç9qñä§Ÿ`ÇÄiêË›ãÑŠ<ßèA#xïQ5"WÃY­ô|éËŸ#ŠišVYû›?àÕWÿO}œ¯?ÿ•JøäáóÂO[JxAÕ$º€p®FäbÔŒ£G03³›,ËFDùãk×xù×?à3OŸ¤×ë4¥V«É£³{¹ry¡À+ª¶Ù„ÈTÓg¢ÂÇ|p$óÊf´ÛmÌ":q¼³wï$½xAA6K0 2‡™á,B-†ñžýÓ#Ù_»z“Ÿ¿ð2Nc¾õÔñµ¯~/œx†ééÉêÝ;ÇÉÒ“ˆ€m.C¶d@TpYDžšÍú€·Þú'ó·=Íúïa¬1ÅÝ›ž…»÷˜œœ¨ÞkŽ~?'v!TÂÀ†g³ˆ žû÷—™˜¯~4ϱK ‰DQð!§½ºJš¦•×ÖÖ‘Ò…N16aÅ€P–aÑ q1ÎbD`þÎ?h67&´÷žÈ9œsE³AU^X]mX\\˜@l‚S­Êu·’`àA1uep\üóU›Ý¿á¬àIâˆÈE˜ R‚(bz½^57®ÿí5¡j‚š 7¢«Š%Ãp¨Î¯_\àȧþE«UÈ0³w7OGÊŽ)*0±;b}}(Šh¯¶¹}c‰]ãÓxHÜ <è š|ÎÎ NwñÒ‹çøìñ§03Z Z[î-t»]ò<çÜ+ØY߉IÀD&˜ BÁpPÅ™b N•ZsÿžñË—ÎÒétHÓô¡·ÓéðÊ™óh7.¤R!Rˆ#‡š<À@Õº†«`@­”k6ÆYš‡ŸýäWܸv‹^¯WÍ„áÙpóÆmμxV#ZÍ&I RHTp£­¸ª(§á@‚ò‘Á8“dœàÎyƒdìuöÌ´k5µÕ÷ßnãò„©Éý4’>ó¨—‚MÑbÒ¦>{ø8‰ðÁãC ÏBŽˆ!>à,b玽žö½”ö½>j»:“Í]ͪ¤¹ÇÈórº ¬­§€ ëÿà00ež,ËË1¦€4àƒb!`ªÅ´Ô";S%ËÞgXµÌ‹ŒJ«Ýí†Ì>\ÕJB ^èöÖ ¢Hqj¨ Î50QL˺VÅJŸ˜™SAïýt 9òN>è#+”ïþðóYšeaÀÔð‚$2º"Êð“0äŸÑ㜉˜wƒ¥gØ„ÈVVVºcccÉÒÒR%Ív›ð;=aª•••.ÁJcÝn÷Csss4 gf¸²ß;çˆã¸ºµZ$IH’„z½N’$Ôj5jµQU×9WnÖV®÷ÅJ¶²²Ò;}úôï®\¹ò `~âð8ðÐúŸ¤½ýY~\ÚÃÇ@“¡öü. XúÿO4‡{*pIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-background.png0000664000175000017500000000302214733247605030270 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<IDATX…Å—K¯WÇuúÌôøÞøˆÈ<”DÁ*Hðà "¾KÄ–ñDdÁ‘"9¹ØŽ¯ïL÷yU‹yÜ™é1‹ˆ–FÓS}ºú7ÿz†ÿó!{ç°ÂgüL ûýoÿòð§ßþÚƒv!ìA9Á}êBÖ¹váàrb©ï?póG=úÙÛßúÆ€¼õðõ‹gÏ?ôVO¸xõc$Æø¿Ü²r»uçÎ[ÀG‘µôoX-ÒZãòò’‹Ë%jNÀý¼Œ(Ÿã]´»š¸…©AèDD¸õù×¹{÷.À?·øóÖ­5=ý”Ÿ?)tý ú´Êï>üõâØiþf?÷`8¸yï; ‘!Çú²oóãµç/ßlgrk6 Ÿ||ÁíÛ·7¡c°Óo 0äÊÀœØA§vVëDÂY—ìö€~Vˆ7îQdÖ&kϹÁkt³È¿ž¼ µF×yYç@PUZk¨«T ¡ C¢-—§:¬ÜÊj­Æ³÷è¾ôE´f/Lúœ]é±\0UT_'vd«€èæbSe9*!4ÚX¨'j^âeXÔ%:Uí-%w[„›‘ÒG;2!…¨xRì@ȃDM6_%¹Âa/j«$Ø 2Û§!UƒêHu 9O:Í6÷C€(ا˹}þÜí¬$^‘\èdÝ€N*`f˜!Lšc­‰ªNbSÂÞCÖž¯þÎùÙ—Ñ=uã|qw†<¯^heݤTu›‡UPkÝ”‡ZƒV‘V»*ÓÚ©G ´&R›sµ|A ¯c¾ž )¡Y¢Ž Çhm7/s µ¶.u¨º µí(Ö€4(G¹YËÖf\-_ ²V.­–$_‘ÇS§Õzº êv캴®°F=‘3 +PUhu½vi³®ÇqÒ)$JÊtîÔëñ>UÀ½ÃK†0ƒRH'ºâRÊ¡=g¤nl•Dí| 0Ž$Hiä†ÛNécd`m£q-RNDuIG!(ÙKaýcFFHednJ­»²>FÛ)u&Î÷ãߘÏz­¶øÓ;ïLdÎÙ{ÿ8ÌÔäl|9…}¾X<ô§$Ïü¥ÖW £R îNçˆD\%Ÿªsäh]Lh'vðEU@HÖhª”V'e(ì•álÞSr3pc¬ÓVôèiÕ…,S«BóH­ ZdR†1vüäÝ3¦BÀ¹Y¦’ÐÃ~ò¡ÛÄiN¼©UÓíßÉWºBhørį^ U h€‡ÍÉã_üêwußmLöƳˆÐu]×cd6›1ŸÏéûž¾ï™ÏçÌf3bŒ»uÛû&þÔüÏ¿üÍCà1жZ¼|7„ð½{÷î}ØM,ÙÓkk ïׇ™ùæ{góMÑomŸ˜Ùï?Ë}Gsàœ½æô XÁz ýézIÀ7rIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-xrandr.png0000664000175000017500000000275114733247605027457 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<fIDATX…Å–ËWÆçœ[ÕÓ™qüèq"@#/üXEüþ ØHlØ!” ;D‘Bl@‘ÈÂÿR$$+A (òÆ"2,2 ñ0#”Èêi÷£ªî½,nUMµÇ6Bx”;]ªêªž:ßùî÷}÷Âg<¤smÀ '\3 Àwônß¾ýý«W¯~7˲áIV/Šâá½{÷Þ¼~ýúëÀRj_ÜÙÙù³™hñfxï§.\¸|ìHÔŸÍó|XUwïþ‰>¸GUVÏ´¨Ë—/_æÚµkäy>Îÿtõó<„@?ü+?þÑOpæžòºÿ}T¾âµ×¾Ç•+W!äm•@gŽÌeÏ€ok„öž’4 Í3;öã­1ã­ñÿ À̺Ærò47¿uƒ7_}Ö¤A 1FbŒ˜®ÆÀúúˆo|óëܸù*›éÇ"õ¡õ‘¾ÿWª4uŽx¯|íe677Y__çåW^Â9‡™aÖœ®9L •ÇgÙãhDØÐåãìpxxˆ™±³³ƒ©CÕ …¶³H:kTBŒÄšŽÑ§Pï}Ë€ˆ`æ~ûÞïØÝÝÅÌøýoþ€3iò«-_"1BŒ©ˆÄHŒBˆa…ï}Ë~  AæÌPÕtHºÞÛÛk©nºï²ì2ôá}…‘Paª ˜È1-…j†ŠáÔ¡*œŸcÿ€£Ñ:ƒae>›B¾Ö£ôÿÚ§,Kʪ¤ò%UUbã{±S§ǦÀ™%!Yb@ÄøèoÛ¨ EQP”%UY²,–”å’ªª8{î,óÅ¢oÅ™KÄãEˆ1âœuCh•® D‡ªR, ö÷÷`6ŸQKb € æËE3Wwê >Mž ¡Õ@w¸ZM+64U´>‡¸¿{Ÿ#E±DDQµ¤ÃZÎ ç€$¾€ˆOs->5¨þQÈŠcŒµúï=‡Ó çŸ?σ0u ÃöY·“õõ –Ë‚#Òé\Òž#U ŠÙÈǺ P¦óC$*fÆ©S›ÌÎà¹Ó§QQ)–EmLj¹ 3‡ÆØÎ¹ˆ_qªŠbvÜmdµ]‰à‹ SÅÔ(Þ{ÊÒ·É—(Ïpæp–QÔ03Æ[c~øÆøÒÅ‹IÌZÛZàòZš¨µ z±ý~ŸÑpÈp´Î™3Ïqv|†Ïás<ÿÂy¶Îo1é÷×øêK_á½wÍÏöwÞ¿ƒˆ>ªã.Ú$I¨ƒeY¡’Õ’Ê—x)ɨXÃ2ÁœÒï¯1Úw•eÁb1¯’'ºêÕ° @ë•NE9sú4ŲDÍ1ô™ÍæL'Sö¦ÿæ“ý)¹»ÍþÁËåœÍS|û;7ùÅ[o³wÿ …[½ZšY7„ä€$Bë,·ÂöGÇœ«çØá4Íu²¢R‡„àÉ]Ž©2ÎyóõŸÖ¡–Qùªq\Ë€t<üX‹/ùXXùSAU[MG!F$¦ô"¡m3½‡G´.€~¿OU¥Ã{™£ÒÏæ +³:¬¬³ºU„à©‚¯ÝTQyŸîût¿òý~?i‬ˆ0ÆHÞëñίޡ,Š£îkÆš]Ï“öÇϱ])³<Ç™1›=\Ù=9 Õd2YŒF£µO?ý„“óż½žL&  ¢ÕF‹Åââ¥K—^ ÎêlwΑeyž“ç9½^^¯G¿ß_9ÖÖÖèõzíï²,#˲Ζíh1™L–·nÝúãööö/݆‹ð"ðe`ãD(8à}à0íÎd é„Ó xÿcÁûŽ˜‚ó¬IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-orientation.png0000664000175000017500000000275114733247605030514 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<fIDATX…Å–ËWÆçœ[ÕÓ™qüèq"@#/üXEüþ ØHlØ!” ;D‘Bl@‘ÈÂÿR$$+A (òÆ"2,2 ñ0#”Èêi÷£ªî½,nUMµÇ6Bx”;]ªêªž:ßùî÷}÷Âg<¤smÀ '\3 Àwônß¾ýý«W¯~7˲áIV/Šâá½{÷Þ¼~ýúëÀRj_ÜÙÙù³™hñfxï§.\¸|ìHÔŸÍó|XUwïþ‰>¸GUVÏ´¨Ë—/_æÚµkäy>Îÿtõó<„@?ü+?þÑOpæžòºÿ}T¾âµ×¾Ç•+W!äm•@gŽÌeÏ€ok„öž’4 Í3;öã­1ã­ñÿ À̺Ærò47¿uƒ7_}Ö¤A 1FbŒ˜®ÆÀúúˆo|óëܸù*›éÇ"õ¡õ‘¾ÿWª4uŽx¯|íe677Y__çåW^Â9‡™aÖœ®9L •ÇgÙãhDØÐåãìpxxˆ™±³³ƒ©CÕ …¶³H:kTBŒÄšŽÑ§Pï}Ë€ˆ`æ~ûÞïØÝÝÅÌøýoþ€3iò«-_"1BŒ©ˆÄHŒBˆa…ï}Ë~  AæÌPÕtHºÞÛÛk©nºï²ì2ôá}…‘Paª ˜È1-…j†ŠáÔ¡*œŸcÿ€£Ñ:ƒae>›B¾Ö£ôÿÚ§,Kʪ¤ò%UUbã{±S§ǦÀ™%!Yb@ÄøèoÛ¨ EQP”%UY²,–”å’ªª8{î,óÅ¢oÅ™KÄãEˆ1âœuCh•® D‡ªR, ö÷÷`6ŸQKb € æËE3Wwê >Mž ¡Õ@w¸ZM+64U´>‡¸¿{Ÿ#E±DDQµ¤ÃZÎ ç€$¾€ˆOs->5¨þQÈŠcŒµúï=‡Ó çŸ?σ0u ÃöY·“õõ –Ë‚#Òé\Òž#U ŠÙÈǺ P¦óC$*fÆ©S›ÌÎà¹Ó§QQ)–EmLj¹ 3‡ÆØÎ¹ˆ_qªŠbvÜmdµ]‰à‹ SÅÔ(Þ{ÊÒ·É—(Ïpæp–QÔ03Æ[c~øÆøÒÅ‹IÌZÛZàòZš¨µ z±ý~ŸÑpÈp´Î™3Ïqv|†Ïás<ÿÂy¶Îo1é÷×øêK_á½wÍÏöwÞ¿ƒˆ>ªã.Ú$I¨ƒeY¡’Õ’Ê—x)ɨXÃ2ÁœÒï¯1Úw•eÁb1¯’'ºêÕ° @ë•NE9sú4ŲDÍ1ô™ÍæL'Sö¦ÿæ“ý)¹»ÍþÁËåœÍS|û;7ùÅ[o³wÿ …[½ZšY7„ä€$Bë,·ÂöGÇœ«çØá4Íu²¢R‡„àÉ]Ž©2ÎyóõŸÖ¡–Qùªq\Ë€t<üX‹/ùXXùSAU[MG!F$¦ô"¡m3½‡G´.€~¿OU¥Ã{™£ÒÏæ +³:¬¬³ºU„à©‚¯ÝTQyŸîût¿òý~?i‬ˆ0ÆHÞëñίޡ,Š£îkÆš]Ï“öÇϱ])³<Ç™1›=\Ù=9 Õd2YŒF£µO?ý„“óż½žL&  ¢ÕF‹Åââ¥K—^ ÎêlwΑeyž“ç9½^^¯G¿ß_9ÖÖÖèõzíï²,#˲Ζíh1™L–·nÝúãööö/݆‹ð"ðe`ãD(8à}à0íÎd é„Ó xÿcÁûŽ˜‚ó¬IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-a11y-keyboard.png0000664000175000017500000000311314733247605030523 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<ÈIDATX…Å—_Œ\UÇ?çÜ;wfwfÿ¶K±n ¥Ðm€Z¢.¨4A1D^ òd¢$5¾ßúêƒM¤EcÒh%hhµÑ¸„,UhˆÅ l±¡´]º;Û¹¿ßñáœ{î™&Цñ$gî̹çü~ßóýý~ßsþÏÍT¾'@°WÙ§@ªê‡~½pð®Ý;iÔjéÕôÞéöò'O=ùÕ?ý(°aˆíyóƒSâL­:ÙT!þ·ÍJŒëÝqãÌà)žúÍišÔòžðÌÑW8ýÏ1€1`Œ)Á|4¿þé.€¸ùãS|eßnÒ4©3À»Ý™sœãõ3Ë4[SXk|7ÿꪾ¿¾tœÃ9Äxÿàð;6¸¸s3Ä9ÇìDÊH–ðƹu°ÉÐ{là´ôZ|Y¿ÀᜂÀ‚3€ÃøGŸñûoiòȃŸà'Nñ½cocÓ2… ņðN½m"0EÉ™€Ñ0ÁiXTRXôîå6_¾w.:»÷®[a}hÞ £® À(<Ž"iÔqŠªG^í"9\XŽ:]VÛ«CóT5Øpa,ø F!8ª~aÌ}ÍÁX¬-s Íxâßzø ´FG8øÓç‘Ú$Fµ SÁ€µo·’„Âu8´³Æ÷÷?ÀòÊoŸ½ÀÒù6g.vXº°Æùö÷9T„æôµL×˜ÎØ:UgÛ¦&×m™dj¼É7ÿ=. ŒŠgA‡X Ù© *ŠÁ ¹ðØw±oïmì›ßÃç'ÇãWÚ—ysé}¶Ï^ÃÄX3¾k¯­ó»?½Ìã ¯ÒíN‘XEÅÀû÷á(¢£Šª`°Øl”÷´Á\âà/Ù¾¹Îç>±ƒûïÙË–™iî¸õ†èt£Ûcáå“]x•…¿ž!›ØJ­µ›¥¨„\R¥ð3 f­¸ÜÇ ‡5c m´ÛzçTxúųüvñž>ð(Õ¶ÿÀùû²%kNÐÚ¶³`8$¢¯ qy¬ª˜Oý x ¢AÌ ÒF‹z6¬ŽI£E}¬mö|^¨V_²SUU¯¶"D•æªR ëúæ•ìJ,i×w8JhT½"b¬âÌx 9":<Ž É]Š“* ¦¬‚" EPÉ1Øp"˜™àÜùeT•k¯ÙĦñNؽ0¿cʼnP!…ÚâÌÔ" ¹úìèÒëñ™¹xêð Ÿ ÙlF&GLd±3‰-ÏIt8Z› èv»´Ûmƒý~Ÿv»múl:'鬔¢ÓéN§Y^^¦Z­Òív#Q4ö€c3àØ&œŸŸçÙ³g´Z-.^¼È•+W¸yófÄ×<°µµE¥RÑ1 ¨Õj؇ŒÀ– ^¯sõêUž?N£ÑàÂ… ‘ŒGA¼Íó<\×Åu–·C1.áD´sm õ÷±D2Á£ÑÈ$ Òž{*:' „fq›þ~¿ÏüüO¹\6LÚ2Ú€qÄõG-Áh4"—Ë™Ì9¥c=?~Ÿ6;—O0oÞ¼assÓhŸN§#îŽ3xZqA°°°€ëº†2û"züø1ÛÛÛ¼~ýšF£A±XœÈ€Ƨކ:þõ¤L&ÑË–Àqæææ( ”J¥È88Ê!ñ(šÀD݆!íÝ]þ~ù’Žõ6¿ŒÒé4<8¦³fâþýû¤R©È»„•ÌL Æ&Ô¡(¥DmlðãO.Á»wH)#U) C …žç SÏó˜d?{>±W²ˆ¾BŠwïòÛ¯MJ‹uc£MMMÑl6©Õjœµ(¥øøñ#©Tê˜  »Ýî0›Í¦uÇa ._†áÐ Ö¯Õoß¾=óæ™L†\.G§ÓPîø¡µºººÖh4~Èçó)Í‚}1éç¹¹9Êå²i³7˜äƒøï^¯7\]]ýhRÿïÊ À÷@þLÇ;{éö¿$ÅJNçT$pøÿ½©Ó\µÔéƒM46FEÓ¤}ÐøâC¶}PÛXkTª¶ƒTÑZ46AÓHÚ4†Š¶V]ÈB@l¤ Ènw·Â²wougÎñá÷›{çÞÝ»è'™{g~3¿s¾ç{þÌ¡U$WS< ƒ²cÇŽ¡{îþ̽Ë{–¯©ÞmbÒÿ¡Ö¾bq½>W»ðãŸ<ù]»v¼ÔÕìè_÷÷v÷æEa Ãé§<—T‹ñʉ—WžÖÝÉBÐÚ\íÜ–·mÿ 0•ìéîY[cnþä‰ã³Ç޹„;H h! ó‘Exãß±ta8Q—°uë¶¾›ß²iywoÏ0ü+Kz®uGD„ǾóÈéÙ™©É  SEB¢¢¨ ¢Q¹¢Õè`nàc»ãffXáüéÀó«vþà‰mx´ HF›—ggæ—)&êTAÅ @DÈT@ËMڠɸá˜À2œ<{rwfggæ+Ï @É€x™6 XòEU4SD”¬d@2²ª}C±`¨ä`®¨fq¿6RÂKÒ͈ÆÄ/g-Æ5…¤Ê¿Æ½jŠ™B–C®XŽ‚F·½•t!±$$ÆUP>ú‰»6Þù©»ß *± ÚdÉ2ˆ§‡_:pzç׿úûýOŸ^qmß²ÙKSoüè[÷?3:òçé{¾ðàm«®ìoQ#m”Qpo”a–4“D×âñ_·á†µ}ïGV®\Ý5:òÒôäø…úäøÙÚ×Ý{Ç–m·Ý¼€Äé"Ò Z@å?óÿžáÙߌŒúÃdoïò¬«»+LMœ›{nßÏÕj ÒSß]°\ðU×øù±ÉƒÏï;óÅøþ÷~àÃCozó¦÷=²çC^½|jtø‹lYʱF'ÔŒØÑ:í[¿ñƯ~÷© áèáƒgÌŒUk×]ÿ¹/}ûÑ…t»ûMn “P-UA‰Â;AC¸ióöÕëû4¨.ŽÙ¬&g[«ozm@}Ù|Ë»nНð Åg¬¬4‘–÷83yÆÄ?ÏÍ4P_ÁF'y}zò²xeH«–á‚y€ôÎ0ƒG¾xÿ¾_ü='Âöwß¾æÎOö}壧Ž¿²w÷Î#ž4º§¶d`f…1öêé9«0ëù¬KXÅŒ¢€¿½BF¦Â†7õ•Nxnß‘Ýß{hĪܸ¹nN^ÝÇÌðÖÛ"¤<0#  fäy^ürÏcû«'^‰ƒ‘Vöæ1Ës‹®äæ8†Yû¤Ü ºEz+àäfdª˜¢ÊÔkõ‡øü3#‡^œRSÁª±Mãwn†»a¹Ç°˜Å¸W,I TXŒˆQBt¿ÁÂá—NkšÍ5m!Õˆƒ©cXNœŒ-oxï´,”Z¾†Vöõw]|ýÂ5bê¢JžCÈ„<bõÇ$SuL šzj8f)ÂBœ–s—ëúWwµ… 9æyaYP½÷¯Üptx¸?/æã`ZùP‘ÆëZ´MUu³È‡;Xê„˲Œ-·¼½Œ"/ŠjÀ¥S'OœÝüÖ-Ö ö®ê£[ó]¦¥¯% o˜ò§ìVÞñf[>qüØYà"P”jÖww_óñ»v|òÖ¡¡õ=¢‚jô9¤ÉXT$¨"qZS4Á0iSÁZKE-e­=üöHBO£³eåÕ{lÙ'6òøÎ-DÑæ¦«Ô!|Þ=¸—W_ÜΪLš“~ƒù=OÕY°‚x‚g_¤þm;€X£«¨eÛݬZ›íN× q{¾D*ÙGéÎ<æÆ4aàãÙZ¨¸Ä‹ÛlD#UE­m[i®ºÒ3›kÁÕXò¥D<Ê¥ï/uPV‹#+B×ô­Ý=“uØ+SL^üeqêªÍÜΓJÄ ‹&Ï\' Œø>ƒâ!¶‡ïº5`AÒv[%¯_ŽQ¸Wa`8Ëȶa"± ù¿ÎQ(U(”«d²ýÿüª°1ê#€íÕÜj7¤Îqìz<‚?vüÎMl]ߦ€QeúŸ<Ùlšñ&èŸdCàãÔ±h[“æßf8÷iD}À݉)N||’Õ[‡Ù<:ÂÀ†A¦srÅ맯ýñ:#ßuê2σ–*À³Ú]†Ö¤oüEer†³ßM,t±¨C¾O ‹ 6k–á• gYò,ˆ[¼ŽQkK½M´N‡€Úiš;êÊýÖÅ—èã¡,‡+pAýåæ‘ùüχ2™ç2¾ÏÏcá)R{ú>m{-æ¬kqÖâTkïõ¼jÝË©–ärãÀMÀ4ÔH{€gÌŠ ç‹À½ÖãˆIZFô ™ @à_’(¾Ç™îÞIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-sound.png0000664000175000017500000000403614733247605027307 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<›IDATX…Å—[l×ÇgfÖ;Þ«wY³Á,cp*$R¥@ @±€r)íK+µ*U­ÚÒTU¥&íCóÒ U5¢TU›P¡BPà¡HE•Må æR‡› Û[³{gv朙>à™Œ <äõ“Fçhæœóý¿ÿw;ÿg±¹˜€öœuú€¨8€äÛo¿½¿½½ýM]׳:!ž²ÿóKÑ\)eݼyó·Þzë7@ØQY¸pᛣ££ÙPq¨|þøy•ÆÇÙy¶\.ÿø¸¥ñ˜ú’R*ëû~|aDÓ´h ×=mýü=ñõ¾ï£”Ê­€nÌn’Râû~´yþžçÑh40M“t:iš8ŽÃÌÌ ¶mcš&‰Dâ 6BåA ¥h ”"‚9JC0J)¦§§)•JtuuQ.—1 ]×£½RJŽðz}¶t „€Ãlƶmnß¾Y’Î/ÃÈ<"p>+ÅaJ{žYg@›F ÇÁó<Êå2ccc8Žƒ£/œE.è¬hl^“!ŸÏ“Ïçé^ׯª—*$R´æ 6Efffð<ÖÖV<Ïöm€ùYUBMJ‰ß÷©×븮K¥RáÌ™3 †Ç› ^áÃwܳ’HéXÚB@ÝL!“»ŸNE%{éÒ¥¸®‹mÛø¾¦ia3z2 ”RQš˜˜@JI6›¥^¯óþ§x¸ðûÑYÄâÔ(mÍ#x3#ž/}nÔ7pä%‚Èú‰‰‰È÷¡žgfïû´´´044„ã8lÛ¶Z­†mÛ¼÷糌.þ¾‘!ð%r <Õ˜ÆqWj¯qèÑh4°,‹mÛ¶á8CCC …èügfA؈’É$®ëR«ÕÈf³lܸ‘óçÏóé­a~ñî_øî·¿ÅâRý¿h~‚é™V†Ö9rô¶mcY›6m"&''ñ<{šU?a¥¹–l&÷d„(„@×uÊå2W¯^å•W^aÅŠ!èééA)Åoßû€|>OÔjµ¨‡Ê;::p‡ëׯS©T¸k\åÝ?ýˆ_¾~”´¿ú D¬M`š&¥R‰‹/òòË/³|ùr–-[ÆéÓ§™˜˜À0Œ0˜¢*W*•Ø»w/š¦á8—.]¢T*‘L&Y!Öò»Ÿœ¦ÃøÒ}F7 ó6”L&ƒ”’þþ~V¯^M:fÏž=†Áýû÷©V«”J%ÚÚÚð<Çq˜ššbppb±H&“a||œGÐÔæ†…h-~! !¹\Ã0 “Éðâ‹/’ÍfÉårär¹¬eYX–Å;w˜žžfÑ¢E¤R)íííìÛ·ÁÁAŽ=J¡P˜"„a®*¥¢ÔI&“,Y²˲@Ó4ššš¢ë–”’F£ïû‹E*•Ê !¸rå Õj•D"¯bN†ôÇ/’ñÿT*E2™DJo«$ 2™LtQõ}?*åÃÃà Gu%þÍàq“Žã8†a˜q…ó„¢ëzt#ŽKìÊ=ç¦iäóyêõzØ[@1;¹|ùòù5kÖl4M3¦âüŸŒùãÓ~:ž6†é9ûÎødh^X¼äx¾2üè¦ãü6ibÅé9‰fàÀáœi/È$IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-automount.png0000664000175000017500000000233214733247605030207 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<WIDATX…Å–MoEÇ3³^ÇÁ„&¡Ô*•Œ„*.p+¥¼H=TÀGè¢J=ð%¸ µ õC Á‰žs(`Ÿ ’¡ª¨RBÕPÚˆ$4Ûû2ópðÎzר‰ƒhy¤ÑîÎÎ<Ïÿù?/3ð?‹*½`ÐOئ€-¨·ÛíO[­Ö‡a6œs(¥‘â Lœ´Ö•}ZëÊ>€$I¢[·n}vöìÙO€Xå ZÝz½ÞxÂÞÐëõ¢•••×€_†Ô?†aÃ9÷4ìS¯×›ÀQà^Ï…Î9ž€<,!€Àaø˜Ž)IÊv†9 sXkg6®µÆ€µçÜÌ òuPž%"33`ŒÁÃíÛ·8yòä¡Ì(…@Ykgb@kRеµ5¶¶¶îܹC«ÕbVÞfÀ, xÚ766X[[cnn€õõu‚ àØ±cE8þ€ýÐ{Ï777év»Ôj5úý~ñ¿Ûí†!KKK³‚P0j»Ú30iÀ0î{{{t:œsÄqLÇ â8 Ýn³»»[$ç4}¹N]f@ï?c iš²ººŠRŠÁ`0Õ­ÕÕUÎ;‡Rê Ê¨`R”k}aaóçÏO\WhÔCB“$!Š¢™J³``¼xãþ`¹{÷.N§ø?®¸ öÔ©S,//c­¯ÈŸxþ;Žcvvv*¦)ã¸Ð7  På„óïÅçG’$ûö’¦i±gÒÚ\·¢Ô u™rßjaÈŒµ–'NpáÂ…ŠW"R1àuXké÷ûS“:_W­‚²árD¤ðÈËAôŠY–MýŸ;W ´Öø1~Ûñ,x@¾iù5ã·§ƒ¤‚*ß@ÊžŒÓ].Ãñ÷q§Œ1ÚZ;ª‚Iç»÷jRÌý»o8~nÚÞ PaÈã:š)W†Aò§¿+±R6àÆP¼ñâBR Áöö‹KK¤i† pnß,Ë€êÅ£Vj`ÖZÈÁè<š£üp(c4>`Ìå+Wøèâ%L8Ïã(ÆŠÊ €Œç@aþ17 Ñð[ãhÔ5ÍFo®_Œ›7"ƒ¾ñm‡ßÿì³øâËD‰ÁJ€(…Èäsb?ñ%= DФ4LBoû>¿üt [4"Ãé3oqóçßXß °µElã8Ù3+Ð| Ý|Ú|HبÎרͅÔ&6+›9Ò~F:HHz)I?&í%¸èDöîaú›˜t› ÞäÌÛïðõW×ð! ûàý÷Üéwþã/a7®‘ ¢" ¹ç€^>&É\>s6x¥^%àšaÂñåGB÷åµ/R@ ÃÊýöw7~¼xéã×3U×6wÈ,€Fòô=Ä]¯ÒQ ‹Â²üÜ÷飴Z9Ýn— Ýq€S+çI•aŠKZxïkª\ï=¾òHTÌÉ_}ä‹Xk›¸Zkž=ö7^=]1ãa¢(â¥wOÑ>vœ‡>uk-!Ò4å Ÿˆýð׌t72a ØKákPm‚ªb6ŽUç\#Ä•õ‹äÛvâ¢Ue¦»ÈÚÙsÍ~E„&ÍÉ`ðTâKÁûK Ð0¹ƒÃY ÎÛÆàûtÚ9z¡BÅ!^PïiuÒfÊÔT¨5["½ºš µüë"Þ[ð›'Ÿ¦g<øÀ½DQÔ88t`‰õÞ`cP¡!ÐÍ+¸í D„?=óýÁˆw×.²mqA›g¦~›k1ÞS† ×éò‡—NSô/²£»[ö/1±Ö²¸p-<˜ñïwN¡ ûoºms³ [yžóÚëÿâñß¿H”Ïw¶Ñë÷PÖX\]ƒþaR6QÅZC>ÛÅXËÚÆyn»Õ’¦)eY¢ªÌÎÎp×*§”§iŠ1†s˜›ßM”µ'q¯“~0‘šm.[[‡”e‰åxÌá½³qœ¥}{¹nÏ.VW×ùÙSÇIÛ]N<ñGÚYŒÌ,2»=e42. ²4G0uJÛhFÖF¤i ãqœÅ å¸d<‘¶·ããŒ‡ÄÆP޼ñæ Î?ª²qö<ÆeÄy£mBÖ"ÏgÀ|F£ÁD«TÞÀfi†R‹L¬¡, FÃ!Æ(C0P†Zp&móÓ§_¦*JªªÀ¹„™»¨êI‡jàYN’dTÞ3ô)Š‹$IJ«k£X(< 0®}¬ÒT³þ G˜ÌrÆFÌ/.QV%ãbÔ%×OFöA‹v{–jЧ•·‰ã˜8Nû }EUSM!"ÉZ´ ŒF >¹1µÈF£QíÜ€5†øð“SO—*”T¨u¤qÂVhwZ¸Ò“$ƒáàòjHDÝœ}9Ú*­M“Á Ï¥¯(ý~œ‹¨*OQU”•çƒVèõ03s@@{B–çx_’¦Â`ëìð€º‰·Žx{{nçbÇÎ9K9’ÈTX£dILž%´ò„m³mff:¤ò4¢•§´Ò„,I“˜$vD‘%,iš (Î:Ò4Çýâä+~¾wî?¿NOsøp/0ûGúß­-àyàпüë8Ú\Vœ>¢åPüdÖ‚ØW¥-QIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-mouse.png0000664000175000017500000000264714733247605027315 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<$IDATX…Å—ÏÅÇ?U½»{w3Ø^Û – ‡nA\PB’ƒ%Q¤`N¾ÿ@ŽáàÊÝ|ð!‰C´â€,° 1D !^ÿŠ#;cÍ:vwz¦w¦ª^Uq˜®¡w™È*QžTꑦ޷>õÞëWÕð6Uùòù¿4˜ò9hœ;wîwÇÿ½RªyèÐ#›/ýö7Ç[œ¥ôÙ_þÊã«'8qâØÌ»ÝÍâwß3½^¯¥”ê?|øð‹/¾ ˜¹âñf³ùz§ÓYxöÙÊÁ ­¢_+:È·øäãË<õä)žîG,?Òª{ðÀüâÉ“«ÅÚÚ:Àr«ÕzøpoÐÀacÌraŽ…†Š1Öï諜?ÿ_¬ÿ“®\å³O¯òÚ«¯pdeµÖ§±ÐPIß³ ÚºŒÀ‚÷ž#1FBôĦç \[£Wx~ù«_sæÌ/ØÊkï¿s¶Öo¬9Ö×›šK„"‚÷­51PkF\¿þN?ý KKKœ>}šõõu¬’eKSý’f!TˆjS Þ¬µŒF£2¤ï(Uë „ðÞ'UÐÞ{RŽbˆµÐ*Cë c Ãá°0h¡UV¢Jk”Õ @¥ˆY–BP1†ét¦±ÖN€­µèL£5Ôù…”÷ï=Y–¥|S‰N)E*Èi¦ô8Ãá<χh¡t}’~%¤D Zk­÷~`0ÄY¨1@¹†Ã!ss(M ~ª_ÞÄç\šu´ÖÚD¸µÝ«}”Š=z„<Ï'£×ëqìØ JQë·½µ9‰€ˆX À¸"0‘QšÐnߟSeEïâ„—_>ËF§ƒµc ÿ~ð€³g_Bœ›ê£”¢}¿3—ô1C`º$)Š¢È­µˆÎÆRQ7M,ÆÀñ•.œGÄÑj=ÊÛÎsìè£ån¿í³³c¤ÓÙX¬µ ƒ- b:ùÍfóÌüüüI¥J)½¸¸Ø;uê‰Ó Jhü`¥2~úâ9zä"njî.ø§í›7o-:çpÎQÅz·Û½ä©úEQÜtÎa­Å9Çß¾¸–)1„©#ˆà½ μÔÎS(>ÿüïYU{0Ü©ÌæææU‰Î9D„»wï5ó¼°ÓÓ0 æækÿ1²ÝËm»ÝnŠ¥vìv»Wß &²³³Ó¶ÖŽÒDï½úàò•b–øÏöO¬®ÌøèÊŸ ï½J3ÆŒF£Ñ¿©x`SDòÔE„[·ïd³^-gGˆ¸úWV+®ß¸5WÕ‘°Y®99 ";çúZë•t0mll,Yë%Ë&óþ#‘Ngc)@etû@¿\sãœëW'‹ˆ¾qëÎpVˆg7n½÷“s¦Ôî§üïð!+"“~B }¿ö ÐnwBU«Ô6)ÿÕ$Iý:o—my?ÖËó]Z%ˆ§lÃÓBj—•¶9ó~8ËŒ1j¯^!Rà^bŒºBʸuº}8'ªšÒò˜¯¦}7@!ÛKLÙÿ÷eåpÏØõáSЀÞ[H!R?üK¾Õ‘Ö™àC_i­‰r¨¿~·ÅI T®ä_R©j>Fý~ÿ’Rªc¬¼zÓØï7vù¥T·(ŠKÀ(-Zý8X~<ÌïsÛuæ€kÀ`£à p€ÝÑùoXÒMhb_œ‰Ã)c%ÀIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-keyboard.png0000664000175000017500000000315414733247605027757 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<éIDATX…Å—ËoKÆ]ÝÕݱcbÆØ’@$"&ÊŠÁšøf{·H³™5K6(k@B€‰ ŒFAâ%E JLŒC@¶;nºÝ]³ ]·í€t“;G:²Õå®óÕwÎwNþÏf¤¾›€ ˆ=Ž>¥8>üíìÙ³—Rf÷2zÞììì?¯\¹òà»±â/ o€Þ½ ž˜RªyêÔ©s@Õâõ,Ëê ‚àψmÛ½ÀAà?Vò,Žc”R €8Žl€J)”R¬¬¬ðäÉ,Ëêxɲ,)—Ë„a¸k­R©P.—éf1 C._¾ÌáÇõ³ôA-~Ô€ˆã˜8Ž©ÕjLNN222B«ÕB)…aär9îܹÃÍ›7iµZ„eYH)™ššâÆ4ä„ôôôðöí[jµÝ ÀH$g$ (¥¨×ëØ¶MµZŶm<Ï#ŽcBjµsss˜¦©ƒ¶Z-Z­óóólll`›››¤÷N|çàZóF€RŠ(аm›J¥Â†a ¥$Š"„H)) äóy¤”†AÇX–…çylooãº.¶mEJ)’ýÿ)€]Ç8ŽC»Ýfbb‚Z­†eY(¥4€7oÞ ”BJ‰eY@&“Áu]Úí6ŽãhiO°~Æ@ضÍää¤ÎÛÖÖJ)|ßg``€k׮鵕•÷b±H±X@A†Ø¶­×S5Ð@$è²Ù,ïÞ½cjjJW¬RŠ0 Y]]ezzšL&£+9Žc<Ïcuu•`šfÇi«Õ*Ùl×u)—ˆ‘¼+:$§?yò$}}}ÌÍÍÑßßϾ}ûØÞÞF)Å… Èçó<}ú”K—.ñõëW”R éïïgzzš‹/òíÛ7 …ŽãÐl6YXX \.§Uð{Hû÷ï§··˲é Ï4MfffbhhH3aa’Ëå(•Jœ8qB¿#„àùóç4›Mâ8Æ0~Ÿ»R¶(ŠRòêÕ+”Rô÷÷säÈâ8& CÇaff†\.Ç™3gÃPÙ‡¨×ëd2†‡‡‰¢¨#¥ "¬[*‰Â0d||œµµ5­Ó4‘RràÀ666Rb𦣣£xž§Õ와It5¢ÄÛí6RJŽ?ν{÷Õ’Käè8GEJ‰BKuppJ¥B©TÒ=ä'ÈÐ)H~X"9ß÷9vì‡Â4MÖ×׉㘕•ŠÅ"¥RI×Ðòò2J)¶¶¶Ðí·Õjáû>®ëj©ïRAºªÕ*/_¾Ô-7”ØÇ¹ÿ>¶mëçív› øòåK‡„¾ÿÎöö6W¯^Mï³[‰½~ýš[·n±±±ÑQXÉïºS•Íf©T*¸®K©TÂó<½V(¸}û6ׯ_×r°ÓÒô¯¯¯wä.“ÉàyÙlç­MÁòò²– Àââ"çÎ#Â0¤ÙlÒe*è* Ã@Á‹/øôéÏž=cvv–ùùy,ËêpÇq:TóøñcLÓäýû÷»öþF7B=ë3™ }}}(¥èééÙuY‘RDZVÍÐÐA0>>NEZ‚]Ö9Œ’ÀéOÇq§ÝnsðàALÓÄ4Í]lÛÐc|xxX3•®ùG'ìFÝwÂÙÙYÆÆÆô¸ô)“ Kbkkk4 |ßçóçϸ®ËØØÍf“Z­F† ìÐ*0è’áÄÄKKK,--uÓöKBE=ÚµvþüùŸ]x©FÔAS>Ÿ'ŸÏÿáàÄ~uã¶´777ý\.çþO£þÂêõº´eîèõ}ÿÔéÓ§öôôXébK” ¥Ä¶míŽãh·m[¯'5cY–.Z!B à^¯ûwïÞý×âââ= – æ^à¯À߀}{Mðo`h¦ÿÛ@–T{Þ#küÞÊ VÏ&IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-datetime.png0000664000175000017500000000326314733247605027754 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<0IDATX…Å—ÍkkÆõ]©®$Ý7Ý¡»qa2ÆbG".³üAñ.rA.¸˜âB¼"¸RÑ•„ÙˆÁ… ³2j4F¢f"IÌítÒE§«º««ÞY˜*ª“ôî‡Ì‚¤êåœç<çœç= ÿg“+€ Èß8fx@`Ïëׯ©Õj躎ªª\¸p®®.nß¾çyœ9s†¥¥%ž={7Þ/h™[!ªª¢( œ:uеµ5Â0¤\.óæÍ>ÌóçÏñ}Ÿ£GR,YZZâĉ¸®Ëðð0¶móøñc|ßoñd«¥Q¢Î]^^¦X,rãÆ 4Mò,Êå2Žã°¸¸ˆišT*Òé4SSS,--1>>ÎÍ›7Y]]%—ËQ«ÕèêêŠÇ0÷ $u *G?µZÞÞÞq¡P P(•JMÓÈf³ÀWí( tvv’Íféíí§)ÃDÆ H$„(IS¹\ÆóO>Ÿ§§§‡|>O­VkiÂÄHÑò!ïÀqVVVèììÄ0 šÍ&²,³¼¼Ÿ ‚€'OžðñãG$IâÞ½{ J¥ð<¡¡!¶ûNHqë1ÊF£Áææ&ûöí£§§‡/^ Ë2ªª222ÂÜܶmcš&¥R‰ëׯǴNNN299 |UÉb±HµZýÅ)¢û?ª“ëºT«Uæçç9þ<'OžÄ÷}$IâÚµk8ŽƒeY ÄwÈvó}Ÿ•m+Å€ˆ¦\.Çúú:W¯^å¯ßÏ—ŸæÖ­[X–…®ë!ð}Ÿ>ì<·T*ÕÒàIñš"!–eÅBãº.ÿñGþñÓO±JJ’D†4›M|ßçòåË„aÈ•+WÈår\ºt‰={öpúôéؾD¤¤E(;::¨×ëȲÌ{`ï–£L&C&“! C‚ À4M¦§§éëë£T*166Æôô4£££xžÇv™ßµÛA@*•²,Èf³x++är9,ËÂuݸiGGGQ…\.ÇÄÄccc4 Êå2ÝÝÝȲOP"ûÖË(ú (JŒ¸V«¡ª*ýýý„aHé»ïèªÕjL¡ªª¼}û–™™²Ù,³³³qlll i®ëÆ=d¿e%‹öAÏóbÊ$IŠ7£væ8NÛŒºÑh`šfÜ?l[ÉâºkšÆýû÷ñ}¿mÀßb𦵕b4ÇñlÛ6×ÖÖâ¿ußnÛwÇq<  e €íyÞŸ*øô!"ýúâ“ÿ‚>·>>Q(IÁT «!¸Á"–F×ÉnÜ™ÌÌíÃî½ÙM´¥µ=pÃî̹÷|Ï÷œó½øŸMä>+  Èw3B Í(ݺuëÛC‡}ãyÞÎw=Žã×µZíê©S§¾"ѱgqqñW!Ä; nͳ±oß¾O'š.õï{ž·3Žãÿ">¾ï+Ú>˲ c õz¹¹9„Û@–el†!¥8†ÞÞíLW«Lõ•J…,Ë| cŒ0;;Ë¥K—BÐl6IÓÔ½7Æ „`×®]!øñòe¾>xX¢0ÄäÎÔ֔Ëež,-±°°ÀáÇ] @2Ë2‹ €$Iرc¾ï“$IqSïÐõõuF£ˆÖ—_¿÷q“$‰óBàyi¹Œ¹r…4MÉÅ‘€° ˆ<Íf³°ßÚí6A`ŒáÕ«WTFG]À¼ !‚€8Ž ,öw%yŒ1¤i €R €;wî¦)SSS“e¤iŠïûÄqÌüü<«««Ôj5fffð}¿ë×Û“‹3 Ï@š¦(¥âF£ášRJé|,­5I’pôèQ´ÖìÙ³‡R©„R !¦w¾aÈ<»¬“çy(¥xôèív›v»ÍÇQJ¡µîúÒ­5J)kkkLLL8?!Y.øVd¾>6+!RJ¹xñ".\ ^¯#¥DJé°¤”ܸqƒN§ÃÍ›7i6›H)è1-ó%ý%H’Äm>þ¼{~îܹ‚1†(ŠPJ¡”bff¦Ð„–)Û7¹Ðß„<{öŒÝ»w»Ú[€Æ–––hµZ´Z-‚ `hhȶ¾I’°¼¼L57‚ys äÇ0MSž?N–e¼|ù’þòcèt:¬­­ÑNSöß»Gë—_ØòOqÿQ±Ún#{ï·* €¨ÝÆÜ¾Mš$4sÂ’/‘1†÷!Í2¯¬hB J%¾__gòäÉn†ðÙ'ŸÄÎô Q)Žùzb‚ðôiZ­QmÉB_S9™f$Žé\½ÊÞžnäç„È)¡´mékgÑÈi¥Â ¾ÙŒ”ü¶¼L†瘔î[Œáææ¦›;rY–¹ïvA0ðLkM…Œ·`¬Ð"ÔC–¦®iæççyñâJ)ÆÆÆ¨×ëLNNE÷ïßgzzºaÿèmÃÀ çLî §OŸröìY ;V<`nnŽññq¤”î¾°æy^ÿÍ·•”p ¡²ž¾[ Ã8ŽYYY¡Z­¢µfïÞ½!œ]ÀÛšöÍ%èu´”’ééiîÞ½‹‚ãÇÓh4(—Ë(¥Ø¿¿»œ¬ÙK x+:ÿ%?NÉæ&•J…J¥Â™3gÜÎ'N¸ÏGŽ8YkMEî¬È]%,(ÜÆÂ(¢V«166Ö½LúD¨ŸÊ¼5 :ζ ô¸)ôIqid„§ Œ\»ÆïV^-¸m²ê·á$ážïóñö¾…Ÿd…Œ¦NŸæå±c¼þ Þd_ ¿¬¦›TAX­VËöÅèèè? nm«4›ÍH£z†Â0Ü7>>þa¥RÑvœ´Öh­ñ<Ïóð}ß­R©ä–ïûî½çynŸ=Ç*dïg~xýúõŸ?~ü°j/æ!àsà0ü¯¤¾½­³ÀÏÀFþ_Ø ûîù»–¯à)è¼ÎMw’IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-a11y-settings.png0000664000175000017500000000311314733247605030563 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<ÈIDATX…Å—_Œ\UÇ?çÜ;wfwfÿ¶K±n ¥Ðm€Z¢.¨4A1D^ òd¢$5¾ßúêƒM¤EcÒh%hhµÑ¸„,UhˆÅ l±¡´]º;Û¹¿ßñáœ{î™&Цñ$gî̹çü~ßóýý~ßsþÏÍT¾'@°WÙ§@ªê‡~½pð®Ý;iÔjéÕôÞéöò'O=ùÕ?ý(°aˆíyóƒSâL­:ÙT!þ·ÍJŒëÝqãÌà)žúÍišÔòžðÌÑW8ýÏ1€1`Œ)Á|4¿þé.€¸ùãS|eßnÒ4©3À»Ý™sœãõ3Ë4[SXk|7ÿꪾ¿¾tœÃ9Äxÿàð;6¸¸s3Ä9ÇìDÊH–ðƹu°ÉÐ{là´ôZ|Y¿ÀᜂÀ‚3€ÃøGŸñûoiòȃŸà'Nñ½cocÓ2… ņðN½m"0EÉ™€Ñ0ÁiXTRXôîå6_¾w.:»÷®[a}hÞ £® À(<Ž"iÔqŠªG^í"9\XŽ:]VÛ«CóT5Øpa,ø F!8ª~aÌ}ÍÁX¬-s Íxâßzø ´FG8øÓç‘Ú$Fµ SÁ€µo·’„Âu8´³Æ÷÷?ÀòÊoŸ½ÀÒù6g.vXº°Æùö÷9T„æôµL×˜ÎØ:UgÛ¦&×m™dj¼É7ÿ=. ŒŠgA‡X Ù© *ŠÁ ¹ðØw±oïmì›ßÃç'ÇãWÚ—ysé}¶Ï^ÃÄX3¾k¯­ó»?½Ìã ¯ÒíN‘XEÅÀû÷á(¢£Šª`°Øl”÷´Á\âà/Ù¾¹Îç>±ƒûïÙË–™iî¸õ†èt£Ûcáå“]x•…¿ž!›ØJ­µ›¥¨„\R¥ð3 f­¸ÜÇ ‡5c m´ÛzçTxúųüvñž>ð(Õ¶ÿÀùû²%kNÐÚ¶³`8$¢¯ qy¬ª˜Oý x ¢AÌ ÒF‹z6¬ŽI£E}¬mö|^¨V_²SUU¯¶"D•æªR ëúæ•ìJ,i×w8JhT½"b¬âÌx 9":<Ž É]Š“* ¦¬‚" EPÉ1Øp"˜™àÜùeT•k¯ÙĦñNؽ0¿cʼnP!…ÚâÌÔ" ¹úìèÒëñ™¹xêð ÷飴Z9Ýn— Ýq€S+çI•aŠKZxïkª\ï=¾òHTÌÉ_}ä‹Xk›¸Zkž=ö7^=]1ãa¢(â¥wOÑ>vœ‡>uk-!Ò4å Ÿˆýð׌t72a ØKákPm‚ªb6ŽUç\#Ä•õ‹äÛvâ¢Ue¦»ÈÚÙsÍ~E„&ÍÉ`ðTâKÁûK Ð0¹ƒÃY ÎÛÆàûtÚ9z¡BÅ!^PïiuÒfÊÔT¨5["½ºš µüë"Þ[ð›'Ÿ¦g<øÀ½DQÔ88t`‰õÞ`cP¡!ÐÍ+¸í D„?=óýÁˆw×.²mqA›g¦~›k1ÞS† ×éò‡—NSô/²£»[ö/1±Ö²¸p-<˜ñïwN¡ ûoºms³ [yžóÚëÿâñß¿H”Ïw¶Ñë÷PÖX\]ƒþaR6QÅZC>ÛÅXËÚÆyn»Õ’¦)eY¢ªÌÎÎp×*§”§iŠ1†s˜›ßM”µ'q¯“~0‘šm.[[‡”e‰åxÌá½³qœ¥}{¹nÏ.VW×ùÙSÇIÛ]N<ñGÚYŒÌ,2»=e42. ²4G0uJÛhFÖF¤i ãqœÅ å¸d<‘¶·ããŒ‡ÄÆP޼ñæ Î?ª²qö<ÆeÄy£mBÖ"ÏgÀ|F£ÁD«TÞÀfi†R‹L¬¡, FÃ!Æ(C0P†Zp&móÓ§_¦*JªªÀ¹„™»¨êI‡jàYN’dTÞ3ô)Š‹$IJ«k£X(< 0®}¬ÒT³þ G˜ÌrÆFÌ/.QV%ãbÔ%×OFöA‹v{–jЧ•·‰ã˜8Nû }EUSM!"ÉZ´ ŒF >¹1µÈF£QíÜ€5†øð“SO—*”T¨u¤qÂVhwZ¸Ò“$ƒáàòjHDÝœ}9Ú*­M“Á Ï¥¯(ý~œ‹¨*OQU”•çƒVèõ03s@@{B–çx_’¦Â`ëìð€º‰·Žx{{nçbÇÎ9K9’ÈTX£dILž%´ò„m³mff:¤ò4¢•§´Ò„,I“˜$vD‘%,iš (Î:Ò4Çýâä+~¾wî?¿NOsøp/0ûGúß­-àyàпüë8Ú\Vœ>¢åPüdÖ‚ØW¥-QIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-printer.png0000664000175000017500000000273614733247605027647 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<[IDATX…Å–?lËÇ?3;;»÷Ç6¾sÐK!zM(„R¤Å"!Jš(Ñ«Ò&e”:)èSD¯HMùÜÐòò0ˆ1ØÒÙ{øv÷vwfRøv´wö…'+_iu»·3¿ßw¾óßoáÿ Ѹ€§œÓ9`š¢?_¾|ùavN3{QãçÏŸÿm}}ý¯ÀDLI|õöíÛM)e÷4“×0Æž?~ ØRI¿¢”êVU€”’íím†Ã¡B|*ÖgáœãìÙ³buuk-avŸoÕtœvÎᜠîÝ»g³,W¯^ÅãßYkBÐ$f­EJ‰Â'‘ROž<¡ÕjÙÇKcŒ'h€šMÎ9”Rôû}÷àÁypp€1!UUùDqPB”RdYFEt»]â8æîÝ»v2™‹_Cqä)FïøhÚH) ÃV«EE(¥8w‡ìïïûdƲ,ó{½išRÎ9Â0¤ÛíÒnÅtÎyu¦¿õ‘õ€4M±ÖÒjµh·ÛžiY–EA†Xk±Ö¢µFAÇ8ç‚)%Y–!åQèv»íß7¯éÂý7rІV«…sŽ(ŠÐZ{ËËË!pÎ!„@kÍd2©MåW¨”Â9G«ÕBkÖšªª<醳¾-·øæßÿàw?û­5QÍ8z<£”¢( :“É!Ae (¥¼?Â0$Š"ªªšñÀ‰Öú¿à·â÷\Y¹À7yî'IÂÎÎA`­¥Óé0 ‚­5iš²¼¼LUUÞ?q£”"MSò<ŸñÀôÍ+ñ~óó_3 xýúõÌÊ—––XZZâ$ÔÇM)å¯úy4ùq'œ9C ª*Ò4õ ë ÷ïßwµ¡~ˆ@UU(¥(Ëçiš²»»ëŒ1þ|ŽeY’eÆÂ0ôDÞ¼yóEÕPks޲,ý‚æ¶€þùøï¸ù§c²} šóç«)ó Xkÿô?dYÆ­[·ÄÇýÙžGY–ŒÇcÐét\­ZÖZŒ1ܹsÇ-8®€D|ýÕ_üË‹/²±±áêb3<ÏÉó€8Ž]]–ç(Š‚K—.‰¦’Ó @ø-ØÛÛ£×ëù‰Qyͳž&e0üàþÔòK)}¬:Æp8„ùSðáÃò<ǃ1†÷ïß³³³s¢üÿ ¬µlmm1™L‚€ jåf=¦)Î9ªªÂC’$¢×ë(s•õ6| I’ˆ3gÎøúÐôƒW Ïsßn1ôû}VVVÄ… üà¢(ØÞÞfooƒƒö÷÷)Ëò“Éé÷ûäyî œ¨@¸þuα¾¾Î£GØÜÜ$MS¯ÒçPwÆëׯsûöm¯lÝÈê/¯&1¸róæMnܸÁææ&»»»¼{÷Ž$IF|üø€……YZZbuu•Á`À•+WRúÅ4·òÄvœ$ ÎñâšíÚÚkkk^ƺÀQ‘±Özõß~OòP’$ÇÈgÏžYcŒŒãØOnV¯/EÝ®¥”H)Éóœ/^X™P<}ú”,Ë(Ë’ªª(ŠÂ×ï/…”­5J)ߪ1bJÀ"”RNkí5k~Åüuò)WoS¨Ê²œLÿûqš (Š PNMo¶_¾|ùýµk×®k­µ”Ò)¥|K­Ëh!üsm°ºìZkqÎyïÔ&l~°Xk'¯^½ú° TµÜ]à—À¯€ÅST`||6ψ:4ŠÓ)¡Æ@ð_ÿÜ%j:êIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-color.png0000664000175000017500000000440214733247605027272 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYsíí ÚòÚtEXtSoftwarewww.inkscape.org›î<tEXtAuthorLapo Calamandreiß‘*\IDATX…ÕWipÇ}Ý3;;«½Ðj%V„q…C #s:IUìP@R$@lU&qv(â8±qâ¢lìŠBQ$. ¸ Œ9â’"@ׂ¤]]»ÒÞ×LOç—¸lYå?yÿf¦ç½÷ýõ ðÿ ·Û=.Æ=OóÎ;¥ÞòÐÞ¾h6›öG}ÿ’Œôë—™õaoyz…ÖV×3ñX˜»/ZyëõE¼ËçKÌ_¶ÌÚ®^e@’ôoÛ6C'øè? —¸îçÏ>[üp:rWW—³³³3ÔÜÜt¨­Í5³ûó¦¦&ƒ,'NøþB‘2D:¶aà€Ï‰ÝyZ[Ýox;½WƒÁ@¢¶®v[ èõúa²,çÄÿÞ(·”ÿÀl²–ºÝnO}}ýÂ[ÑÓÉœˆNô€ŠvP] Ï`KNÎŽD"ÖÚÚZ}»§íï©©©!Ù,¬© îÒà/Ñdü‚‚‚”õÄo¤§§_ƒLk>/—>F€1Å)Ž9«w48ËAW•ˆœ…@%€”¸`±X¤U«Wý45Õ¾&N:Ì'Ü+6œÇpúg¸›Ýõ=Ê!„ Òø¥`¤1˜ª·"´a¬ÁêñF£y‰ïÆE‘ª×0{æ¬ —»Ö›ÿZ‚„å$=Ó²­³PV~vwvv¶ï €¦i¯™'üajÑ[!JI0Ñèþç:· ÔBM 4 „è ±޹^@ÐpzI‚,&Ccvu6:½¾Øî=;÷ìÚµ‹õÈ@VVÖi èžZ &î I'@:ÿ˜+B- ÔB͵áœg t–v¢€p ÄÍ—¶GKK·³(kìQ î ðþÐ0±˜‡ä~Ð8*€’¡“dèÊ?‹ßZÇ9ÐÌìÐL7 ‰VD¨LC&ýn6´{>þtËçÎ |+.W{U‡×sÚ²x/ÂH×["€©‚X•xÏ€Ñ*€HŒÐT )4ù)‹q äà_¢~ÍãtH÷ §Óé0™Lo‰¢øcI’ì”RÂ|>°Xb‡^‚Qõ”BLà3E4Ú’­ T×8ã#£0Ô¶"5@…Bª§³ãF»·cݵÊk[‹‹‹•û 8NGŸ>Ö݆¤¤É‰ºzø7o‚PY]4 R‹L͋”Ñ)ÉN„r€«¹V=,_0ŠQDH鄨²fÇøä˜Ö1ÔWkj®¾ïrµ­\°`#v{JSüJ% ¼þ:Œ-- ¢Áf!·Ô§ˆ €s. ˆf (&U³lðÆãpż+þ»aETTžÄYQ5h£äyX”÷êo:ß}gm®Ç„P9rbK èmÑ»âÝëEÀ)Âmi¨ 9Бꀿ*$å˜Á{A x·<€SŽšðIÜ V ;ÒêêÜ} ”/ýõм¡k¬¢NmÞ vð ¢xÏŒÕ ˆ"št&œ¶çØÓn"ÀÙ¿§äÕŠŠŠÈuóçÏntt¤ËÍ.¨¹ît&ÂákÊ£4¿¶ïغÒÕÖÁÇ-ÞȲroooÓfÌ™3µ7\½ú1©¯½¹>ÐÕ›;©?V-†}öžhíì¬í W¯±qó‡/ƒAÞà¬W‹æÌ™‰¯™ª_‡‡š°§(~á•®ÕT×^«kR£>ßyŸÇu]Þ¿ÏÄÄÇ'‹‘N§õ`-7Ú.©TŠR©„ÖšL&ãG¤³³“B¡€1¦!@¸®»m)H§Ó|úô ¥ÏŸ?çáÇ säÈ,ë«¿MüŠ÷£>þÌìì,¡Pˆ©©)¦¦¦¸zõ*‡& áº.µZÍçmƘm‰ÀÐÐB’É$333\¿~ƒ"„ X,R.—ñ<cŒòm,@øæG\¼x‘099IWW÷îÝ£££ƒùùy´Ö´Öh­ýˆ/C°Zk™œœ$ 144ÄÙ³g˜››Àq<ÏCã88Ž`ü= µÞ4ù¥K—H¥RX–ÅØØ'OžäãÇäóy¤””RìÞ½c •J¾æ)ZkµÙ¸®Ë… H¥R¸®Ë;w8tèÏž=Ckã8D"ÚÛÛÙ³gBü ©q©l©Ôj5†‡‡ä7nÜ@kÍË—/q‡}ûöÇÙµkW“­)åÊBä÷ß# Z­222“'O‡Ãœ?žl6‹ã88p€žžÂáðºöõ¬ÐÈÇ·ö@­Vctt”§OŸF R©‹Åèíí%‰lhï;X¬ž°´Öܾ}›ééi¢Ñ(ýýýÄãqŽ=J4Ýx5ÇòVoE6Âøø8Éd’îînN:E__ß7=^õ¬¨–âd2Éýû÷9wî'Nœ ­­mKÄ>–ß–ÿBAµZåíÛ·Mñxœ»wﲸ¸H>Ÿ'ŸÏošTk͇°m»9B¡”"‰Íf×\@)µnOø½]skk+¶m7C,ËB)Õd´Ù–ü{P°´¤”Ò¿,þ (¥VCcŒ±m»!`'¼^Û¶Ïà>~üøïk×®i¿/Ø øN)¥ÈårE  (ÏÌÌ$oݺÕæÌ™_‚Á`óF¨cqqÑÛªÏóL¹\Ö¯_¿^¸|ùò8ƒ¥?§-ÀÏ@ŒUÕq0üd³<Ù’¥Ê¸“ð×ü ÀT‡odíéIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/32x32/apps/csd-power.png0000664000175000017500000000357114733247605027316 0ustar fabiofabio‰PNG  IHDR szzôsBIT|dˆ pHYs|4k¡tEXtSoftwarewww.inkscape.org›î<öIDATX…µ—ËWÆçÞªê×d:¶Ç!¶!ÈV¤DJ9‹ì›,# $ÿɱ °àoÈÉ ¤HìAŠ"Ä"R"±B Q2ÊkŒñ#ÝÓ3]UÝÕUuï=YTu§¦=°àŽŽæv½ÎWß÷Ó}„o·äÕW_½þÆoü Hʲ¤ª*ªªb½_­V”eIQÕ;wþôî»ïÞÂ7=8êì-ФîŠ_y啟gYöûu¢Åb±‰år¹ÙEÁõë×#àMÀ‘3ÅÜ:Qïµ×^»}íÚµß^½zõòÍ›7‡ŒF#ƒý~ŸÕjEš¦Ü¿Ÿ,ËÈóœ,ËX,8çðÞS×5/^Ä{¿‰ÃÃÃÍ9ï=ÀÃ4MýÖ[oý(£ÄÕ~¿ÿ›étzyww—¢(°ÖÇ1I’à½Ç9GUUEÁb± Ë2æó9Y–áœÃ9G]×Äq¼ä½g2™lε×]Ç¿þ|¸XÅ•$I¨ëš²,‰ã˜(Šˆ¢¡,ËÞu]wx*Öçº,¬#„@år¹\în<0ß|æ™g’áp(ƒÁ`ßZ«u]“ç¹EsN«ª:)Ëòn]׈ˆ&IƒAðÞkAëº.\¸ä½Wï}pÎ1™LÖu­ÞûPU•îííõ=zôdׄ8xî¹ç>¸}ûöS@ݲÚðýäÖ­[¶ÇÖá¶>?չϟl?÷úë¯ï€[3à;.ÕNÂÐ~îÆ7­uò«À -€i'–ª*ëœÑذ æ¬Õ-Ûõu_ŸŸ³Å@÷F³¹+Ó9¾ýÖß  B;מو¼÷›\ÿ‰³ÿ7 º ¬=sø §$èÞ¸ÐEµ•øÛJ°ÍÀÀ§À¿Ù’ õÀ)òÜùñ¿üÂÈóÃ}TJ ' êÉÊcîÏ?!¨'OPW‡¨à´Æ…šäI‚v‡óý+Læ÷(ËÅ*gUä¸ú˜»—'ooŸ°(¢b¶ÅÚFx!(éJy0‡Z«+øÐ¼ºsB`§×€Þ±ŠÍ`YÀr E®†|)åš±Ç<  ª-ûbÆâ‚6a\#‚Ä‚ñkœ’U3fé„ÙÉ_{Bí ¥§oOç‹:‰e-¡¢ Ú²¡í_ÀDº ÚjZ‰Æ\=̓ì_ˆ <5þ.ÏîýˆÇ÷˜L9šO9>™2O;¹ÎªŒb¤ñ€P (ŠÕ€¶ô[mþnœUµÄ®Hàaþ)w§ŸS¯G½òÞ‚,ÊÈ4§Z7?þc@TŒ]SÑTÀšLVµ m´fŒDß¼ÀAþ>q¬¯U¬ki×ú›3:aki/lÞXlË€mz%2 È5 Dâ…'|é>ÄÄže1åhþˆ<­(rÏjé(ËFÌãe(" ¬"¦¡_L£}㉀¶2µ <cÀ ‡õ{˜8`Q¾³ó}žÞ»ÅQ:e:›2=šðe4åxv¸Î¾Õ ¥Ñì[ Zú¥ c”Ö+˜¦D*¨¼¾‡•((“ê>ÿòcsG‘zV™c•ù&a§ø¿ö€6Tš®·6Ÿ˜¯eÑFϨé˜ÆˆQ€àšçZß–ó)í;=@¶:¡öFùÍËGáh8j÷ “$±&½ˆ$ް±Å¹š¢^¿<œ«ð¾¤vµVuEߎLY—š¯2õAÕUµÔe_9‰JozUmlL¯ö†P›‘ÿÞ¼³Ì¢Äóáá…ŸùO\ºÄèÊÎ;Çn²Ëx0f4±X,H«”Y1#MSò<'MSÂbK\YâÛ!Å9‡wuqÛîµB/ÏŸ­%póùüªîF#Š¢ØLDÝ©g=3¬V«Í8–eý~Ÿ²,IÓt{Ùì»ÇB÷i~M«m{Ê0¾qãÆþîîîÎxܼõp8d8ÒëõN ªº)k-£Ñk-"rj ±ÖbŒÁÓ”¸ªúð£>úËl6û+pom†à¥6vùÿ®xxXt¿›à ¶¾!ÿ‡õmfh '*€¯*ø§¥²EIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/0000775000175000017500000000000014733247605023732 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/0000775000175000017500000000000014733247605024675 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-screensaver-proxy.png0000664000175000017500000000216714733247605031657 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<ôIDAT8¥”ÍoUUÅ{Ÿsîkß+ÚJ©H@Ûò)Zˆ“jb‚u"‰Qƒ61q‚ÿãÀy !!Έ‰ÑšhªUJ+%A0m"‰áõãÞsï9ÇÁ}ï! Fãžd¯µöÞg-áÖþ_¥[€¦§§''''ßÜÝ:DDUõ‰SJÅìììÛSSSß[ ±}ûöw÷Þ“çùß6eYF–ewm48ç}8`¾õõ|Cžçœƒªr»8UeçÎqªªº]%1F¶najê0!„ÐgÊÒ›¢(˜™™gaáÖÚ°ÈM‚ƒÏ`` ÕAü pŠÌÍÍ“çyØTU ƈ1еk ˆ Àž‡Ç8tè)ÆÆ¶±iÓFbL\¸p…ßû£w©cOyUUÒÖF: ‰cÇŽðÚë/ ª½u4›Mvìxˆ¹Ó‹ÌΞ¨E‰!¥ÔU¬À{/1F‹µ}8kxù•ƒyõyªª¢( >úð3áèÑɲŒ‰}»¹Ñ^ãÇùK¤”µ„ðÞ €ÖŒ‰”™ÍÈ\ƒCC¼tøYŠ¢ ( ¾üb‡`ùîÛ3xï)Š‚‰‰„¢ˆ¨ZRJt§W€PU’R¨¥‘5Ù¿oç,Þ{VWWY^¾JYzÊÒ³xö"yžã½G†7ÝCéŠíîøæñʪ$¥„uÎöqÏ`ï=s?œãÓIŠˆ2±7»vÖN©JPãˆ1öú, ÝUµ8Ó`}%§( jÒŠÖ}µˆÖG½q½Ý3ÒêÊ ÁY!ÆHA±€”eY³Ø ç\¹r­ÇB Ù—aéüšÄJ»MQ¤”øuéVúqΑRêöÕÀ!I)¡j°&cízÉÂüyvïcóæ<ý\mA:{dmm_./ƒœ†Sbç?w !Hmƒ³Jæš|þÉ6ô³qxˆñ]#Ü^KKËÌÏüÄPkœSBô¦¯×L‚`T1ªX;Ä©fxô±-ìydœ,«ƒÏž‹ç/sõçël½ÿAœ‚QÁvwœW+N)IgbŠ$´Ã\:»Êâé¯èo F*Ãðà0Ã÷n&”D%*Ø”c$ÆØ³4UUu)ËPÛ:ÕIce «§‚m*UPV×}ç˜õÞS‹;²B ï=O<¹7–Õ|²VQŒÆH£"ˆÖªEDMSbçÞqñÞkçb¸²²RæyÎ[ô7Þ•ÿ¦RJäyNžç´Ûíˆh?~üýªªÞj4Î#uЫcPU‘^ÂÅ›™BÄSÇ©(ŠòĉÓ@»+­lÿIê•KÀꟆ©[€†}IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-background.png0000664000175000017500000000214414733247605030272 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<áIDAT8¥•M‹E†ŸªîÛ÷Þ™É÷$2!q‚;—ÉFDÄ…âÆ½ÿÁ?$¸tçB!\è?PL„ ¨Á|ˆ ™¹÷vWw}œªãâÎô€Y嬺ÏSo½ç­jëex³ÒW@ßÞ¾óÉÍ›·¾©kÛÌrֺȸˆ™f0ÖcГ݀1µ’'@Eƒû¾xÿã2ÀôÞ¿µ=»˜s&¥ô¿Rªª¢iš×J­ëšº®é/¯¼síJ ̺®Ÿœ2…_ÿþ—g¾°·zöÚƒé¨êZÈ“Y®æ;—ÈÅ”•U;ã,žÉ{×Ì¥ë{x&À¬IŠsŽ{/zžNw™?{Þûç÷Ü\_æíyª¦ç>‚ée=0ecjØfW.óøéœs¨¤°{Tº!ð2,K ‡‡ÛòTH‹ß0gæ 6ïÊ *Ñ#CÒà9Û!DÍ3‹ó‘C"ír¥i±››p¨„~¦ž¾«CUN€sÉÁ“|ÀäŒÄ¨€­²ä¢ª¸9Ì×:•år3¿P×CM‡÷KêâI°–a ø@)Iù„UuNŸ„eúU_Êj56[¿Ôê(-ÃÁ]õ³›¨–#p)ê<ê#¥Š=áqBU !³êßvšÛv£8¬L}ÖÅ}u篎Y.®Ú=fø´K.ÙZKÌ•¡÷jœ¹óÒ•¹ÊÚ•Byé2ovÈÞªuÆ4ç| 6"bT•’33Y„"²‰TLXY'Aæ`ùˆ §§¨¤Ÿ¨vž¢yíqL05`R\ûc5SK@³V~cQjÂú„§ËvES9 ÚÞב&“31F°H29glNÔ ™PU#8IMŒG`‰°Z0©·a ¸ž¸­T9%ŽŠMJ ›2ªÅø²Éê0†õ)ö6ȱe65HÛé°h‘ª!ÆH"£ÇQ")%44bŠÖ÷AÍ0èÑ"˜ÁD†aI^ã–+ü| #1n¬ §dcŒœÍK®KK}ºiþ´oàvuÎþu”Û.ëV›‹³,¶š_â 4ïr=BŠv·$FD¸À’æ9Í…ùôÑÙ½±ùi_ªz½C¤P…ÍÝRMïVçÙfOä8¥"˜®ëØß¿A„­4èNŽco³£ZUÅ”b´±:þTj=¶Ø¿±O×u„Æá•¾Ä9ÇùS3>ýà@Å«e_ó<~cÄ9‡ï½¥ÚøþkûÙç_nÍfµµ†’Ø2SׯcfÛV«Ú€œ‹.´JѬ¢ ³Ô ¹à‡A¾»sû+ =ÞÒ6p˜òfå'€ûAžÁtÞ±¹IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-xrandr.png0000664000175000017500000000177714733247605027464 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<|IDAT8¥”MkœU†¯sžó¾“¯NbMè¤ê"‹¸RmI»uaýRu©& ´?ÄD0ˆ %d#è_Pj6Ñ…qL h2MfÞÉÌùx\¼3“‰”øÀáÀáœëÜÜχálþ_èÐÊÊÊõ›7o~佯ªžîœinllÜ]ZZúÑ•ùùù§§§_l6›Eq.©cccLLL077· ÜrÀH»}rñèèˆååO¸÷Ý÷ç¿ôÊËܹó>Þû ÀˆðÞÛ¢U°~oƒ?ç¯ß[gqñ]1  Zzn­\¼õÚ«ÔfkÿÜc¤¶Ýn×(Š1§yûðî¼³ø6Ƙ3ëqÑ?÷ÞX×ûÅ §¿^}þ*V,7n,055E«U`zÅ¢ª( ª$M¤”ŠU•‚p½ËÚÿU¬ððáOìíîqÿþ:']r—ŸV¸*ª  ÉFRLÅ}ÉSgN2ÆÆÇÙßßçð°Au¢Z>2 „)Ú-b7BÀGOŠ‘â@q畼ÂööÏü¾S'*„nº„Ðch6›=Å‘#1B ¨*Þûb“R,mA$C¬å·:õú.‡ªš,säYNL%ؘ€1ç„’•ŒLŒÑ¤”+` ÝiS¯×9l4¨äyÉÕSpð›"1YL/­ÖJ?yfŒ1†Ž©]ªÑ=épqê"V„ÆAƒ”ÆZ²LȲœêèGe3)JæÜ°Ç¦ôØ£ª„±Fqx¯d.C¬066ÎäÔ$33Ó\~z–ÉÉ \[xïŸ}ú9›››zù:õ¸o¼X‹ˆ`­àœÃŠett”‰ê8O<9ÉìåóÏÎS«]¢Z½ÀÜÜ®Ýgkk kì?¬@UËþ‡1–#y1B‰NÛSï³ûëüðíÍ¢ÉìS3loÿBŒe;± ³§ªƒ–m5é´»dYNærò,lj#ić€5–úÎκÒ{c0=Åà b FC¼ùÖ|ýÕ7ˆX¬8œ¬bÊ]RêÕlŠÄ˜)Säöí×ûsb¼Ô*ZíV«Å•+ϱ°pý±Cæßâää„¢(8>>ö@rÀñêêê—!„÷*•J&"ÆZ‹µöï;@9Ê¥Ã{ŒQ;Ž_[[û8î–qà r.¹CÂ:Ðú ûÂêje›°IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-orientation.png0000664000175000017500000000177714733247605030521 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<|IDAT8¥”MkœU†¯sžó¾“¯NbMè¤ê"‹¸RmI»uaýRu©& ´?ÄD0ˆ %d#è_Pj6Ñ…qL h2MfÞÉÌùx\¼3“‰”øÀáÀáœëÜÜχálþ_èÐÊÊÊõ›7o~佯ªžîœinllÜ]ZZúÑ•ùùù§§§_l6›Eq.©cccLLL077· ÜrÀH»}rñèèˆååO¸÷Ý÷ç¿ôÊËܹó>Þû ÀˆðÞÛ¢U°~oƒ?ç¯ß[gqñ]1  Zzn­\¼õÚ«ÔfkÿÜc¤¶Ýn×(Š1§yûðî¼³ø6Ƙ3ëqÑ?÷ÞX×ûÅ §¿^}þ*V,7n,055E«U`zÅ¢ª( ª$M¤”ŠU•‚p½ËÚÿU¬ððáOìíîqÿþ:']r—ŸV¸*ª  ÉFRLÅ}ÉSgN2ÆÆÇÙßßçð°Au¢Z>2 „)Ú-b7BÀGOŠ‘â@q畼ÂööÏü¾S'*„nº„Ðch6›=Å‘#1B ¨*Þûb“R,mA$C¬å·:õú.‡ªš,säYNL%ؘ€1ç„’•ŒLŒÑ¤”+` ÝiS¯×9l4¨äyÉÕSpð›"1YL/­ÖJ?yfŒ1†Ž©]ªÑ=épqê"V„ÆAƒ”ÆZ²LȲœêèGe3)JæÜ°Ç¦ôØ£ª„±Fqx¯d.C¬066ÎäÔ$33Ó\~z–ÉÉ \[xïŸ}ú9›››zù:õ¸o¼X‹ˆ`­àœÃŠett”‰ê8O<9ÉìåóÏÎS«]¢Z½ÀÜÜ®Ýgkk kì?¬@UËþ‡1–#y1B‰NÛSï³ûëüðíÍ¢ÉìS3loÿBŒe;± ³§ªƒ–m5é´»dYNærò,lj#ić€5–úÎκÒ{c0=Åà b FC¼ùÖ|ýÕ7ˆX¬8œ¬bÊ]RêÕlŠÄ˜)Säöí×ûsb¼Ô*ZíV«Å•+ϱ°pý±Cæßâää„¢(8>>ö@rÀñêêê—!„÷*•J&"ÆZ‹µöï;@9Ê¥Ã{ŒQ;Ž_[[û8î–qà r.¹CÂ:Ðú ûÂêje›°IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-a11y-keyboard.png0000664000175000017500000000211114733247605030516 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<ÆIDAT8¥”]ˆUe†ŸµÏ>gÎx&™qj¦ñ‡0d2Ó•Ê 4ê*Š.‚n¢ ‹èº‹ º+ˆ¨!£$èJŠÀˆ,Q¬ •1lÓ†ü™qü™Óœ}öúébŸ³Ç¹tÁÇw±×÷~ï~ßw}Âün¬bÐëï|ºñ¾ ëߤvc¨Ñ>tð𠯼øô¾èYµúέƒ‹Vœ>7ÍôÌìíkñ¹m ¯—eC‹X1:ú!°&êj,8uöÛ8FZí!Ik A¸šg<ÿèJT£ÔSãr³E’¤¤i…J@D ‚Û+Ô* ÇÎå BDA7Ì·”KÍ5 €ØÀ‡0ˆ.S!Fê¯=÷"›}Ï‘ÉdN‹è ã„;Ž—À‰™K$ADàîsŒ¼=S0Dgq¯ÏÉÑ‘"¢Xæ.@’˜©¸Ô03’Dj$Œô×™˜n39£œhVyuóÇ,¨W9ð/T{* 4RFúkL^É8sÙ13<L¥”"""Â1S’f/L²võ*^zê~DÆ'Îrbb’xò‘E,_2Lµš²÷çC|±÷$ƒ˜)NtÄ/46Oí0ž”Þýño6u€5K<ûøƒ<±q-ÇÇOóÖÖ/906EÒw i­CÍ }Í P÷Â]+Ì’”Zÿbþl.ä·£'KM÷ÿ~œƒSu*ýK‘´ó‚™Q`u‹™IÅS%™oÞÕiŽLm¾y˜*ᎌ%$‚ðˆÒ<—ù£ÑÛS£•µ‰êÕ½¸{YǼ¢V5©Z jˆ‰PÆ+LÙpÏ(;¾û‰ç¡{ïfË®1¤’–àªFHRÄÍÄÃ1WÌrÔ´\Ã7·-½•Ï÷á³=GX<|3C}1¯Ç,Ç\ñ(¥ )ÆË;Ú)ª…ªŠªòÀÃ|³kç[U¦²:;wïgÃèPù½èµBã§dîbî¨y\Õмͦu+Ùöí¯8‚Ûwþ¦u+Qm—}Ý3æN“×É1P 'ל ðâi#Ìxボ¼œ’TrÆfáím_ÓÎR¤âÐI…ªBt_ŠNÜga£mgÅ\·?Î'ÅÕš•I8|@AµŒž³°ÑËÔÌEº©ðfó¿|ýÈ /?ó0Ó›\O ô7X>2È©c9àÀ&&Nõö ŽÜ•5›9–µÏZbYV‰v–’g5ò¬*Ö®¢Yêí–x;keh+ÃZ-Ëg[3—.¶þ¿òÉû›·LŸ?³»; `Ðs]tçªü4ÿ1^…d5ÇÔÖIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-xsettings.png0000664000175000017500000000170614733247605030206 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<CIDAT8¥•»N+IE×énÓ—‡16Œ,!‹G`,Y‚ ®Î'ð #Òù‰F|ÁL@F‚øHL@‚@&[–ÐÅ<,»»^àêkk^%UÐÕªÝû¬³«Z˜Â熛:>>þ±Ùlþ ÄŸNÚíö/GGGF@¼½½ý[>Ÿo8çPJÇßpΑËåù÷bœsh­qÎQ­VŸ"à‹RjɃˆðøøÈÕÕ‡‡‡,--†áÿZ¢ˆ^¯‡R*| ”Rb­E)Åòò2{{{h­±Ö2QJñððÀåå%J)”R¤iJ·Ûåââ‚4M‡x-€Àƒ1†~¿Ïëë+óóót:¬µ8ç°ÖòþþÎÝÝÖÚl}4qss“­y€´ÖcF„aH.—#I¬µh­3A`­Aι¬7Zëå‰ýÀC’$¬­­Q«Õ‚ sàż°Ÿ"’=k­QJ ¥”xaÏ6MÓ¿ O‹ŒF#h6›¼¼¼L ‹G‘ñ©T*œÑív988À“¹tÎÍ èõz8çˆã˜ûû{êõ:J©ïÕMš'ÆæææhµZìîîR¯×1Ædù‘ž–3•Lz•¥B<ôiÿ¬µf0ÏçÙßßçéé ­\.Óh4Œ1Y‰ÑZ‹1&‹–oœw3 X\\$—ËÑï÷) h­i·Û\__ÓívÙÜÜô©@‚‰ðL½"I¢("ŽãìÝÎΫ««t:Z­V†b‚Hfûü“p¹\¦V«eUYk)‹”J%â8žNR–Š Åt÷½{ßù“““,ËÕj5{7š‰ñŒ±ÖŠ¿„üF­5"‚sŽ ŠÅ"N‡F£1sú|u€?ßsì‹o¤½?|ý @†Xk‰¢ˆõõõÑ ¨T*3wÊÄñ ^D(½¾² |ûˆ ãñ˜R©D†¬¬¬dî¼°_sÎ1ý‡%ìp8Lý†÷­-ÞÙ‚É š¹Z›s€8‡I$×H3"Ñ"¥Ò£ï\ÖÝÓó°7Acdhh¨vp࣓E/YðB!¼¼ 8\hCUÈÔ0S²L‰fÌ]µ°nýÆ®r¹ @¦Qˆ™yÁw‘¼ ÎÄËqÄ)1@¦Ä¦ÑÔL ¹S\AÄØ¾cç²å+ú{D ³-ߊa Õñ±™/>ýðlÌÓ&ˆ5€ ñ€s<÷òžmÅÒ‚R:Æ›—Á·‡ì››˜5%¡#GH.¹tdøÌèé¡ãgç/‚ä‚1Uš©ÈYš9l·Ù™ÚìØÈðxeìüdµ2r¹sQ¹£X*•ºº{oi‡bQœˆák¦‘ @äÚàëõúÜ—Ÿ}pt|ôŸªzì·Ÿ/ìzæÕ-ík|p­M†54Šª!ó fQç⎻×o^2zþïéêőٕ«û»Ë]Ýík¤-Üwª–TjFŒÆ\ÌPK>St†¹bEC5¸9—H2ÇÐÉcçÞyã•§&«õFQ% #‹Šf†©’ÎÌ0mÍŠ4 Œˆš©"ù€yí…§¿§8 Íô* –³z¦iÂa4ª./73¹³oeÇê5nŸ®MÕ½Ä;Ä ^Î ^¤Uè Ñ U#šbj,ê\\ì»keÇ™¿N7×ÇÖõ¯_»ûõ7ûSÓ§$M»FG¶ªÀòWãöP 3à þ8qb¨7îþínÛÑÛÓÛ)^$Ý‚KsYœ€ä ffj f–©b(#fbã•Ê•¯¾þîðCC‡2WÿS`ÐÌ;Ûn‰¿è±IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-housekeeping.png0000664000175000017500000000157614733247605030651 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<ûIDAT8¥”Mh]UÇsî½yï%yƈh»ˆ6‘n”V° XѺºtSu-ˆ[îëRt#ˆ. RAPZé&ˆXR¨ ‘ZÔ¢hI­j“×û>ï9sÆÅÍû¸Å:0›{™ßüφª!ÜYXtêåã>µñ$øúP5ÍúkW7ÞxõÌùS v¨fï-oüú4fÿ[¼cˆ°5¿ø>p<êÖΛ*ºw…f¨ÁŒ;hEû. žø"ˆ&qOPκEÄŒÂÖè»× %Ø«öfÆ _6ïå¥Ö„l\뽎ÀNcDÃî°ÊI·Í¡ØEƒýÓ\  ƒàtf÷à›Á¸P›åh÷ꎊ(-Ê.)@‚L4]5jN8g³ä>ptp‹UW¿qì±E“É©ñV˜çA¹")ËE‹})¨Vg3TŸ¢a:´áÜì¿u<¿;‡sJÃTx2U&%-;@Â@%„Èe»PjÏæÍ“Ïóú3Ë$Áã½ççžç3­±Ù÷ ¼Žk*€”`U4ÄJ^iÕ2N<Ác À+/>Î''Ÿãà|Jf1 ãËæ…/ë‚*€¤€hPQMFÏéì»›û=ÌÁÃH²ÌF¹²t§ß>ÁVÇóõ»gé]m#Nu'h(—*!¯Lî•#=4¾uF~£Õ%(Å/×é'B3KH0B4B¡«Ê¤ Ík›|¿z©:A+sóV—ùÙ?ÿ†EŒýÎшÃÈŠ‘Çh¤t¾øŽ¯>X¥ßîmƒ ï7¶:üyå:ní'p N­:ŸÈÄ+nÛÇ ÐËë¬:ÏÂò}¬Ya½Õáæß9íO/²„ãöš!k–8åVd@öÃ:ÝËë\:ó-‰ æ€iG6–·BR æjÅNG(ÛN0 › ÈÕ ¦@þa»óÑ`nîµF’Ì ‚$ NqNÄ9Ä9í1Ãb¦E3LÌè©çùi .Ô°Ôv³›è׀οˆËÚ@Žž:ÑIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-sound.png0000664000175000017500000000232414733247605027303 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<QIDAT8¥”MhTWÇ÷}Í$/“̼ĉ‰šZÔMi ”Zš•]¸r×E¡BWÝe%î nºí¦]Ù]I¡è"hA1¤Ó¢ ahóÕ$L:)ÉL 3óÞ»÷¾×…y„vQê³¹÷ñ¿ÿó{çÁѼYÄG„îܹ3~îܹ/¢(ʆñ¿£(Â0 uuõó™™™²dúúú¾ ‚ંÃùŸ,Æñ‘Ìçó_@¶Õjå¢("Ž_WbFšZk´ÖX–…eYh­wi&DQD«Õê²ÖÁ¡ˆ¢!Dúq†Ø¶ÍØØ£££d2‚  \.S©TRâ8q§Æq,,)¥HÜ4›M¸|ù2¥R‰ééiÚí6Zk2™ SSSܸqƒùùy¶¶¶Èf³©k)¥0#)7Š"šÍ&…B‘‘îÝ»G©TÂqºÜNÜÎNÂ0äÁƒLOO322B¡P ÙlEQŠ x HJih­QJáû>.\àþýû ‘³[ܼ¨ùôb™Ï&*|ü~žÑ³Eêõ:wïÞåüùóø¾R ­5RJ#E¡”‡ 2??OOO¶®35´€½ÿ¶ Á€¿ÂGgO£ô³žS*•8~ü8ÕjÓ4QJ¥(ÒvwwéîîæéÓ§4 &ÎF8þ:±ŽyôûI.½ÕÙC—±Ã䘋mÛÌÎÎÒÓÓC½^?Œâ¨c¥AÐl6±,‹b´ˆeÃì/.«™K¯9VÊÜšœ5úûûÙÝÝ%‚EâØ„”R(¥Ãß÷‘R"¥C dr9^,¼`âæ™¼¦íw |ßOźB$Âh­ ‚€v»aloo³m¼Ë[q…©÷búNÀq L^òá›ÓÔj äóyÚíö០@DQ$´Öär9VVV¦ÑhðãB¿ã -¹z¦ÆÕá†Üe/ìåû¹ßR2>>ÎÚÚ®ë&-+á”±ã8Ôj5ŠÅ"½½½<~ö’ï‡Yµ?ă4Ã/«C|ýÃ?=û•cÇŽáyÕj•ýö+öö÷Ž2ÖZ ­5¦i’ËåX^^æúõëÌÍÍ1ûè9;œ:yh±±ù3aÒßßÏää$ËËËär9^-³SS8õ¥Œ‰ãX(¥ˆã×uÙÞÞfii‰k×®±³³C¹\¦ºõ'žç1::Joo/KKKA€çyP>C1“e3ÞGÚ-ŽãÏóh4”J%ŠÅ"W®\Á¶m¦”­­-ÖÖÖèììÄó<\×åöíÛÌÌÌüJ©tÞ…¸®K6›¥^¯³±±iš$ÃÔÕÕ…çy˜¦I†„aÈ“'OÒµš ˆ¤”¡Rê_—|GGé®Nî”R(¥Èd2¬¯¯cYRʈ,`qqñ[¥Ô'Žã8¦ibBaFê6‰C»7NªÃ0¬T*ßû‰58dx³ðM ù7nŠtL:IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-automount.png0000664000175000017500000000152514733247605030210 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<ÒIDAT8­”Mk$U†Ÿs»ºªÒ•nÂ&1 n0¸šEfþ‘ìQ³AÄ+?~‚º”ÌJ\è¸ $›ü€f“¶S=Õuï9.ª«¦¿…ñ@Aݪ{Ÿûž÷Ž0›…Mööö>ØÚÚúÚÌb³êŸ_êõä!3CDšµª""ffÅñññãÝÝÝãH666¾Y]]}ð†j¸ººúø0Rï}æ½ÿ?¸xï—4!HáÎ"•ýÖ, U€h| w)vÎQ–%ívU½uïh4¢»‚ÜvÎBàää3c{{çÜ­p|/$„ÀìS§}ttÄÍÍ yžsxxˆªbfsûC”eùÚŠœÎ9Úí6ôûýæ»™±¿¿ÏÎΪ:§¼æDP> Žã˜óósÒ4%Žã¦xPòââ‚^¯7•Ùøb™×]Q¼÷\^^r}}½ÐË$Ièt:s™NZ!Þ{ñÞ#"¸ÊvT•³³3NOO‚ó|4ÈméÞé_JRLZü s^SÉy÷þûdîÕà×_þÐýgÏ~þîÉÓ/>}¯°öõ`hù°ðEQø|8¼sH§IÒZZZj¥ieIäV–cÿÕ—Ÿ ƒ~ízF¿ƒEéÓy›|?d4zÜü¯µë´°ÀiIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-clipboard.png0000664000175000017500000000245414733247605030116 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<©IDAT8¥•ÍeÆ÷óõžéôÐVb´Ê´)*0D©nü3\²&!°Ã˜¨ 7FcâF·+ÓM¡òQ‘B:eŒÑ0 0L‡9sÎ{Îû¾Ï§‹™Ô-WrïžçÎu]Ï}Ýp7„¯†rW£ç_úÅ…SËÿ<ŒÒ•‘‚(eTÊ>æÒÿßV¢E”1J[#¥PRöI ÝÆo<ÿ›Ÿ¾xÝÕèäò«µ,®¦ ƒµjHç_â±£-FJ(à½Á{/ýxν.”EU@DS@b‹Ñm4 È%QJÞ—( ¥,J R1¤$ÚΓRdÖv‹@OtÍ,K.hQ8­È1RR ¤ˆÑ Ó~ƹs'¶ÝF"™rpη 1t¤‰Á €1Ðø9ÎZœ5h óz—û$¶æ=î­"?zö»lÿåÛó '‡-ÏI9b ¤”‰9“â¾2¨¼ä‰9#)QrËw–*žY{’7ÿÅýßXass€ÿ)n}ü)+§—¹|å-®|¸ƒrRʤ”ñ1 @ŠEb Äð±c¾ó+˧ˆ1²0¨ØÙÙÁ9‡sŽÛ·o3ìW¤”8{z‰8ûŒ9'‚ÖÖ(€¶kI1T$šo^{Ÿ­­-œsŒF#êzF=›3pαµµÅ›ï\Çë£(­q¦B´¦¤¢=®§ãlë1N[¤æÜ·îá‰GWð]Ëââ"W®^ãÒÕÑ\\;ÍÚ“3™Lxâ±3DÖYßüœÖŒH1Óvs猔˜IÁ3Ô-?üÞ*ÃAc )%Þýð_{à,÷Üwšwon’RÂÃpÐç¹§WÈœä1F—O´1Ú‡Vs!Æx†”Ãe'ErL;ð·”‚ˆì7óX)CŒ@ Ñûáþ»xñg¿åúëcÈ9óƒµó,-ÌxpÔðìÚ£äœ1ÆðÞû7xá•׸ùIMÛÎi»†à½b™NÆÉ vŒRŽìŽñùÞk-Þ{FGpñ™oªœsŒ'5jtº¦³)eövwÒÆÔÓ½Ò43¼ï!Гg~ˆœ3ÖZúý>UUQUý~k-9gY^ÂÅšžë¡•!ÇDá0yS”JYªª¨“üáÏåâÓxý­²òð«Îpõí°¾ñžZ=Ï¥¿ýíºÏ‚ñ(%T½>ÊZ}Ç (E´2ôªÎA ŸŒøÕŸ.#ÕºÙà±³ðö{lÜ.\û÷eN|ý®ïîÒ­¿˜cm+£]ã*ºÐá}ƒh=rï=×?óò/GIêÑ?r ·pŸ ®ß§é:Æ{»ëˆ!~a…µV\åhÚ–®iP rJLë(ØþQZehÒ ¥…®ë躊àC¤×ж³zÊt²—ïX‘KŽÑ7-M[CD žÕÄà¦@“¥Ðy×ÂÏyápl+ƒ>1ºfÒÙÓõ7.ýþ›gÆ?ÑÎY¡ä„ïæY)%J)ì`A%JÉ][JÉä\È9Óä\Új Di¬­T×Ì»­›ïü˜Þù<‡À@ÅWC ÜfÿI€d{¬éIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-mouse.png0000664000175000017500000000174314733247605027307 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<`IDAT8¥•»oU‡¿ylfÖ$B$¦$–hi(x”.@‘Ò!Yð'ÐS"¨(!©SP¤  q ‚ŽÈ/%Q6‘ì]gìÙÝ™¹s/…gÝì†su«ó;ß=3çÜs&-àÿ™Ÿ­¬¬¼µ°°ðe«ÕJ¯_ÿ8žŸŸ?3Ñë={avvÆ´ÛiÚ×ïô­[ß[©vww?¿}ûöV $iš~Óï÷ß½tiqï•—/N–eÁúÝ;\¸ð"ï½ÿ!i{fÂþÜ<ívº÷äÉÓ‹I’Ì„@Z–åy9úï&¶XÍÍï¾e·7`sçnÞ¸ˆièD„¢(ÎíÀZXkqÎá§¶VŠ?ÿ~ÊÕ«Ë,//óÇ_tU5tÎ9¬µXk€x,¸úôñjŒ­µx`ZçD‚XkÆqŒ8w“a`­£×ëÕ`G 8µ­u8£ŒµV‘s~ #b±ÖÖÿц1Ó:­U4–qF)U$IÂpXÄàñþyPÅ8çèt:uq=Aà¬k‚ `8Æ"‚Rj˜pZë¾1†n·;k”‘ñ¢ˆÑ¬®~ÂææÛÛÛ|öé*bôdµ±{{ÝYc UU個?77÷N’$oA¦irxåõËmO½¼gñ¥ÞXz“k×>âµWºglýøÓÚáö΃™ªª888¸“eÙ!àºÝîšR ¥÷7¶­$Ö F£«±¦áÿýþ£ø^¯÷3àbÀçy¾©”ªÂ0L=z|Vic[­(/ÎÒÒ’äL£Í´ÛétÎ*¥¨ªªÌó|ðaí߯ªj µ¦,Ëh}ý·ÁtViм@÷Ö~”ei­QJ €}€¸0Æ(c ƶv6®ìI{çÁCFqÆ TǰÖZ3dÙAì=m÷_!Ïö³–µc ÖZØq°ˆˆ®œ<Ï[abÅœ ŽâˆÃ4ÃËsø…ïßy.PœÞVTL®àIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-datetime.png0000664000175000017500000000203514733247605027746 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<šIDAT8¥”±OI‡¿™]|@)…çy(¥( „aH†H))•J”Ëe¢(ʨk-€È„GJ¹¸¸ÈP­VÇÃùù9333$IB½^§T*±³³“Ën…syÆQ‘¦)?æàà€F£ÁÕÕÖZ‚  ÙlæMÛÜÜÄZ‹R*wH–ñc€$IÐZÇ1??Žïû¼{÷­5Ãá8ŽG¾ì|™usÆYÙcccc8::"yýšc( ÄqÌ£Gh·ÛÔëujµív›ããc€òÎÇ9ŠB¡€R ß÷IÔØaæ(X\\djjŠ÷ïß³²²’;ânXF}œ5OkRŠ øÃjJ‘ y5{{{#ÃqzzŠRêïÍ»E!„pZkVWWi6›!F^µ¯G6Ϋ««ÜÜÜä¶óÛï÷“(ŠxðàÏž=û×wøKâƒÁ€8Žéõz°>Ð{ùòå®1æG¥Ô˜çyâç!¥Bˆœc†ÌZëÒ4ÅZ묵¤iê†Ã¡~õêÕo@/K­|¨ÿ”êç1~¢?½½ÿI•if¡IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-media-keys.png0000664000175000017500000000174114733247605030205 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<^IDAT8¥•ÍK$GÆUÝÕö|jDW²èÜl–YaÌm/{Ù»§àÕ?$§ÈzÝ,+ø'HB6Ag0¬ ø±‹BÈÌØãÌTWUÓÝΰ ,øBÓ}èúõó>ïSÕ‚ÁܯÜhssó‡ùùùŸ¡{‚;ëkkkøÀP¥RùexxxñžP¦§§7€} ÔZ­µc8::ÂóÙçÎZdN‚ÓÓLLLÇq }€8Ž…µ–ÃÃCfgg‰ã˜›››Ì9Â0ddd„Ó ¾{ò„f£u.ûàW¥¿¿}Ëøú:q Àƒ1†n·K³ÙdjjŠr¹œ ò~øI"J¹¿IÉ7ó`q±x" k-¾}ôïÅ Z­V–×—ÙôžÏçz÷Ž?«U¾ú4óØ#!Ñïqº1„œœœ ”"ŸÏÓjµ( ‹E|ß§Þhdvõ_©âTØ${{{,,,pyyI­VÃ÷}ŠÅ"“““½áø>$ݤKY™ÇýÃ3Ö¢”ê)ª×(—Ë(¥î€IƘÿ÷§v¤Š}ßgii‰³³3fff% C„àþ¨öÕÀY!Ò}~E\ž’Ëå/Ðõ:9çp­ˆ¢€†1üýéÓÀù²2+Òv&>ä¯j•ËW¯ø’êÃä³gŠ“ä°Qik-¥R‰ÒË—_í¯~p³ÙÔ€õæÖÖÖ­õOaB¤”"¹<§¤C×ÿ윣Ýnw···šéϳ|Íýÿymàˆþ~fÿ¤zkaIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-a11y-settings.png0000664000175000017500000000211114733247605030556 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<ÆIDAT8¥”]ˆUe†ŸµÏ>gÎx&™qj¦ñ‡0d2Ó•Ê 4ê*Š.‚n¢ ‹èº‹ º+ˆ¨!£$èJŠÀˆ,Q¬ •1lÓ†ü™qü™Óœ}öúébŸ³Ç¹tÁÇw±×÷~ï~ßw}Âün¬bÐëï|ºñ¾ ëߤvc¨Ñ>tð𠯼øô¾èYµúέƒ‹Vœ>7ÍôÌìíkñ¹m ¯—eC‹X1:ú!°&êj,8uöÛ8FZí!Ik A¸šg<ÿèJT£ÔSãr³E’¤¤i…J@D ‚Û+Ô* ÇÎå BDA7Ì·”KÍ5 €ØÀ‡0ˆ.S!Fê¯=÷"›}Ï‘ÉdN‹è ã„;Ž—À‰™K$ADàîsŒ¼=S0Dgq¯ÏÉÑ‘"¢Xæ.@’˜©¸Ô03’Dj$Œô×™˜n39£œhVyuóÇ,¨W9ð/T{* 4RFúkL^É8sÙ13<L¥”"""Â1S’f/L²võ*^zê~DÆ'Îrbb’xò‘E,_2Lµš²÷çC|±÷$ƒ˜)NtÄ/46Oí0ž”Þýño6u€5K<ûøƒ<±q-ÇÇOóÖÖ/906EÒw i­CÍ }Í P÷Â]+Ì’”Zÿbþl.ä·£'KM÷ÿ~œƒSu*ýK‘´ó‚™Q`u‹™IÅS%™oÞÕiŽLm¾y˜*ᎌ%$‚ðˆÒ<—ù£ÑÛS£•µ‰êÕ½¸{YǼ¢V5©Z jˆ‰PÆ+LÙpÏ(;¾û‰ç¡{ïfË®1¤’–àªFHRÄÍÄÃ1WÌrÔ´\Ã7·-½•Ï÷á³=GX<|3C}1¯Ç,Ç\ñ(¥ )ÆË;Ú)ª…ªŠªòÀÃ|³kç[U¦²:;wïgÃèPù½èµBã§dîbî¨y\Õмͦu+Ùöí¯8‚Ûwþ¦u+Qm—}Ý3æN“×É1P 'ל ðâi#Ìxボ¼œ’TrÆfáím_ÓÎR¤âÐI…ªBt_ŠNÜga£mgÅ\·?Î'ÅÕš•I8|@AµŒž³°ÑËÔÌEº©ðfó¿|ýÈ /?ó0Ó›\O ô7X>2È©c9àÀ&&Nõö ŽÜ•5›9–µÏZbYV‰v–’g5ò¬*Ö®¢Yêí–x;keh+ÃZ-Ëg[3—.¶þ¿òÉû›·LŸ?³»; `Ðs]tçªü4ÿ1^…d5ÇÔÖIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-cursor.png0000664000175000017500000000245414733247605027474 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<©IDAT8¥•ÍeÆ÷óõžéôÐVb´Ê´)*0D©nü3\²&!°Ã˜¨ 7FcâF·+ÓM¡òQ‘B:eŒÑ0 0L‡9sÎ{Îû¾Ï§‹™Ô-WrïžçÎu]Ï}Ýp7„¯†rW£ç_úÅ…SËÿ<ŒÒ•‘‚(eTÊ>æÒÿßV¢E”1J[#¥PRöI ÝÆo<ÿ›Ÿ¾xÝÕèäò«µ,®¦ ƒµjHç_â±£-FJ(à½Á{/ýxν.”EU@DS@b‹Ñm4 È%QJÞ—( ¥,J R1¤$ÚΓRdÖv‹@OtÍ,K.hQ8­È1RR ¤ˆÑ Ó~ƹs'¶ÝF"™rpη 1t¤‰Á €1Ðø9ÎZœ5h óz—û$¶æ=î­"?zö»lÿåÛó '‡-ÏI9b ¤”‰9“â¾2¨¼ä‰9#)QrËw–*žY{’7ÿÅýßXass€ÿ)n}ü)+§—¹|å-®|¸ƒrRʤ”ñ1 @ŠEb Äð±c¾ó+˧ˆ1²0¨ØÙÙÁ9‡sŽÛ·o3ìW¤”8{z‰8ûŒ9'‚ÖÖ(€¶kI1T$šo^{Ÿ­­-œsŒF#êzF=›3pαµµÅ›ï\Çë£(­q¦B´¦¤¢=®§ãlë1N[¤æÜ·îá‰GWð]Ëââ"W®^ãÒÕÑ\\;ÍÚ“3™Lxâ±3DÖYßüœÖŒH1Óvs猔˜IÁ3Ô-?üÞ*ÃAc )%Þýð_{à,÷Üwšwon’RÂÃpÐç¹§WÈœä1F—O´1Ú‡Vs!Æx†”Ãe'ErL;ð·”‚ˆì7óX)CŒ@ Ñûáþ»xñg¿åúëcÈ9óƒµó,-ÌxpÔðìÚ£äœ1ÆðÞû7xá•׸ùIMÛÎi»†à½b™NÆÉ vŒRŽìŽñùÞk-Þ{FGpñ™oªœsŒ'5jtº¦³)eövwÒÆÔÓ½Ò43¼ï!Гg~ˆœ3ÖZúý>UUQUý~k-9gY^ÂÅšžë¡•!ÇDá0yS”JYªª¨“üáÏåâÓxý­²òð«Îpõí°¾ñžZ=Ï¥¿ýíºÏ‚ñ(%T½>ÊZ}Ç (E´2ôªÎA ŸŒøÕŸ.#ÕºÙà±³ðö{lÜ.\û÷eN|ý®ïîÒ­¿˜cm+£]ã*ºÐá}ƒh=rï=×?óò/GIêÑ?r ·pŸ ®ß§é:Æ{»ëˆ!~a…µV\åhÚ–®iP rJLë(ØþQZehÒ ¥…®ë躊àC¤×ж³zÊt²—ïX‘KŽÑ7-M[CD žÕÄà¦@“¥Ðy×ÂÏyápl+ƒ>1ºfÒÙÓõ7.ýþ›gÆ?ÑÎY¡ä„ïæY)%J)ì`A%JÉ][JÉä\È9Óä\Új Di¬­T×Ì»­›ïü˜Þù<‡À@ÅWC ÜfÿI€d{¬éIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-printer.png0000664000175000017500000000203414733247605027634 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<™IDAT8¥•¿oGÇ?³»³3ç;±äØ9ÉHF†Ê‰ŠÒº§JBJ‘.]zÚTQ*”téˆèøN„HXÈn ÄŽH—ý=3/ì'ŽøJ+M±ó}ß÷}ï«Q‡âÝ ÇˆnÞ¼ùáåË—¿ €ˆü¯J©Ž°¾wïÞׯ_ÿ9Ìæææ×“Éä“wT ÀÆÆÆ7ÀNضmG!”RܺuKö÷÷e0œˆ¨,K677Õµk×”ˆÐ¶í2`ï½ !E³ÙL.\¸]¹r…²,qÎѶ-išâ½Gk÷ï=§OŸæöíÛÌf³põêUBÀ{¯€¸|¡çÏg0³´´Äp8dmmgÏžQ–%ZkÒ4Eksç\ÿïÒÒÞ{þMUM~)Ÿ³2ˆ°Ö’$ J)¬µÔuÝ ­5"B’$XkÇXk !BÀ9%¿F¹ùÉßeõ·-Œ1ÄqLUUäyNǤiÚ{ªµæÔ©ScX^^feecLO|ÌŠ÷ÓIØYý’7Šxï±Ö²¶¶vlPQ¡µ&MÓ¾XÛ¶’ç9"ò_âMÓB`6›…‡Eݶäy޵–<ÏQJqttÄ`0àÌ™3o*¦'.ŠÂýðã÷|ôÁLju]S×5q÷ÄJ)¼÷ý–h­±Ö"ò*ožÕ¼÷‚¿øƒíímuçÎéZï.Îçs%"L&锵m Àöö¶z=4B P  œsöÓéçˆj}c À1ÅgÏž•ÖZœsh­ûNÖ××ßìÊöÄEQ˜ƒƒœsòäÉâ8>Qò¼÷2H’„¢(LGLÁdY†sŽ,ËÔ¥K—Ô`0ÀƒˆPEÿµmKÓ4TUEY–ÔuM–edYF’$„LïqǺ®kÚ¶e:²X,¸ÿ>»»»4MóV¥"¹sçØÙÙa:RUZkâ8Ö½âÎøî|þüy.^¼ÈÑÑ=âåË—}1ŒF#¶¶¶Ç}¼“$éöúŸu{ðàÇVªÃêêê[/ ‹Å+’$éýøñcé­Øßßÿ³ªªqžçTUÕ«;)Œ1Xk‡<}úôEgEpÎ5""êú¤Ýç\„Èööö¾KÓô3¥”nšFœsEQ©8Žy³˜ˆ "]Ò$„@UUª,K5ŸÏÛ½½½o¬“6Öyýæ½*àÈÿo5Ê3ÀuIEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-color.png0000664000175000017500000000250314733247605027270 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYsSSV\étEXtSoftwarewww.inkscape.org›î<tEXtAuthorLapo Calamandreiß‘*IDAT8•“{lSuÇ¿¿{oÛÛ×]éZÜtB ·1&„ø 1 E!1$‰N@£¨‘dFÁ`"àƒ¨Q"2uCY„ò¯Á޽ìÅìsk·v]×ÝÞû»?ÿP’±0¿ÿ“s>9ùžs€q*Ìõz½Yã­çÆS …²E½zI¯®Æ ¿§Âáž3þúù¬§s»PY¹óü~ÿ~¿wW0ØUp;×ÑÑ!ÆúÚi¸,pMb­m­~lßÎcŒóz½Ë!ÿw555®á,axÀû‚«;T¨Ï,xËëõz‰Ä«ÕÈR±ýÏÙa00¤xÆâÚZÇÁ¿o­‰ôvå+M„ê‰Z ^º+8™Lœ4ë õg·!¥Ë̲¿ðÍiUÝ ¹ù×Z¦Ô“¯÷ìn á„£5þ%ô&†ö).^¾üÛpֈ剢i§øäVÆ$‘A<¶ìJ‰Z„3pF¨©n4Èï;zÄRX-6¤°ØäXù·gLpVVV$ª™+ú§,@À ¤¶ŸAƒé œ„“ТuA°E& ßøNTT쪩9 <ϯ7>³—ðv£ 'À\Û¦½E @àDð0Ï å…ÎWÿuÎ!‰Ü”KÛ†\K‹Uij†¦ð MíћПmBË4'4erŸ 2M‡¤ËÄ$K´¨5 ‡J|¾PñªU«(ñù|ÏZx¾l ¸˜<ˆN'@ I :†ì) ÒÔ=eCwr­‰.€0 ÒTM†¬ BIR,™¸…âó‰òæ ²œœlŠÅyV_=!w:—PÕ‘‡ˆã>ô×çBuüèo®Ó¢%v³m+L]í7r :|hQÎÔœÝÙ&s>u» moTI.´'Eˆf!½bþ,EI*ÖáÁî<Ì‚g G¿^®¬9_^~ü½MMUÃG$«7n¼ÿ±93—¬XþbÉO»Ëx%¡€ Š:› œQDAî$)UÃT§Yº@ϯee¯]ºz­* SÀÈaßïÛçÛR[{ö÷J>ꂈf§ *åYUR`œŠ¢¡Á7×ì)Î4›%zñÌ™þŒ8·ÒÒR£Óž±åÊÉ«  ª ã: äÅLá ˆ%RÐÀ@¾àǼGæï¿}awOŸž½íÜñ‹>æææ†½½=â8æöö–ÎÎN,Ëú7 cÌ›ÇqL©Tâää„ùùyÊå2¾ïãû>ÙlÇqÐZKâXDäÅ<•1†ååe*• Åb‘ééi...èéé!ŸÏ“ËåPJ!"IÆ’Dñ*¸Õj±²²ÂÙÙ…B¾¾>îîî§···Ý’, ¼]ûëëëT«UfggéïïgjjŠÁÁAž~?žv¦”RI)ä¹¶¶¶¨T* fffi |¶°ˆÈ p¥RÁó<¶··~Öœnž§§§©ûV«ÅÜÜžçáy^ºXDxìö…2™L: @k-¹\î]®økÊd2ŠdólÛ–ŽŽŽwƒÿO¶m§Ž›a>tuu}zœõ7]½&¥¾ïb~›œœü¼¸¸ø§ã8úþþ>üY·µZíëæææ:ð%±åŸøõŸi€ø;Ìo0Þåš±IEND®B`‚cinnamon-settings-daemon-6.4.3/files/usr/share/icons/hicolor/22x22/apps/csd-power.png0000664000175000017500000000234714733247605027314 0ustar fabiofabio‰PNG  IHDRÄ´l;sBIT|dˆ pHYs,,”ƒtEXtSoftwarewww.inkscape.org›î<dIDAT8¥”A‹×Çõúõ´vF;£][v$¯Œb‘K0ù9ß#A’K>BNºEü-|ô5'å¢`ÁŽ è‚ÁH쮼ÖÌÎLO÷ôL÷ë~U9ìÌj¥« ŠªU¿W¼÷OxÝäBž>yòäO»»»¿Y­V”eIQçñôôô»‡~tzì5Ðýû÷?¼}ûö_ïܹspõêÕÞh4b41ŸÏo½³X,˜ÍfEÁjµ"„@¿ßÿ1MÓoçóy˜ÍfmÓ4¨jurròé£G~ð@oÿÁb±øc×mž$ Î9z½1F¶ÏçsBˆY–]¯ëú“<Ï™N§„!0 zÀ_<E±F_Ôu½WU•wÎY×u,—Kò88øçƒJy È€¸9;½uëÖ—f€ÖÌ:3kEÄ9çÞ2³NUOÛ¶˜YôÞïÝ»'ÀÚÑ̤×ë鸅F ¦iªÀ›Î¦æ*pxŒµª: ú7T±…_Œošln_Sàx ÔÀ¥m‘Pխ̶ áoB·à €á&Ÿjfr>âË÷>ÿÏßÿ|eçz’H*ÑZLÕ¢Eû~òïOÚ.X§­E:‹QÖïíºdГèÒñì…”ÕÌ­Ã<Íß9þðÄ,c•¼Èç×V¡wž¨‘¨j‘ÃyIgN[Ô"Q•®kÉ’Hj+º:’/¦ÔU……š*Öýó‰ÙŒof¨)¸ˆ8%A¹´­‚7PL—³w)Ö9WüÝá'’1Ó1‹°ãÕQØfᜒxAEqDT"Ù%H€¨‚!\|€k›1«yžÿ—r^ªŽÔôu°˜Iš‚xÅyQL'JoGðÑÎz~}ý·œ,ŸQé2ϯöö9œ0™ŒÉgÇÈE°KÄCâ ç ÜÆÅÈv.ÊCd}>ýçoŸ=æÙì”Ó5ëeK‚âüë`| .Q¸xî™ÊFÐ_åŸñ»ý?pØ|õ½÷øåàm^fc^&/™NŽqs.$Q$œ"^ɘ{6^tO‰¾ o§,¦ßS̪e‹˜"à^]ž I.1Ä)$—DÄ+=Ve›'d*üÔ~‡Ï”ww¸‘þ‚±óc3­7Ø-Ø™PSÔ@PÔgçÁ6’‹48`º>d>þò´eY¶˜)"¯&¾rÐ|üQþõðùû7nº½ý}¹²7d¸;b]–6žýÔ.Š‚bQX³®Å·*Êš]#ý¦siÓ¸Ë]皦I.éG7¾á#¸ñq1èûêæ~¯eä=½þÝáÛ´Áa‹%ÍdM1QŠ¢ Ï+š¦!„p·ùr¹Ü3 ”?þâîÝ»ƒápxṲ̀iŠ¢²,™L&]žçR–%MÓˆ™¹¦iºº®iÛÖêº&„`!ªªªŸ>}ú/ Øþj}àgŸüϱ8Vÿ¤`Àm:0_IEND®B`‚cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/0000775000175000017500000000000014733247605022265 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/cinnamon-settings-session.c0000664000175000017500000002677514733247605027573 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2006-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "cinnamon-settings-session.h" #ifdef HAVE_LOGIND #include #endif typedef struct { GSource source; GPollFD pollfd; #ifdef HAVE_LOGIND sd_login_monitor *monitor; #endif } SdSource; #ifdef HAVE_LOGIND static gboolean sd_source_prepare (GSource *source, gint *timeout) { *timeout = -1; return FALSE; } static gboolean sd_source_check (GSource *source) { SdSource *sd_source = (SdSource *)source; return sd_source->pollfd.revents != 0; } static gboolean sd_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { SdSource *sd_source = (SdSource *)source; gboolean ret; g_warn_if_fail (callback != NULL); ret = (*callback) (user_data); sd_login_monitor_flush (sd_source->monitor); return ret; } static void sd_source_finalize (GSource *source) { SdSource *sd_source = (SdSource*)source; sd_login_monitor_unref (sd_source->monitor); } static GSourceFuncs sd_source_funcs = { sd_source_prepare, sd_source_check, sd_source_dispatch, sd_source_finalize }; static GSource * sd_source_new (void) { GSource *source; SdSource *sd_source; int ret; source = g_source_new (&sd_source_funcs, sizeof (SdSource)); sd_source = (SdSource *)source; if ((ret = sd_login_monitor_new (NULL, &sd_source->monitor)) < 0) { g_printerr ("Error getting login monitor: %d", ret); } else { sd_source->pollfd.fd = sd_login_monitor_get_fd (sd_source->monitor); sd_source->pollfd.events = G_IO_IN; g_source_add_poll (source, &sd_source->pollfd); } return source; } #endif static void cinnamon_settings_session_finalize (GObject *object); #define CINNAMON_SETTINGS_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CINNAMON_TYPE_SETTINGS_SESSION, CinnamonSettingsSessionPrivate)) #define CONSOLEKIT_NAME "org.freedesktop.ConsoleKit" #define CONSOLEKIT_PATH "/org/freedesktop/ConsoleKit" #define CONSOLEKIT_INTERFACE "org.freedesktop.ConsoleKit" #define CONSOLEKIT_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" #define CONSOLEKIT_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" #define CONSOLEKIT_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" #define CONSOLEKIT_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" struct CinnamonSettingsSessionPrivate { GSource *sd_source; // used in logind mode GDBusProxy *proxy_session; // used in consolekit mode GCancellable *cancellable; // used in consolekit mode gchar *session_id; CinnamonSettingsSessionState state; }; enum { PROP_0, PROP_STATE, PROP_LAST }; G_DEFINE_TYPE (CinnamonSettingsSession, cinnamon_settings_session, G_TYPE_OBJECT) CinnamonSettingsSessionState cinnamon_settings_session_get_state (CinnamonSettingsSession *session) { g_return_val_if_fail (CINNAMON_IS_SETTINGS_SESSION (session), CINNAMON_SETTINGS_SESSION_STATE_UNKNOWN); return session->priv->state; } static void cinnamon_settings_session_set_state (CinnamonSettingsSession *session, gboolean active) { CinnamonSettingsSessionState state; state = active ? CINNAMON_SETTINGS_SESSION_STATE_ACTIVE : CINNAMON_SETTINGS_SESSION_STATE_INACTIVE; if (session->priv->state != state) { session->priv->state = state; g_object_notify (G_OBJECT (session), "state"); } } static void cinnamon_settings_session_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CinnamonSettingsSession *session = CINNAMON_SETTINGS_SESSION (object); switch (prop_id) { case PROP_STATE: g_value_set_enum (value, session->priv->state); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } GType cinnamon_settings_session_state_get_type (void) { static GType etype = 0; if (etype == 0) { static const GEnumValue values[] = { { CINNAMON_SETTINGS_SESSION_STATE_UNKNOWN, "unknown", "Unknown" }, { CINNAMON_SETTINGS_SESSION_STATE_ACTIVE, "active", "Active" }, { CINNAMON_SETTINGS_SESSION_STATE_INACTIVE, "inactive", "Inactive" }, { 0, NULL, NULL } }; etype = g_enum_register_static ("CinnamonSettingsSessionState", values); } return etype; } static void cinnamon_settings_session_class_init (CinnamonSettingsSessionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = cinnamon_settings_session_get_property; object_class->finalize = cinnamon_settings_session_finalize; g_type_class_add_private (klass, sizeof (CinnamonSettingsSessionPrivate)); g_object_class_install_property (object_class, PROP_STATE, g_param_spec_enum ("state", "The session state", NULL, CINNAMON_TYPE_SETTINGS_SESSION_STATE, CINNAMON_SETTINGS_SESSION_STATE_UNKNOWN, G_PARAM_READABLE)); } #ifdef HAVE_LOGIND static gboolean sessions_changed (gpointer user_data) { CinnamonSettingsSession *session = user_data; gboolean active; active = sd_session_is_active (session->priv->session_id); cinnamon_settings_session_set_state (session, active); return TRUE; } #endif static void cinnamon_settings_session_proxy_signal_cb (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, CinnamonSettingsSession *session) { gboolean active; if (g_strcmp0 (signal_name, "ActiveChanged") == 0) { g_variant_get (parameters, "(b)", &active); g_debug ("emitting active: %i", active); cinnamon_settings_session_set_state (session, active); } } static void is_active_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gboolean active = FALSE; GError *error = NULL; GVariant *result; CinnamonSettingsSession *session = CINNAMON_SETTINGS_SESSION (user_data); /* is our session active */ result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("IsActive failed: %s", error->message); g_error_free (error); return; } g_variant_get (result, "(b)", &active); cinnamon_settings_session_set_state (session, active); /* watch for changes */ g_signal_connect (session->priv->proxy_session, "g-signal", G_CALLBACK (cinnamon_settings_session_proxy_signal_cb), session); g_variant_unref (result); } static void got_session_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CinnamonSettingsSession *session = CINNAMON_SETTINGS_SESSION (user_data); /* connect to session */ session->priv->proxy_session = g_dbus_proxy_new_for_bus_finish (res, &error); if (session->priv->proxy_session == NULL) { g_warning ("cannot connect to %s: %s", session->priv->session_id, error->message); g_error_free (error); return; } /* is our session active */ g_dbus_proxy_call (session->priv->proxy_session, "IsActive", NULL, G_DBUS_CALL_FLAGS_NONE, -1, session->priv->cancellable, is_active_cb, session); } static void got_session_path_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GVariant *result; GError *error = NULL; CinnamonSettingsSession *session = CINNAMON_SETTINGS_SESSION (user_data); result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("Failed to get session for pid: %s", error->message); g_error_free (error); return; } g_variant_get (result, "(o)", &session->priv->session_id); g_debug ("ConsoleKit session ID: %s", session->priv->session_id); /* connect to session */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_NAME, session->priv->session_id, CONSOLEKIT_SESSION_INTERFACE, session->priv->cancellable, got_session_proxy_cb, session); g_variant_unref (result); } static void got_manager_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GDBusProxy *proxy_manager; GError *error = NULL; guint32 pid; CinnamonSettingsSession *session = CINNAMON_SETTINGS_SESSION (user_data); proxy_manager = g_dbus_proxy_new_for_bus_finish (res, &error); if (proxy_manager == NULL) { g_warning ("cannot connect to ConsoleKit: %s", error->message); g_error_free (error); return; } /* get the session we are running in */ pid = getpid (); g_dbus_proxy_call (proxy_manager, "GetSessionForUnixProcess", g_variant_new ("(u)", pid), G_DBUS_CALL_FLAGS_NONE, -1, session->priv->cancellable, got_session_path_cb, session); g_object_unref (proxy_manager); } static void cinnamon_settings_session_init (CinnamonSettingsSession *session) { session->priv = CINNAMON_SETTINGS_SESSION_GET_PRIVATE (session); #ifdef HAVE_LOGIND if (access("/run/systemd/seats/", F_OK) == 0) { // sd_booted () sd_pid_get_session (getpid(), &session->priv->session_id); session->priv->sd_source = sd_source_new (); g_source_set_callback (session->priv->sd_source, sessions_changed, session, NULL); g_source_attach (session->priv->sd_source, NULL); sessions_changed (session); g_debug ("Using logind"); } else #endif /* HAVE_LOGIND */ { g_debug ("Using consolekit"); session->priv->cancellable = g_cancellable_new (); /* connect to ConsoleKit */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, CONSOLEKIT_NAME, CONSOLEKIT_MANAGER_PATH, CONSOLEKIT_MANAGER_INTERFACE, session->priv->cancellable, got_manager_proxy_cb, session); } } static void cinnamon_settings_session_finalize (GObject *object) { CinnamonSettingsSession *session; session = CINNAMON_SETTINGS_SESSION (object); g_free (session->priv->session_id); if (session->priv->sd_source != NULL) { g_source_destroy (session->priv->sd_source); g_source_unref (session->priv->sd_source); } g_cancellable_cancel (session->priv->cancellable); if (session->priv->proxy_session != NULL) g_object_unref (session->priv->proxy_session); g_clear_object (&session->priv->cancellable); G_OBJECT_CLASS (cinnamon_settings_session_parent_class)->finalize (object); } CinnamonSettingsSession * cinnamon_settings_session_new (void) { CinnamonSettingsSession *session; session = g_object_new (CINNAMON_TYPE_SETTINGS_SESSION, NULL); return CINNAMON_SETTINGS_SESSION (session); } cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/meson.build0000664000175000017500000000103514733247605024426 0ustar fabiofabiocsd_sources = [ 'cinnamon-settings-profile.c', 'cinnamon-settings-profile.h', 'cinnamon-settings-session.c', 'cinnamon-settings-session.h', ] csd_deps = [ config_h, glib, gio, ] if using_logind csd_deps += logind endif csd_lib = library( 'csd', csd_sources, include_directories: include_dirs, dependencies: csd_deps, install: true, install_dir: apilibdir, ) csd_dep = declare_dependency( include_directories: include_dirs, link_with: csd_lib, dependencies: csd_deps, ) cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/cinnamon-settings-profile.c0000664000175000017500000000370414733247605027533 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include "cinnamon-settings-profile.h" void _cinnamon_settings_profile_log (const char *func, const char *note, const char *format, ...) { va_list args; char *str; char *formatted; if (format == NULL) { formatted = g_strdup (""); } else { va_start (args, format); formatted = g_strdup_vprintf (format, args); va_end (args); } if (func != NULL) { str = g_strdup_printf ("MARK: %s %s: %s %s", g_get_prgname(), func, note ? note : "", formatted); } else { str = g_strdup_printf ("MARK: %s: %s %s", g_get_prgname(), note ? note : "", formatted); } g_free (formatted); g_access (str, F_OK); g_free (str); } cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/cinnamon-settings-profile.h0000664000175000017500000000430114733247605027532 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __CINNAMON_SETTINGS_PROFILE_H #define __CINNAMON_SETTINGS_PROFILE_H #include G_BEGIN_DECLS #ifdef ENABLE_PROFILING #ifdef G_HAVE_ISO_VARARGS #define cinnamon_settings_profile_start(...) _cinnamon_settings_profile_log (G_STRFUNC, "start", __VA_ARGS__) #define cinnamon_settings_profile_end(...) _cinnamon_settings_profile_log (G_STRFUNC, "end", __VA_ARGS__) #define cinnamon_settings_profile_msg(...) _cinnamon_settings_profile_log (NULL, NULL, __VA_ARGS__) #elif defined(G_HAVE_GNUC_VARARGS) #define cinnamon_settings_profile_start(format...) _cinnamon_settings_profile_log (G_STRFUNC, "start", format) #define cinnamon_settings_profile_end(format...) _cinnamon_settings_profile_log (G_STRFUNC, "end", format) #define cinnamon_settings_profile_msg(format...) _cinnamon_settings_profile_log (NULL, NULL, format) #endif #else #define cinnamon_settings_profile_start(...) #define cinnamon_settings_profile_end(...) #define cinnamon_settings_profile_msg(...) #endif void _cinnamon_settings_profile_log (const char *func, const char *note, const char *format, ...) G_GNUC_PRINTF (3, 4); G_END_DECLS #endif /* __CINNAMON_SETTINGS_PROFILE_H */ cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon/cinnamon-settings-session.h0000664000175000017500000000506614733247605027566 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2010-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CINNAMON_SETTINGS_SESSION_H #define __CINNAMON_SETTINGS_SESSION_H #include G_BEGIN_DECLS #define CINNAMON_TYPE_SETTINGS_SESSION (cinnamon_settings_session_get_type ()) #define CINNAMON_SETTINGS_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CINNAMON_TYPE_SETTINGS_SESSION, CinnamonSettingsSession)) #define CINNAMON_SETTINGS_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CINNAMON_TYPE_SETTINGS_SESSION, CinnamonSettingsSessionClass)) #define CINNAMON_IS_SETTINGS_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CINNAMON_TYPE_SETTINGS_SESSION)) #define CINNAMON_IS_SETTINGS_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CINNAMON_TYPE_SETTINGS_SESSION)) #define CINNAMON_SETTINGS_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CINNAMON_TYPE_SETTINGS_SESSION, CinnamonSettingsSessionClass)) #define CINNAMON_TYPE_SETTINGS_SESSION_STATE (cinnamon_settings_session_state_get_type()) typedef struct CinnamonSettingsSessionPrivate CinnamonSettingsSessionPrivate; typedef struct { GObject parent; CinnamonSettingsSessionPrivate *priv; } CinnamonSettingsSession; typedef struct { GObjectClass parent_class; } CinnamonSettingsSessionClass; typedef enum { CINNAMON_SETTINGS_SESSION_STATE_UNKNOWN, CINNAMON_SETTINGS_SESSION_STATE_ACTIVE, CINNAMON_SETTINGS_SESSION_STATE_INACTIVE, } CinnamonSettingsSessionState; GType cinnamon_settings_session_get_type (void); GType cinnamon_settings_session_state_get_type (void); CinnamonSettingsSession *cinnamon_settings_session_new (void); CinnamonSettingsSessionState cinnamon_settings_session_get_state (CinnamonSettingsSession *session); G_END_DECLS #endif /* __CINNAMON_SETTINGS_SESSION_H */ cinnamon-settings-daemon-6.4.3/.gitignore0000664000175000017500000000040214733247605017350 0ustar fabiofabioconfig.guess config.sub obj-x86_64-linux-gnu debian/tmp/ debian/files debian/cinnamon-settings-daemon/ debian/cinnamon-settings-daemon-dev/ debian/*.substvars debian/*.install debian/*.links debian/.debhelper/ debian/debhelper-build-stamp debian/*.debhelper cinnamon-settings-daemon-6.4.3/README0000664000175000017500000000000014733247605016232 0ustar fabiofabiocinnamon-settings-daemon-6.4.3/data/0000775000175000017500000000000014733247605016275 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/data/meson.build0000664000175000017500000000317414733247605020444 0ustar fabiofabiopkg_api = 'cinnamon-settings-daemon-3.0' proj_name = meson.project_name() enums_header = [ 'csd-enums.h', ] include_enums = include_directories('.') install_headers( enums_header, subdir: join_paths(pkg_api, proj_name), ) mkenums = gnome.mkenums( 'org.cinnamon.settings-daemon.enums.xml', sources: enums_header, comments: '', fhead: '', vhead: ' <@type@ id=\'org.cinnamon.settings-daemon.@EnumName@\'>', vprod: ' ', vtail: ' ', ftail: '', install_header: true, install_dir: schemadir, ) schemas = [ 'org.cinnamon.settings-daemon.peripherals.gschema.xml', 'org.cinnamon.settings-daemon.peripherals.wacom.gschema.xml', 'org.cinnamon.settings-daemon.plugins.gschema.xml', 'org.cinnamon.settings-daemon.plugins.power.gschema.xml', 'org.cinnamon.settings-daemon.plugins.color.gschema.xml', 'org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml', 'org.cinnamon.settings-daemon.plugins.xsettings.gschema.xml', 'org.cinnamon.settings-daemon.plugins.housekeeping.gschema.xml', 'org.cinnamon.settings-daemon.plugins.xrandr.gschema.xml', ] schema_conf = configuration_data() schema_conf.set('GETTEXT_PACKAGE', proj_name) foreach schema : schemas configure_file( input: schema + '.in.in', output: schema, configuration: schema_conf, install_dir: schemadir, ) endforeach pkg.generate( name: proj_name, description: 'cinnamon-settings-daemon specific enumarations', subdirs: pkg_api, requires: 'glib-2.0', ) cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.peripherals.wacom.gschema.xml.in.in0000664000175000017500000001262714733247605032561 0ustar fabiofabio true

Wacom stylus absolute mode Enable this to set the tablet to absolute mode. [-1, -1, -1, -1] Wacom tablet area Set this to x1, y1 and x2, y2 of the area usable by the tools. false Wacom tablet aspect ratio Enable this to restrict the Wacom tablet area to match the aspect ratio of the output. true Wacom tablet automatic rotation Enable this to automatically rotate the Wacom tablet area to match the rotation of the output. 'none' Wacom tablet rotation Set this to 'none', 'cw' for 90 degree clockwise, 'half' for 180 degree, and 'ccw' for 90 degree counterclockwise. true Wacom touch feature Enable this to move the cursor when the user touches the tablet. false Wacom tablet PC feature Enable this to only report stylus events when the tip is pressed. ["", "", ""] Wacom display mapping EDID information of monitor to map tablet to. Must be in the format [vendor, product, serial]. ["","",""] disables mapping. [0, 0, 100, 100] Wacom stylus pressure curve Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] Wacom stylus button mapping Set this to the logical button mapping. -1 Wacom stylus pressure threshold Set this to the pressure value at which a stylus click event is generated. [0, 0, 100, 100] Wacom eraser pressure curve Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] Wacom eraser button mapping Set this to the logical button mapping. -1 Wacom eraser pressure threshold Set this to the pressure value at which an eraser click event is generated. 'none' Wacom button action type The type of action triggered by the button being pressed. '' Key combination for the custom action The keyboard shortcut generated when the button is pressed for custom actions. ['', ''] Key combinations for a touchring or touchstrip custom action The keyboard shortcuts generated when a touchring or touchstrip is used for custom actions (up followed by down). ["", "", ""] cinnamon-settings-daemon-6.4.3/data/csd-enums.h0000664000175000017500000000703514733247605020351 0ustar fabiofabio/* * Copyright © 2010 Bastien Nocera * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Authors: * Bastien Nocera */ #ifndef __csd_enums_h__ #define __csd_enums_h__ typedef enum { CSD_FONT_ANTIALIASING_MODE_NONE, CSD_FONT_ANTIALIASING_MODE_GRAYSCALE, CSD_FONT_ANTIALIASING_MODE_RGBA } CsdFontAntialiasingMode; typedef enum { CSD_FONT_HINTING_NONE, CSD_FONT_HINTING_SLIGHT, CSD_FONT_HINTING_MEDIUM, CSD_FONT_HINTING_FULL } CsdFontHinting; typedef enum { CSD_FONT_RGBA_ORDER_RGBA, CSD_FONT_RGBA_ORDER_RGB, CSD_FONT_RGBA_ORDER_BGR, CSD_FONT_RGBA_ORDER_VRGB, CSD_FONT_RGBA_ORDER_VBGR } CsdFontRgbaOrder; typedef enum { CSD_SMARTCARD_REMOVAL_ACTION_NONE, CSD_SMARTCARD_REMOVAL_ACTION_LOCK_SCREEN, CSD_SMARTCARD_REMOVAL_ACTION_FORCE_LOGOUT } CsdSmartcardRemovalAction; typedef enum { CSD_BELL_MODE_ON, CSD_BELL_MODE_OFF, CSD_BELL_MODE_CUSTOM } CsdBellMode; typedef enum { CSD_TOUCHPAD_HANDEDNESS_RIGHT, CSD_TOUCHPAD_HANDEDNESS_LEFT, CSD_TOUCHPAD_HANDEDNESS_MOUSE } CsdTouchpadHandedness; typedef enum { CSD_XRANDR_BOOT_BEHAVIOUR_DO_NOTHING, CSD_XRANDR_BOOT_BEHAVIOUR_CLONE, CSD_XRANDR_BOOT_BEHAVIOUR_DOCK, CSD_XRANDR_BOOT_BEHAVIOUR_FOLLOW_LID } CsdXrandrBootBehaviour; typedef enum { CSD_WACOM_ROTATION_NONE, CSD_WACOM_ROTATION_CW, CSD_WACOM_ROTATION_CCW, CSD_WACOM_ROTATION_HALF } CsdWacomRotation; typedef enum { CSD_WACOM_ACTION_TYPE_NONE, CSD_WACOM_ACTION_TYPE_CUSTOM, CSD_WACOM_ACTION_TYPE_SWITCH_MONITOR, CSD_WACOM_ACTION_TYPE_HELP } CsdWacomActionType; typedef enum { CSD_POWER_ACTION_BLANK, CSD_POWER_ACTION_SUSPEND, CSD_POWER_ACTION_SHUTDOWN, CSD_POWER_ACTION_HIBERNATE, CSD_POWER_ACTION_INTERACTIVE, CSD_POWER_ACTION_NOTHING } CsdPowerActionType; typedef enum { CSD_UPDATE_TYPE_ALL, CSD_UPDATE_TYPE_SECURITY, CSD_UPDATE_TYPE_NONE } CsdUpdateType; typedef enum { CSD_NUM_LOCK_STATE_UNKNOWN, CSD_NUM_LOCK_STATE_ON, CSD_NUM_LOCK_STATE_OFF } CsdNumLockState; typedef enum { CSD_INPUT_SOURCES_SWITCHER_OFF, CSD_INPUT_SOURCES_SWITCHER_SHIFT_L, CSD_INPUT_SOURCES_SWITCHER_ALT_L, CSD_INPUT_SOURCES_SWITCHER_CTRL_L, CSD_INPUT_SOURCES_SWITCHER_SHIFT_R, CSD_INPUT_SOURCES_SWITCHER_ALT_R, CSD_INPUT_SOURCES_SWITCHER_CTRL_R, CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT_L, CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT_R, CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT_L, CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT_R, CSD_INPUT_SOURCES_SWITCHER_SHIFT_L_SHIFT_R, CSD_INPUT_SOURCES_SWITCHER_ALT_L_ALT_R, CSD_INPUT_SOURCES_SWITCHER_CTRL_L_CTRL_R, CSD_INPUT_SOURCES_SWITCHER_ALT_SHIFT, CSD_INPUT_SOURCES_SWITCHER_CTRL_SHIFT, CSD_INPUT_SOURCES_SWITCHER_ALT_CTRL, CSD_INPUT_SOURCES_SWITCHER_CAPS, CSD_INPUT_SOURCES_SWITCHER_SHIFT_CAPS, CSD_INPUT_SOURCES_SWITCHER_ALT_CAPS, CSD_INPUT_SOURCES_SWITCHER_CTRL_CAPS } CsdInputSourcesSwitcher; #endif /* __csd_enums_h__ */ ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootcinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.housekeeping.gschema.xml.in.incinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.housekeeping.gschema.xml.in0000664000175000017500000000311314733247605032665 0ustar fabiofabio [] Mount paths to ignore Specify a list of mount paths to ignore when they run low on space. 0.05 Free percentage notify threshold Percentage free space threshold for initial warning of low disk space. If the percentage free space drops below this, a warning will be shown. 0.01 Subsequent free space percentage notify threshold Specify the percentage that the free disk space should reduce by before issuing a subsequent warning. 1 Free space notify threshold Specify an amount in GB. If the amount of free space is more than this, no warning will be shown. 10 Minimum notify period for repeated warnings Specify a time in minutes. Subsequent warnings for a volume will not appear more often than this period. cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.xsettings.gschema.xml.in.in0000664000175000017500000000756714733247605032655 0ustar fabiofabio 'rgba' Antialiasing The type of antialiasing to use when rendering fonts. Possible values are: "none" for no antialiasing, "grayscale" for standard grayscale antialiasing, and "rgba" for subpixel antialiasing (LCD screens only). 'slight' Hinting The type of hinting to use when rendering fonts. Possible values are: "none" for no hinting, "slight" for basic, "medium" for moderate, and "full" for maximum hinting (may cause distortion of letter forms). 'rgb' RGBA order The order of subpixel elements on an LCD screen; only used when antialiasing is set to "rgba". Possible values are: "rgb" for red on left (most common), "bgr" for blue on left, "vrgb" for red on top, "vbgr" for red on bottom. [] List of explicitly disabled GTK+ modules A list of strings representing the GTK+ modules that will not be loaded, even if enabled by default in their configuration. [] List of explicitly enabled GTK+ modules A list of strings representing the GTK+ modules that will be loaded, usually in addition to conditional and forcibly disabled ones. {} A dictionary of XSETTINGS to override This dictionary maps XSETTINGS names to overrides values. The values must be either strings, signed int32s or (in the case of colors), 4-tuples of uint16 (red, green, blue, alpha; 65535 is fully opaque). false Menus Have Icons Whether menus may display an icon next to a menu entry. false Buttons Have Icons Whether buttons may display an icon in addition to the button text. false Use headerbar for file dialogs true Show the 'Input Methods' menu Whether the context menus of entries and text views should offer to change the input method. true Show the 'Unicode Control Character' menu Whether the context menus of entries and text views should offer to insert control characters. true Only show mnemonics on when the Alt key is pressed Whether mnemonics should be automatically shown and hidden when the user presses the Alt key. cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.peripherals.gschema.xml.in.in0000664000175000017500000002230614733247605031447 0ustar fabiofabio 'none' Smartcard removal action Set this to one of "none", "lock-screen", or "force-logout". The action will get performed when the smartcard used for log in is removed. true 0 'on' Possible values are "on", "off", and "custom". 400 100 '' Keyboard Bell Custom Filename File name of the bell sound to be played. true Remember NumLock state When set to true, GNOME will remember the state of the NumLock LED between sessions. 'unknown' NumLock state The remembered state of the NumLock LED. 'off' Modifiers-only input sources switcher shortcut true Whether the tablet's orientation is locked, or rotated automatically. '' Device hotplug custom command Command to be run when a device is added or removed. true 30 Key Repeat Interval Delay between repeats in milliseconds. 500 Initial Key Repeat Delay Initial key repeat delay in milliseconds. 0 Mouse wheel emulation button. 0 to disable the feature. false deprecated - see org.cinnamon.desktop.peripherals.mouse false deprecated - see org.cinnamon.desktop.peripherals.mouse false deprecated - see org.cinnamon.desktop.peripherals.mouse false deprecated - see org.cinnamon.desktop.peripherals.mouse -1 deprecated - see org.cinnamon.desktop.peripherals.mouse false deprecated - see org.cinnamon.desktop.peripherals.mouse -1 deprecated - see org.cinnamon.desktop.peripherals.mouse 400 deprecated - see org.cinnamon.desktop.peripherals.mouse 8 deprecated - see org.cinnamon.desktop.peripherals.mouse true deprecated - see org.cinnamon.desktop.peripherals.mouse true Disable touchpad while typing Set this to TRUE if you have problems with accidentally hitting the touchpad while typing. 3 Set scrolling mode on touchpad 0 to 2, 0 is disabled, 1 is two-finger scrolling, 2 is edge scrolling, 3 is automatic selection false true Enable mouse clicks with touchpad Set this to TRUE to be able to send mouse clicks by tapping on the touchpad. 3 Click action on clickpads 0 through 2, 0 is single click action, 1 emulates mouse buttons in bottom corners, 2 is multi-finger click, 3 is automatic selection true Enable touchpad Set this to TRUE to enable all touchpads. false Disable the touchpad when an external mouse is connected Set this to TRUE to disable the touchpad when an external mouse is connected (only available with libinput) 'mouse' Touchpad button orientation Swap left and right mouse buttons for left-handed mice with 'left', 'right' for right-handed, 'mouse' to follow the mouse setting. false Custom Motion Acceleration Whether or not to use a custom motion acceleration value. -1 Motion Acceleration Acceleration multiplier for mouse motion. A value of -1 is the system default. false Custom Motion Threshold Whether or not to use a custom motion threshold value. -1 Motion Threshold Distance in pixels the pointer must move before accelerated mouse motion is activated. A value of -1 is the system default. true Natural scrolling Set this to TRUE to enable natural (reverse) scrolling for touchpads. cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.xrandr.gschema.xml.in.in0000664000175000017500000000111414733247605032101 0ustar fabiofabio '/etc/cinnamon-settings-daemon/xrandr/monitors.xml' deprecated - handled by muffin 'follow-lid' deprecated - handled by muffin cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in0000664000175000017500000000124314733247605030607 0ustar fabiofabio ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootcinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.incinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.i0000664000175000017500000001340114733247605032457 0ustar fabiofabio '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys '' deprecated - moved to org.cinnamon.desktop.keybindings.media-keys cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.power.gschema.xml.in.in0000664000175000017500000002446614733247605031756 0ustar fabiofabio 30 The brightness of the screen when idle This is the laptop panel screen brightness used when the session is idle. false Dim the screen after a period of inactivity when on AC power If the screen should be dimmed to save power when the computer is idle when on AC power. true Dim the screen after a period of inactivity when on battery power If the screen should be dimmed to save power when the computer is idle when on battery power. 90 The default amount of time to dim the screen after idle The default amount of time to dim the screen after idle. 1800 Sleep timeout display when on AC The amount of time in seconds before the display turns off when the computer is on AC power. 1800 Sleep timeout display when on battery The amount of time in seconds before the display turns off when the computer is on battery power. 0 Sleep timeout computer when on AC The amount of time in seconds the computer on AC power needs to be inactive before it goes to sleep. A value of 0 means never. 'suspend' Whether to hibernate, suspend or do nothing when inactive The type of sleeping that should be performed when the computer is inactive. 0 Sleep timeout computer when on battery The amount of time in seconds the computer on battery power needs to be inactive before it goes to sleep. A value of 0 means never. 'suspend' Whether to hibernate, suspend or do nothing when inactive The type of sleeping that should be performed when the computer is inactive. 'suspend' Suspend button action The action to take when the system suspend button is pressed. 'hibernate' Hibernate button action The action to take when the system hibernate button is pressed. 'suspend' Power button action The action to take when the system power button is pressed. 'suspend' Laptop lid close action on battery The action to take when the laptop lid is closed and the laptop is on battery power. 'suspend' Laptop lid close action when on AC The action to take when the laptop lid is closed and the laptop is on AC power. false Laptop lid, when closed, will suspend even if there is an external monitor plugged in With no external monitors plugged in, closing a laptop's lid will suspend the machine (as set by the lid-close-battery-action and lid-close-ac-action keys). By default, however, closing the lid when an external monitor is present will not suspend the machine, so that one can keep working on that monitor (e.g. for docking stations or media viewers). Set this key to False to keep the default behavior, or to True to suspend the laptop whenever the lid is closed and regardless of external monitors. 'hibernate' Battery critical low action The action to take when the battery is critically low. 10 Percentage considered low The percentage of the battery when it is considered low. Only valid when use-time-for-policy is false. 4 Percentage considered critical The percentage of the battery when it is considered critical. Only valid when use-time-for-policy is false. 3 Percentage action is taken The percentage of the battery when the critical action is performed. Only valid when use-time-for-policy is false. 1200 The time remaining when low The time remaining in seconds of the battery when it is considered low. Only valid when use-time-for-policy is true. 420 The time remaining when critical The time remaining in seconds of the battery when it is considered critical. Only valid when use-time-for-policy is true. 240 The time remaining when action is taken The time remaining in seconds of the battery when critical action is taken. Only valid when use-time-for-policy is true. false Whether to use time-based notifications If time based notifications should be used. If set to false, then the percentage change is used instead, which may fix a broken ACPI BIOS. false If the computer should lock when entering suspend mode If the computer should lock during suspend - replaces ubuntu-lock-on-suspend false Use the backlight helper application by default Setting this to true forces cinnamon-settings-daemon to use the backlight helper application to provide backlight control. This will usually fix backlight control problems on laptops where X11 picks the wrong interface, or uses an interface incorrectly. Adjust backlight-preference-order if the default selection logic still chooses the wrong interface. ['firmware','platform','raw'] Search order for backlight control interfaces Controls the type of interfaces the backlight-helper will search for to control the backlight. This can be useful for working around systems with broken default backlight control behavior which provide multiple interfaces. If you are having problems, try setting 'raw' to a higher priority. true Whether or not cinnamon-settings-daemon inhibits logind's handling of lid switch This setting should be true in all distributions and for all users. Only set it to false, if you want to prevent Cinnamon from handling lid switch events. In this case, you should not rely on Cinnamon's lid actions and use the logind ones instead. 2 In percent, minimum allowable brightness adjustment. This will become 0 percent brightness true Low battery notifications for wireless keyboard Whether to show low battery notifications for wireless keyboard devices. true Low battery notifications for wireless mouse Whether to show low battery notifications for wireless mouse devices. true Low battery notifications for other connected devices Whether to show low battery notifications for connected devices other than keyboards and mice. cinnamon-settings-daemon-6.4.3/data/org.cinnamon.settings-daemon.plugins.color.gschema.xml.in.in0000664000175000017500000000526414733247605031733 0ustar fabiofabio 0 The duration a display profile is valid This is the number of days after which the display color profile is considered invalid. 0 The duration a printer profile is valid This is the number of days after which the printer color profile is considered invalid. false If the night light mode is enabled Night light mode changes the color temperature of your display when the sun has gone down or at preset times. 2700 Temperature of the display when enabled This temperature in Kelvin is used to modify the screen tones when night light mode is enabled. Higher values are bluer, lower redder. 'auto' Set the way start and stop times are determined Setting to 'auto' will use the system timezone to determine sunrise and sunset. Using 'manual' mode allows specifying exact start and stop times (night-light-schedule-from and -to). 20.00 The start time When “night-light-schedule-automatic†is disabled, use this start time in hours from midnight. 6.00 The end time When “night-light-schedule-automatic†is disabled, use this end time in hours from midnight. (91,181) The last detected position When location services are available this represents the last detected location. The default value is an invalid value to ensure it is always updated at startup. cinnamon-settings-daemon-6.4.3/AUTHORS0000664000175000017500000000011014733247605016424 0ustar fabiofabioJonathan Blandford William Jon McCann cinnamon-settings-daemon-6.4.3/COPYING0000664000175000017500000004312214733247605016421 0ustar fabiofabio GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. cinnamon-settings-daemon-6.4.3/.github/0000775000175000017500000000000014733247605016724 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/.github/ISSUE_TEMPLATE.md0000664000175000017500000000043614733247605021434 0ustar fabiofabio ``` * csd version ('dpkg --list | grep cinnamon-settings-daemon' in Mint/Ubuntu) * Distribution - (Mint 17.2, Arch, Fedora 25, etc...) * Graphics hardware *and* driver used * 32 or 64 bit ``` **Issue** **Steps to reproduce** **Expected behaviour** **Other information** cinnamon-settings-daemon-6.4.3/.github/workflows/0000775000175000017500000000000014733247605020761 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/.github/workflows/build.yml0000664000175000017500000000112414733247605022601 0ustar fabiofabioname: Build on: push: branches: - master pull_request: branches: - master workflow_dispatch: inputs: debug_enabled: type: boolean description: 'Start an SSH server on failure.' required: false default: false jobs: build: uses: linuxmint/github-actions/.github/workflows/do-builds.yml@master with: commit_id: master ############################## Comma separated list - like 'linuxmint/xapp, linuxmint/cinnamon-desktop' dependencies: linuxmint/cinnamon-desktop ############################## cinnamon-settings-daemon-6.4.3/README.rst0000664000175000017500000001067414733247605017063 0ustar fabiofabio``cinnamon-settings-daemon`` is a collection of plugins. These plugins are started by ``cinnamon-session`` when you log in. The plugins run in the background, each with its own process. PLUGINS ======= Here is a description of each plugin. a11y-settings ------------- automount --------- background ---------- clipboard --------- Xorg features two ways of copying and pasting content. The first one is ``X-clipboard``, which is commonly used in edit menus and when using ``Ctrl+C`` and ``Ctrl+V``. The second one is ``X-selection`` which is used when selecting content with the mouse and pasting it with a middle-click. When you copy content from a window, that content is available either in ``X-clipboard`` or ``X-selection`` until the application which owns that window is terminated. This plugin keeps the content of ``X-clipboard`` in memory, so that even if the owner application exits, the content continues to be available. color ----- common ------ datetime -------- dummy ----- This is a dummy plugin. It doesn't do anything. housekeeping ------------ **thumbnail cache** The thumbnail cache is cleaned up according to the settings stored in ``org.cinnamon.desktop.thumbnail-cache``. This is done 2 minutes after login and then once each day. **low disk space** Every minute, the plugin checks the mounted volume to see if they have low disk space, according to the settings stored in ``org.cinnamon.settings-daemon.plugins.housekeeping``. The plugin shows a notification when a volume is full. keyboard -------- This plugin handles the keyboard. **keyboard settings** It reads and listens to the ``org.cinnamon.settings-daemon.peripherals.keyboard`` settings and applies the configuration. **numlock state** It also listens to the state of the numlock key and saves it in the settings to ensure the state is remembered and preserved for the next session. **keyboard layout** The layout selection is done in the ``cinnamon-control-center`` ``region`` plugin (which is presented to the user in the ``cinnamon-settings`` ``keyboard`` module). That configuration is set directly via ``gkbd`` (``libgnomekbd``) and ``xkl`` (``libxklavier``). This plugin reads and listens to that configuration and assigns it to the keyboard. **hotplug command** Although it isn't configured by default or used by ``cinnamon-settings``, when a keyboard is plugged in, or removed, this plugin executes the command specified in ``org.cinnamon.settings-daemon.peripherals.input-devices hotplug-command`` with a series of arguments to specify the event type, the device, etc. An example script which can be used for such a command is available in ``plugins/common/input-device-example.sh``. media-keys ---------- power ----- print-notifications ------------------- This plugin shows printer notifications. On DBUS, it listens to events on ``org.cups.cupsd.Notifier``. ``libnotify`` is used to show the notifications. screensaver-proxy ----------------- smartcard --------- wacom ----- This plugin handles Wacom tablets. It reads and listens to the ``org.cinnamon.settings-daemon.peripherals.wacom`` and applies the configuration in X11. xsettings --------- This plugin sets the settings for GTK and Xft. TESTING ======= To test a plugin: 1. Kill the running CSD plugin 2. Build the project 3. Run the built plugin in verbose mode For example: * ``killall csd-sound`` (you might have to kill it twice, if CSM tries to restart it) * ``dpkg-buildpackage`` * ``plugins/sound/csd-sound --verbose`` TODO ==== - Remove custom keybinding code (we handle that in Cinnamon now) - do we want to handle media keys in cinnamon also? Would get around the 'no meta keys while a menu is open' issue. - Switch to Gnome's keyboard layout (gsettings) handler - basically reverting Ubuntu's patch for this. This will allow us to implement ibus popups directly in Cinnamon - Look into backgrounds - we should be able to eliminate the background manager in the cinnamon gnome 3.8 compat rollup, and continue to handle backgrounds as we currently do - Investigate: How to keep gnome-settings-daemon from autostarting. It checks for environment=GNOME... which means Cinnamon also - is it time to have our own freedesktop.org name? -- Update on this: Setting session name to Cinnamon works - then add to main.c in cinnamon, to set XDG_CURRENT_DESKTOP=GNOME makes sure apps keep showing up - Multiple backgrounds on multiple monitors - /etc/acpi/powerbtn.sh - add cinnamon-settings-daemon to script - how? postinst? cinnamon-settings-daemon-6.4.3/makepot0000775000175000017500000000026714733247605016757 0ustar fabiofabio#!/bin/bash xgettext --language=C --keyword=_ --keyword=N_ --output=cinnamon-settings-daemon.pot cinnamon-settings-daemon/*.c cinnamon-settings-daemon/*.h plugins/*/*.c plugins/*/*.h cinnamon-settings-daemon-6.4.3/install-scripts/0000775000175000017500000000000014733247605020517 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/install-scripts/meson_update_icon_cache.py0000664000175000017500000000045014733247605025706 0ustar fabiofabio#!/usr/bin/python3 import os import subprocess themedir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'icons', 'hicolor') if not os.environ.get('DESTDIR'): print('Updating gtk icon cache... %s' % themedir) subprocess.call(['gtk-update-icon-cache', '-f', '-t', themedir]) cinnamon-settings-daemon-6.4.3/install-scripts/meson.build0000664000175000017500000000120214733247605022654 0ustar fabiofabio# These scripts run as post-installation scripts. # They're designed to do nothing if DESTDIR is set, which happens # during debian builds for instance - there's a fake install target # so running these would be pointless. # When using deb packaging, these aren't needed, as these operations # are run automatically by the package manager. # They're really only necessary in straight builds where 'ninja install' # will be run directly, to install the program onto the system. # Re-compile gsettings meson.add_install_script('meson_install_schemas.py') # Update the Gtk icon cache meson.add_install_script('meson_update_icon_cache.py') cinnamon-settings-daemon-6.4.3/install-scripts/meson_mk_symlink.py0000664000175000017500000000121014733247605024441 0ustar fabiofabio#!/usr/bin/python3 import os import subprocess import sys orig_arg = sys.argv[1] target_arg =sys.argv[2] exec_name = sys.argv[3] prefix = os.environ.get('MESON_INSTALL_DESTDIR_PREFIX') orig_path = os.path.join(prefix, orig_arg, exec_name) dest_path = os.path.join(prefix, target_arg, exec_name) if os.path.lexists(dest_path): subprocess.call(['unlink', dest_path]) print('Adding symlink %s -> %s' % (orig_path, dest_path)) subprocess.call(['mkdir', '-p', os.path.dirname(dest_path)]) if not os.environ.get('DESTDIR'): subprocess.call(['ln', '-s', orig_path, dest_path]) else: subprocess.call(['ln', '-rs', orig_path, dest_path]) cinnamon-settings-daemon-6.4.3/install-scripts/meson_install_schemas.py0000664000175000017500000000042614733247605025445 0ustar fabiofabio#!/usr/bin/python3 import os import subprocess schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') if not os.environ.get('DESTDIR'): print('Compiling gsettings schemas...') subprocess.call(['glib-compile-schemas', schemadir]) cinnamon-settings-daemon-6.4.3/ChangeLog0000664000175000017500000042612114733247605017144 0ustar fabiofabio2008-08-03 C de-Avillez * plugins/mouse/gsd-mouse-manager.c: add '-k' to syndaemon call, in order to ignore modifier keys when monitoring keyboard. Thanks to Dag Asheim for spotting this, and proposing a patch. 2008-07-01 Sergey Udaltsov * configure.ac, plugins/keyboard/gsd-keyboard-xkb.c: depend on libxklavier 4.0, updated API 2009-06-01 Jens Granseuer * plugins/housekeeping/gsd-disk-space.c: include config.h so the notifications stuff can actually be built (bug #584217) 2009-05-06 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (make_menu_item_for_output_title): Make the menu item label explicitly black. We don't want to follow the theme's colors, as the label is always shown against a light pastel background --- using the theme's colors makes the label hard to read on "inverse" themes. Fixes the cinnamon-settings-daemon part of bug #556050. 2009-04-15 Thomas H.P. Andersen * plugins/xrandr/gsd-xrandr-manager.c: (status_icon_start): * configure.ac: Replace deprecated gtk symbol gtk_status_icon_set_tooltip. Bump required gtk to 2.16. (bug #578480) 2009-04-14 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (print_countdown_text): use ngettext for the reset dialog (bug #575409) ==================== 2.26.1 ==================== 2009-04-14 Jens Granseuer * NEWS: * configure.ac: release 2.26.1 2009-04-11 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (gsd_keybindings_manager_start): move the lookup of allowed keys after the directory has been cached in callback registration to avoid GConf roundtrip (bug #578539) 2009-04-11 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (start_keyboard_idle_cb): preload GConf keyboard directory recursively to avoid roundtrips (bug #578542) 2009-04-08 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (user_says_things_are_ok): Use 30 seconds for the confirmation timeout, so that monitors can settle down and the user will have a chance to read the message. 2009-04-03 Jens Granseuer Patch by: * plugins/media-keys/Makefile.am: don't install the plugin descriptor if the plugin isn't installed (bug #577815) 2009-04-02 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (numlock_gconf_state_key): use info level instead of warning for the "NumLock remembering disabled" message (bug #577578) 2009-03-28 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (sanitize), (generate_fn_f7_configs): if the sanitized array ends up having no members at all return a NULL configuration since the following code assumes it has at least one valid setup if it's not NULL. Fixes a crash when closing the lid on some laptops (bug #576875) 2009-03-27 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (on_notification_closed), (on_slow_keys_action), (on_sticky_keys_action), (ax_slowkeys_warning_post_bubble), (ax_stickykeys_warning_post_bubble), (gsd_a11y_keyboard_manager_stop): fix crash when closing the a11y notification bubble caused by incompatible changes in libnotify API (bug #576535). Also remove workarounds for bugs in libnotify < 0.4.5 2009-03-27 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (restore_backup_configuration), (try_to_apply_intended_configuration): remove unused variables 2009-03-26 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (ensure_current_configuration_is_saved): New helper function. Ensures that a monitors.xml exists with the current/unchanged configuration, so that a latter gnome_rr_config_save() will create a backup file out of *that* original configuration. This lets the "revert" function from gnome-display-properties work properly on an initial login, even when there is no monitors.xml already present. 2009-03-25 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (restore_backup_configuration): Handle the case where no backup file was created for monitors.xml, because *that* file didn't exist (such as on a first-time login). 2009-03-25 Federico Mena Quintero Centralize the handling of GNOME_RR_ERROR_NO_MATCHING_CONFIG, as that is not really an error. * plugins/xrandr/gsd-xrandr-manager.c (apply_configuration_from_filename): New helper function; centralizes the handling of gnome_rr_config_apply_from_filename() and ignores GNOME_RR_ERROR_NO_MATCHING_CONFIG. That is not actually an error; it just means that the user probably changed his monitors and the stored set of configurations doesn't have a config that is usable for the new monitors. (restore_backup_configuration): Use apply_configuration_from_filename(). (try_to_apply_intended_configuration): Likewise. (apply_intended_configuration): Likewise. (apply_stored_configuration_at_startup): Likewise. 2009-03-19 Federico Mena Quintero http://bugzilla.gnome.org/show_bug.cgi?id=576006 - The confirmation dialog from the RANDR plugin can appear behind the window from gnome-display-properties. This also depends on a change to gnome-control-center. * plugins/xrandr/gsd-xrandr-manager.xml: Add an org.gnome.SettingsDaemon.XRANDR_2 interface in addition to the old XRANDR one, with an ApplyConfiguration method that also takes a parent window ID and a timestamp. * plugins/xrandr/gsd-xrandr-manager.c (gsd_xrandr_manager_2_apply_configuration): Implement the new DBus method with the parent window and timestamp. (user_says_things_are_ok): Use the parent window. 2009-03-19 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (user_says_things_are_ok): Revert the use of g_timeout_add_seconds(), since we actually care that the user sees real second ticks in the dialog. This isn't a neverending timeout anyway. 2009-03-18 Jens Granseuer * cinnamon-settings-daemon/Makefile.am: * plugins/a11y-keyboard/Makefile.am: * plugins/background/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/dummy/Makefile.am: * plugins/font/Makefile.am: * plugins/housekeeping/Makefile.am: * plugins/keybindings/Makefile.am: * plugins/keyboard/Makefile.am: * plugins/media-keys/Makefile.am: * plugins/mouse/Makefile.am: * plugins/screensaver/Makefile.am: * plugins/sound/Makefile.am: * plugins/typing-break/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrdb/Makefile.am: * plugins/xsettings/Makefile.am: revert build patch from r763 ==================== 2.26.0 ==================== 2009-03-16 Rodrigo Moya * NEWS: * configure.ac: release 2.26.0 2009-03-07 Jens Granseuer Based on patch by: Christopher Taylor * cinnamon-settings-daemon/Makefile.am: * plugins/a11y-keyboard/Makefile.am: * plugins/background/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/dummy/Makefile.am: * plugins/font/Makefile.am: * plugins/housekeeping/Makefile.am: * plugins/keybindings/Makefile.am: * plugins/keyboard/Makefile.am: * plugins/media-keys/Makefile.am: * plugins/mouse/Makefile.am: * plugins/screensaver/Makefile.am: * plugins/sound/Makefile.am: * plugins/typing-break/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrdb/Makefile.am: * plugins/xsettings/Makefile.am: make build work with -Wl,-z,defs linker options (bug #574452) ==================== 2.25.92 ==================== 2009-03-02 Jens Granseuer * NEWS: * configure.ac: release 2.25.92 2009-03-02 Jens Granseuer * cinnamon-settings-daemon/Makefile.am: also install the plugin header file because it is needed for custom plugins (bug #573610) 2009-02-23 Jens Granseuer * data/cinnamon-settings-daemon.schemas.in: add missing keys for a11y shortcut names (bug #572807) 2009-02-22 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (user_says_things_are_ok): use g_timeout_add_seconds instead of g_timeout_add 2009-02-21 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (timeout_response_cb): revert the screen resolution change if the user closes the window or hits escape (bug #571492) 2009-02-21 Jens Granseuer Fix compiler warnings. * plugins/housekeeping/gsd-disk-space.c: add missing include * plugins/housekeeping/gsd-housekeeping-manager.c: ditto * plugins/housekeeping/gsd-disk-space.h: don't declare public functions static 2009-02-20 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (parse_binding), (bindings_get_entry): don't output a warning for disabled shortcuts 2009-02-15 Jens Granseuer Patch by: Leo Iannacone * plugins/media-keys/gsd-media-keys-window.c: (on_expose_event): fix alignment of the composited media window (bug #567249) 2009-02-15 Luca Ferretti reviewed by: Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (ax_slowkeys_warning_post_dialog), (ax_stickykeys_warning_post_dialog): * plugins/mouse/gsd-mouse-manager.c: (set_mousetweaks_daemon): Don't use legacy icons for keyboard and mouse (bug #571823) 2009-02-15 Luca Ferretti reviewed by: Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (user_says_things_are_ok): HIG fix for button labels (bug #571819) 2009-02-15 Luca Ferretti reviewed by: Jens Granseuer * plugins/keyboard/modmap-dialog.glade: Fix label for "Don't show this message again" checkbox, isn't a `string change` due to reusing a yet available label (bug #571821) 2009-02-11 Jens Granseuer * plugins/common/eggaccelerators.c: (egg_accelerator_parse_virtual): don't return TRUE if we can't parse the accelerator at all; fixes crash with invalid keyboard shortuts (bug #571329) 2009-02-11 Matthias Clasen Bug 570590 – a11y plugin warning * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: Avoid warnings due to notifications on nonexisting statusicons. 2009-02-08 Jens Granseuer Patch by: Nirbheek Chauhan * configure.ac: add --without-libnotify to disable notifications (bug #570885) 2009-02-06 Matthias Clasen Bug 570743 – restart on crash * data/cinnamon-settings-daemon.desktop.in.in: Have gnome-session restart g-s-d if it crashes (heaven forbid!). 2009-02-04 Vincent Untz * configure.in: post-release bump to 2.25.91 ==================== 2.25.90 ==================== 2009-02-04 Vincent Untz * NEWS: * configure.in: version 2.25.90 2009-02-04 Vincent Untz * data/Makefile.am: fix distcheck 2009-02-03 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (restore_backup_configuration): Use gnome_rr_config_apply_from_filename(), as that's the new, non-deprecated API. (try_to_apply_intended_configuration): Likewise. (apply_intended_configuration): Likewise. (apply_stored_configuration_at_startup): Likewise. 2009-02-01 Frederic Peters * plugins/housekeeping/Makefile.am: * plugins/housekeeping/gsd-disk-space.c: add low diskspace checker files to housekeeping plug-in Makefile.am; and make its clean and setup methods available are made available. (bug #570132) 2009-01-31 Theppitak Karoonboonyanan * plugins/media-keys/Makefile.am: Fix include paths for non-source-dir builds. (bug #569955) 2009-01-28 Jens Granseuer * configure.ac: require gnome-desktop 2.25.6 due to recent changes 2009-01-27 Federico Mena Quintero http://bugzilla.gnome.org/show_bug.cgi?id=545115 - Ask for confirmation, with a timeout, after changing the RANDR configuration for if we leave the user with an unusable display. This also handles the case where the machine may crash after changing the configuration; the old/known-good configuration will be restored when the user restarts his session. Refactor: * plugins/xrandr/gsd-xrandr-manager.c (apply_stored_configuration_at_startup): Factor out the logic to apply the stored configuration at startup. (gsd_xrandr_manager_start): Use the function above. During startup, restore the backup configuration if it existed, to recover from the case when the machine crashes while applying an intended configuration. * plugins/xrandr/gsd-xrandr-manager.c (apply_stored_configuration_at_startup): First see if we have a backup configuration; if so, it means the machine or g-s-d crashed while changing the RANDR parameters. If there is no backup configuration, then we have a known-good configuration which we can use. (apply_intended_configuration): New function, used to load the intended configuration (i.e. the non-backup one). (restore_backup_configuration): Utility function to overwrite the known-bad configuration with the known-good backup one. Use a timeout-confirmation dialog after changing the display configuration: * plugins/xrandr/gsd-xrandr-manager.c (try_to_apply_intended_configuration): New function; applies the intended configuration, restores the backup configuration if that fails, or asks the user to confirm if the intended configuration is usable. (gsd_xrandr_manager_apply_configuration): Use try_to_apply_intended_configuration() in the implementation of the D-Bus method to apply RANDR configurations. This way all apps which use this D-Bus method will get confirmation for free. (output_rotation_item_activate_cb): Use try_to_apply_intended_configuration() so that the RANDR tray-icon also uses the confirmation/backup logic. (restore_backup_configuration): Restore the screen configuration itself in addition to restoring the file on disk from the backup. (user_says_things_are_ok): New utility function to handle a timeout-confirmation dialog. Fix error reporting at startup: * plugins/xrandr/gsd-xrandr-manager.c (error_message): Handle the case where the status_icon is not created yet; this happens during startup or when the status_icon is disabled by the user. Handle the case where there is no matching configuration at startup; this is not an error: * plugins/xrandr/gsd-xrandr-manager.c (apply_intended_configuration): "no matching configuration" is not an error when looking for a suitable configuration in monitors.xml; it simply means that the user has a different set of monitors than the ones that are available in that file. 2009-01-24 Jens Granseuer Patch by: Andres Freund Fix possible crash when pressing Fn-F7 (bug #568713) * plugins/xrandr/gsd-xrandr-manager.c: (handle_fn_f7): only try to dereference the error when it was actually set 2009-01-27 Federico Mena Quintero http://bugzilla.gnome.org/show_bug.cgi?id=545115 - Ask for confirmation, with a timeout, after changing the RANDR configuration for if we leave the user with an unusable display. This also handles the case where the machine may crash after changing the configuration; the old/known-good configuration will be restored when the user restarts his session. Refactor: * plugins/xrandr/gsd-xrandr-manager.c (apply_stored_configuration_at_startup): Factor out the logic to apply the stored configuration at startup. (gsd_xrandr_manager_start): Use the function above. 2009-01-26 Ray Strode Delay drawing the background until SessionRunning. * plugins/background/gsd-background-manager.c: (queue_draw_background): Cancel queued draw if nautilus is now running. (on_bus_message), (draw_background_after_session_loads), (gsd_background_manager_start): wait for SessionRunning and then queue background draw (gsd_background_manager_stop): remove message filter 2009-01-24 Jens Granseuer Patch by: Andres Freund Fix possible crash when pressing Fn-F7 (bug #568713) * plugins/xrandr/gsd-xrandr-manager.c: (handle_fn_f7): only try to dereference the error when it was actually set 2009-01-22 Bastien Nocera * data/apps_gnome_settings_daemon_keybindings.schemas.in: KEY_FILE maps to XF86Explorer, so use that to launch the file manager in the user's home directory 2009-01-19 Ray Strode Add crossfade transition when switching bgs (bug 552857) * plugins/background/gsd-background-manager.c (draw_background): Add use_crossfade argument that initiates the fade if TRUE. (on_bg_changed): call draw_background with crossfade. (on_bg_transitioned): new function that calls draw_background without crossfade during slide show transitioning. (setup_bg): set up transitioned signal handler. (queue_draw_background): draw_background without crossfade after 8 second timeout waiting for nautilus. 2009-01-19 Ray Strode * plugins/background/gsd-background-manager.c (gsd_background_manager_start): Don't draw_background immediately when nautilus is disabled. gnome_bg_load_from_preferences forces a "changed" signal to get emitted which will queue a draw anyway 2009-01-18 Jens Granseuer * plugins/media-keys/Makefile.am: fix automake warning 2009-01-18 Jens Granseuer * configure.ac: fix build with PulseAudio, too (bug #568179) 2009-01-17 Jens Granseuer * plugins/media-keys/Makefile.am: fix build without PulseAudio (bug #568015) 2009-01-15 Bastien Nocera * plugins/media-keys/cut-n-paste/*: Cut'n'paste code from the PulseAudio enabled code in gnome-media's gnome-volume-control * plugins/media-keys/actions/acme-volume-*.[ch]: Remove the old AcmeVolume code * plugins/media-keys/actions/acme.glade: * plugins/media-keys/actions/acme.h: Move to plugins/media-keys/ * configure.ac: Tell config.h when PulseAudio support is disabled * plugins/media-keys/gsd-media-keys-manager.c (update_dialog), (on_stream_event_notify), (do_sound_action), (update_default_sink), (on_control_ready), (on_control_default_sink_changed), (do_action), (gsd_media_keys_manager_start), (gsd_media_keys_manager_stop): Use PulseAudio directly to change the volume. It will automatically change the volume of the default audio output for the machine (Closes: #567177) * plugins/media-keys/Makefile.am: * plugins/media-keys/actions/Makefile.am: Changes for the above 2009-01-15 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (binding_unregister_keys), (gsd_keybindings_manager_stop): also ungrab keys when this module is disabled 2009-01-15 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (gsd_media_keys_manager_stop): ungrab shortcut keys when the plugin is disabled (bug #567867) 2009-01-14 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (gsd_xrandr_manager_start): If there was no file with a stored configuration, don't pop up an error message --- this is not an error when the daemon starts up. Fixes https://bugzilla.novell.com/show_bug.cgi?id=465968 2009-01-10 William Jon McCann * plugins/sound/gsd-sound-manager.c (register_config_callback): Fix typo. 2009-01-08 Jens Granseuer Based on a patch by: Lennart Poettering * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/sound/Makefile.am: * plugins/sound/gsd-sound-manager.c: * plugins/sound/gsd-sound-plugin.h: * plugins/sound/sound.cinnamon-settings-plugin.in: Add a new sound plugin that tells PulseAudio to drop its sample cache when the sound theme changes (bug #545386). 2009-01-08 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (gsd_media_keys_manager_grab_media_player_keys), (gsd_media_keys_manager_release_media_player_keys): add a little debugging output when de/registering media players (bug #564433) 2009-01-05 Bastien Nocera * plugins/xrdb/gsd-xrdb-manager.c (apply_settings): Quiet xrdb when there are duplicate rules in the .ad files (Closes: #566610) 2008-12-30 Matthias Clasen Bug 565310 – support hotkeys for a11y tools * configure.ac: Set GNOME_KEYBINDINGS_KEYSDIR. * data/cinnamon-settings-daemon.schemas.in: Add missing schemas for the keys in /destkop/gnome/applications/at, and also add new schemas for keys in /desktop/gnome/keybindings that define global keybindings for turning ATs on and off. Todo: There are no default key combinations in the schema yet. * data/50-accessibility.xml.in: Keybinding file to group the new keybindings in an "Accessibility" section in the keybinding capplet. * data/Makefile.am: Install the keybinding file in the proper location. * po/POTFILES.in: Add 50-accessibility.xml.in. 2008-12-31 Rodrigo Moya Patch by Vincent Untz from openSUSE package (bug #557647) * configure.ac: require giounix for diskspace checker * Makefile.am: * plugins/housekeeping/gsd-disk-space.[ch]: add low diskspace checker to housekeeping plugin. * plugins/housekeeping/gsd-housekeeping-manager.c (gsd_housekeeping_manager_start, gsd_housekeeping_manager_stop): start/stop the low diskspace checker. * plugins/housekeeping/housekeeping.cinnamon-settings-plugin.in: add new plugin capability to description * po/POTFILES.in: add new files 2008-12-28 Jens Granseuer * plugins/screensaver/gsd-screensaver-manager.c: (start_screensaver_cb), (gsd_screensaver_manager_start): spawn screensaver after a 30 second timeout instead of when idle so that it doesn't compete with other processes when the session starts (bug #564059). Also plug a few small leaks. 2008-12-28 Jens Granseuer Based on patch by: Jasper Lievisse Adriaanse * plugins/media-keys/gsd-media-keys-manager.c: (do_eject_action), (do_action): better support for Eject and Sleep actions on OpenBSD and FreeBSD (bug #565472) 2008-12-28 Jens Granseuer Patch by: Jasper Lievisse Adriaanse * plugins/typing-break/gsd-typing-break-manager.c: include signal.h to fix build on OpenBSD (bug #565470) 2008-12-28 Jens Granseuer Patch by: Frederic Peters * cinnamon-settings-daemon/main.c: (main): initialize thread system since ORBit no longer does it for us (#565515) ==================== 2.25.3 ==================== 2008-12-18 Bastien Nocera * NEWS: upd * configure.ac: 2.25.3 update gnome-desktop requirements for the new GnomeRR API * plugins/xrandr/Makefile.am: Fix distcheck 2008-12-07 Ray Strode Restore AccessX bits to original values on exit * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (struct CsdA11yKeyboardManagerPrivate): add new field to cache original AccessX bits. (start_a11y_keyboard_idle_cb): save bits. (restore_server_xkb_config), (gsd_a11y_keyboard_manager_stop): restore bits when stopping. 2008-12-07 Ray Strode Shutdown properly when bus goes away. Previously we were just letting libdbus call exit(1) for us. * cinnamon-settings-daemon/main.c (get_session_bus): Set up a filter function to catch disconection events. (bus_message_handler): quit event loop when disconnected from bus. 2008-12-07 Ray Strode Shutdown properly when killed. * cinnamon-settings-daemon/main.c (on_term_signal): top half of signal handling code. close a pipe when getting SIGTERM. (on_term_signal_pipe_closed), (watch_for_term_signal), (set_session_over_handler): bottom half. Quit event loop when term pipe gets closed. 2008-12-07 Ray Strode * cinnamon-settings-daemon/main.c: Rename pipefds to daemon_pipe_fds. This fits the naming style of the surrounding code better. Also, we're going to need another pipe, so better to use a specific name here. 2008-12-09 Jens Granseuer Patch by: Pedro Fragoso * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.h: * plugins/common/eggaccelerators.c: * plugins/common/eggaccelerators.h: * plugins/mouse/gsd-locate-pointer.h: only use top-level headers for glib and GTK+ (bug #563796) 2008-12-08 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (error_message): make libnotify optional again (bug #563226) (handle_fn_f7): fix memory leak, use g_debug instead of g_print 2008-12-07 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemon_detach): Don't call umask (bug #563543) 2008-12-04 Jens Granseuer * plugins/mouse/gsd-mouse-manager.c: (set_devicepresence_handler): fix crash with X servers that don't provide XInput (bug #562977) 2008-12-02 Federico Mena Quintero Use a DBus interface to tell the XRANDR manager to apply the stored configuration, instead of an X client message, so that we can pass errors back to the caller. * plugins/xrandr/gsd-xrandr-manager.xml: Trivial DBus interface to tell the XRANDR manager to apply the stored configuration. * plugins/xrandr/gsd-xrandr-manager.c (gsd_xrandr_manager_apply_configuration): Moved from on_client_message(). Now we are a DBus-Glib method, so that we can pass back errors to the remote caller. * plugins/xrandr/Makefile.am: Add the machinery to generate DBus glue. 2008-12-02 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (error_message): Renamed from error_dialog(); use libnotify instead of ugly dialogs for error messages. (gsd_xrandr_manager_start): Proxy the error from gnome_rr_screen_new() to our caller. (gsd_xrandr_manager_start): Display an error if we cannot apply the initially-loaded configuration. (generate_fn_f7_configs, get_allowed_rotations_for_output): Pass GError arguments to the gnome_rr_*() functions. (handle_fn_f7): Display an error if we cannot refresh the screen configuration or apply the new one. (output_rotation_item_activate_cb): Display an error if the rotation cannot be applied. Tue Dec 2 15:37:21 2008 Søren Sandmann * plugins/xrandr/gsd-xrandr-manager.c: Add support for fn-F7 type keys. ==================== 2.25.2 ==================== 2008-12-01 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.25.2 release. 2008-11-29 Jens Granseuer * plugins/keyboard/gsd-keyboard-xkb.c: (gsd_keyboard_xkb_init): fix check for xklavier device discovery 2008-11-29 Jens Granseuer * configure.ac: fix checks for various X11 libraries (bug #562661) * plugins/mouse/gsd-mouse-manager.c: (set_left_handed), (gsd_mouse_manager_idle_cb), (gsd_mouse_manager_stop): * plugins/xrandr/gsd-xrandr-manager.c: adapt ifdefs accordingly 2008-11-27 Sergey Udaltsov * configure.ac, plugins/keyboard/gsd-keyboard-xkb.c: introduce dependency on libxklavier 3.8. Use "new device" notification to reload XKB configuration when new keyboard is plugged in 2008-11-24 Behdad Esfahbod * cinnamon-settings-daemon/main.c (parse_args), (main): Fix --no-daemon (bug #562175) 2008-11-24 Jens Granseuer When multiple keys (keycodes) were mapped to the same keysym, g-s-d would only accept the first of those keycodes in the keymap as a valid shortcut. To fix this, instead of checking against a single keycode, we need to grab all keycodes that match the respective keysym (bug #561275). With thanks to Mario Limonciello * plugins/common/eggaccelerators.c: (egg_accelerator_parse_virtual): * plugins/common/eggaccelerators.h: possibly return multiple keycodes * plugins/common/gsd-keygrab.c: (grab_key_unsafe), (key_uses_keycode), (match_key): grab all matching keys * plugins/common/gsd-keygrab.h: * plugins/keybindings/gsd-keybindings-manager.c: (parse_binding), (bindings_get_entry), (same_keycode), (same_key), (key_already_used), (binding_register_keys), (gsd_keybindings_manager_stop): * plugins/media-keys/gsd-media-keys-manager.c: (update_kbd_cb), (init_kbd), (gsd_media_keys_manager_stop): update to handle changes in data structures 2008-11-23 Jens Granseuer Patch by: * configure.ac: add bundle_loader linker flag to fix compilation on MacOS X (bug #522673) 2008-11-20 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (find_by_time), (gsd_media_keys_manager_grab_media_player_keys): fix handling of time = GDK_CURRENT_TIME. Previously, apps that registered with GDK_CURRENT_TIME would be trumped by any app that registered with time != 0 (bug #559797) 2008-11-20 Jens Granseuer * plugins/mouse/gsd-mouse-manager.c: (set_devicepresence_handler): trap X errors so we don't crash on X servers that don't support DevicePresence (bug #560618) 2008-11-13 Jens Granseuer * data/desktop_gnome_keybindings.schemas.in: fix typo 2008-11-11 Matthias Clasen Bug 553434 – lockdown in the keybinding plugin * data/Makefile.am: Install the new schema file. * data/desktop_gnome_keybindings.schemas.in: Add schema for /desktop/gnome/keybindings/allowed_keys. * plugins/keybindings/gsd-keybinding-manager.c: Support locking down keybindings with a list of allowed keys. 2008-11-10 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemon_start): Check return value of pipe(). 2008-11-10 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemon_start), (daemon_detach), (daemon_terminate_parent), (main): Fork before gtk_init (bug #559695) 2008-11-09 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (do_sound_action): add debugging output for volume_step 2008-11-08 Jens Granseuer Patch by: William Grant * plugins/mouse/gsd-mouse-manager.c: (devicepresence_filter): listen for DeviceEnabled instead of DeviceAdded so we can be sure it has been initialized (bug #559827) 2008-11-06 Behdad Esfahbod * plugins/background/gsd-background-manager.c (setup_bg), (queue_draw_background), (gsd_background_manager_start): Delay constructing the GnomeBg object until we need it. This avoids unneeded change triggers caused by a bug in gnome-screensaver (fixed in trunk it seems). (bug #559639) 2008-11-06 Behdad Esfahbod * data/cinnamon-settings-daemon.schemas.in: Reshuffle plugin priorities a bit. Now that we do many of the plugins in idle callback, those can be put at the end. 2008-11-06 Behdad Esfahbod * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (maybe_show_status_icon), (ax_slowkeys_warning_post_bubble), (ax_stickykeys_warning_post_bubble), (gsd_a11y_keyboard_manager_stop), (gsd_a11y_keyboard_manager_ensure_status_icon), (gsd_a11y_keyboard_manager_init): Init status icon only when needed (bug #559558) 2008-11-06 Behdad Esfahbod * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (start_a11y_keyboard_idle_cb), (gsd_a11y_keyboard_manager_start): Start manager in idle callback (bug #559564) * plugins/media-keys/gsd-media-keys-manager.c (start_media_keys_idle_cb), (gsd_media_keys_manager_start): Start manager in idle callback (bug #559564). Leave the acme initialization in the main start function to force gstreamer cache up to date check before we let other applications start. 2008-11-06 Behdad Esfahbod * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (get_xkb_desc_rec): * plugins/common/gsd-keygrab.c (have_xkb): Remove more unnecessary X error traps and synchs (bug #559562) 2008-11-06 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (xkb_enabled), (gsd_a11y_keyboard_manager_start): remove unnecessary X error traps (bug #559562) 2008-11-05 Behdad Esfahbod * plugins/xsettings/fontconfig-monitor.c (fontconfig_cache_init): * plugins/xsettings/fontconfig-monitor.h: * plugins/xsettings/gsd-xsettings-manager.c (start_fontconfig_monitor): Only initialize fontconfig when starting up. A cache update is redundant there. (bug #559550) 2008-11-05 Behdad Esfahbod * plugins/keyboard/gsd-keyboard-manager.c (start_keyboard_idle_cb), (gsd_keyboard_manager_start): Start manager in idle callback (bug #559482) 2008-11-05 Behdad Esfahbod * plugins/keyboard/gsd-keyboard-xkb.c (gsd_keyboard_xkb_init): Add some performance logging annotations around libxklavier calls. 2008-11-05 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (numlock_xkb_init): XkbQueryExtension and friends shouldn't cause errors, so no need to try and trap them (bug #559346) ==================== 2.25.1 ==================== 2008-11-04 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.25.1 release 2008-11-04 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemonize), (main): Use a pipe to communicate between child and parent process instead of a signal. Signals are not queued, so if the child tried to signal the parent before the parent got a chance to wait for it, the signal would be lost and parent wait indefinitely for a signal that would never arrive. 2008-11-04 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemonize): Don't close stderr. Otherwise we just lose all our warnings that will not end up in ~/.xsession-errors. Also fix indentation. 2008-11-03 Jens Granseuer * plugins/keyboard/gsd-keyboard-xkb.c: add missing include 2008-11-03 Behdad Esfahbod * cinnamon-settings-daemon/main.c (daemonize), (main): Make parent wait for initialization in children to finish before returning. This makes gnome-session to wait for initialization to be done before spawning other processes. This way, apps start up with the right xsettings and other settings, and don't have to handle change signals right after starting up. (bug #559168) 2008-11-03 Behdad Esfahbod * cinnamon-settings-daemon/cinnamon-settings-manager.c (_load_file), (gnome_settings_manager_start), (gnome_settings_manager_stop): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c (gnome_settings_plugin_info_set_enabled_key_name): * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (register_config_callback): * plugins/keybindings/gsd-keybindings-manager.c (register_config_callback), (gsd_keybindings_manager_start): * plugins/keyboard/gsd-keyboard-manager.c (gsd_keyboard_manager_start): * plugins/keyboard/gsd-keyboard-xkb.c (register_config_callback): * plugins/mouse/gsd-mouse-manager.c (register_config_callback): * plugins/typing-break/gsd-typing-break-manager.c (gsd_typing_break_manager_start): * plugins/xrandr/gsd-xrandr-manager.c (gsd_xrandr_manager_start): * plugins/xsettings/gsd-xsettings-manager.c (register_config_callback), (gnome_xsettings_manager_start): Preload gconf dirs when feasible (bug #559167) 2008-11-03 Behdad Esfahbod * plugins/clipboard/gsd-clipboard-manager.c (start_clipboard_idle_cb), (gsd_clipboard_manager_start): Start manager in idle callback (bug #559166) * plugins/mouse/gsd-mouse-manager.c (gsd_mouse_manager_idle_cb), (gsd_mouse_manager_start): Start manager in idle callback (bug #559166) * plugins/xsettings/fontconfig-monitor.c (fontconfig_cache_update), (update): * plugins/xsettings/fontconfig-monitor.h: * plugins/xsettings/gsd-xsettings-manager.c (start_fontconfig_monitor_idle_cb), (start_fontconfig_monitor), (stop_fontconfig_monitor): Start fontconfig monitors in idle callback. However, make sure fontconfig caches are up to date during initialization (bug #559166) 2008-11-03 Behdad Esfahbod * plugins/mouse/gsd-mouse-manager.c (set_mousetweaks_daemon): Don't run "mousetweaks -s" at startup time (#559165) All "mousetweaks -s" does is shutdown the already-running daemon. When g-s-d starts, there is no daemon running. So, remember that and do not try to shut the non-existing daemon down. 2008-11-03 Behdad Esfahbod * plugins/common/gsd-keygrab.c (setup_modifiers), (grab_key_real), (grab_key_unsafe): * plugins/common/gsd-keygrab.h: * plugins/keybindings/gsd-keybindings-manager.c (binding_register_keys): * plugins/media-keys/gsd-media-keys-manager.c (update_kbd_cb), (init_kbd): Don't trap errors around grab_key (bug #559164) Such that we can do a single gdk_flush for multiple keys. The only downside is that we cannot write out in the warning which key is being accessed by another app. Not that we really care. 2008-11-03 Behdad Esfahbod * plugins/font/gsd-font-manager.c (setup_dir), (empty_check_dir), (setup_font_dir), (setup_cursor_dir), (load_font_paths), (gsd_font_manager_start): Cleanup font module (bug #559163) The old code had several flaws: - It tried to create directories in user's home even if we didn't have any use for them. - It called mkfontdir and XSync even if there was no fonts installed. The new code does the following: - Only call mkfontdir and XSync if there's actually any fonts in the relevant dirs. - Remove the ~/.gnome2/share/fonts and/or ~/.gnome2/share/cursor-fonts if they are empty and no cursor font is set. 2008-11-03 Behdad Esfahbod * cinnamon-settings-daemon/cinnamon-settings-manager.c (_load_file): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c (gnome_settings_plugin_info_fill_from_file), (load_plugin_module): * plugins/font/gsd-font-manager.c (child_watch_cb), (spawn_with_input): * plugins/keyboard/gsd-keyboard-xkb.c (gsd_keyboard_xkb_init): * plugins/xrandr/gsd-xrandr-manager.c (gsd_xrandr_manager_start): * plugins/xsettings/gsd-xsettings-manager.c (child_watch_cb), (spawn_with_input), (start_fontconfig_monitor), (stop_fontconfig_monitor), (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop): Improve performance logging annotations (bug #559162) 2008-11-03 Behdad Esfahbod * data/cinnamon-settings-daemon.schemas.in: Disable xrdb plugin by default (#bug #557807) 2008-11-02 Jens Granseuer * configure.ac: remove AM_MAINTAINER_MODE because it is deprecated and supposedly unsafe (bug #558503) 2008-11-01 Jens Granseuer Patch by: William Grant * plugins/mouse/gsd-mouse-manager.c: (devicepresence_filter), (set_devicepresence_handler), (set_mouse_settings), (gsd_mouse_manager_start), (gsd_mouse_manager_stop): listen for X device changes, and reconfigure the mouse if necessary so that the settings aren't ignored when hotplugging (bug #549267) 2008-10-29 Jens Granseuer Get rid of libgnome (bug #557808). * configure.ac: bump required gtk+ version to 2.13.1 * cinnamon-settings-daemon/main.c: (main): don't use g_program_init * plugins/a11y-keyboard/Makefile.am: * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (ax_response_callback), (ax_stickykeys_response), (ax_slowkeys_response), (on_slow_keys_action), (on_sticky_keys_action): replace gnome_help_display_desktop with gtk_show_uri 2008-10-29 Jens Granseuer * plugins/screensaver/gsd-screensaver-manager.c: (gsd_screensaver_manager_start): fix plugin activation, too 2008-10-29 Jens Granseuer * plugins/screensaver/gsd-screensaver-manager.c: (start_screensaver_idle_cb), (gsd_screensaver_manager_start): fix broken changes to screensaver plugin 2008-10-29 Jens Granseuer Remove ESD-based sound plugin (bug #557806). This means that g-s-d will no longer start a sound server (esd or PulseAudio) at session startup. This should be handled using the autostart mechanism of gnome-session instead. * configure.ac: * plugins/Makefile.am: * plugins/sound/Makefile.am: * plugins/sound/gsd-sound-manager.c: * plugins/sound/gsd-sound-manager.h: * plugins/sound/gsd-sound-plugin.c: * plugins/sound/gsd-sound-plugin.h: * plugins/sound/sound.cinnamon-settings-plugin.in: remove sound plugin 2008-10-29 Rodrigo Moya * plugins/screensaver/gsd-screensaver-manager.c (gsd_screensaver_manager_start): spawn screensaver process in idle callback as it was before. 2008-10-23 Jens Granseuer Based on a patch by: Bogdan Butnaru * plugins/media-keys/gsd-media-keys-window.c: (draw_waves), (draw_cross), (draw_action_volume): make the composited volume images more clear: draw waves matching current volume and show a cross when muted (bug #557307) 2008-10-23 Jens Granseuer * plugins/media-keys/actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_finalize), (acme_volume_gstreamer_close_real), (acme_volume_gstreamer_open), (acme_volume_gstreamer_close), (acme_volume_gstreamer_init), (acme_volume_gstreamer_class_init): * plugins/media-keys/actions/acme-volume-gstreamer.h: clean up Volume initialization so that we don't get non-functional volume keys when the plugin starts up with an invalid configuration initially, even if the configuration is fixed afterwards (bug #552383) 2008-10-19 Matthias Clasen Bug 556797 – support the Gtk/ButtonImages XSetting * plugins/xsettings/gsd-xsettings-manager.c: Support the Gtk/ButtonImages xsetting. 2008-10-15 Matthias Clasen Bug 556307 – show the shutdown dialog when the power button is pressed * plugins/media-keys/gsd-media-keys-manager.c (do_exit_action): Show the shutdown dialog when the power button is pressed, not the logout dialog. 2008-10-12 Christian Persch Bug 555553 – format not a string literal and no format arguments * cinnamon-settings-daemon/cinnamon-settings-manager.c * cinnamon-settings-daemon/cinnamon-settings-module.c * cinnamon-settings-daemon/main.c * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c * plugins/xrdb/gsd-xrdb-manager.c: Use printf safely. 2008-10-06 Matthias Clasen Bug 555873 – fix gdm keyboard layout handling even more * plugins/keyboard/gsd-keyboard-xkb.c (apply_xkb_settings): Try harder to handle initial-login situations correctly, while not overwriting any user configuration. 2008-10-06 Matthias Clasen Bug 554525 – fix the picking up of the gdm layout * plugins/keyboard/gsd-keyboard-xkb.c (apply_xkb_settings): Active a specific group only after activating the right keyboard configuration. Because the other way around doesn't work. 2008-10-05 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (set_server_from_gconf): don't make togglekeys_enable depend on global AccessX state (bug #555009) 2008-10-04 Jens Granseuer Patch by: Eric Piel * plugins/xrandr/gsd-xrandr-manager.c: (output_rotation_item_activate_cb): ignore the "activate" signal for deselected items so that the rotation setting doesn't reset when the systray menu is opened (bug #554951) ==================== 2.24.0 ==================== 2008-09-23 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.24.0 release. 2008-09-22 Michael J. Chudobiak * plugins/housekeeping/gsd-housekeeping-manager.c: Made the housekeeping plugin less aggressive by default (bug #552680). Code freeze break approved by release team. 2008-09-16 Matthias Clasen * plugins/keyboard/gsd-keyboard-xkb.c: Remove an accidentally added debug printf. 2008-09-12 Jens Granseuer Also allow linking the module state to other boolean keys by using a string value that is the name of the key to use. Note that in this case the state won't be updated at runtime due to GConf limitations. * plugins/xsettings/gsd-xsettings-manager.c: (get_gtk_modules): enable linking to other keys 2008-09-12 Jens Granseuer Specify GTK modules to load in a GConf directory instead of the single /desktop/gnome/gtk-modules key. Apps can now easily install additional modules by dropping a key with the name of the module and a boolean value (enabled/disabled) into /apps/gnome_settings_daemon/gtk-modules/ (bug #539840). * plugins/xsettings/gsd-xsettings-manager.c: (get_gtk_modules), (gtk_modules_callback), (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop): remove the old gtk-modules key in favor of a GConf directory 2008-09-12 Jens Granseuer * COPYING: add GPLv2 copyright notice explicitly so that newer versions of autotools don't declare us GPLv3 (bug #551956) 2008-09-11 Jens Granseuer Make the volume popup not crash when invoking it on any screen but the first when using a compositing manager (bug #551677) * plugins/media-keys/gsd-media-keys-window.c: (gsd_media_keys_window_real_realize), (gsd_media_keys_window_init): do not set the window colormap at init time where we'll only use the colormap of the default screen. Instead, whenever the window is realized, update the colormap to match the current screen. 2008-09-10 Jens Granseuer Patch by: Simon Zheng * cinnamon-settings-daemon/main.c: (main): fix the fix for read-only home directories from bug #530975 ==================== 2.23.92 ==================== 2008-09-08 Rodrigo Moya * NEWS: prepare for 2.23.92 release. 2008-09-06 Matthias Clasen Bug 551062 – try harder to use the keyboard layout passed by gdm * plugins/keyboard/gsd-keyboard-xkb.c: Be tolerant of variants when trying to match the gdm-provided keyboard layout to the existing keyboard configuration. ==================== 2.23.91 ==================== 2008-09-01 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.23.91 release. 2008-08-28 William Jon McCann * configure.ac: Belated post release version bump 2008-08-27 Jens Granseuer * plugins/xsettings/gsd-xsettings-manager.c: (setup_xsettings_managers): use g_warning instead of g_error when setup fails so we don't abort (bug #549483) 2008-08-26 William Jon McCann * plugins/a11y-keyboard/Makefile.am: * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c (dpi_from_pixels_and_mm), (get_dpi_from_x_server), (config_get_large_print), (config_set_large_print): * plugins/a11y-keyboard/test-a11y-preferences-dialog.c (test_window), (main): Use a scale factor instead of a fixed DPI. Add a test program. 2008-08-22 William Jon McCann * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (on_notification_closed): Oops. Missing comma. 2008-08-22 William Jon McCann * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (on_notification_closed): Fix a crash due to an incorrect signal handler definition. 2008-08-21 Jens Granseuer * plugins/keyboard/gsd-keyboard-xkb.c: (apply_xkb_settings): fix a constness warning 2008-08-19 Claude Paroz * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.glade: Removed the translatable property on stock gtk-close. ==================== 2.23.90 ==================== 2008-08-18 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.23.90 release. 2008-08-14 William Jon McCann * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c (get_dpi_from_x_server): Use gdk api to get dpi. 2008-08-13 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (status_icon_popup_menu): Create the RANDR configuration and labeler before the menu items. 2008-08-13 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (status_icon_popup_menu): Add a separator to the menu before "Configure display settings". 2008-08-13 Federico Mena Quintero * plugins/xrandr/gsd-xrandr-manager.c (status_icon_popup_menu): When the menu comes up, create a GnomeRRLabeler so that the user can identify which physical monitors we are talking about. This will actually be visible in the popup menu once we implement the rotation commands. (status_icon_popup_menu_selection_done_cb): Hide and destroy the GnomeRRLabeler. (struct CsdXrandrManagerPrivate): New field "labeler". 2008-08-12 Federico Mena Quintero * configure.ac: For LIBSOUNDS, check for libgnomeui, not just libgnome. 2008-08-12 Jens Granseuer Even if we can't properly remove a client message handler at least make sure everything works as expected when enabling/disabling the plugin at runtime * plugins/xrandr/gsd-xrandr-manager.c: (on_client_message), (gsd_xrandr_manager_start): pass the manager as user data instead of the screen because the manager will remain stable during the lifetime of the daemon; also, don't filter messages when the plugin is disabled 2008-08-12 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (status_icon_start): remove obsolete comment 2008-08-11 Jens Granseuer * configure.ac: require gnome-desktop 2.23.90 * plugins/xrandr/gsd-xrandr-manager.c: (gsd_xrandr_manager_start), (gsd_xrandr_manager_stop), (gsd_xrandr_manager_init): try harder to clean up in _stop so we can enable/disable the plugin on the fly; not quite there, yet 2008-08-10 Jens Granseuer Patch by: Matthias Clasen * plugins/xrandr/gsd-xrandr-manager.c: (gsd_xrandr_manager_start): fail on start if we couldn't set up xrandr (bug #546446) 2008-08-08 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (gsd_xrandr_manager_init): pass the manager as callback data so we don't crash with a NULL pointer in on_randr_event 2008-08-08 Jens Granseuer * plugins/xrandr/gsd-xrandr-manager.c: (gsd_xrandr_manager_start): remove warning that isn't 2008-08-05 Jens Granseuer * configure.ac: require glib >= 2.17.3 * plugins/xsettings/fontconfig-monitor.c: (monitor_files): use g_file_monitor instead of g_file_monitor_file/directory (bug #546372) 2008-08-05 Jens Granseuer * plugins/font/gsd-font-manager.c: (gsd_font_manager_class_init), (gsd_font_manager_init): remove some unnecessary boilerplate 2008-08-05 Jens Granseuer * plugins/a11y-keyboard/Makefile.am: put the glade file where all the others are 2008-08-05 Jens Granseuer * configure.ac: simplify libnotify check, fix fontconfig result output 2008-08-05 William Jon McCann * configure.ac: * plugins/a11y-keyboard/Makefile.am: * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c (get_int), (set_clear), (maybe_show_status_icon), (on_notification_closed), (on_slow_keys_action), (on_sticky_keys_action), (ax_slowkeys_warning_post_bubble), (ax_slowkeys_warning_post_dialog), (ax_slowkeys_warning_post), (ax_stickykeys_warning_post_bubble), (ax_stickykeys_warning_post_dialog), (ax_stickykeys_warning_post), (set_gconf_from_server), (keyboard_callback), (gsd_a11y_keyboard_manager_start), (gsd_a11y_keyboard_manager_stop), (on_preferences_dialog_response), (on_status_icon_activate), (gsd_a11y_keyboard_manager_init): * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c (gsd_a11y_preferences_dialog_set_property), (gsd_a11y_preferences_dialog_get_property), (gsd_a11y_preferences_dialog_constructor), (gsd_a11y_preferences_dialog_dispose), (gsd_a11y_preferences_dialog_class_init), (on_response), (config_get_string), (config_get_bool), (dpi_from_pixels_and_mm), (get_dpi_from_x_server), (config_get_large_print), (config_set_large_print), (config_get_high_contrast), (config_set_high_contrast), (config_get_sticky_keys), (config_set_sticky_keys), (config_get_bounce_keys), (config_set_bounce_keys), (config_get_slow_keys), (config_set_slow_keys), (config_have_at_gconf_condition), (config_get_at_screen_reader), (config_get_at_screen_keyboard), (config_get_at_screen_magnifier), (config_set_at_screen_reader), (config_set_at_screen_keyboard), (config_set_at_screen_magnifier), (on_sticky_keys_checkbutton_toggled), (on_bounce_keys_checkbutton_toggled), (on_slow_keys_checkbutton_toggled), (on_high_contrast_checkbutton_toggled), (on_at_screen_reader_checkbutton_toggled), (on_at_screen_keyboard_checkbutton_toggled), (on_at_screen_magnifier_checkbutton_toggled), (on_large_print_checkbutton_toggled), (ui_set_sticky_keys), (ui_set_bounce_keys), (ui_set_slow_keys), (ui_set_high_contrast), (ui_set_at_screen_reader), (ui_set_at_screen_keyboard), (ui_set_at_screen_magnifier), (ui_set_large_print), (key_changed_cb), (setup_dialog), (gsd_a11y_preferences_dialog_init), (gsd_a11y_preferences_dialog_finalize), (gsd_a11y_preferences_dialog_new): * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.glade: * plugins/a11y-keyboard/gsd-a11y-preferences-dialog.h: Add status icon when a11y hotkeys are enabled. Display Universal Access Preferences when it is clicked. Fixes #526070 2008-08-04 Jens Granseuer * configure.ac: fix PulseAudio check to not output "no" twice ==================== 2.23.6 ==================== 2008-08-04 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.23.6 release. 2008-08-03 Jens Granseuer * plugins/common/gsd-keygrab.c: (setup_modifiers), (grab_key), (match_key): resolve NumLock dynamically and make sure we ignore it so using e.g. the media keys works even when NumLock is on (still bug #165343) Tue Jul 29 01:09:46 2008 Søren Sandmann * plugins/xrandr/gsd-xrandr-manager.c (start_or_stop_icon): Make the display notification icon configurable. 2008-07-26 Matthias Clasen Bug 544733 – use standard icon names in the volume OSD, initially * plugins/media-keys/actions/acme.glade: Use standard icon names for the OSD. 2008-07-26 Wouter Bolsterlee * configure.ac: Bump glib dependency to 2.15. Fixes bug #544737. 2008-07-25 Rob Bradford * configure.ac: libsounds needs to use gtk+-2.0 now libgnomeui is removed. 2008-07-24 James Sharpe * configure.ac: * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: * plugins/sound/gsd-sound-manager.c: Remove libgnomeui. (bug #544347) ==================== 2.23.5 ==================== Thu Jul 24 14:48:04 2008 Søren Sandmann * Downgrade intltool requirement to 0.37.1. This bug http://bugzilla.gnome.org/show_bug.cgi?id=537352 says that's what I'm supposed to do. * Bump version number to 2.23.5 * NEWS: Update this file. 2008-07-22 Lennart Poettering Fixes #539786 * plugins/xsettings/gsd-xsettings-manager.c: add three new xsettings for event sounds. 2008-07-16 Jens Granseuer Patch by: Damien Carbery * data/cinnamon-settings-daemon-uninstalled.pc.in: fix include path for building against the uninstalled package (bug #543289) 2008-07-15 Gerd Kohlberger * plugins/mouse/gsd-mouse-manager.c: (set_mousetweaks_daemon): Remove 'daemon' from the warning message (see bug #543095). 2008-07-15 Jens Granseuer * plugins/common/gsd-keygrab.c: (match_key): always remove Shift from the consumed modifiers if we're matching the lowercase symbol to make more shortcuts with Shift work (bug #542275) Wed Jul 9 11:48:02 2008 Søren Sandmann * plugins/xrandr/gsd-xrandr-manager.c: Call the new gnome_rr functions instead of the old ones. 2008-06-28 Jens Granseuer * plugins/common/gsd-keygrab.c: don't ignore any ModX modifiers. This should finally make g-s-d recognize keybindings with Super and Meta although we still don't handle the corresponding virtual modifiers (bug #165343) 2008-06-20 Jens Granseuer * plugins/common/gsd-keygrab.c: (match_key): fix accel check so that we don't match e.g. XF86RaiseVolume if + XF86RaiseVolume was pressed (bug #538699). Also fix build without XKB 2008-06-18 Jens Granseuer * Makefile.am: * configure.ac: require intltool >= 0.40 2008-06-18 Jens Granseuer * configure.ac: bump gnome-desktop requirement to 2.23.5 Tue Jun 17 19:41:55 2008 Søren Sandmann * Merge randr-12 branch into trunk Mon Jun 16 14:50:53 2008 Søren Sandmann * Port to new gnome-desktop API Mon Jun 16 14:30:13 2008 Søren Sandmann * Merge from trunk. 2008-06-17 Colin Walters http://bugzilla.gnome.org/show_bug.cgi?id=533198 * configure.ac: Detect PulseAudio at build time; if available, default to always starting it (ignore the legacy esd GConf key /desktop/gnome/sound/enable_esd). If you're a system administrator or OS builder and want to disable PulseAudio, you should preferably figure out what the problem you have with it is; but failing that, just remove it from the install image. * plugins/sound/gsd-sound-manager.c: If we're not compiled with legacy sound pref, always start sound. ==================== 2.23.4 ==================== 2008-06-17 Rodrigo Moya * configure.ac: * NEWS: update for 2.23.4 release. 2008-06-14 Jens Granseuer Based on a patch by: Brian Cameron * configure.ac: * plugins/sound/Makefile.am: * plugins/sound/gsd-sound-manager.c: (start_gnome_sound): if available use the esd_serverdir variable to locate the esd daemon so it can be started even if it's not in the PATH (bug #531868) 2008-06-13 Jens Granseuer Based on a patch by: Bastien Nocera * plugins/common/gsd-keygrab.c: (match_key): properly match keybindings that need Shift for resolving the keysym (bug #536581) 2008-06-07 Behdad Esfahbod (Commit this again) * configure.ac: Check for fontconfig instead of xft2. * plugins/xsettings/Makefile.am: * plugins/xsettings/gsd-xsettings-manager.c (fontconfig_callback), (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop): Send a Fontconfig/Timestamp xsettings notification whenever fontconfig configurations change. (bug #490374) * plugins/xsettings/fontconfig-monitor.c: * plugins/xsettings/fontconfig-monitor.h: Monitor fontconfig configuration files using gio. ==================== 2.23.3 ====================== 2008-06-03 Jens Granseuer * configure.ac: use correct release number 2008-06-03 Jens Granseuer * NEWS: Update for 2.23.3 release. 2008-06-02 Behdad Esfahbod * configure.ac: * plugins/xsettings/Makefile.am: * plugins/xsettings/fontconfig-monitor.c: * plugins/xsettings/fontconfig-monitor.h: * plugins/xsettings/gsd-xsettings-manager.c (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop): Revert previous change. Working on a slightly different design. (bug #490374) 2008-06-02 Behdad Esfahbod * configure.ac: Check for fontconfig instead of xft2. * plugins/xsettings/Makefile.am: * plugins/xsettings/gsd-xsettings-manager.c (fontconfig_callback), (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop): Send a Fontconfig/Timestamp xsettings notification whenever fontconfig configurations change. (bug #490374) * plugins/xsettings/fontconfig-monitor.c: * plugins/xsettings/fontconfig-monitor.h: Monitor fontconfig configuration files using gio. 2008-06-02 Jens Granseuer * configure.ac: do not add stuff to GST_LIBS when gstreamer is disabled. Fixes build without gstreamer (bug #536177) 2008-06-02 Gerd Kohlberger * plugins/mouse/gsd-locate-pointer.c: (timeline_frame_cb): Keep animation centered below pointer. Bug #531665 2008-05-30 Jens Granseuer * plugins/font/gsd-font-manager.c: (load_xcursor_theme): fix a few leaks 2008-05-27 Jens Granseuer * cinnamon-settings-daemon/cinnamon-settings-manager.c: (_unload_plugin), (_unload_all): stop all plugins on shutdown 2008-05-27 Lucas Rocha * cinnamon-settings-daemon/main.c (set_session_over_handler, on_session_over, main): listen to "SessionOver" D-Bus signal from Session Manager to know when to shutdown. Bug #522017. 2008-05-14 William Jon McCann * plugins/mouse/gsd-mouse-manager.c (filter): Bummer. Revert part of last commit. 2008-05-14 William Jon McCann * plugins/mouse/gsd-mouse-manager.c (filter): Don't eat keypresses for multimedia key events Patch by Bastien Nocera 2008-05-13 Jens Granseuer * plugins/background/gsd-background-manager.c: (gsd_background_manager_start): reuse the GConf client we already have 2008-05-13 William Jon McCann * configure.ac: * plugins/background/Makefile.am: * plugins/background/gsd-background-manager.c (draw_background), (queue_draw_background), (on_bg_changed), (gconf_changed_callback), (watch_bg_preferences), (gsd_background_manager_start), (gsd_background_manager_stop): Use new gnome-desktop background preference loading api. Drop use of libbackground. 2008-05-08 Carlos Garnacho * plugins/media-keys/gsd-media-keys-window.c (gsd_media_keys_window_real_realize): New function, sets a fully transparent input shape, so that clicks go through the media keys windows. Bug #531862. (gsd_media_keys_window_class_init): The usual glue. 2008-05-08 Carlos Garnacho * plugins/mouse/gsd-locate-pointer.c (set_transparent_shape): new function, sets a fully transparent shape to the whole window. (timeline_finished_cb) (gsd_locate_pointer): set the window transparent once the animation is finished, and before it's shown for the first time. The shape will be changed afterwards while running the animation. This fixes some artifacts shown when showing/moving the window, bug #531861. (locate_pointer_expose): Plug a leak. 2008-05-02 Jens Granseuer Patch by: Brian Cameron * cinnamon-settings-daemon/main.c: (main): don't die when the user's home directory is read-only (bug #530975) 2008-05-02 Jens Granseuer Based on a patch by: Matthias Clasen * plugins/keyboard/gsd-keyboard-xkb.c: (apply_xkb_settings), (gsd_keyboard_xkb_init): if the user set a keyboard layout from the login screen, try to keep that setting (bug #531589) 2008-05-02 Jens Granseuer * plugins/background/gsd-background-manager.c: (gsd_background_manager_start): add a comment explaining why we are applying the prefs regardless of nautilus 2008-05-02 Jens Granseuer Patch by: Matthias Clasen * plugins/background/gsd-background-manager.c: (gsd_background_manager_start): eventually apply the settings even if nautilus is supposed to be handling the background to make people running without nautilus happy (bug #531487) 2008-04-29 Bastien Nocera * plugins/common/gsd-keygrab.c (have_xkb), (match_key): When checking whether a key matches our key event, check the keysym from the key event, to avoid triggering another keybindings with the same keycode, but different keysym, Fixes Eject being triggered when pressing the Stop key with the default inet keymap (Closes: #530356) 2008-04-23 Vincent Untz * configure.ac: post release version bump. ==================== 2.23.1.1 ==================== 2008-04-23 Vincent Untz * configure.in: * NEWS: Update for 2.23.1.1 release. 2008-04-21 Lucas Rocha Install .desktop for cinnamon-settings-daemon in a standard autostart directory as required by new gnome-session (bug #526984). * configure.ac: expand $libexecdir to be used on .desktop file. * acinclude.m4: added new m4 macro (AS_AC_EXPAND) for expanding variables. * data/Makefile.am, data/cinnamon-settings-daemon.desktop.in.in: install g-s-d .desktop file. 2008-04-21 Rodrigo Moya * configure.ac: post release version bump. ==== 2.23.1 ==== 2008-04-21 Rodrigo Moya * configure.in: * NEWS: Update for release. 2008-04-20 Jens Granseuer * plugins/media-keys/actions/acme-volume-alsa.c: (acme_volume_alsa_finalize), (acme_volume_alsa_class_init): * plugins/media-keys/actions/acme-volume-dummy.c: (acme_volume_dummy_finalize), (acme_volume_dummy_class_init): * plugins/media-keys/actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_finalize), (acme_volume_gstreamer_class_init): * plugins/media-keys/actions/acme-volume-oss.c: (acme_volume_oss_finalize), (acme_volume_oss_class_init): * plugins/media-keys/actions/acme-volume.c: (acme_volume_class_init): drop redundant GType stuff 2008-04-19 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (bindings_get_entry): remove some code (and translatable strings) for error that can never happen 2008-04-18 Jens Granseuer * plugins/mouse/gsd-mouse-manager.c: (set_mousetweaks_daemon): when we can't launch the daemon reset the GConf keys before showing the error dialog. If we wait until after the dialog is closed, the user can still toggle the settings while it's open 2008-04-13 Jens Granseuer Extract some functionality used by several plugins into a separate shared helper library (bug #525426). * configure.ac: * plugins/Makefile.am: * plugins/common/Makefile.am: * plugins/common/gsd-keygrab.c: * plugins/common/gsd-keygrab.h: * plugins/common/eggaccelerators.c: * plugins/common/eggaccelerators.h: new shared components * plugins/keybindings/Makefile.am: * plugins/keybindings/eggaccelerators.c: * plugins/keybindings/eggaccelerators.h: * plugins/keybindings/gsd-keybindings-manager.c: (binding_register_keys), (keybindings_filter): * plugins/media-keys/Makefile.am: * plugins/media-keys/actions/Makefile.am: * plugins/media-keys/actions/acme.h: * plugins/media-keys/eggaccelerators.c: * plugins/media-keys/eggaccelerators.h: * plugins/media-keys/gsd-media-keys-manager.c: (update_kbd_cb), (init_kbd), (acme_filter_events): make keybindings and media-keys plugins use the shared components 2008-04-13 Sergey Udaltsov * plugins/keyboard/gsd-keyboard-xkb.c: dropped gconf backup 2008-04-12 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (do_grab): * plugins/media-keys/gsd-media-keys-manager.c: (grab_key): make some tiny optimizations and add some more comments on what's happening 2008-04-12 Jens Granseuer * cinnamon-settings-daemon/main.c: * plugins/media-keys/gsd-media-keys-manager.c: DBus API has been stable for a while; don't define DBUS_API_SUBJECT_TO_CHANGE anymore 2008-04-12 Jens Granseuer * cinnamon-settings-daemon/main.c: (acquire_name_on_proxy), (bus_register), (main): fix a few small leaks 2008-04-12 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (init_screens): drop redundant code 2008-04-11 Jens Granseuer * cinnamon-settings-daemon/main.c: turn into a daemon by default and make --no-daemon work 2008-04-11 Jens Granseuer * plugins/sound/gsd-sound-plugin.c: (impl_deactivate): fix typo 2008-04-11 Jens Granseuer Make xrandr, xrdb, and xsettings plugin deactivation work * plugins/xrandr/gsd-xrandr-manager.c: (apply_settings): cleanup * plugins/xrandr/gsd-xrandr-plugin.c: (impl_deactivate): * plugins/xrdb/gsd-xrdb-plugin.c: (impl_deactivate): * plugins/xsettings/gsd-xsettings-plugin.c: (impl_deactivate): stop manager on deactivation * plugins/xrdb/gsd-xrdb-manager.c: (gsd_xrdb_manager_start), (gsd_xrdb_manager_stop): * plugins/xsettings/gsd-xsettings-manager.c: (gsd_xsettings_error_quark), (find_translation_entry), (xsettings_callback), (register_config_callback), (terminate_cb), (setup_xsettings_managers), (gnome_xsettings_manager_start), (gnome_xsettings_manager_stop), (gnome_xsettings_manager_init): clean up properly on stop 2008-04-11 Jens Granseuer Make typing-break plugin deactivation work * plugins/typing-break/gsd-typing-break-manager.c: (register_config_callback), (gsd_typing_break_manager_start), (gsd_typing_break_manager_stop): clean up properly on stop * plugins/typing-break/gsd-typing-break-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-11 Jens Granseuer Make screensaver and sound plugin deactivation work (sort of). The screensaver is currently not reaped when deactivating the plugin, but since the plugin should go away anyway, it doesn't seem worth adding that right now. For the sound plugin, esd is currently not reaped when HAVE_ESD is set. Maybe we want to get rid of the esd API altogether? * plugins/sound/gsd-sound-manager.c: (apply_settings), (register_config_callback), (gsd_sound_manager_start), (gsd_sound_manager_stop): clean up a bit more on stop * plugins/screensaver/gsd-screensaver-plugin.c: (impl_deactivate): * plugins/sound/gsd-sound-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-11 Jens Granseuer Make mouse plugin deactivation work * plugins/mouse/gsd-mouse-manager.c: (register_config_callback), (gsd_mouse_manager_init), (gsd_mouse_manager_start), (gsd_mouse_manager_stop): clean up properly on stop * plugins/mouse/gsd-mouse-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-11 Jens Granseuer * plugins/keyboard/gsd-keyboard-xkb.c: (gsd_keyboard_xkb_shutdown): clear the user callback data even if initialiation failed * plugins/keyboard/gsd-xmodmap.c: (gsd_load_modmap_files): properly NULL-terminate g_build_filename 2008-04-11 Jens Granseuer Make media-keys plugin deactivation work * plugins/media-keys/gsd-media-keys-manager.c: (acme_error), (dialog_init), (init_kbd), (gsd_media_keys_manager_stop), (register_manager): clean up properly on stop * plugins/media-keys/gsd-media-keys-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-11 Jens Granseuer * plugins/keyboard/gsd-xmodmap.c: (check_button_callback), (gsd_load_modmap_files), (response_callback), (remove_string_from_list), (remove_button_clicked_callback), (load_button_clicked_callback), (gsd_modmap_dialog_call): fix memory leaks 2008-04-10 Jens Granseuer Make keyboard plugin deactivation work * plugins/keyboard/gsd-keyboard-manager.c: (register_config_callback), (gsd_keyboard_manager_start), (gsd_keyboard_manager_stop): * plugins/keyboard/gsd-keyboard-xkb.c: (register_config_callback), (gsd_keyboard_xkb_init), (gsd_keyboard_xkb_shutdown): * plugins/keyboard/gsd-keyboard-xkb.h: clean up properly on stop * plugins/keyboard/gsd-keyboard-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer Make keybinding plugin deactivation work * plugins/keybindings/gsd-keybindings-manager.c: (register_config_callback), (gsd_keybindings_manager_start), (gsd_keybindings_manager_stop): clean up properly on stop * plugins/keybindings/gsd-keybindings-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer * plugins/font/gsd-font-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer * plugins/dummy/gsd-dummy-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer * plugins/clipboard/gsd-clipboard-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer Make background plugin deactivation work * plugins/background/gsd-background-manager.c: (gsd_background_manager_start), (gsd_background_manager_stop): clean up properly on stop * plugins/background/gsd-background-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (gsd_a11y_keyboard_manager_stop): also remove GConf watch directory 2008-04-10 Jens Granseuer Make housekeeping plugin deactivation work * plugins/housekeeping/gsd-housekeeping-manager.c: (register_config_callback), (gsd_housekeeping_manager_start), (gsd_housekeeping_manager_stop), (gsd_housekeeping_manager_init): clean up properly on stop * plugins/housekeeping/gsd-housekeeping-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer Make a11y-keyboard plugin deactivation work * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (register_config_callback), (gsd_a11y_keyboard_manager_start), (gsd_a11y_keyboard_manager_stop): properly clean up on _stop * plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.c: (impl_deactivate): stop manager on deactivation 2008-04-10 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (get_xkb_desc_rec), (set_server_from_gconf), (ax_slowkeys_warning_dialog_post), (ax_stickykeys_warning_dialog_post), (set_gconf_from_server), (cb_xkb_event_filter), (gsd_a11y_keyboard_manager_init): more cleanup 2008-04-10 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (grab_key_real): remove excessive key grab logging 2008-04-09 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (numlock_xkb_init), (numlock_set_xkb_state), (numlock_gconf_state_key), (numlock_xkb_callback), (numlock_install_xkb_callback), (apply_settings), (gsd_keyboard_manager_start): split XKB initialization and calbback installation which allows us to get rid of some more special-casing and yet another static variable 2008-04-09 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (xkb_enabled), (get_xkb_desc_rec), (gsd_a11y_keyboard_manager_start): don't install any listeners or callbacks when XKB is not available 2008-04-09 Michael J. Chudobiak * plugins/housekeeping/gsd-housekeeping-manager.c: (gsd_housekeeping_manager_stop): Purge thumbnail cache on shutdown if and only if the max size or max age parameters have been set to zero (for paranoid people) (bug #526999). 2008-04-07 Jens Granseuer Currently, the percentage by which to lower or raise the volume when hitting the multimedia keys is taken from GConf, with 6 being the default. We don't have any settings dialogs to actually change it, though. If the user now selects a mixer that supports fewer volume levels than the GConf setting implies (100/6) it becomes impossible to change the volume (without fiddling with the GConf setting). This patch adds a "threshold" property to the AcmeVolume class that denotes the minimum percentage required to actually affect the volume. The plugin now uses the step size read from GConf or the mixer threshold, depending on which one is bigger. (bug #441910) * plugins/media-keys/actions/acme-volume-alsa.c: (acme_volume_alsa_get_threshold), (acme_volume_alsa_class_init): * plugins/media-keys/actions/acme-volume-dummy.c: (acme_volume_dummy_get_threshold), (acme_volume_dummy_class_init): * plugins/media-keys/actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_get_threshold), (acme_volume_gstreamer_class_init): * plugins/media-keys/actions/acme-volume-oss.c: (acme_volume_oss_get_threshold), (acme_volume_oss_class_init), (acme_volume_oss_mixer_check): * plugins/media-keys/actions/acme-volume.c: (acme_volume_get_threshold): * plugins/media-keys/actions/acme-volume.h: add get_threshold method * plugins/media-keys/gsd-media-keys-manager.c: (do_sound_action): use gconf value or threshold, depending on what's bigger 2008-04-07 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (do_sound_action): only use the built-in default for volume_step if we get an error from GConf, not just when the value is 0 which might be what the user wants (see the discussion on the Thinkpad driver again) 2008-04-07 Jens Granseuer Remove the Thinkpad driver again. See bug #524425 for some discussion. * configure.ac: * plugins/media-keys/actions/Makefile.am: * plugins/media-keys/actions/acme-volume-thinkpad.c: * plugins/media-keys/actions/acme-volume-thinkpad.h: * plugins/media-keys/actions/acme-volume.c: (acme_volume_new): remove extra Thinkpad support 2008-04-06 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (gsd_keyboard_get_hostname_key), (numlock_set_xkb_state), (numlock_gconf_state_key), (numlock_get_gconf_state), (numlock_set_gconf_state), (numlock_xkb_callback), (numlock_install_xkb_callback), (apply_settings), (gsd_keyboard_manager_start), (gsd_keyboard_manager_init): * plugins/keyboard/gsd-keyboard-xkb.c: (gsd_keyboard_xkb_init): * plugins/keyboard/gsd-keyboard-xkb.h: continued attempt at making XKB setup and error handling a bit less arcane and crufty 2008-04-06 Jens Granseuer * plugins/keyboard/gsd-keyboard-xkb.c: * plugins/keyboard/gsd-keyboard-xkb.h: initialize inited_ok or behaviour is undefined when xkb setup fails; don't export XklEngine 2008-04-06 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (do_action): make "Home" keybinding work again 2008-04-05 Jens Granseuer * configure.ac: * plugins/media-keys/actions/Makefile.am: hook up the Thinkpad support 2008-04-05 Jens Granseuer Patch by: Lorne Applebaum <4lorne@gmail.com> * plugins/media-keys/actions/acme-volume-thinkpad.c: * plugins/media-keys/actions/acme-volume-thinkpad.h: * plugins/media-keys/actions/acme-volume.c: (acme_volume_new): add a special volume subclass for better support of IBM Thinkpad hardware volume buttons (bug #524425) 2008-04-05 Jens Granseuer Patch by: Lorne Applebaum <4lorne@gmail.com> * plugins/media-keys/actions/acme-volume-dummy.h: fix TYPE macro and remove an unimplemented prototype 2008-04-01 Jens Granseuer * plugins/keyboard/gsd-keyboard-manager.c: (gsd_keyboard_manager_start): apply keyboard settings on startup, too (bug #525440) 2008-03-31 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (bindings_get_entry): fix various leaks and other memory management issues 2008-03-31 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (bindings_get_entry), (binding_register_keys): remove trailing newlines from messages since g_warning already takes care of those 2008-03-31 Jens Granseuer * plugins/keybindings/gsd-keybindings-manager.c: (do_grab): * plugins/media-keys/gsd-media-keys-manager.c: (grab_key): don't try to add grabs with invalid modifiers 2008-03-30 Gerd Kohlberger * plugins/mouse/gsd-mouse-manager.c: (set_mousetweaks_daemon): Set gconf keys back to false, if mousetweaks isn't installed. Bug #525042. 2008-03-30 Jens Granseuer * plugins/xsettings/gsd-xsettings-manager.c: add mapping for Gtk/Modules xsetting using GConf path /desktop/gnome/gtk-modules (bug #507386) 2008-03-30 Jens Granseuer * plugins/housekeeping/gsd-housekeeping-manager.c: change data types to match glib; avoid using time_t 2008-03-30 Jens Granseuer * plugins/media-keys/actions/acme-volume-dummy.c: (acme_volume_dummy_init), (acme_volume_dummy_class_init): change to use G_DEFINE_TYPE instead of open-coding it 2008-03-29 Jens Granseuer * configure.ac: fix profiling to be off by default 2008-03-29 Jens Granseuer * cinnamon-settings-daemon/main.c: mark string for translation 2008-03-29 Jens Granseuer * plugins/keybindings/eggaccelerators.c: (egg_accelerator_parse_virtual): * plugins/media-keys/eggaccelerators.c: (egg_accelerator_parse_virtual): readd a chunk that got lost in the last commit. *sigh*. Why do we have several differing copies of those files? 2008-03-29 Jens Granseuer * plugins/keybindings/eggaccelerators.c: (egg_accelerator_parse_virtual), (egg_virtual_accelerator_name), (egg_virtual_accelerator_label), (egg_keymap_resolve_virtual_modifiers), (egg_keymap_virtualize_modifiers), (reload_modmap), (egg_keymap_get_modmap): * plugins/keybindings/eggaccelerators.h: fix mismatched modifier mapping between egg and GTK (so that e.g. works) and replace some custom functionality with stock GTK 2008-03-29 Jens Granseuer * plugins/media-keys/eggaccelerators.c: (egg_accelerator_parse_virtual), (egg_virtual_accelerator_name), (egg_virtual_accelerator_label), (egg_keymap_resolve_virtual_modifiers), (egg_keymap_virtualize_modifiers), (reload_modmap), (egg_keymap_get_modmap): * plugins/media-keys/eggaccelerators.h: fix mismatched modifier mapping between egg and GTK (so that e.g. works) and replace some custom functionality with stock GTK 2008-03-29 Jens Granseuer * plugins/housekeeping/gsd-housekeeping-manager.c: (get_gconf_int_with_default): rename to better reflect what it does, and also use the default passed in if we don't get an int from GConf, or we'll end up with a value of 0 which is certainly not what we want (purge_thumbnail_cache): update callers 2008-03-28 Michael J. Chudobiak * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/housekeeping/Makefile.am: * plugins/housekeeping/gsd-housekeeping-manager.c: (thumb_data_free), (read_dir_for_purge), (purge_old_thumbnails), (sort_file_mtime), (get_gconf_int_with_nonzero_default), (purge_thumbnail_cache), (do_cleanup), (do_cleanup_once), (do_cleanup_soon), (bindings_callback), (register_config_callback), (gsd_housekeeping_manager_start), (gsd_housekeeping_manager_stop), (gsd_housekeeping_manager_class_init), (gsd_housekeeping_manager_init), (gsd_housekeeping_manager_new): * plugins/housekeeping/gsd-housekeeping-manager.h: * plugins/housekeeping/gsd-housekeeping-plugin.c: (gsd_housekeeping_plugin_init), (gsd_housekeeping_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_housekeeping_plugin_class_init): * plugins/housekeeping/gsd-housekeeping-plugin.h: * plugins/housekeeping/housekeeping.cinnamon-settings-plugin.in: Added a new "housekeeping" plugin to set limits on the size and age of the thumbnail cache (bug #523159). 2008-03-25 Jens Granseuer Patch by: Matthias Clasen * plugins/mouse/gsd-mouse-manager.c: (filter): don't eat key events; other plugins might need them as well (bug #523676) 2008-03-24 William Jon McCann * configure.ac: Add some stuff to the configuration summary. * plugins/media-keys/gsd-media-keys-manager.c: (gsd_media_keys_manager_start): Add a few more profiling points. 2008-03-24 William Jon McCann * cinnamon-settings-daemon/Makefile.am: * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (set_server_from_gconf), (gsd_a11y_keyboard_manager_start): * plugins/background/Makefile.am: * plugins/background/gsd-background-manager.c: (apply_prefs), (gsd_background_manager_start): * plugins/clipboard/gsd-clipboard-manager.c: (gsd_clipboard_manager_start): * plugins/dummy/gsd-dummy-manager.c: (gsd_dummy_manager_start): * plugins/font/gsd-font-manager.c: (load_xcursor_theme), (load_cursor), (gsd_font_manager_start): * plugins/keybindings/gsd-keybindings-manager.c: (gsd_keybindings_manager_start): * plugins/keyboard/gsd-keyboard-manager.c: (gsd_keyboard_manager_start): * plugins/media-keys/Makefile.am: * plugins/media-keys/gsd-media-keys-manager.c: (init_kbd), (gsd_media_keys_manager_start): * plugins/mouse/gsd-mouse-manager.c: (gsd_mouse_manager_start): * plugins/screensaver/gsd-screensaver-manager.c: (gsd_screensaver_manager_start): * plugins/sound/gsd-sound-manager.c: (start_gnome_sound), (reload_foreach_cb), (apply_settings), (gsd_sound_manager_start): * plugins/typing-break/gsd-typing-break-manager.c: (setup_typing_break), (gsd_typing_break_manager_start): * plugins/xrandr/gsd-xrandr-manager.c: (apply_settings): * plugins/xrdb/gsd-xrdb-manager.c: (apply_settings), (gsd_xrdb_manager_start): * plugins/xsettings/gsd-xsettings-manager.c: (xft_settings_set_xsettings), (xft_settings_set_xresources), (update_xft_settings), (gnome_xsettings_manager_start): Add profiling points to plugins. 2008-03-24 William Jon McCann * cinnamon-settings-daemon/cinnamon-settings-manager.c: (compare_location), (_load_file), (_load_dir): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (debug_info), (gnome_settings_plugin_info_fill_from_file), (gnome_settings_plugin_info_deactivate), (load_plugin_module), (gnome_settings_plugin_info_activate), (gnome_settings_plugin_info_is_active), (gnome_settings_plugin_info_get_enabled), (gnome_settings_plugin_info_is_available), (gnome_settings_plugin_info_get_name), (gnome_settings_plugin_info_get_description), (gnome_settings_plugin_info_get_authors), (gnome_settings_plugin_info_get_website), (gnome_settings_plugin_info_get_copyright), (gnome_settings_plugin_info_get_location), (gnome_settings_plugin_info_get_priority), (gnome_settings_plugin_info_set_priority): Fix a refcounting bug. Add a few more checks. Fix up a leak. Fixes #524183 2008-03-24 William Jon McCann * plugins/media-keys/gsd-media-keys-manager.c: (acme_filter_events): * plugins/sound/gsd-sound-manager.c: (start_gnome_sound): Fix two compiler warnings. 2008-03-24 William Jon McCann * cinnamon-settings-daemon/cinnamon-settings-manager.c: (gnome_settings_manager_start): * cinnamon-settings-daemon/cinnamon-settings-profile.c: (_gnome_settings_profile_log): * cinnamon-settings-daemon/cinnamon-settings-profile.h: * cinnamon-settings-daemon/main.c: (main): Add missing files. Add some more profiling points. 2008-03-24 William Jon McCann * configure.ac: * cinnamon-settings-daemon/Makefile.am: * cinnamon-settings-daemon/cinnamon-settings-manager.c: (_load_file), (_load_dir), (_load_all), (gnome_settings_manager_start): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (gnome_settings_plugin_info_fill_from_file), (load_plugin_module), (_activate_plugin): * cinnamon-settings-daemon/main.c: (bus_register), (main): Add some profiling code. Must specify --enable-profiling to configure. Can now be profiled like so: strace -ttt -f -o /tmp/logfile.strace cinnamon-settings-daemon python plot-timeline.py -o prettygraph.png /tmp/logfile.strace See: http://www.gnome.org/~federico/news-2006-03.html#09 2008-03-24 Jens Granseuer Patch by: Alexey Shabalin * plugins/sound/gsd-sound-manager.c: (apply_settings): now that "starting esd" can mean either esd or PulseAudio, check the GConf setting for starting the sound server even when esd is disabled (bug #523743) 2008-03-24 Jens Granseuer * plugins/dummy/Makefile.am: remove NULL definition so authors using this as the base for their own plugins don't get strange ideas 2008-03-20 William Jon McCann * plugins/media-keys/Makefile.am: * plugins/media-keys/gsd-media-keys-manager.c: (grab_key_real), (init_kbd), (acme_filter_events), (gsd_media_keys_manager_start): * plugins/media-keys/test-media-keys.c: (main): Add a tool to test media keys. 2008-03-16 William Jon McCann * plugins/sound/gsd-sound-manager.c: (reset_esd_pid), (start_gnome_sound), (wait_on_child), (stop_child), (stop_gnome_sound), (apply_settings), (gsd_sound_manager_dispose): Fix handling of child process. 2008-03-14 Jens Granseuer * plugins/media-keys/gsd-media-keys-window.c: (remove_hide_timeout): reset opacity when removing the timeout so that the fadeout is restarted when media keys are pressed while the popup is already fading out (bug #522499) 2008-03-13 Jens Granseuer * plugins/media-keys/actions/acme.glade: remove unused properties (and, in particular, an unused translated string) 2008-03-13 Jens Granseuer Patch by: Danny Baumann * plugins/media-keys/gsd-media-keys-window.c: (gsd_media_keys_window_new): set window type hint on the volume popup (bug #522232) 2008-03-11 Jens Granseuer * plugins/typing-break/gsd-typing-break-manager.c: (setup_typing_break): pass data to the timeout so shutting down the typing monitor works instead of segfaulting (bug #521786) (gsd_typing_break_manager_start): use g_timeout_add_seconds instead of g_timeout_add 2008-03-10 Rodrigo Moya * configure.ac: Post release version bump ==== 2.22.0 ==== 2008-03-10 Rodrigo Moya * NEWS: Update for release. 2008-03-08 Jens Granseuer * data/Makefile.am: * data/apps_gnome_settings_daemon_default_editor.schemas.in: * data/cinnamon-settings-daemon.schemas.in: remove obsolete settings for the removed default editor plugin 2008-03-01 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (ax_response_callback): don't pass the GError argument if we're not going to use it. Also remove some unnecessary casting 2008-02-29 William Jon McCann * cinnamon-settings-daemon/main.c: Disable debug by default again. 2008-02-29 Jens Granseuer * configure.ac: * plugins/mouse/Makefile.am: when building with XInput support, actually link against libXi, or we'll fail to load the plugin due to unresolved symbols (bug #519488) 2008-02-29 William Jon McCann * configure.ac: Post release version bump ==== 2.21.92 ==== 2008-02-29 William Jon McCann * NEWS: Update for release. 2008-02-29 William Jon McCann * configure.ac: Remove Werror. 2008-02-29 Jens Granseuer * cinnamon-settings-daemon/cinnamon-settings-manager.c: (register_manager), (gnome_settings_manager_start): minor clean-up 2008-02-28 William Jon McCann * cinnamon-settings-daemon/cinnamon-settings-manager.c: (gnome_settings_manager_error_quark), (_load_file), (gnome_settings_manager_awake), (gnome_settings_manager_start), (gnome_settings_manager_start_with_settings_prefix), (_set_settings_prefix), (gnome_settings_manager_set_property), (gnome_settings_manager_get_property), (gnome_settings_manager_class_init), (gnome_settings_manager_finalize), (gnome_settings_manager_new): * cinnamon-settings-daemon/cinnamon-settings-manager.h: * cinnamon-settings-daemon/cinnamon-settings-manager.xml: * cinnamon-settings-daemon/main.c: (main): When dbus activated only load the plugins when requested instead of at startup. Add a new method to start and set plugin settings prefix. This allows gdm to use dbus activation. It also fixes cases where g-s-d is activated and plugins are loaded unintentionally. 2008-02-29 Wouter Bolsterlee * plugins/sound/gsd-sound-manager.c (apply_settings): Add braces to fix amgiguous else. Avoids compiler warnings. 2008-02-28 Bastien Nocera * plugins/sound/gsd-sound-manager.c (reset_esd_pid), (start_gnome_sound), (stop_gnome_sound), (apply_settings), (gsd_sound_manager_stop): Start the sound server ourselves, as we need it to cache samples. If esd (or the PulseAudio esd compat bits) isn't available, just print an error, and don't try to cache the samples If you use PulseAudio instead of esound in your distribution, build with --disable-esd passed to configure (Closes: #518075) 2008-02-25 William Jon McCann * cinnamon-settings-daemon/main.c: (gsd_log_default_handler), (main): Add --debug command line option. Only print DEBUG level messages if --debug is used. 2008-02-25 William Jon McCann * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (gnome_settings_plugin_info_fill_from_file): Don't warn on missing priority since we don't recommend that it be used. 2008-02-22 William Jon McCann * data/cinnamon-settings-daemon.schemas.in: Take a stab at defining the default load priorities. Fixes #518155 2008-02-22 William Jon McCann * data/cinnamon-settings-daemon.schemas.in: * cinnamon-settings-daemon/cinnamon-settings-manager.c: (_load_file): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (gnome_settings_plugin_info_set_priority): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.h: Allow gconf to override priorities. Set sound plugin priority to 1 (highest). Fixes #515340 2008-02-22 William Jon McCann * cinnamon-settings-daemon/Makefile.am: * cinnamon-settings-daemon/cinnamon-settings-manager.c: (_load_info), (maybe_activate_plugin), (compare_location), (compare_priority), (on_plugin_activated), (on_plugin_deactivated), (_load_file), (_load_dir), (_load_all), (_unload_all), (gnome_settings_manager_start), (gnome_settings_manager_stop), (gnome_settings_manager_constructor), (gnome_settings_manager_class_init), (gnome_settings_manager_finalize): * cinnamon-settings-daemon/cinnamon-settings-manager.h: * cinnamon-settings-daemon/cinnamon-settings-manager.xml: * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (gnome_settings_plugin_info_class_init), (gnome_settings_plugin_info_set_enabled_key_name), (_deactivate_plugin), (_activate_plugin): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.h: * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.c: * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.h: Merge PluginsEngine functionality into Manager. Emit signals when plugins are activated or deactivated. Fixes #515341 2008-02-22 William Jon McCann * cinnamon-settings-daemon/Makefile.am: * cinnamon-settings-daemon/cinnamon-settings-manager.c: (gnome_settings_manager_start), (gnome_settings_manager_stop), (gnome_settings_manager_constructor), (gnome_settings_manager_finalize): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.c: (gnome_settings_plugin_info_finalize), (gnome_settings_plugin_info_class_init), (gnome_settings_plugin_info_init), (gnome_settings_plugin_info_fill_from_file), (plugin_enabled_cb), (gnome_settings_plugin_info_set_enabled_key_name), (gnome_settings_plugin_info_new_from_file), (_deactivate_plugin), (gnome_settings_plugin_info_deactivate), (load_plugin_module), (_activate_plugin), (gnome_settings_plugin_info_activate), (gnome_settings_plugin_info_is_active), (gnome_settings_plugin_info_get_enabled), (gnome_settings_plugin_info_is_available), (gnome_settings_plugin_info_get_name), (gnome_settings_plugin_info_get_description), (gnome_settings_plugin_info_get_authors), (gnome_settings_plugin_info_get_website), (gnome_settings_plugin_info_get_copyright), (gnome_settings_plugin_info_get_location), (gnome_settings_plugin_info_get_priority): * cinnamon-settings-daemon/cinnamon-settings-plugin-info.h: * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.c: (gnome_settings_plugins_engine_load), (maybe_activate_plugin), (compare_location), (compare_priority), (gnome_settings_plugins_engine_load_file), (gnome_settings_plugins_engine_load_dir), (gnome_settings_plugins_engine_load_all), (gnome_settings_plugins_engine_unload_all), (gnome_settings_plugins_engine_start), (gnome_settings_plugins_engine_garbage_collect), (gnome_settings_plugins_engine_stop), (gnome_settings_plugins_engine_get_plugins_list), (_set_gconf_prefix), (gnome_settings_plugins_engine_set_property), (gnome_settings_plugins_engine_get_property), (gnome_settings_plugins_engine_class_init), (gnome_settings_plugins_engine_init), (gnome_settings_plugins_engine_finalize), (gnome_settings_plugins_engine_new): * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.h: Refactor the PluginInfo structure into a class. This will facilitate fixing bug #515341 2008-02-22 Bastien Nocera * configure.ac: Only enable ALSA and OSS support if we don't have GStreamer support, as the media-keys code doesn't have any fallbacks if GStreamer fails to load (see acme-volume.c's _new ()) 2008-02-19 Vincent Untz * plugins/keyboard/gsd-keyboard-manager.c: (gsd_keyboard_get_hostname_key): escape the hostname before using it in a gconf path since it might contain invalid characters. Fix bug #517259. 2008-02-19 Jens Granseuer * configure.ac: remove some unused stuff * plugins/sound/Makefile.am: add missing ESD_CFLAGS/LIBS 2008-02-19 Jens Granseuer * configure.ac: * plugins/xrandr/Makefile.am: * plugins/xrandr/gsd-xrandr-manager.c: (gsd_xrandr_manager_class_init), (gsd_xrandr_manager_init), (gsd_xrandr_manager_finalize): build with XRandR if available, makes setting screen geometry at login time work again (bug #517418) 2008-02-16 Jens Granseuer * cinnamon-settings-daemon/main.c: mark string as translatable 2008-02-14 Jens Granseuer * plugins/background/gsd-background-manager.c: (gsd_background_manager_start): at startup, don't apply background prefs twice and don't check for nautilus running since we're usually started first 2008-02-12 Kjartan Maraas * configure.ac: Fix for 515956. Build with Gio. ==== 2.21.91 ==== 2008-02-11 Rodrigo Moya * configure.ac: * NEWS: prepare for 2.21.91. 2008-02-11 Rodrigo Moya Fixes bug #513990 * plugins/background/gsd-background-manager.c: use GIO instead of gnome-vfs. * plugins/configure.ac: * plugins/Makefile.am: * plugins/default-editor/*: removed useless default editor plugin. 2008-02-11 Rodrigo Moya Patch by Wouter Bolsterlee * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.c (gnome_settings_plugins_engine_load_all): assign return value from g_slist_sort to the plugins list variable. (bug #515340) 2008-02-10 Jens Granseuer * cinnamon-settings-daemon/main.c: update the default GConf prefix to match the changes from r112 or bug #514411 2008-02-09 Jens Granseuer Support for defining plugin start order got lost in the split from gnome-control-center, but it is essential for some plugins to work correctly. With this change the "Priority" keyword can be used in the ".cinnamon-settings-plugin" file to set plugin priorities. Priority can take values from 1 upwards, with 1 being maximum priority and 100 being the default if nothing is specified by the plugin. For multiple plugins with identical priority start order is undefined. (bug #515340) * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.c: (gnome_settings_plugins_engine_load), (activate_plugin), (compare_location), (compare_priority), (gnome_settings_plugins_engine_load_file), (gnome_settings_plugins_engine_load_all), (gnome_settings_plugins_engine_init), (gnome_settings_plugins_engine_shutdown), (gnome_settings_plugins_engine_get_plugins_list), (gnome_settings_plugins_engine_get_plugin_copyright), (gnome_settings_plugins_engine_get_plugin_priority): * cinnamon-settings-daemon/cinnamon-settings-plugins-engine.h: add back support for defining plugin start order 2008-02-09 Jens Granseuer * plugins/media-keys/gsd-media-keys-manager.c: (gsd_media_keys_manager_stop): declare variables at the beginning of a block to make older compilers happy 2008-02-09 Jens Granseuer * plugins/clipboard/gsd-clipboard-manager.c: (gsd_clipboard_error_quark): fix copy'n'paste error (bug #515426) 2008-02-08 Sebastien Bacher * configure.ac: check for xinput (bug #514942) 2008-02-08 Jens Granseuer * plugins/background/gsd-background-manager.c: (gsd_background_manager_start), (gsd_background_manager_stop): * plugins/keybindings/gsd-keybindings-manager.c: (gsd_keybindings_manager_start): * plugins/media-keys/gsd-media-keys-manager.c: (gsd_media_keys_manager_stop): fix leaks * plugins/default-editor/gsd-default-editor-manager.c: (gsd_default_editor_manager_start): fix leak and pass the correct data to the mime type callback * plugins/xsettings/gsd-xsettings-manager.c: (gnome_xsettings_manager_start): unref the GConfClient only after we're done with it 2008-02-08 Jens Granseuer * plugins/clipboard/gsd-clipboard-manager.c: (gsd_kbd_a11y_error_quark), (gsd_clipboard_manager_start): make sure we return a GError if initialization fails 2008-02-08 Matthias Clasen * plugins/keyboard/gsd-keyboard-manager.c (gsd_keyboard_manager_start): Load the XKB settings initially. Fixes bug #511771. 2008-02-07 Jens Granseuer * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: (gsd_kbd_a11y_error_quark), (gsd_a11y_keyboard_manager_start): make sure we return a GError if initialization fails (bug #514926) 2008-02-06 Jens Granseuer * plugins/media-keys/gsd-media-keys-window.c: (volume_controls_set_visible), (window_set_icon_name), (window_set_icon_file), (volume_level_changed), (gsd_media_keys_window_class_init), (gsd_media_keys_window_init): release the glade XML file as soon as possible and keep track of the two widgets we need. This way we can also get rid of the custom finalize method 2008-02-06 Jens Granseuer * data/cinnamon-settings-daemon.schemas.in: use gnome_settings_daemon for the GConf path. This is what the other g-s-d settings use as well, and there is no good reason to use two separate paths (bug #514411) 2008-02-06 Jens Granseuer * configure.ac: add separate checks for libbackground * plugins/background/libbackground/*: delete files and use the external copy from gnome-control-center to avoid duplication 2008-02-05 Jens Granseuer Based on a patch by: Damien Carberry * configure.ac: * data/cinnamon-settings-daemon-uninstalled.pc.in: add uninstalled.pc file for building against an uninstalled copy of g-s-d (bug #511820) 2008-02-05 Jens Granseuer Based on a patch by: Damien Carberry * Makefile.am: * autogen.sh: * configure.ac: * plugins/a11y-keyboard/Makefile.am: * plugins/background/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/default-editor/Makefile.am: * plugins/dummy/Makefile.am: * plugins/font/Makefile.am: * plugins/keybindings/Makefile.am: * plugins/keyboard/Makefile.am: * plugins/media-keys/Makefile.am: * plugins/media-keys/actions/Makefile.am: * plugins/mouse/Makefile.am: * plugins/screensaver/Makefile.am: * plugins/sound/Makefile.am: * plugins/typing-break/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrdb/Makefile.am: * plugins/xsettings/Makefile.am: * src: rename the src folder to cinnamon-settings-daemon. This is needed so we can supply an uninstalled.pc file for g-s-d (see discussion in bug #511820) 2008-02-04 Jens Granseuer * plugins/screensaver/gsd-screensaver-manager.c: (gsd_screensaver_manager_start): don't crash when running the screensaver fails. The plugin relies on the GError it passes always being filled in if we couldn't start the module, so set it up properly in those cases (bug #514385) 2008-02-04 Luca Ferretti reviewed by: Jens Granseuer * data/apps_gnome_settings_daemon_default_editor.schemas.in: * data/apps_gnome_settings_daemon_keybindings.schemas.in: * data/apps_gnome_settings_daemon_screensaver.schemas.in: * data/desktop_gnome_font_rendering.schemas.in: * data/cinnamon-settings-daemon.schemas.in: Review short and long descriptions for GConf keys, bug #514047. 2008-02-02 Jens Granseuer * src/Makefile.am: remove duplicate CFLAGS (and NULL) 2008-02-01 Christian Persch * configure.ac: Install the settings plugin to $(libdir)/cinnamon-settings-daemon-2.0. Fixes install with libdir == libexecdir, bug #504203. 2008-02-01 Christian Persch Bug #513246. * acinclude.m4: * configure.ac: * plugins/a11y-keyboard/Makefile.am: * plugins/background/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/default-editor/Makefile.am: * plugins/dummy/Makefile.am: * plugins/font/Makefile.am: * plugins/keybindings/Makefile.am: * plugins/keyboard/Makefile.am: * plugins/media-keys/Makefile.am: * plugins/media-keys/actions/Makefile.am: * plugins/mouse/Makefile.am: * plugins/screensaver/Makefile.am: * plugins/sound/Makefile.am: * plugins/typing-break/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrdb/Makefile.am: * plugins/xsettings/Makefile.am: Use a flat directory instead of a directory hierarchy to install the plugins into. Install data files under $(pkgdatadir), not under $(libdir). * src/Makefile.am: * src/cinnamon-settings-plugins-engine.c: (gnome_settings_plugin_info_free), (gnome_settings_plugins_engine_load), (gnome_settings_plugins_engine_load_file), (gnome_settings_plugins_engine_load_dir): Don't scan the plugins directory recursively. Use GSlice for the plugin info struct. ==== 2.21.90.2 ==== 2008-01-30 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.21.90.2. 2008-01-30 Gabor Kelemen * data/apps_gnome_settings_daemon_keybindings.schemas.in: Change E-mail schema's descriptions to be more verbose and sensible. Fix #512766. 2008-01-30 Christian Persch * configure.ac: * plugins/a11y-keyboard/Makefile.am: * plugins/a11y-keyboard/a11y-keyboard.cinnamon-settings-plugin.desktop .in: * plugins/background/Makefile.am: * plugins/background/background.cinnamon-settings-plugin.desktop.in: * plugins/clipboard/Makefile.am: * plugins/clipboard/clipboard.cinnamon-settings-plugin.desktop.in: * plugins/default-editor/Makefile.am: * plugins/default-editor/default-editor.cinnamon-settings-plugin.deskt op.in: * plugins/dummy/Makefile.am: * plugins/dummy/dummy.cinnamon-settings-plugin.desktop.in: * plugins/font/Makefile.am: * plugins/font/font.cinnamon-settings-plugin.desktop.in: * plugins/keybindings/Makefile.am: * plugins/keybindings/keybindings.cinnamon-settings-plugin.desktop.in: * plugins/keyboard/Makefile.am: * plugins/keyboard/keyboard.cinnamon-settings-plugin.desktop.in: * plugins/media-keys/Makefile.am: * plugins/media-keys/media-keys.cinnamon-settings-plugin.desktop.in: * plugins/mouse/Makefile.am: * plugins/mouse/mouse.cinnamon-settings-plugin.desktop.in: * plugins/screensaver/Makefile.am: * plugins/screensaver/screensaver.cinnamon-settings-plugin.desktop.in: * plugins/sound/Makefile.am: * plugins/sound/libsounds/Makefile.am: * plugins/sound/sound.cinnamon-settings-plugin.desktop.in: * plugins/typing-break/Makefile.am: * plugins/typing-break/typing-break.cinnamon-settings-plugin.desktop.in: * plugins/xrandr/Makefile.am: * plugins/xrandr/xrandr.cinnamon-settings-plugin.desktop.in: * plugins/xrdb/Makefile.am: * plugins/xrdb/xrdb.cinnamon-settings-plugin.desktop.in: * plugins/xsettings/Makefile.am: * plugins/xsettings/xsettings.cinnamon-settings-plugin.desktop.in: * po/POTFILES.in: No need to use weird naming of .cinnamon-settings-daemon.in files. Bug #512048. 2008-01-29 Rodrigo Moya * data/org.gnome.SettingsDaemon.service.in: use correct binary path. ==== 2.21.90.1 ==== 2008-01-29 Rodrigo Moya * NEWS: * configure.ac: prepare for 2.21.90.1. 2008-01-29 Rodrigo Moya * src/Makefile.am: use plain $libexecdir for g-s-d binary. ==== 2.21.90 ==== 2008-01-28 Rodrigo Moya * configure.ac: * NEWS: prepare for 2.21.90. 2008-01-28 Wouter Bolsterlee * data/Makefile.am: Suppress verbose GConf schema installation output. 2008-01-28 Wouter Bolsterlee * src/Makefile.am: Don't use weird autofu stuff to install cinnamon-settings-daemon into another directory, but define gsddir and gsd_PROGRAMS instead. Fixes bug #504203. 2008-01-28 Wouter Bolsterlee * data/org.gnome.SettingsDaemon.service.in: * src/Makefile.am: Hopefully allow $(libdir) to be the same directory as $(libexecdir) by installing the cinnamon-settings-daemon binary into a subdirectory of $(libexecdir), i.e. $(libexecdir)/cinnamon-settings-daemon/cinnamon-settings-daemon. Fixes bug #504203. 2008-01-28 Wouter Bolsterlee * src/main.c: (main): Don't leak the GnomeProgram instance. 2008-01-28 Wouter Bolsterlee * configure.ac: * src/main.c: (main): Initialize GnomeProgram to avoid critical warnings from libgnome. Fixes bug #509770. 2008-01-26 Jens Granseuer * data/cinnamon-settings-daemon.pc.in: DBus API has been frozen for a while now. No longer define DBUS_API_SUBJECT_TO_CHANGE 2008-01-25 Soren Sandmann * plugins/background/gsd-background-manager.c (GNOME_DESKTOP_USE_UNSTABLE_API): Define this macro before including gnome-bg.h 2008-01-25 Jens Granseuer * plugins/xsettings/gsd-xsettings-manager.c: (xft_settings_set_xresources): don't try to reference a non-existing variable (left-over cruft from the patch for bug #505470) 2008-01-25 Jens Granseuer * data/cinnamon-settings-daemon.schemas.in: fix typo in typing break key. Bug #510429. 2008-01-25 Jens Granseuer Patch by: * configure.ac: readd check for XFT2 that got lost in the g-s-d split. Bug #510925. 2008-01-25 Christian Persch * plugins/xsettings/gsd-xsettings-manager.c: (xft_settings_set_xresources): Use g_ascii_dtostr instead of setlocale. Bug #505470. 2008-01-25 Christian Persch * plugins/media-keys/Makefile.am: Fix build with builddir != srcdir. BUg #509142. 2008-01-24 Jens Granseuer * configure.ac: quote function names in AC_DEFUN to fix "underquoted definition" autoconf warning 2008-01-23 Kjartan Maraas * plugins/mouse/gsd-locate-pointer.c: (timeline_frame_cb), (timeline_finished_cb): Fix a couple typos that broke the build. 2008-01-22 Carlos Garnacho * plugins/mouse/gsd-locate-pointer.c: Reworked, add a more appealing animation if there's a composite manager present, also use a similar animation for the non-composite case, so most of the code is shared. * plugins/mouse/gsd-timeline.[ch]: New files, object to control the "locate pointer" animation. * plugins/mouse/Makefile.am: Added these files to build. ==== 2.21.5.2 ==== 2008-01-15 Rodrigo Moya * configure.ac: * NEWS: prepare for 2.21.5.2. 2008-01-15 Rodrigo Moya * plugins/sound/Makefile.am: * plugins/sound/libsounds/Makefile.am: use a libtool library for x86_64 warnings. * configure.ac: automake fixes for allowing long file names in tar.gz. ==== 2.21.5.1 ==== 2008-01-15 Rodrigo Moya * configure.ac: * NEWS: prepare for 2.21.5.1. ==== 2.21.5 ==== 2008-01-15 Rodrigo Moya * NEWS: prepare for 2.21.5. 2008-01-14 Rodrigo Moya * data/cinnamon-settings-daemon.pc.in: reverted last patch. 2008-01-14 Rodrigo Moya * data/cinnamon-settings-daemon.pc.in: added dbusapidir variable, for the gnome-control-center module to access the .xml DBus interfaces file. 2008-01-14 Denis Washington * plugins/xrandr/Makefile.in: This was probably committed by accident, remove it. 2008-01-14 Denis Washington * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c: Only consider /desktop/gnome/accessibility/keyboard/enable as option for enabling keyboard a11y features from the keyboard, not as global switch to turn all a11y features on/off. 2008-01-14 Denis Washington Patch from Gerd Kohlberger (bug #503547) * plugins/mouse/gsd-mouse-manager.c: Mousetweaks support. 2008-01-14 Rodrigo Moya * plugins/media-keys/gsd-media-keys-manager.c: reverted patch from bug #165343. 2007-12-24 Christian Persch * plugins/xsettings/gsd-xsettings-manager.c: Add Gtk/IMModule XSetting. Bug #504182, patch by Akira TAGOH. 2007-12-22 William Jon McCann * plugins/xsettings/gsd-xsettings-manager.c: use new setting from libgnome to make toolbar icon size setting work (bug #401030) Merge from gnome-control-center. 2007-12-22 William Jon McCann * plugins/xsettings/Makefile.am: * plugins/xsettings/gnome-xsettings-manager.c: * plugins/xsettings/gnome-xsettings-manager.h: * plugins/xsettings/gnome-xsettings-plugin.c: * plugins/xsettings/gnome-xsettings-plugin.h: * plugins/xsettings/gsd-xsettings-manager.c: * plugins/xsettings/gsd-xsettings-plugin.c: Rename files to be consistent with other plugins. 2007-12-21 William Jon McCann * plugins/background/Makefile.am: * plugins/background/background.cinnamon-settings-plugin.desktop.in: * plugins/background/gsd-background-manager.c: (gsd_background_manager_init): * plugins/background/test-background.c: (idle), (main): Init gnome-vfs and use the correct name in the desktop file. 2007-12-21 William Jon McCann * configure.ac: * plugins/background/gsd-background-manager.c: (nautilus_is_running), (apply_prefs), (queue_apply), (background_callback), (on_bg_changed), (gsd_background_manager_start): Merge g-c-c patch for animated backgrounds. Require gnome-desktop 2.21.4. Patch from: Soeren Sandmann 2007-12-18 William Jon McCann * configure.ac: Post release version bump ==== 2.21.4 ==== 2007-12-18 William Jon McCann * NEWS: Update for release. 2007-12-18 William Jon McCann * configure.ac: Update version number. 2007-12-18 William Jon McCann * src/cinnamon-settings-manager.c: (gnome_settings_manager_awake): * src/main.c: Turn off daemonizing for now since it confused D-Bus service activation. 2007-12-18 William Jon McCann * src/Makefile.am: * src/cinnamon-settings-manager.c: (gnome_settings_manager_awake), (register_manager), (gnome_settings_manager_class_init), (gnome_settings_manager_new): * src/cinnamon-settings-manager.h: * src/cinnamon-settings-manager.xml: Provide the awake method and install the dbus api header. 2007-12-17 William Jon McCann * plugins/background/Makefile.am: * plugins/sound/Makefile.am: Fix distcheck. 2007-12-17 William Jon McCann * plugins/Makefile.am: * plugins/a11y-keyboard/a11y-keyboard.cinnamon-settings-plugin.desktop .in: * plugins/a11y-keyboard/gsd-a11y-keyboard-manager.h: * plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.c: (gsd_a11y_keyboard_plugin_init), (gsd_a11y_keyboard_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_a11y_keyboard_plugin_class_init): * plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.h: Add a11y keyboard plugin. 2007-12-17 William Jon McCann * configure.ac: * plugins/Makefile.am: * plugins/typing-break/Makefile.am: * plugins/typing-break/gsd-typing-break-manager.c: (register_config_callback), (typing_break_timeout), (child_watch), (setup_typing_break), (typing_break_callback), (really_setup_typing_break), (gsd_typing_break_manager_start), (gsd_typing_break_manager_stop), (gsd_typing_break_manager_set_property), (gsd_typing_break_manager_get_property), (gsd_typing_break_manager_constructor), (gsd_typing_break_manager_dispose), (gsd_typing_break_manager_class_init), (gsd_typing_break_manager_init), (gsd_typing_break_manager_finalize), (gsd_typing_break_manager_new): * plugins/typing-break/gsd-typing-break-manager.h: * plugins/typing-break/gsd-typing-break-plugin.c: (gsd_typing_break_plugin_init), (gsd_typing_break_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_typing_break_plugin_class_init): * plugins/typing-break/gsd-typing-break-plugin.h: * plugins/typing-break/typing-break.cinnamon-settings-plugin.desktop.in: Add typing break plugin. 2007-12-17 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/sound/Makefile.am: * plugins/sound/gsd-sound-manager.c: (start_gnome_sound), (stop_gnome_sound), (reload_foreach_cb), (apply_settings), (register_config_callback), (sound_callback), (gsd_sound_manager_start), (gsd_sound_manager_stop), (gsd_sound_manager_set_property), (gsd_sound_manager_get_property), (gsd_sound_manager_constructor), (gsd_sound_manager_dispose), (gsd_sound_manager_class_init), (gsd_sound_manager_init), (gsd_sound_manager_finalize), (gsd_sound_manager_new): * plugins/sound/gsd-sound-manager.h: * plugins/sound/gsd-sound-plugin.c: (gsd_sound_plugin_init), (gsd_sound_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_sound_plugin_class_init): * plugins/sound/gsd-sound-plugin.h: * plugins/sound/sound.cinnamon-settings-plugin.desktop.in: * plugins/xrandr/Makefile.in: Add sound plugin 2007-12-17 William Jon McCann * data/cinnamon-settings-daemon.schemas.in: Add schemas for media keys. 2007-12-17 William Jon McCann * configure.ac: * plugins/Makefile.am: * plugins/dummy/gsd-dummy-manager.c: * plugins/media-keys/Makefile.am: * plugins/media-keys/actions/Makefile.am: * plugins/media-keys/actions/acme-volume-alsa.c: (acme_volume_alsa_finalize), (acme_volume_alsa_set_mute), (acme_volume_alsa_get_mute), (acme_volume_alsa_get_volume), (acme_volume_alsa_set_volume), (acme_volume_alsa_close_real), (acme_volume_alsa_open), (acme_volume_alsa_close), (acme_volume_alsa_init), (acme_volume_alsa_class_init): * plugins/media-keys/actions/acme-volume-alsa.h: * plugins/media-keys/actions/acme-volume-dummy.c: (acme_volume_dummy_finalize), (acme_volume_dummy_set_mute), (acme_volume_dummy_get_mute), (acme_volume_dummy_get_volume), (acme_volume_dummy_set_volume), (acme_volume_dummy_init), (acme_volume_dummy_class_init), (acme_volume_dummy_get_type): * plugins/media-keys/actions/acme-volume-dummy.h: * plugins/media-keys/actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_finalize), (acme_volume_gstreamer_set_mute), (update_state), (acme_volume_gstreamer_get_mute), (acme_volume_gstreamer_get_volume), (acme_volume_gstreamer_set_volume), (acme_volume_gstreamer_close_real), (_acme_set_mixer), (acme_volume_gstreamer_open), (acme_volume_gstreamer_close), (acme_volume_gstreamer_init), (acme_volume_gstreamer_class_init): * plugins/media-keys/actions/acme-volume-gstreamer.h: * plugins/media-keys/actions/acme-volume-oss.c: (acme_volume_oss_finalize), (acme_volume_oss_vol_check), (acme_volume_oss_set_mute), (acme_volume_oss_get_mute), (acme_volume_oss_get_volume), (acme_volume_oss_set_volume), (acme_volume_oss_init), (acme_volume_oss_class_init), (acme_volume_oss_mixer_check): * plugins/media-keys/actions/acme-volume-oss.h: * plugins/media-keys/actions/acme-volume.c: (acme_volume_class_init), (acme_volume_init), (acme_volume_get_volume), (acme_volume_set_volume), (acme_volume_get_mute), (acme_volume_set_mute), (acme_volume_mute_toggle), (acme_volume_new): * plugins/media-keys/actions/acme-volume.h: * plugins/media-keys/actions/acme.glade: * plugins/media-keys/actions/acme.h: * plugins/media-keys/eggaccelerators.c: (is_alt), (is_ctl), (is_modx), (is_ctrl), (is_shft), (is_shift), (is_control), (is_release), (is_meta), (is_super), (is_hyper), (is_keycode), (egg_accelerator_parse_virtual), (egg_virtual_accelerator_name), (egg_keymap_resolve_virtual_modifiers), (egg_keymap_virtualize_modifiers), (reload_modmap), (egg_keymap_get_modmap): * plugins/media-keys/eggaccelerators.h: * plugins/media-keys/gsd-marshal.list: * plugins/media-keys/gsd-media-keys-manager.c: (init_screens), (acme_error), (get_term_command), (execute), (do_sleep_action), (dialog_init), (grab_key_real), (grab_key), (is_valid_shortcut), (update_kbd_cb), (init_kbd), (dialog_show), (do_unknown_action), (do_help_action), (do_mail_action), (do_media_action), (do_www_action), (do_exit_action), (do_eject_action), (do_sound_action), (find_by_application), (find_by_time), (gsd_media_keys_manager_grab_media_player_keys), (gsd_media_keys_manager_release_media_player_keys), (gsd_media_player_key_pressed), (do_multimedia_player_action), (do_action), (acme_get_screen_from_event), (acme_filter_events), (gsd_media_keys_manager_start), (gsd_media_keys_manager_stop), (gsd_media_keys_manager_set_property), (gsd_media_keys_manager_get_property), (gsd_media_keys_manager_constructor), (gsd_media_keys_manager_dispose), (gsd_media_keys_manager_class_init), (gsd_media_keys_manager_init), (gsd_media_keys_manager_finalize), (register_manager), (gsd_media_keys_manager_new): * plugins/media-keys/gsd-media-keys-manager.h: * plugins/media-keys/gsd-media-keys-manager.xml: * plugins/media-keys/gsd-media-keys-plugin.c: (gsd_media_keys_plugin_init), (gsd_media_keys_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_media_keys_plugin_class_init): * plugins/media-keys/gsd-media-keys-plugin.h: * plugins/media-keys/gsd-media-keys-window.c: (fade_timeout), (hide_timeout), (remove_hide_timeout), (add_hide_timeout), (update_window), (volume_controls_set_visible), (window_set_icon_name), (window_set_icon_file), (action_changed), (volume_level_changed), (volume_muted_changed), (gsd_media_keys_window_set_action), (gsd_media_keys_window_set_volume_muted), (gsd_media_keys_window_set_volume_level), (curved_rectangle), (load_pixbuf), (render_eject), (draw_eject), (draw_action_eject), (draw_waves), (draw_speaker), (render_speaker), (draw_volume_boxes), (draw_action_volume), (draw_action), (on_expose_event), (gsd_media_keys_window_real_show), (gsd_media_keys_window_real_hide), (gsd_media_keys_window_class_init), (gsd_media_keys_window_is_valid), (initialize_alpha_mode), (gsd_media_keys_window_init), (gsd_media_keys_window_finalize), (gsd_media_keys_window_new): * plugins/media-keys/gsd-media-keys-window.h: * plugins/media-keys/media-keys.cinnamon-settings-plugin.desktop.in: * plugins/media-keys/test-media-window.c: (update_state), (test_window), (main): * plugins/xrandr/Makefile.in: Add media keys plugin. 2007-12-17 William Jon McCann * configure.ac: * data/Makefile.am: * data/apps_gnome_settings_daemon_default_editor.schemas.in: * data/apps_gnome_settings_daemon_keybindings.schemas.in: * data/apps_gnome_settings_daemon_screensaver.schemas.in: * data/desktop_gnome_font_rendering.schemas.in: * plugins/default-editor/Makefile.am: * plugins/default-editor/gsd-default-editor-manager.c: (gsd_default_editor_manager_init): * plugins/keyboard/Makefile.am: * plugins/keyboard/gsd-keyboard-manager.c: * plugins/mouse/gsd-mouse-manager.c: * plugins/screensaver/gsd-screensaver-manager.c: (gsd_screensaver_manager_start): * plugins/xrandr/Makefile.in: * plugins/xrandr/gsd-xrandr-manager.c: * plugins/xrdb/Makefile.am: Add other schemas. Fix some zero length private data. Fix some install dirs. Add libgnomekbd deps. 2007-12-17 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/screensaver/Makefile.am: * plugins/screensaver/gsd-screensaver-manager.c: (key_toggled_cb), (gsd_screensaver_manager_start), (gsd_screensaver_manager_stop), (gsd_screensaver_manager_set_property), (gsd_screensaver_manager_get_property), (gsd_screensaver_manager_constructor), (gsd_screensaver_manager_dispose), (gsd_screensaver_manager_class_init), (gsd_screensaver_manager_init), (gsd_screensaver_manager_finalize), (gsd_screensaver_manager_new): * plugins/screensaver/gsd-screensaver-manager.h: * plugins/screensaver/gsd-screensaver-plugin.c: (gsd_screensaver_plugin_init), (gsd_screensaver_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_screensaver_plugin_class_init): * plugins/screensaver/gsd-screensaver-plugin.h: * plugins/screensaver/screensaver.cinnamon-settings-plugin.desktop.in: Add screensaver plugin. 2007-12-17 William Jon McCann * plugins/background/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/default-editor/Makefile.am: * plugins/dummy/Makefile.am: * plugins/font/Makefile.am: * plugins/keybindings/Makefile.am: * plugins/mouse/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrandr/Makefile.in: * plugins/xrdb/Makefile.am: * plugins/xsettings/Makefile.am: Install in subdirectories 2007-12-17 William Jon McCann * plugins/keyboard/Makefile.am: * plugins/keyboard/modmap-dialog.glade: Add missing glade file. 2007-12-17 William Jon McCann * plugins/font/gsd-font-manager.c: * src/cinnamon-settings-plugins-engine.c: (gnome_settings_plugins_engine_load_file), (gnome_settings_plugins_engine_activate_plugin), (gnome_settings_plugins_engine_deactivate_plugin): Fix an extraneous / in gconf path. Add a dummy var to pad out private data. 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/background/Makefile.am: * plugins/background/background.cinnamon-settings-plugin.desktop.in: * plugins/background/gsd-background-manager.c: (applier_idle), (background_callback), (gsd_background_manager_start), (gsd_background_manager_stop), (gsd_background_manager_set_property), (gsd_background_manager_get_property), (gsd_background_manager_constructor), (gsd_background_manager_dispose), (gsd_background_manager_class_init), (gsd_background_manager_init), (gsd_background_manager_finalize), (gsd_background_manager_new): * plugins/background/gsd-background-manager.h: * plugins/background/gsd-background-plugin.c: (gsd_background_plugin_init), (gsd_background_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_background_plugin_class_init): * plugins/background/gsd-background-plugin.h: Add background plugin. 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/default-editor/default-editor.cinnamon-settings-plugin.deskt op.in: * plugins/keybindings/Makefile.am: * plugins/keybindings/eggaccelerators.c: (is_alt), (is_ctl), (is_modx), (is_ctrl), (is_shft), (is_shift), (is_control), (is_release), (is_meta), (is_super), (is_hyper), (is_keycode), (egg_accelerator_parse_virtual), (egg_virtual_accelerator_name), (egg_keymap_resolve_virtual_modifiers), (egg_keymap_virtualize_modifiers), (reload_modmap), (egg_keymap_get_modmap): * plugins/keybindings/eggaccelerators.h: * plugins/keybindings/gsd-keybindings-manager.c: (get_screens_list), (entry_get_string), (parse_binding), (compare_bindings), (bindings_get_entry), (key_already_used), (grab_key), (do_grab), (binding_register_keys), (screen_exec_display_string), (get_exec_environment), (keybindings_filter), (bindings_callback), (register_config_callback), (gsd_keybindings_manager_start), (gsd_keybindings_manager_stop), (gsd_keybindings_manager_set_property), (gsd_keybindings_manager_get_property), (gsd_keybindings_manager_constructor), (gsd_keybindings_manager_dispose), (gsd_keybindings_manager_class_init), (gsd_keybindings_manager_init), (gsd_keybindings_manager_finalize), (gsd_keybindings_manager_new): * plugins/keybindings/gsd-keybindings-manager.h: * plugins/keybindings/gsd-keybindings-plugin.c: (gsd_keybindings_plugin_init), (gsd_keybindings_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_keybindings_plugin_class_init): * plugins/keybindings/gsd-keybindings-plugin.h: * plugins/keybindings/keybindings.cinnamon-settings-plugin.desktop.in: * plugins/keyboard/keyboard.cinnamon-settings-plugin.desktop.in: * plugins/mouse/mouse.cinnamon-settings-plugin.desktop.in: Add keybindings plugin. 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/mouse/Makefile.am: * plugins/mouse/gsd-locate-pointer.c: (locate_pointer_expose), (setup_window), (create_window), (locate_pointer_timeout), (gsd_locate_pointer): * plugins/mouse/gsd-locate-pointer.h: * plugins/mouse/gsd-mouse-manager.c: (gsd_mouse_manager_stop), (gsd_mouse_manager_set_property), (gsd_mouse_manager_get_property), (gsd_mouse_manager_constructor), (gsd_mouse_manager_dispose), (gsd_mouse_manager_class_init), (supports_xinput_devices), (configure_button_layout), (xinput_device_has_buttons), (set_xinput_devices_left_handed), (set_left_handed), (set_motion_acceleration), (set_motion_threshold), (filter), (set_locate_pointer), (mouse_callback), (register_config_callback), (gsd_mouse_manager_init), (gsd_mouse_manager_start), (gsd_mouse_manager_finalize), (gsd_mouse_manager_new): * plugins/mouse/gsd-mouse-manager.h: * plugins/mouse/gsd-mouse-plugin.c: (gsd_mouse_plugin_init), (gsd_mouse_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_mouse_plugin_class_init): * plugins/mouse/gsd-mouse-plugin.h: * plugins/mouse/mouse.cinnamon-settings-plugin.desktop.in: Add mouse plugin. 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/keyboard/Makefile.am: * plugins/keyboard/delayed-dialog.c: (gsd_delayed_show_dialog), (delayed_show_timeout), (message_filter): * plugins/keyboard/delayed-dialog.h: * plugins/keyboard/gsd-keyboard-manager.c: (xfree86_set_keyboard_autorepeat_rate), (xkb_set_keyboard_autorepeat_rate), (gsd_keyboard_get_hostname_key), (numlock_NumLock_modifier_mask), (numlock_set_xkb_state), (numlock_gconf_state_key), (numlock_get_gconf_state), (numlock_set_gconf_state), (numlock_xkb_callback), (numlock_install_xkb_callback), (apply_settings), (register_config_callback), (gsd_keyboard_manager_start), (gsd_keyboard_manager_stop), (gsd_keyboard_manager_set_property), (gsd_keyboard_manager_get_property), (gsd_keyboard_manager_constructor), (gsd_keyboard_manager_dispose), (gsd_keyboard_manager_class_init), (gsd_keyboard_manager_init), (gsd_keyboard_manager_finalize), (gsd_keyboard_manager_new): * plugins/keyboard/gsd-keyboard-manager.h: * plugins/keyboard/gsd-keyboard-plugin.c: (gsd_keyboard_plugin_init), (gsd_keyboard_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_keyboard_plugin_class_init): * plugins/keyboard/gsd-keyboard-plugin.h: * plugins/keyboard/gsd-keyboard-xkb.c: (gsd_keyboard_log_appender), (activation_error), (apply_settings), (apply_xkb_settings), (gsd_keyboard_xkb_analyze_sysconfig), (gsd_chk_file_list), (gsd_keyboard_xkb_chk_lcl_xmm), (gsd_keyboard_xkb_set_post_activation_callback), (gsd_keyboard_xkb_evt_filter), (register_config_callback), (gsd_keyboard_xkb_init), (gsd_keyboard_xkb_load): * plugins/keyboard/gsd-keyboard-xkb.h: * plugins/keyboard/gsd-xmodmap.c: (check_button_callback), (gsd_load_modmap_files), (response_callback), (get_selected_files_func), (remove_string_from_list), (remove_button_clicked_callback), (load_button_clicked_callback), (gsd_modmap_dialog_call): * plugins/keyboard/gsd-xmodmap.h: * plugins/keyboard/keyboard.cinnamon-settings-plugin.desktop.in: * plugins/xrandr/Makefile.in: Add the keyboard plugin. 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/default-editor/Makefile.am: * plugins/default-editor/default-editor.cinnamon-settings-plugin.deskt op.in: * plugins/default-editor/gsd-default-editor-manager.c: (sync_changes_cb), (register_config_callback), (vfs_change_cb), (gsd_default_editor_manager_start), (gsd_default_editor_manager_stop), (gsd_default_editor_manager_set_property), (gsd_default_editor_manager_get_property), (gsd_default_editor_manager_constructor), (gsd_default_editor_manager_dispose), (gsd_default_editor_manager_class_init), (gsd_default_editor_manager_init), (gsd_default_editor_manager_finalize), (gsd_default_editor_manager_new): * plugins/default-editor/gsd-default-editor-manager.h: * plugins/default-editor/gsd-default-editor-plugin.c: (gsd_default_editor_plugin_init), (gsd_default_editor_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_default_editor_plugin_class_init): * plugins/default-editor/gsd-default-editor-plugin.h: * plugins/font/Makefile: * plugins/font/Makefile.in: Add default editor plugin 2007-12-16 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/font/Makefile: * plugins/font/Makefile.am: * plugins/font/Makefile.in: * plugins/font/delayed-dialog.c: (gnome_settings_delayed_show_dialog), (delayed_show_timeout), (message_filter): * plugins/font/delayed-dialog.h: * plugins/font/font.cinnamon-settings-plugin.desktop.in: * plugins/font/gsd-font-manager.c: (write_all), (child_watch_cb), (spawn_with_input), (load_xcursor_theme), (load_cursor), (gsd_font_manager_start), (gsd_font_manager_stop), (gsd_font_manager_set_property), (gsd_font_manager_get_property), (gsd_font_manager_constructor), (gsd_font_manager_dispose), (gsd_font_manager_class_init), (gsd_font_manager_init), (gsd_font_manager_finalize), (gsd_font_manager_new): * plugins/font/gsd-font-manager.h: * plugins/font/gsd-font-plugin.c: (gsd_font_plugin_init), (gsd_font_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_font_plugin_class_init): * plugins/font/gsd-font-plugin.h: Add font plugin 2007-12-14 William Jon McCann * data/cinnamon-settings-daemon.schemas.in: Add schemas for clipboard and xrandr. 2007-12-14 William Jon McCann * configure.ac: * plugins/Makefile.am: * plugins/clipboard/Makefile.am: * plugins/clipboard/clipboard.cinnamon-settings-plugin.desktop.in: * plugins/clipboard/gsd-clipboard-manager.c: (target_data_ref), (target_data_unref), (conversion_free), (send_selection_notify), (finish_selection_request), (clipboard_bytes_per_item), (save_targets), (find_content_target), (find_content_type), (find_conversion_requestor), (get_property), (receive_incrementally), (send_incrementally), (convert_clipboard_manager), (convert_clipboard_target), (collect_incremental), (convert_clipboard), (clipboard_manager_process_event), (clipboard_manager_event_filter), (clipboard_manager_watch_cb), (gsd_clipboard_manager_start), (gsd_clipboard_manager_stop), (gsd_clipboard_manager_set_property), (gsd_clipboard_manager_get_property), (gsd_clipboard_manager_constructor), (gsd_clipboard_manager_dispose), (gsd_clipboard_manager_class_init), (gsd_clipboard_manager_init), (gsd_clipboard_manager_finalize), (gsd_clipboard_manager_new): * plugins/clipboard/gsd-clipboard-manager.h: * plugins/clipboard/gsd-clipboard-plugin.c: (gsd_clipboard_plugin_init), (gsd_clipboard_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_clipboard_plugin_class_init): * plugins/clipboard/gsd-clipboard-plugin.h: * plugins/clipboard/list.c: (list_foreach), (list_prepend), (list_free), (list_find), (list_remove), (list_length), (list_copy): * plugins/clipboard/list.h: * plugins/clipboard/xutils.c: (init_atoms), (timestamp_predicate), (get_server_time): * plugins/clipboard/xutils.h: Port over the clipboard module. 2007-12-14 William Jon McCann * configure.ac: * plugins/xrdb/Makefile.am: * plugins/xrdb/data/Editres.ad: * plugins/xrdb/data/Emacs.ad: * plugins/xrdb/data/General.ad: * plugins/xrdb/data/Makefile.am: * plugins/xrdb/data/Motif.ad: * plugins/xrdb/data/Tk.ad: * plugins/xrdb/data/Xaw.ad: Add the .ad files. 2007-12-14 William Jon McCann * configure.ac: * plugins/Makefile.am: * plugins/xrandr/Makefile.am: * plugins/xrandr/Makefile.in: * plugins/xrandr/gsd-xrandr-manager.c: (get_rotation), (get_resolution), (get_rate), (find_closest_size), (apply_settings), (gsd_xrandr_manager_start), (gsd_xrandr_manager_stop), (gsd_xrandr_manager_set_property), (gsd_xrandr_manager_get_property), (gsd_xrandr_manager_constructor), (gsd_xrandr_manager_dispose), (gsd_xrandr_manager_class_init), (gsd_xrandr_manager_init), (gsd_xrandr_manager_finalize), (gsd_xrandr_manager_new): * plugins/xrandr/gsd-xrandr-manager.h: * plugins/xrandr/gsd-xrandr-plugin.c: (gsd_xrandr_plugin_init), (gsd_xrandr_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_xrandr_plugin_class_init): * plugins/xrandr/gsd-xrandr-plugin.h: * plugins/xrandr/xrandr.cinnamon-settings-plugin.desktop.in: Add xrandr plugin. 2007-12-14 William Jon McCann * configure.ac: * plugins/Makefile.am: * plugins/dummy/Makefile.am: * plugins/dummy/gsd-dummy-manager.c: (gsd_dummy_manager_start), (gsd_dummy_manager_stop), (gsd_dummy_manager_set_property), (gsd_dummy_manager_get_property), (gsd_dummy_manager_constructor), (gsd_dummy_manager_dispose), (gsd_dummy_manager_class_init), (gsd_dummy_manager_init), (gsd_dummy_manager_finalize), (gsd_dummy_manager_new): * plugins/dummy/gsd-dummy-manager.h: * plugins/dummy/gsd-dummy-plugin.c: (impl_activate), (impl_deactivate), (gsd_dummy_plugin_class_init): * plugins/dummy/gsd-dummy-plugin.h: Build the dummy. 2007-12-14 William Jon McCann * configure.ac: * data/cinnamon-settings-daemon.schemas.in: * plugins/Makefile.am: * plugins/dummy/Makefile.am: * plugins/dummy/dummy.cinnamon-settings-plugin.desktop.in: * plugins/dummy/gsd-dummy-manager.c: (gsd_xrdb_manager_start), (gsd_xrdb_manager_stop), (gsd_xrdb_manager_set_property), (gsd_xrdb_manager_get_property), (gsd_xrdb_manager_constructor), (gsd_xrdb_manager_dispose), (gsd_xrdb_manager_class_init), (gsd_xrdb_manager_init), (gsd_xrdb_manager_finalize), (gsd_xrdb_manager_new): * plugins/dummy/gsd-dummy-manager.h: * plugins/dummy/gsd-dummy-plugin.c: (gsd_dummy_plugin_init), (gsd_dummy_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_dummy_plugin_class_init): * plugins/dummy/gsd-dummy-plugin.h: * plugins/xrdb/Makefile.am: * plugins/xrdb/gsd-xrdb-manager.c: (append_color_define), (color_shade), (append_theme_colors), (scan_ad_directory), (compare_basenames), (scan_for_files), (append_file), (append_xresource_file), (write_all), (child_watch_cb), (spawn_with_input), (apply_settings), (theme_changed), (gsd_xrdb_manager_start), (gsd_xrdb_manager_stop), (gsd_xrdb_manager_set_property), (gsd_xrdb_manager_get_property), (gsd_xrdb_manager_constructor), (gsd_xrdb_manager_dispose), (gsd_xrdb_manager_class_init), (gsd_xrdb_manager_init), (gsd_xrdb_manager_finalize), (gsd_xrdb_manager_new): * plugins/xrdb/gsd-xrdb-manager.h: * plugins/xrdb/gsd-xrdb-plugin.c: (gsd_xrdb_plugin_init), (gsd_xrdb_plugin_finalize), (impl_activate), (impl_deactivate), (gsd_xrdb_plugin_class_init): * plugins/xrdb/gsd-xrdb-plugin.h: * plugins/xrdb/xrdb.cinnamon-settings-plugin.desktop.in: * plugins/xsettings/gnome-xsettings-manager.h: Port over the xrdb module. Also add a skeleton plugin dir. 2007-12-14 William Jon McCann * MAINTAINERS: * configure.ac: * src/main.c: (get_bus_proxy), (acquire_name_on_proxy), (get_session_bus), (bus_register), (main): Grab a name on the session bus. 2007-12-14 William Jon McCann * configure.ac, etc: Initial checkin. Previously lived in gdm module. cinnamon-settings-daemon-6.4.3/NEWS0000664000175000017500000000000014733247605016051 0ustar fabiofabiocinnamon-settings-daemon-6.4.3/COPYING.LIB0000664000175000017500000006350414733247605017034 0ustar fabiofabio GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! cinnamon-settings-daemon-6.4.3/cinnamon-settings-daemon.pot0000664000175000017500000006660014733247605023021 0ustar fabiofabio# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-11-27 09:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: plugins/a11y-settings/csd-a11y-settings-manager.c:265 msgid "Screen reader not found." msgstr "" #: plugins/a11y-settings/csd-a11y-settings-manager.c:266 msgid "Please install the 'orca' package." msgstr "" #: plugins/a11y-settings/csd-a11y-settings-manager.c:273 msgid "Open accessibility settings" msgstr "" #: plugins/automount/csd-automount-manager.c:150 #, c-format msgid "Unable to mount %s" msgstr "" #: plugins/automount/csd-automount-manager.c:278 #, c-format msgid "Unable to open a folder for %s" msgstr "" #: plugins/automount/csd-autorun.c:346 msgid "Ask what to do" msgstr "" #: plugins/automount/csd-autorun.c:352 msgid "Do Nothing" msgstr "" #: plugins/automount/csd-autorun.c:358 msgid "Open Folder" msgstr "" #: plugins/automount/csd-autorun.c:501 #, c-format msgid "Unable to eject %p" msgstr "" #: plugins/automount/csd-autorun.c:503 #, c-format msgid "Unable to unmount %p" msgstr "" #: plugins/automount/csd-autorun.c:710 msgid "You have just inserted an Audio CD." msgstr "" #: plugins/automount/csd-autorun.c:712 msgid "You have just inserted an Audio DVD." msgstr "" #: plugins/automount/csd-autorun.c:714 msgid "You have just inserted a Video DVD." msgstr "" #: plugins/automount/csd-autorun.c:716 msgid "You have just inserted a Video CD." msgstr "" #: plugins/automount/csd-autorun.c:718 msgid "You have just inserted a Super Video CD." msgstr "" #: plugins/automount/csd-autorun.c:720 msgid "You have just inserted a blank CD." msgstr "" #: plugins/automount/csd-autorun.c:722 msgid "You have just inserted a blank DVD." msgstr "" #: plugins/automount/csd-autorun.c:724 msgid "You have just inserted a blank Blu-Ray disc." msgstr "" #: plugins/automount/csd-autorun.c:726 msgid "You have just inserted a blank HD DVD." msgstr "" #: plugins/automount/csd-autorun.c:728 msgid "You have just inserted a Photo CD." msgstr "" #: plugins/automount/csd-autorun.c:730 msgid "You have just inserted a Picture CD." msgstr "" #: plugins/automount/csd-autorun.c:732 msgid "You have just inserted a medium with digital photos." msgstr "" #: plugins/automount/csd-autorun.c:734 msgid "You have just inserted a digital audio player." msgstr "" #: plugins/automount/csd-autorun.c:736 msgid "" "You have just inserted a medium with software intended to be automatically " "started." msgstr "" #: plugins/automount/csd-autorun.c:739 msgid "You have just inserted a medium." msgstr "" #: plugins/automount/csd-autorun.c:741 msgid "Choose what application to launch." msgstr "" #: plugins/automount/csd-autorun.c:751 #, c-format msgid "" "Select how to open \"%s\" and whether to perform this action in the future " "for other media of type \"%s\"." msgstr "" #: plugins/automount/csd-autorun.c:779 msgid "_Always perform this action" msgstr "" #: plugins/automount/csd-autorun.c:788 msgid "_Cancel" msgstr "" #: plugins/automount/csd-autorun.c:789 msgid "_Ok" msgstr "" #: plugins/automount/csd-autorun.c:794 msgid "_Eject" msgstr "" #: plugins/automount/csd-autorun.c:797 msgid "_Unmount" msgstr "" #: plugins/color/csd-color-calibrate.c:138 msgid "Color" msgstr "" #: plugins/color/csd-color-calibrate.c:144 msgid "Recalibrate now" msgstr "" #: plugins/color/csd-color-calibrate.c:186 msgid "Recalibration required" msgstr "" #: plugins/color/csd-color-calibrate.c:198 #, c-format msgid "The display '%s' should be recalibrated soon." msgstr "" #: plugins/color/csd-color-calibrate.c:207 #, c-format msgid "The printer '%s' should be recalibrated soon." msgstr "" #: plugins/color/csd-color-calibrate.c:345 #: plugins/color/csd-color-calibrate.c:361 msgid "Cinnamon Settings Daemon Color Plugin" msgstr "" #: plugins/color/csd-color-calibrate.c:347 msgid "Color calibration device added" msgstr "" #: plugins/color/csd-color-calibrate.c:363 msgid "Color calibration device removed" msgstr "" #: plugins/housekeeping/csd-disk-space.c:334 #, c-format msgid "Low Disk Space on \"%s\"" msgstr "" #: plugins/housekeeping/csd-disk-space.c:336 #, c-format msgid "" "The volume \"%s\" has only %s disk space remaining. You may free up some " "space by emptying the trash." msgstr "" #: plugins/housekeeping/csd-disk-space.c:340 #: plugins/housekeeping/csd-ldsm-dialog.c:78 #, c-format msgid "The volume \"%s\" has only %s disk space remaining." msgstr "" #: plugins/housekeeping/csd-disk-space.c:345 #: plugins/housekeeping/csd-ldsm-dialog.c:202 msgid "Low Disk Space" msgstr "" #: plugins/housekeeping/csd-disk-space.c:347 #, c-format msgid "" "This computer has only %s disk space remaining. You may free up some space " "by emptying the trash." msgstr "" #: plugins/housekeeping/csd-disk-space.c:350 #: plugins/housekeeping/csd-ldsm-dialog.c:81 #, c-format msgid "This computer has only %s disk space remaining." msgstr "" #: plugins/housekeeping/csd-disk-space.c:365 msgid "Disk space" msgstr "" #: plugins/housekeeping/csd-disk-space.c:372 msgid "Examine" msgstr "" #: plugins/housekeeping/csd-disk-space.c:380 #: plugins/housekeeping/csd-ldsm-dialog.c:434 msgid "Empty Trash" msgstr "" #: plugins/housekeeping/csd-disk-space.c:387 #: plugins/housekeeping/csd-ldsm-dialog.c:449 msgid "Ignore" msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:63 msgid "Don't show any warnings again for this file system" msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:65 msgid "Don't show any warnings again" msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:97 msgid "" "You can free up disk space by emptying the Trash, removing unused programs " "or files, or moving files to another disk or partition." msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:100 msgid "" "You can free up disk space by removing unused programs or files, or by " "moving files to another disk or partition." msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:105 msgid "" "You can free up disk space by emptying the Trash, removing unused programs " "or files, or moving files to an external disk." msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:108 msgid "" "You can free up disk space by removing unused programs or files, or by " "moving files to an external disk." msgstr "" #: plugins/housekeeping/csd-ldsm-dialog.c:442 msgid "Examine..." msgstr "" #: plugins/keyboard/csd-keyboard-xkb.c:87 #, c-format msgid "" "Error activating XKB configuration.\n" "There can be various reasons for that.\n" "\n" "If you report this situation as a bug, include the results of\n" " %s\n" " %s\n" " %s\n" " %s" msgstr "" #: plugins/keyboard/csd-keyboard-xkb.c:256 msgid "_Layouts" msgstr "" #: plugins/keyboard/csd-keyboard-xkb.c:262 msgid "Show _Keyboard Layout..." msgstr "" #: plugins/keyboard/csd-keyboard-xkb.c:269 msgid "Region and Language Settings" msgstr "" #: plugins/power/csd-power-manager.c:1118 msgid "UPS Discharging" msgstr "" #: plugins/power/csd-power-manager.c:1123 #, c-format msgid "%s of UPS backup power remaining" msgstr "" #: plugins/power/csd-power-manager.c:1144 #: plugins/power/csd-power-manager.c:1364 #: plugins/power/csd-power-manager.c:1542 #: plugins/power/csd-power-manager.c:1691 msgid "Power" msgstr "" #: plugins/power/csd-power-manager.c:1276 msgid "Battery low" msgstr "" #: plugins/power/csd-power-manager.c:1279 msgid "Laptop battery low" msgstr "" #: plugins/power/csd-power-manager.c:1286 #, c-format msgid "Approximately %s remaining (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1291 msgid "UPS low" msgstr "" #: plugins/power/csd-power-manager.c:1297 #, c-format msgid "Approximately %s of remaining UPS backup power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1302 #: plugins/power/csd-power-manager.c:1467 msgid "Mouse battery low" msgstr "" #: plugins/power/csd-power-manager.c:1305 msgid "Wireless mouse is low in power" msgstr "" #: plugins/power/csd-power-manager.c:1309 #: plugins/power/csd-power-manager.c:1474 msgid "Keyboard battery low" msgstr "" #: plugins/power/csd-power-manager.c:1312 msgid "Wireless keyboard is low in power" msgstr "" #: plugins/power/csd-power-manager.c:1316 #: plugins/power/csd-power-manager.c:1482 msgid "PDA battery low" msgstr "" #: plugins/power/csd-power-manager.c:1319 #, c-format msgid "PDA is low in power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1323 #: plugins/power/csd-power-manager.c:1492 #: plugins/power/csd-power-manager.c:1502 msgid "Cell phone battery low" msgstr "" #: plugins/power/csd-power-manager.c:1326 #, c-format msgid "Cell phone is low in power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1330 msgid "Media player battery low" msgstr "" #: plugins/power/csd-power-manager.c:1333 #, c-format msgid "Media player is low in power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1337 #: plugins/power/csd-power-manager.c:1511 msgid "Tablet battery low" msgstr "" #: plugins/power/csd-power-manager.c:1340 #, c-format msgid "Tablet is low in power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1344 #: plugins/power/csd-power-manager.c:1520 msgid "Attached computer battery low" msgstr "" #: plugins/power/csd-power-manager.c:1347 #, c-format msgid "Attached computer is low in power (%.0f%%)" msgstr "" #: plugins/power/csd-power-manager.c:1381 msgid "Battery is low" msgstr "" #: plugins/power/csd-power-manager.c:1423 msgid "Battery critically low" msgstr "" #: plugins/power/csd-power-manager.c:1426 #: plugins/power/csd-power-manager.c:1607 msgid "Laptop battery critically low" msgstr "" #: plugins/power/csd-power-manager.c:1435 msgid "Plug in your AC adapter to avoid losing data." msgstr "" #: plugins/power/csd-power-manager.c:1439 msgid "Computer will suspend very soon unless it is plugged in." msgstr "" #: plugins/power/csd-power-manager.c:1443 msgid "Computer will hibernate very soon unless it is plugged in." msgstr "" #: plugins/power/csd-power-manager.c:1447 msgid "Computer will shutdown very soon unless it is plugged in." msgstr "" #: plugins/power/csd-power-manager.c:1455 #: plugins/power/csd-power-manager.c:1643 msgid "UPS critically low" msgstr "" #: plugins/power/csd-power-manager.c:1461 #, c-format msgid "" "Approximately %s of remaining UPS power (%.0f%%). Restore AC power to your " "computer to avoid losing data." msgstr "" #: plugins/power/csd-power-manager.c:1470 msgid "" "Wireless mouse is very low in power. This device will soon stop functioning " "if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1477 msgid "" "Wireless keyboard is very low in power. This device will soon stop " "functioning if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1485 #, c-format msgid "" "PDA is very low in power (%.0f%%). This device will soon stop functioning if " "not charged." msgstr "" #: plugins/power/csd-power-manager.c:1495 #, c-format msgid "" "Cell phone is very low in power (%.0f%%). This device will soon stop " "functioning if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1505 #, c-format msgid "" "Media player is very low in power (%.0f%%). This device will soon stop " "functioning if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1514 #, c-format msgid "" "Tablet is very low in power (%.0f%%). This device will soon stop functioning " "if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1523 #, c-format msgid "" "Attached computer is very low in power (%.0f%%). The device will soon " "shutdown if not charged." msgstr "" #: plugins/power/csd-power-manager.c:1560 #: plugins/power/csd-power-manager.c:1570 #: plugins/power/csd-power-manager.c:1706 msgid "Battery is critically low" msgstr "" #: plugins/power/csd-power-manager.c:1615 msgid "" "The battery is below the critical level and this computer will power-off when the battery becomes completely empty." msgstr "" #: plugins/power/csd-power-manager.c:1621 msgid "" "The battery is below the critical level and this computer is about to " "suspend.\n" "NOTE: A small amount of power is required to keep your computer in a " "suspended state." msgstr "" #: plugins/power/csd-power-manager.c:1628 msgid "" "The battery is below the critical level and this computer is about to " "hibernate." msgstr "" #: plugins/power/csd-power-manager.c:1633 msgid "" "The battery is below the critical level and this computer is about to " "shutdown." msgstr "" #: plugins/power/csd-power-manager.c:1651 msgid "" "UPS is below the critical level and this computer will power-off when " "the UPS becomes completely empty." msgstr "" #: plugins/power/csd-power-manager.c:1657 msgid "" "UPS is below the critical level and this computer is about to hibernate." msgstr "" #: plugins/power/csd-power-manager.c:1662 msgid "UPS is below the critical level and this computer is about to shutdown." msgstr "" #: plugins/power/csd-power-manager.c:2262 msgid "Lid has been opened" msgstr "" #: plugins/power/csd-power-manager.c:2407 msgid "Lid has been closed" msgstr "" #: plugins/power/gpm-common.c:47 msgid "Unknown time" msgstr "" #: plugins/power/gpm-common.c:52 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:62 #, c-format msgid "%i hour" msgid_plural "%i hours" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:68 #, c-format msgid "%i %s %i %s" msgstr "" #: plugins/power/gpm-common.c:69 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:70 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:358 #, c-format msgid "provides %s laptop runtime" msgstr "" #: plugins/power/gpm-common.c:369 #, c-format msgid "%s %s remaining" msgstr "" #: plugins/power/gpm-common.c:390 plugins/power/gpm-common.c:407 #, c-format msgid "%s %s until charged" msgstr "" #: plugins/power/gpm-common.c:397 #, c-format msgid "provides %s battery runtime" msgstr "" #: plugins/power/gpm-common.c:488 msgid "Product:" msgstr "" #: plugins/power/gpm-common.c:492 plugins/power/gpm-common.c:495 #: plugins/power/gpm-common.c:498 plugins/power/gpm-common.c:501 msgid "Status:" msgstr "" #: plugins/power/gpm-common.c:492 msgid "Missing" msgstr "" #: plugins/power/gpm-common.c:495 plugins/power/gpm-common.c:780 msgid "Charged" msgstr "" #: plugins/power/gpm-common.c:498 plugins/power/gpm-common.c:768 msgid "Charging" msgstr "" #: plugins/power/gpm-common.c:501 plugins/power/gpm-common.c:772 msgid "Discharging" msgstr "" #: plugins/power/gpm-common.c:506 msgid "Percentage charge:" msgstr "" #: plugins/power/gpm-common.c:510 msgid "Vendor:" msgstr "" #: plugins/power/gpm-common.c:515 msgid "Technology:" msgstr "" #: plugins/power/gpm-common.c:519 msgid "Serial number:" msgstr "" #: plugins/power/gpm-common.c:523 msgid "Model:" msgstr "" #: plugins/power/gpm-common.c:528 msgid "Charge time:" msgstr "" #: plugins/power/gpm-common.c:534 msgid "Discharge time:" msgstr "" #: plugins/power/gpm-common.c:541 msgid "Excellent" msgstr "" #: plugins/power/gpm-common.c:543 msgid "Good" msgstr "" #: plugins/power/gpm-common.c:545 msgid "Fair" msgstr "" #: plugins/power/gpm-common.c:547 msgid "Poor" msgstr "" #: plugins/power/gpm-common.c:551 msgid "Capacity:" msgstr "" #: plugins/power/gpm-common.c:557 plugins/power/gpm-common.c:582 msgid "Current charge:" msgstr "" #: plugins/power/gpm-common.c:563 msgid "Last full charge:" msgstr "" #: plugins/power/gpm-common.c:569 plugins/power/gpm-common.c:587 msgid "Design charge:" msgstr "" #: plugins/power/gpm-common.c:574 msgid "Charge rate:" msgstr "" #: plugins/power/gpm-common.c:606 msgid "AC adapter" msgid_plural "AC adapters" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:610 msgid "Laptop battery" msgid_plural "Laptop batteries" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:614 msgid "UPS" msgid_plural "UPSs" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:618 msgid "Monitor" msgid_plural "Monitors" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:622 msgid "Mouse" msgid_plural "Mice" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:626 msgid "Keyboard" msgid_plural "Keyboards" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:630 msgid "PDA" msgid_plural "PDAs" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:634 msgid "Cell phone" msgid_plural "Cell phones" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:638 msgid "Media player" msgid_plural "Media players" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:642 msgid "Tablet" msgid_plural "Tablets" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:646 msgid "Computer" msgid_plural "Computers" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:651 msgid "Game controller" msgid_plural "Game controllers" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:655 msgid "Unknown device" msgid_plural "Unknown devices" msgstr[0] "" msgstr[1] "" #: plugins/power/gpm-common.c:726 msgid "Lithium Ion" msgstr "" #: plugins/power/gpm-common.c:730 msgid "Lithium Polymer" msgstr "" #: plugins/power/gpm-common.c:734 msgid "Lithium Iron Phosphate" msgstr "" #: plugins/power/gpm-common.c:738 msgid "Lead acid" msgstr "" #: plugins/power/gpm-common.c:742 msgid "Nickel Cadmium" msgstr "" #: plugins/power/gpm-common.c:746 msgid "Nickel metal hydride" msgstr "" #: plugins/power/gpm-common.c:750 msgid "Unknown technology" msgstr "" #: plugins/power/gpm-common.c:776 msgid "Empty" msgstr "" #: plugins/power/gpm-common.c:784 msgid "Waiting to charge" msgstr "" #: plugins/power/gpm-common.c:788 msgid "Waiting to discharge" msgstr "" #: plugins/power/gpm-common.c:792 msgid "Unknown" msgstr "" #: plugins/power/gpm-common.c:821 msgid "Laptop battery not present" msgstr "" #: plugins/power/gpm-common.c:825 msgid "Laptop battery is charging" msgstr "" #: plugins/power/gpm-common.c:829 msgid "Laptop battery is discharging" msgstr "" #: plugins/power/gpm-common.c:833 msgid "Laptop battery is empty" msgstr "" #: plugins/power/gpm-common.c:837 msgid "Laptop battery is charged" msgstr "" #: plugins/power/gpm-common.c:841 msgid "Laptop battery is waiting to charge" msgstr "" #: plugins/power/gpm-common.c:845 msgid "Laptop battery is waiting to discharge" msgstr "" #: plugins/power/gpm-common.c:854 msgid "UPS is charging" msgstr "" #: plugins/power/gpm-common.c:858 msgid "UPS is discharging" msgstr "" #: plugins/power/gpm-common.c:862 msgid "UPS is empty" msgstr "" #: plugins/power/gpm-common.c:866 msgid "UPS is charged" msgstr "" #: plugins/power/gpm-common.c:875 msgid "Mouse is charging" msgstr "" #: plugins/power/gpm-common.c:879 msgid "Mouse is discharging" msgstr "" #: plugins/power/gpm-common.c:883 msgid "Mouse is empty" msgstr "" #: plugins/power/gpm-common.c:887 msgid "Mouse is charged" msgstr "" #: plugins/power/gpm-common.c:896 msgid "Keyboard is charging" msgstr "" #: plugins/power/gpm-common.c:900 msgid "Keyboard is discharging" msgstr "" #: plugins/power/gpm-common.c:904 msgid "Keyboard is empty" msgstr "" #: plugins/power/gpm-common.c:908 msgid "Keyboard is charged" msgstr "" #: plugins/power/gpm-common.c:917 msgid "PDA is charging" msgstr "" #: plugins/power/gpm-common.c:921 msgid "PDA is discharging" msgstr "" #: plugins/power/gpm-common.c:925 msgid "PDA is empty" msgstr "" #: plugins/power/gpm-common.c:929 msgid "PDA is charged" msgstr "" #: plugins/power/gpm-common.c:938 msgid "Cell phone is charging" msgstr "" #: plugins/power/gpm-common.c:942 msgid "Cell phone is discharging" msgstr "" #: plugins/power/gpm-common.c:946 msgid "Cell phone is empty" msgstr "" #: plugins/power/gpm-common.c:950 msgid "Cell phone is charged" msgstr "" #: plugins/power/gpm-common.c:959 msgid "Media player is charging" msgstr "" #: plugins/power/gpm-common.c:963 msgid "Media player is discharging" msgstr "" #: plugins/power/gpm-common.c:967 msgid "Media player is empty" msgstr "" #: plugins/power/gpm-common.c:971 msgid "Media player is charged" msgstr "" #: plugins/power/gpm-common.c:980 msgid "Tablet is charging" msgstr "" #: plugins/power/gpm-common.c:984 msgid "Tablet is discharging" msgstr "" #: plugins/power/gpm-common.c:988 msgid "Tablet is empty" msgstr "" #: plugins/power/gpm-common.c:992 msgid "Tablet is charged" msgstr "" #: plugins/power/gpm-common.c:1001 msgid "Computer is charging" msgstr "" #: plugins/power/gpm-common.c:1005 msgid "Computer is discharging" msgstr "" #: plugins/power/gpm-common.c:1009 msgid "Computer is empty" msgstr "" #: plugins/power/gpm-common.c:1013 msgid "Computer is charged" msgstr "" #: plugins/power/gpm-common.c:1023 msgid "Game controller is charging" msgstr "" #: plugins/power/gpm-common.c:1027 msgid "Game controller is discharging" msgstr "" #: plugins/power/gpm-common.c:1031 msgid "Game controller is empty" msgstr "" #: plugins/power/gpm-common.c:1035 msgid "Game controller is charged" msgstr "" #: plugins/print-notifications/csd-printer.c:890 msgid "Configuring new printer" msgstr "" #: plugins/print-notifications/csd-printer.c:892 msgid "Please wait..." msgstr "" #: plugins/print-notifications/csd-printer.c:919 msgid "Missing printer driver" msgstr "" #: plugins/print-notifications/csd-printer.c:928 #, c-format msgid "No printer driver for %s." msgstr "" #: plugins/print-notifications/csd-printer.c:933 msgid "No driver for this printer." msgstr "" #: plugins/print-notifications/csd-printer.c:1031 #: plugins/print-notifications/csd-print-notifications-manager.c:273 #: plugins/print-notifications/csd-print-notifications-manager.c:846 #: plugins/print-notifications/csd-print-notifications-manager.c:936 #: plugins/print-notifications/csd-print-notifications-manager.c:979 msgid "Printers" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:439 #, c-format msgid "Printer '%s' is low on toner." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:443 #, c-format msgid "Printer '%s' has no toner left." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:447 #, c-format msgid "Printer '%s' may not be connected." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:451 #, c-format msgid "The cover is open on printer '%s'." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:455 #, c-format msgid "There is a missing print filter for printer '%s'." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:460 #, c-format msgid "The door is open on printer '%s'." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:464 #, c-format msgid "Printer '%s' is low on a marker supply." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:468 #, c-format msgid "Printer '%s' is out of a marker supply." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:472 #, c-format msgid "Printer '%s' is low on paper." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:476 #, c-format msgid "Printer '%s' is out of paper." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:480 #, c-format msgid "Printer '%s' is currently off-line." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:484 #, c-format msgid "There is a problem on printer '%s'." msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:532 msgid "Toner low" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:534 msgid "Toner empty" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:536 msgid "Not connected?" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:538 msgid "Cover open" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:540 msgid "Printer configuration error" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:542 msgid "Door open" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:544 msgid "Marker supply low" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:546 msgid "Out of a marker supply" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:548 msgid "Paper low" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:550 msgid "Out of paper" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:552 msgid "Printer off-line" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:554 #: plugins/print-notifications/csd-print-notifications-manager.c:922 msgid "Printer error" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:603 msgid "Printer added" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:624 #: plugins/print-notifications/csd-print-notifications-manager.c:662 msgid "Printing stopped" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:626 #: plugins/print-notifications/csd-print-notifications-manager.c:632 #: plugins/print-notifications/csd-print-notifications-manager.c:638 #: plugins/print-notifications/csd-print-notifications-manager.c:644 #: plugins/print-notifications/csd-print-notifications-manager.c:656 #: plugins/print-notifications/csd-print-notifications-manager.c:664 #: plugins/print-notifications/csd-print-notifications-manager.c:672 #: plugins/print-notifications/csd-print-notifications-manager.c:680 #: plugins/print-notifications/csd-print-notifications-manager.c:688 #: plugins/print-notifications/csd-print-notifications-manager.c:701 #, c-format msgid "'%s' on %s" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:630 #: plugins/print-notifications/csd-print-notifications-manager.c:670 msgid "Printing canceled" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:636 #: plugins/print-notifications/csd-print-notifications-manager.c:678 msgid "Printing aborted" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:642 #: plugins/print-notifications/csd-print-notifications-manager.c:686 msgid "Printing completed" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:654 #: plugins/print-notifications/csd-print-notifications-manager.c:699 msgid "Printing" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:916 msgid "Printer report" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:919 msgid "Printer warning" msgstr "" #: plugins/print-notifications/csd-print-notifications-manager.c:929 #, c-format msgid "Printer '%s': '%s'." msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:530 msgid "received error or hang up from event source" msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:664 msgid "NSS security system could not be initialized" msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:792 msgid "no suitable smartcard driver could be found" msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:806 #, c-format msgid "smartcard driver '%s' could not be loaded" msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:878 #, c-format msgid "could not watch for incoming card events - %s" msgstr "" #: plugins/smartcard/csd-smartcard-manager.c:1276 msgid "encountered unexpected error while waiting for smartcard events" msgstr "" cinnamon-settings-daemon-6.4.3/meson_options.txt0000664000175000017500000000250014733247605021016 0ustar fabiofabiooption( 'dbus_service_dir', type: 'string', value: '', description: 'Used to specify the dbus service dir' ) option( 'dbus_system_dir', type: 'string', value: '', description: 'Used to specify the dbus system dir' ) option( 'use_polkit', type: 'feature', value: 'auto', description: 'Whether to use polkit in the build' ) option( 'use_logind', type: 'feature', value: 'auto', description: 'Whether to use logind in the build' ) option( 'use_gudev', type: 'feature', value: 'enabled', description: 'Whether GUdev support should be enabled (not optional on Linux platforms)' ) option( 'use_cups', type: 'feature', value: 'enabled', description: 'Whether cups (and therefore the print notifications plugin) support should be enabled' ) option( 'use_smartcard', type: 'feature', value: 'enabled', description: 'Set to false to disable smartcard support' ) option( 'use_color', type: 'feature', value: 'enabled', description: 'Whether the color plugin should be enabled' ) option( 'use_wacom', type: 'feature', value: 'auto', description: 'Whether the wacom plugin should be enabled' ) option( 'enable_debug', type: 'boolean', value: false, description: 'Show additional build warnings' ) cinnamon-settings-daemon-6.4.3/po/0000775000175000017500000000000014733247605016002 5ustar fabiofabiocinnamon-settings-daemon-6.4.3/po/POTFILES.in0000664000175000017500000000510514733247605017560 0ustar fabiofabio# Files with translatable strings. # Please keep this file in alphabetical order. data/org.cinnamon.settings-daemon.peripherals.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.color.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.housekeeping.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.power.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.xrandr.gschema.xml.in.in data/org.cinnamon.settings-daemon.plugins.xsettings.gschema.xml.in.in [type: gettext/ini]plugins/a11y-keyboard/a11y-keyboard.cinnamon-settings-plugin.in plugins/a11y-keyboard/csd-a11y-keyboard-manager.c plugins/a11y-keyboard/csd-a11y-preferences-dialog.c [type: gettext/glade]plugins/a11y-keyboard/csd-a11y-preferences-dialog.ui [type: gettext/ini]plugins/a11y-settings/a11y-settings.cinnamon-settings-plugin.in [type: gettext/ini]plugins/automount/automount.cinnamon-settings-plugin.in plugins/automount/csd-automount-manager.c plugins/automount/csd-automount-plugin.c plugins/automount/csd-autorun.c [type: gettext/ini]plugins/background/background.cinnamon-settings-plugin.in [type: gettext/ini]plugins/clipboard/clipboard.cinnamon-settings-plugin.in [type: gettext/ini]plugins/color/color.cinnamon-settings-plugin.in plugins/color/csd-color-manager.c [type: gettext/ini]plugins/dummy/dummy.cinnamon-settings-plugin.in plugins/housekeeping/csd-disk-space.c plugins/housekeeping/csd-ldsm-dialog.c plugins/keyboard/csd-keyboard-manager.c [type: gettext/ini]plugins/keyboard/keyboard.cinnamon-settings-plugin.in plugins/media-keys/cut-n-paste/gvc-mixer-control.c plugins/media-keys/csd-media-keys-manager.c [type: gettext/ini]plugins/media-keys/media-keys.cinnamon-settings-plugin.in plugins/mouse/csd-mouse-manager.c [type: gettext/ini]plugins/mouse/mouse.cinnamon-settings-plugin.in plugins/power/gpm-common.c plugins/power/csd-power-manager.c plugins/power/org.cinnamon.settings-daemon.plugins.power.policy.in.in [type: gettext/ini]plugins/power/power.cinnamon-settings-plugin.in plugins/print-notifications/csd-printer.c plugins/print-notifications/csd-print-notifications-manager.c [type: gettext/ini]plugins/print-notifications/print-notifications.cinnamon-settings-plugin.in plugins/smartcard/csd-smartcard.c plugins/smartcard/csd-smartcard-manager.c plugins/xrandr/csd-xrandr-manager.c [type: gettext/ini]plugins/xrandr/xrandr.cinnamon-settings-plugin.in plugins/xsettings/csd-xsettings-manager.c [type: gettext/ini]plugins/xsettings/xsettings.cinnamon-settings-plugin.in cinnamon-settings-daemon-6.4.3/po/POTFILES.skip0000664000175000017500000000154714733247605020126 0ustar fabiofabio# Files with translatable strings to skip. # Please keep this file in alphabetical order. # data/org.cinnamon.settings-daemon.peripherals.gschema.xml.in data/org.cinnamon.settings-daemon.peripherals.wacom.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.color.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.housekeeping.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.media-keys.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.power.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.updates.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.xrandr.gschema.xml.in data/org.cinnamon.settings-daemon.plugins.xsettings.gschema.xml.in plugins/power/org.cinnamon.settings-daemon.plugins.power.policy.in plugins/wacom/org.cinnamon.settings-daemon.plugins.wacom.policy.in cinnamon-settings-daemon-6.4.3/po/Makefile.in.in0000664000175000017500000001575614733247605020472 0ustar fabiofabio# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # Copyright (C) 2004-2008 Rodney Dawes # # This file may be copied and used freely without restrictions. It may # be used in projects which are not available under a GNU Public License, # but which still want to provide support for the GNU gettext functionality. # # - Modified by Owen Taylor to use GETTEXT_PACKAGE # instead of PACKAGE and to look for po2tbl in ./ not in intl/ # # - Modified by jacob berkman to install # Makefile.in.in and po2tbl.sed.in for use with glib-gettextize # # - Modified by Rodney Dawes for use with intltool # # We have the following line for use by intltoolize: # INTLTOOL_MAKEFILE GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ datarootdir = @datarootdir@ libdir = @libdir@ localedir = @localedir@ subdir = po install_sh = @install_sh@ # Automake >= 1.8 provides @mkdir_p@. # Until it can be supposed, use the safe fallback: mkdir_p = $(install_sh) -d INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot ALL_LINGUAS = @ALL_LINGUAS@ PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi) USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi) USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) DISTFILES = Makefile.in.in POTFILES.in $(POFILES) EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS POTFILES = \ # This comment gets stripped out CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) .SUFFIXES: .SUFFIXES: .po .pox .gmo .mo .msg .cat AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V)) INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY)) INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@; .po.pox: $(MAKE) $(GETTEXT_PACKAGE).pot $(MSGMERGE) $* $(GETTEXT_PACKAGE).pot -o $*.pox .po.mo: $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $< .po.gmo: $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && gencat $@ $*.msg all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: $(GETTEXT_PACKAGE).pot: $(POTFILES) $(GENPOT) install: install-data install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ dir=$(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $$dir; \ if test -r $$lang.gmo; then \ $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ else \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $(srcdir)/$$lang.gmo as" \ "$$dir/$(GETTEXT_PACKAGE).mo"; \ fi; \ if test -r $$lang.gmo.m; then \ $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ if test -r $(srcdir)/$$lang.gmo.m ; then \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $(srcdir)/$$lang.gmo.m as" \ "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ true; \ fi; \ fi; \ done # Empty stubs to satisfy archaic automake needs dvi info ctags tags CTAGS TAGS ID: # Define this as empty until I found a useful application. install-exec installcheck: uninstall: linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ done check: all $(GETTEXT_PACKAGE).pot rm -f missing notexist srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m if [ -r missing -o -r notexist ]; then \ exit 1; \ fi mostlyclean: rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp rm -f .intltool-merge-cache clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES stamp-it rm -f *.mo *.msg *.cat *.cat.m *.gmo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f Makefile.in.in distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(DISTFILES) dists="$(DISTFILES)"; \ extra_dists="$(EXTRA_DISTFILES)"; \ for file in $$extra_dists; do \ test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ done; \ for file in $$dists; do \ test -f $$file || file="$(srcdir)/$$file"; \ ln $$file $(distdir) 2> /dev/null \ || cp -p $$file $(distdir); \ done update-po: Makefile $(MAKE) $(GETTEXT_PACKAGE).pot tmpdir=`pwd`; \ linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ echo "$$lang:"; \ result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ if $$result; then \ if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.gmo failed!"; \ rm -f $$tmpdir/$$lang.new.po; \ fi; \ done Makefile POTFILES: stamp-it @if test ! -f $@; then \ rm -f stamp-it; \ $(MAKE) stamp-it; \ fi stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cinnamon-settings-daemon-6.4.3/po/LINGUAS0000664000175000017500000000000014733247605017015 0ustar fabiofabio