Adding upstream version 48.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
d8950f2d0b
commit
18b565039d
371 changed files with 405983 additions and 0 deletions
120
.gitignore
vendored
Normal file
120
.gitignore
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
aclocal.m4
|
||||||
|
autom4te.cache
|
||||||
|
compile
|
||||||
|
config.guess
|
||||||
|
config.h*
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
config.sub
|
||||||
|
configure
|
||||||
|
depcomp
|
||||||
|
INSTALL
|
||||||
|
install-sh
|
||||||
|
intltool-*
|
||||||
|
libtool
|
||||||
|
ltmain.sh
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
Makefile.in.in
|
||||||
|
missing
|
||||||
|
mkinstalldirs
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.gmo
|
||||||
|
*~
|
||||||
|
man/gnome-settings-daemon.1
|
||||||
|
po/POTFILES
|
||||||
|
po/stamp-it
|
||||||
|
po/.intltool-merge-cache
|
||||||
|
stamp-h1
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
gnome-settings-daemon/gnome-settings-client.h
|
||||||
|
gnome-settings-daemon/gnome-settings-daemon
|
||||||
|
gnome-settings-daemon/gnome-settings-manager-glue.h
|
||||||
|
gnome-settings-daemon/gnome-settings-daemon-localeexec
|
||||||
|
gnome-settings-daemon/gsd-screen-saver-glue.c
|
||||||
|
gnome-settings-daemon/gsd-screen-saver-glue.h
|
||||||
|
gnome-settings-daemon/gsd-session-manager-glue.c
|
||||||
|
gnome-settings-daemon/gsd-session-manager-glue.h
|
||||||
|
gnome-settings-daemon/gsd-shell-glue.c
|
||||||
|
gnome-settings-daemon/gsd-shell-glue.h
|
||||||
|
data/*.pc
|
||||||
|
data/*.xml
|
||||||
|
data/*.xml.in
|
||||||
|
data/*.valid
|
||||||
|
data/gnome-settings-daemon.desktop
|
||||||
|
data/gnome-settings-daemon.desktop.in
|
||||||
|
data/50-accessibility.xml
|
||||||
|
data/org.gnome.SettingsDaemon.service
|
||||||
|
*.gnome-settings-plugin
|
||||||
|
plugins/a11y-keyboard/test-a11y-preferences-dialog
|
||||||
|
plugins/a11y-keyboard/gsd-test-a11y-keyboard
|
||||||
|
plugins/a11y-settings/gsd-test-a11y-settings
|
||||||
|
plugins/background/test-background
|
||||||
|
plugins/common/gsd-common-enums.c
|
||||||
|
plugins/common/gsd-common-enums.h
|
||||||
|
plugins/common/gsd-test-input-helper
|
||||||
|
plugins/common/test-egg-key-parsing
|
||||||
|
plugins/datetime/gsd-test-datetime
|
||||||
|
plugins/datetime/geoclue.c
|
||||||
|
plugins/datetime/geoclue.h
|
||||||
|
plugins/datetime/timedated.c
|
||||||
|
plugins/datetime/timedated.h
|
||||||
|
plugins/housekeeping/gsd-disk-space-test
|
||||||
|
plugins/housekeeping/gsd-empty-trash-test
|
||||||
|
plugins/housekeeping/gsd-purge-temp-test
|
||||||
|
plugins/housekeeping/gsd-test-housekeeping
|
||||||
|
plugins/keyboard/gsd-input-sources-switcher
|
||||||
|
plugins/keyboard/gsd-test-keyboard
|
||||||
|
plugins/media-keys/gsd-marshal.c
|
||||||
|
plugins/media-keys/gsd-marshal.h
|
||||||
|
plugins/media-keys/gsd-media-keys-manager-glue.h
|
||||||
|
plugins/media-keys/gsd-test-media-keys
|
||||||
|
plugins/media-keys/shell-key-grabber.c
|
||||||
|
plugins/media-keys/shell-key-grabber.h
|
||||||
|
plugins/media-keys/test-media-keys
|
||||||
|
plugins/media-keys/test-media-window
|
||||||
|
plugins/smartcard/gsd-smartcard-enum-types.c
|
||||||
|
plugins/smartcard/gsd-smartcard-enum-types.h
|
||||||
|
plugins/smartcard/gsd-smartcard.h
|
||||||
|
plugins/smartcard/gsd-test-smartcard
|
||||||
|
plugins/smartcard/org.gnome.Smartcard.c
|
||||||
|
plugins/smartcard/org.gnome.Smartcard.h
|
||||||
|
plugins/smartcard/org.gnome.ScreenSaver.c
|
||||||
|
plugins/smartcard/org.gnome.ScreenSaver.h
|
||||||
|
plugins/smartcard/org.gnome.SessionManager.c
|
||||||
|
plugins/smartcard/org.gnome.SessionManager.h
|
||||||
|
plugins/mouse/gsd-test-mouse
|
||||||
|
plugins/power/gsd-backlight-helper
|
||||||
|
plugins/power/gsd-power-enums-update
|
||||||
|
plugins/power/gsd-power-enums.c
|
||||||
|
plugins/power/gsd-power-enums.h
|
||||||
|
plugins/power/gsd-test-power
|
||||||
|
plugins/power/org.gnome.settings-daemon.plugins.power.policy
|
||||||
|
plugins/power/org.gnome.settings-daemon.plugins.power.policy.in
|
||||||
|
plugins/print-notifications/gsd-printer
|
||||||
|
plugins/print-notifications/gsd-test-print-notifications
|
||||||
|
plugins/remote-display/gsd-test-remote-display
|
||||||
|
plugins/rfkill/gsd-test-rfkill
|
||||||
|
plugins/screensaver-proxy/gsd-test-screensaver-proxy
|
||||||
|
plugins/sharing/gsd-test-sharing
|
||||||
|
plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.c
|
||||||
|
plugins/smartcard/org.gnome.SettingsDaemon.Smartcard.h
|
||||||
|
plugins/sound/gsd-test-sound
|
||||||
|
plugins/updates/gsd-test-updates
|
||||||
|
plugins/wacom/gsd-list-wacom
|
||||||
|
plugins/wacom/gsd-test-wacom
|
||||||
|
plugins/wacom/gsd-test-wacom-osd
|
||||||
|
plugins/wacom/gsd-wacom-led-helper
|
||||||
|
plugins/wacom/gsd-wacom-oled-helper
|
||||||
|
plugins/wacom/gsd-wacom-resources.c
|
||||||
|
plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy
|
||||||
|
plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in
|
||||||
|
plugins/xsettings/gsd-test-xsettings
|
||||||
|
plugins/xsettings/test-gtk-modules
|
||||||
|
plugins/xsettings/test-wm-button-layout-translations
|
||||||
|
tests/shiftkey
|
||||||
|
test-driver
|
323
.gitlab-ci.yml
Normal file
323
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
include:
|
||||||
|
- remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml'
|
||||||
|
- component: gitlab.gnome.org/GNOME/citemplates/release-service@master
|
||||||
|
inputs:
|
||||||
|
job-stage: "deploy"
|
||||||
|
dist-job-name: "dist"
|
||||||
|
tarball-artifact-path: "build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
FDO_DISTRIBUTION_VERSION: latest
|
||||||
|
FDO_DISTRIBUTION_TAG: "x86_64-2024-08-30.1"
|
||||||
|
FDO_UPSTREAM_REPO: GNOME/gnome-settings-daemon
|
||||||
|
# Expiry sets fdo.expires on the image
|
||||||
|
FEDORA_IMAGE: "$CI_REGISTRY/$FDO_UPSTREAM_REPO/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG"
|
||||||
|
FDO_EXPIRES_AFTER: 8w
|
||||||
|
FEDORA_DEPENDENCIES: >
|
||||||
|
@c-development
|
||||||
|
alsa-lib-devel
|
||||||
|
colord-devel
|
||||||
|
compiler-rt
|
||||||
|
cups-devel
|
||||||
|
fontconfig-devel
|
||||||
|
gcr-devel
|
||||||
|
geoclue2-devel geocode-glib-devel
|
||||||
|
gettext
|
||||||
|
git
|
||||||
|
glib2-devel
|
||||||
|
gnome-desktop3-devel
|
||||||
|
gnome-session
|
||||||
|
gobject-introspection
|
||||||
|
gobject-introspection-devel
|
||||||
|
gsettings-desktop-schemas-devel
|
||||||
|
gtk3-devel
|
||||||
|
lcms2-devel
|
||||||
|
lcov gcovr clang libasan libubsan libtsan
|
||||||
|
libcanberra-devel
|
||||||
|
libgtop2-devel
|
||||||
|
libgudev-devel
|
||||||
|
libgweather4-devel
|
||||||
|
libnotify-devel
|
||||||
|
librsvg2-devel
|
||||||
|
libwacom-devel
|
||||||
|
libX11-devel
|
||||||
|
libXi-devel
|
||||||
|
libXtst-devel
|
||||||
|
libXfixes-devel
|
||||||
|
llvm
|
||||||
|
mesa-dri-drivers
|
||||||
|
meson
|
||||||
|
ModemManager-glib-devel
|
||||||
|
NetworkManager-libnm-devel
|
||||||
|
nss-devel
|
||||||
|
perl-interpreter
|
||||||
|
polkit-devel
|
||||||
|
pulseaudio-libs-devel
|
||||||
|
python3-gobject python3-dbusmock
|
||||||
|
umockdev
|
||||||
|
upower-devel
|
||||||
|
wayland-devel
|
||||||
|
which
|
||||||
|
xorg-x11-drv-wacom-devel
|
||||||
|
xorg-x11-server-Xvfb
|
||||||
|
xorg-x11-server-Xwayland
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- prepare
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- manual
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
.Log files: &log_files [./*.log, _build/meson-logs/]
|
||||||
|
|
||||||
|
.Build logs: &save_build_logs
|
||||||
|
artifacts:
|
||||||
|
name: log
|
||||||
|
when: always
|
||||||
|
paths: *log_files
|
||||||
|
|
||||||
|
.Git Untracked files: &save_untracked_files
|
||||||
|
artifacts:
|
||||||
|
name: untracked
|
||||||
|
when: always
|
||||||
|
paths:
|
||||||
|
- ./*
|
||||||
|
expire_in: 3h30min
|
||||||
|
|
||||||
|
.Show Info: &environment_information
|
||||||
|
build-aux/ci/ci-helper.sh "INFO" &&
|
||||||
|
build-aux/ci/ci-helper.sh "GIT_INFO"
|
||||||
|
|
||||||
|
.Build procedure: &build_procedure
|
||||||
|
echo "== Building ==" &&
|
||||||
|
rm -rf _build/ &&
|
||||||
|
meson setup --werror . _build ${BUILD_OPTS} &&
|
||||||
|
ninja -C _build 2>&1 | tee compilation.log
|
||||||
|
|
||||||
|
.Run Tests: &run_tests
|
||||||
|
echo "== Testing ==" &&
|
||||||
|
mkdir -m 1777 /tmp/.X11-unix
|
||||||
|
meson test -C _build --verbose --no-stdsplit
|
||||||
|
|
||||||
|
##
|
||||||
|
# Stage: Prepare
|
||||||
|
##
|
||||||
|
build-fedora-container@x86_64:
|
||||||
|
extends:
|
||||||
|
- .fdo.container-build@fedora@x86_64
|
||||||
|
stage: prepare
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||||
|
FDO_DISTRIBUTION_PACKAGES: $FEDORA_DEPENDENCIES
|
||||||
|
FDO_DISTRIBUTION_EXEC: |
|
||||||
|
./.gitlab-ci/install-meson-project.sh \
|
||||||
|
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \
|
||||||
|
master
|
||||||
|
|
||||||
|
dnf install -y 'dnf-command(builddep)'
|
||||||
|
dnf builddep -y pipewire
|
||||||
|
dnf builddep -y mutter
|
||||||
|
|
||||||
|
./.gitlab-ci/install-meson-project.sh \
|
||||||
|
https://gitlab.gnome.org/GNOME/glib.git \
|
||||||
|
2.81.1
|
||||||
|
|
||||||
|
./.gitlab-ci/install-meson-project.sh \
|
||||||
|
https://gitlab.freedesktop.org/pipewire/pipewire.git \
|
||||||
|
1.2.3
|
||||||
|
|
||||||
|
./.gitlab-ci/install-meson-project.sh \
|
||||||
|
https://gitlab.gnome.org/GNOME/mutter.git \
|
||||||
|
main
|
||||||
|
|
||||||
|
##
|
||||||
|
# Stage: Build
|
||||||
|
#
|
||||||
|
# Checks if GNOME Settings Daemon is properly building and installing. This is the
|
||||||
|
# most important stage of the CI, and no MR should ever be merged if it breaks
|
||||||
|
# any of them.
|
||||||
|
##
|
||||||
|
build:
|
||||||
|
<<: *save_untracked_files
|
||||||
|
stage: build
|
||||||
|
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
image:
|
||||||
|
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||||
|
needs:
|
||||||
|
- job: build-fedora-container@x86_64
|
||||||
|
artifacts: false
|
||||||
|
|
||||||
|
script:
|
||||||
|
- *environment_information
|
||||||
|
- *build_procedure
|
||||||
|
|
||||||
|
- echo "== Installing =="
|
||||||
|
- ninja -C _build install
|
||||||
|
|
||||||
|
- echo "== Report =="
|
||||||
|
- build-aux/ci/ci-helper.sh "WARNINGS"
|
||||||
|
|
||||||
|
# Save all but git-related files
|
||||||
|
- rm -rf .git .gitignore .gitmodules
|
||||||
|
|
||||||
|
except:
|
||||||
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
|
||||||
|
##
|
||||||
|
# Stage: Test
|
||||||
|
#
|
||||||
|
# Runs the unit tests.
|
||||||
|
##
|
||||||
|
test:
|
||||||
|
<<: *save_build_logs
|
||||||
|
stage: test
|
||||||
|
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
image:
|
||||||
|
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
|
||||||
|
script:
|
||||||
|
- *environment_information
|
||||||
|
|
||||||
|
- |
|
||||||
|
if [[ -n "${CI_COMMIT_TAG}" ]]; then
|
||||||
|
*run_tests
|
||||||
|
|
||||||
|
echo "== Distro Test =="
|
||||||
|
mkdir -m 1777 /tmp/.X11-unix
|
||||||
|
ninja dist -C _build
|
||||||
|
else
|
||||||
|
echo "== Testing =="
|
||||||
|
mkdir -m 1777 /tmp/.X11-unix
|
||||||
|
meson test -C _build --verbose --no-stdsplit
|
||||||
|
fi
|
||||||
|
|
||||||
|
except:
|
||||||
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
- $CI_COMMIT_TITLE =~ /^Update.*translation$/
|
||||||
|
|
||||||
|
dist:
|
||||||
|
stage: test
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
needs:
|
||||||
|
- build-fedora-container@x86_64
|
||||||
|
script:
|
||||||
|
- mkdir -m 1777 /tmp/.X11-unix
|
||||||
|
- meson setup build
|
||||||
|
- meson compile -C build
|
||||||
|
- meson dist -C build
|
||||||
|
artifacts:
|
||||||
|
expose_as: 'Tarball'
|
||||||
|
paths:
|
||||||
|
- build/meson-dist/
|
||||||
|
|
||||||
|
# Runs the coverage test.
|
||||||
|
coverage:
|
||||||
|
<<: *save_build_logs
|
||||||
|
stage: test
|
||||||
|
# Appears to be broken on Fedora Rawhide as of 2018-02-05
|
||||||
|
allow_failure: true
|
||||||
|
variables:
|
||||||
|
BUILD_OPTS: "-Db_coverage=true"
|
||||||
|
coverage: '/^Lines:.\d+.\d+.(\d+\.\d+\%)/'
|
||||||
|
only:
|
||||||
|
- master@GNOME/gnome-settings-daemon
|
||||||
|
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
image:
|
||||||
|
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||||
|
needs:
|
||||||
|
- job: build-fedora-container@x86_64
|
||||||
|
artifacts: false
|
||||||
|
|
||||||
|
script:
|
||||||
|
- *environment_information
|
||||||
|
- *build_procedure
|
||||||
|
- *run_tests
|
||||||
|
|
||||||
|
- ninja -C _build coverage-html
|
||||||
|
|
||||||
|
# Parse the report to get the coverage result
|
||||||
|
- |
|
||||||
|
echo == Coverage ==
|
||||||
|
sed -e 's/<[^>]*>//g' _build/meson-logs/coveragereport/index.html | tr -d ' \t' | grep -A3 -P '^Lines:$' | tr '\n' ' '; echo
|
||||||
|
|
||||||
|
##
|
||||||
|
# Stage: deploy
|
||||||
|
#
|
||||||
|
# Deploys and publishes artifacts
|
||||||
|
##
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
# Don't error in case coverage failed
|
||||||
|
allow_failure: true
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
image:
|
||||||
|
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||||
|
needs:
|
||||||
|
- coverage
|
||||||
|
script:
|
||||||
|
- mv _build/meson-logs/coveragereport/ public/
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
only:
|
||||||
|
- master@GNOME/gnome-settings-daemon
|
||||||
|
|
||||||
|
##
|
||||||
|
# Stage: Manual
|
||||||
|
#
|
||||||
|
# Runs the sanitizers [address, thread, undefined, and memory].
|
||||||
|
##
|
||||||
|
.sanitizer: &sanitizer
|
||||||
|
<<: *save_build_logs
|
||||||
|
stage: manual
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- *environment_information
|
||||||
|
- *build_procedure
|
||||||
|
- *run_tests
|
||||||
|
extends:
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
image:
|
||||||
|
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||||
|
|
||||||
|
except:
|
||||||
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
- $CI_COMMIT_TITLE =~ /^Update.*translation$/
|
||||||
|
|
||||||
|
asan:
|
||||||
|
<<: *sanitizer
|
||||||
|
# ASAN requires debugging capabilities
|
||||||
|
tags: [ asan ]
|
||||||
|
variables:
|
||||||
|
BUILD_OPTS: "-Db_sanitize=address"
|
||||||
|
|
||||||
|
tsan:
|
||||||
|
<<: *sanitizer
|
||||||
|
variables:
|
||||||
|
BUILD_OPTS: "-Db_sanitize=thread"
|
||||||
|
|
||||||
|
ubsan:
|
||||||
|
<<: *sanitizer
|
||||||
|
variables:
|
||||||
|
BUILD_OPTS: "-Db_sanitize=undefined"
|
||||||
|
|
||||||
|
msan:
|
||||||
|
<<: *sanitizer
|
||||||
|
variables:
|
||||||
|
BUILD_OPTS: "-Db_sanitize=memory -Db_lundef=false"
|
||||||
|
CC: "clang"
|
103
.gitlab-ci/install-meson-project.sh
Executable file
103
.gitlab-ci/install-meson-project.sh
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<-EOF
|
||||||
|
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
|
||||||
|
|
||||||
|
Check out and install a meson project
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-Dkey=val Option to pass on to meson
|
||||||
|
--subdir Build subdirectory instead of whole project
|
||||||
|
--prepare Script to run before build
|
||||||
|
--libdir Setup the project with a different libdir
|
||||||
|
--destdir Install the project to an additional destdir
|
||||||
|
|
||||||
|
-h, --help Display this help
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMP=$(getopt \
|
||||||
|
--name=$(basename $0) \
|
||||||
|
--options='D:h' \
|
||||||
|
--longoptions='subdir:' \
|
||||||
|
--longoptions='prepare:' \
|
||||||
|
--longoptions='libdir:' \
|
||||||
|
--longoptions='destdir:' \
|
||||||
|
--longoptions='help' \
|
||||||
|
-- "$@")
|
||||||
|
|
||||||
|
eval set -- "$TEMP"
|
||||||
|
unset TEMP
|
||||||
|
|
||||||
|
MESON_OPTIONS=()
|
||||||
|
SUBDIR=.
|
||||||
|
PREPARE=:
|
||||||
|
DESTDIR=""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-D)
|
||||||
|
MESON_OPTIONS+=( -D$2 )
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--subdir)
|
||||||
|
SUBDIR=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--prepare)
|
||||||
|
PREPARE=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--libdir)
|
||||||
|
MESON_OPTIONS+=( --libdir=$2 )
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
--destdir)
|
||||||
|
DESTDIR=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -lt 2 ]]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO_URL="$1"
|
||||||
|
COMMIT="$2"
|
||||||
|
|
||||||
|
CHECKOUT_DIR=$(mktemp --directory)
|
||||||
|
trap "rm -rf $CHECKOUT_DIR" EXIT
|
||||||
|
|
||||||
|
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
|
||||||
|
|
||||||
|
pushd "$CHECKOUT_DIR/$SUBDIR"
|
||||||
|
sh -c "$PREPARE"
|
||||||
|
meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}"
|
||||||
|
|
||||||
|
# Install it to an additional directory e.g., system extension directory
|
||||||
|
if [ -n "${DESTDIR}" ]; then
|
||||||
|
sudo meson install -C _build --destdir=$DESTDIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo meson install -C _build
|
||||||
|
popd
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "subprojects/gvc"]
|
||||||
|
path = subprojects/gvc
|
||||||
|
url = https://gitlab.gnome.org/GNOME/libgnome-volume-control.git
|
2
AUTHORS
Normal file
2
AUTHORS
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Jonathan Blandford <jrb@redhat.com>
|
||||||
|
William Jon McCann <mccann@jhu.edu>
|
340
COPYING
Normal file
340
COPYING
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 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.
|
504
COPYING.LIB
Normal file
504
COPYING.LIB
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
1
MAINTAINERS
Normal file
1
MAINTAINERS
Normal file
|
@ -0,0 +1 @@
|
||||||
|
See gnome-settings-daemon.doap
|
65
README
Normal file
65
README
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
Introduction to GNOME Settings Daemon
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
The GNOME Settings Daemon is responsible for setting various parameters of a
|
||||||
|
GNOME Session and the applications that run under it.
|
||||||
|
|
||||||
|
This package is known to build and work properly using an LFS-9.0 platform.
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Required:
|
||||||
|
|
||||||
|
* colord-1.4.4 (http://www.linuxfromscratch.org/blfs/view/systemd/general/colord.html)
|
||||||
|
* Fontconfig-2.13.1 (http://www.linuxfromscratch.org/blfs/view/systemd/general/fontconfig.html)
|
||||||
|
* GeoClue-2.5.3 (http://www.linuxfromscratch.org/blfs/view/systemd/basicnet/geoclue2.html)
|
||||||
|
* geocode-glib-3.26.1 (http://www.linuxfromscratch.org/blfs/view/systemd/gnome/geocode-glib.html)
|
||||||
|
* gnome-desktop-3.32.2 (http://www.linuxfromscratch.org/blfs/view/systemd/gnome/gnome-desktop.html)
|
||||||
|
* Little CMS-2.9 (http://www.linuxfromscratch.org/blfs/view/systemd/general/lcms2.html)
|
||||||
|
* libcanberra-0.30 (http://www.linuxfromscratch.org/blfs/view/systemd/multimedia/libcanberra.html)
|
||||||
|
* libgweather-3.32.2 (http://www.linuxfromscratch.org/blfs/view/systemd/gnome/libgweather.html)
|
||||||
|
* libnotify-0.7.8 (http://www.linuxfromscratch.org/blfs/view/systemd/x/libnotify.html)
|
||||||
|
* librsvg-2.44.14 (http://www.linuxfromscratch.org/blfs/view/systemd/general/librsvg.html)
|
||||||
|
* libwacom-0.29 (http://www.linuxfromscratch.org/blfs/view/systemd/general/libwacom.html)
|
||||||
|
* PulseAudio-12.2 (http://www.linuxfromscratch.org/blfs/view/systemd/multimedia/pulseaudio.html)
|
||||||
|
* Systemd-241 (http://www.linuxfromscratch.org/blfs/view/systemd/general/systemd.html)
|
||||||
|
* UPower-0.99.10 (http://www.linuxfromscratch.org/blfs/view/systemd/general/upower.html)
|
||||||
|
* Xorg Wacom Driver-0.37.0 (http://www.linuxfromscratch.org/blfs/view/systemd/x/x7driver.html#xorg-wacom-driver)
|
||||||
|
|
||||||
|
Recommended:
|
||||||
|
|
||||||
|
* ALSA-1.1.9 (http://www.linuxfromscratch.org/blfs/view/systemd/multimedia/alsa.html)
|
||||||
|
* Cups-2.2.12 (http://www.linuxfromscratch.org/blfs/view/systemd/pst/cups.html)
|
||||||
|
* NetworkManager-1.20.0 (http://www.linuxfromscratch.org/blfs/view/systemd/basicnet/networkmanager.html)
|
||||||
|
* NSS-3.45 (http://www.linuxfromscratch.org/blfs/view/systemd/postlfs/nss.html)
|
||||||
|
* Wayland-1.17.0 (http://www.linuxfromscratch.org/blfs/view/systemd/general/wayland.html)
|
||||||
|
|
||||||
|
Optional
|
||||||
|
|
||||||
|
* python-dbusmock (https://github.com/martinpitt/python-dbusmock)
|
||||||
|
* umockdev (https://github.com/martinpitt/umockdev)
|
||||||
|
|
||||||
|
|
||||||
|
Build
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Install GNOME Settings Daemon by running the following commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir build &&
|
||||||
|
cd build &&
|
||||||
|
|
||||||
|
meson --prefix=/usr --sysconfdir=/etc .. &&
|
||||||
|
ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
To check the results, execute: `ninja test`. Note that you must have
|
||||||
|
python-dbusmock installed in order for the tests to complete successfully. Some
|
||||||
|
tests in the "power" testsuite may fail depending on the init system in use.
|
||||||
|
|
||||||
|
Now, as the root user:
|
||||||
|
```bash
|
||||||
|
ninja install
|
||||||
|
```
|
61
build-aux/ci/ci-helper.sh
Executable file
61
build-aux/ci/ci-helper.sh
Executable file
|
@ -0,0 +1,61 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
function do_print_labels(){
|
||||||
|
|
||||||
|
if [[ -n "${1}" ]]; then
|
||||||
|
label_len=${#1}
|
||||||
|
span=$(((54 - $label_len) / 2))
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "= ======================================================== ="
|
||||||
|
printf "%s %${span}s %s %${span}s %s\n" "=" "" "$1" "" "="
|
||||||
|
echo "= ======================================================== ="
|
||||||
|
else
|
||||||
|
echo "= ========================= Done ========================= ="
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_show_info(){
|
||||||
|
|
||||||
|
local compiler=gcc
|
||||||
|
|
||||||
|
echo -n "Processors: "; grep -c ^processor /proc/cpuinfo
|
||||||
|
grep ^MemTotal /proc/meminfo
|
||||||
|
id; uname -a
|
||||||
|
printenv
|
||||||
|
echo '-----------------------------------------'
|
||||||
|
cat /etc/*-release
|
||||||
|
echo '-----------------------------------------'
|
||||||
|
|
||||||
|
if [[ ! -z $CC ]]; then
|
||||||
|
compiler=$CC
|
||||||
|
fi
|
||||||
|
echo 'Compiler version'
|
||||||
|
$compiler --version
|
||||||
|
echo '-----------------------------------------'
|
||||||
|
$compiler -dM -E -x c /dev/null
|
||||||
|
echo '-----------------------------------------'
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_check_warnings(){
|
||||||
|
|
||||||
|
cat compilation.log | grep "warning:" | awk '{total+=1}END{print "Total number of warnings: "total}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------- -----------
|
||||||
|
if [[ $1 == "INFO" ]]; then
|
||||||
|
do_print_labels 'Build environment '
|
||||||
|
do_show_info
|
||||||
|
do_print_labels
|
||||||
|
|
||||||
|
elif [[ $1 == "GIT_INFO" ]]; then
|
||||||
|
do_print_labels 'Commit'
|
||||||
|
git log --pretty=format:"%h %cd %s" -1; echo
|
||||||
|
do_print_labels
|
||||||
|
|
||||||
|
elif [[ $1 == "WARNINGS" ]]; then
|
||||||
|
do_print_labels 'Warning Report '
|
||||||
|
do_check_warnings
|
||||||
|
do_print_labels
|
||||||
|
fi
|
39
data/gnome-settings-daemon.convert
Normal file
39
data/gnome-settings-daemon.convert
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
[org.gnome.settings-daemon.peripherals.smartcard]
|
||||||
|
removal-action = /desktop/gnome/peripherals/smartcard/removal_action
|
||||||
|
|
||||||
|
[org.gnome.settings-daemon.plugins.housekeeping]
|
||||||
|
free-percent-notify = /apps/gnome_settings_daemon/plugins/housekeeping/free_percent_notify
|
||||||
|
free-percent-notify-again = /apps/gnome_settings_daemon/plugins/housekeeping/free_percent_notify_again
|
||||||
|
free-size-gb-no-notify = /apps/gnome_settings_daemon/plugins/housekeeping/free_size_gb_no_notify
|
||||||
|
ignore-paths = /apps/gnome_settings_daemon/plugins/housekeeping/ignore_paths
|
||||||
|
min-notify-period = /apps/gnome_settings_daemon/plugins/housekeeping/min_notify_period
|
||||||
|
|
||||||
|
[org.gnome.settings-daemon.plugins.media-keys]
|
||||||
|
calculator = /apps/gnome_settings_daemon/keybindings/calculator
|
||||||
|
email = /apps/gnome_settings_daemon/keybindings/email
|
||||||
|
eject = /apps/gnome_settings_daemon/keybindings/eject
|
||||||
|
help = /apps/gnome_settings_daemon/keybindings/help
|
||||||
|
home = /apps/gnome_settings_daemon/keybindings/home
|
||||||
|
logout = /apps/gnome_settings_daemon/keybindings/power
|
||||||
|
media = /apps/gnome_settings_daemon/keybindings/media
|
||||||
|
next = /apps/gnome_settings_daemon/keybindings/next
|
||||||
|
pause = /apps/gnome_settings_daemon/keybindings/pause
|
||||||
|
play = /apps/gnome_settings_daemon/keybindings/play
|
||||||
|
previous = /apps/gnome_settings_daemon/keybindings/previous
|
||||||
|
screensaver = /apps/gnome_settings_daemon/keybindings/screensaver
|
||||||
|
search = /apps/gnome_settings_daemon/keybindings/search
|
||||||
|
stop = /apps/gnome_settings_daemon/keybindings/stop
|
||||||
|
touchpad = /apps/gnome_settings_daemon/keybindings/touchpad
|
||||||
|
volume-down = /apps/gnome_settings_daemon/keybindings/volume_down
|
||||||
|
volume-mute = /apps/gnome_settings_daemon/keybindings/volume_mute
|
||||||
|
volume-up = /apps/gnome_settings_daemon/keybindings/volume_up
|
||||||
|
www = /apps/gnome_settings_daemon/keybindings/www
|
||||||
|
|
||||||
|
[org.gnome.settings-daemon.peripherals.mouse]
|
||||||
|
double-click = /desktop/gnome/peripherals/mouse/double_click
|
||||||
|
drag-threshold = /desktop/gnome/peripherals/mouse/drag_threshold
|
||||||
|
|
||||||
|
[org.gnome.settings-daemon.plugins.xsettings]
|
||||||
|
antialiasing = /desktop/gnome/font_rendering/antialiasing
|
||||||
|
hinting = /desktop/gnome/font_rendering/hinting
|
||||||
|
rgba-order = /desktop/gnome/font_rendering/rgba_order
|
127
data/gnome-settings-daemon/gsd-enums.h
Normal file
127
data/gnome-settings-daemon/gsd-enums.h
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2010 Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* 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 <hadess@hadess.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __gsd_enums_h__
|
||||||
|
#define __gsd_enums_h__
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_FONT_ANTIALIASING_MODE_NONE,
|
||||||
|
GSD_FONT_ANTIALIASING_MODE_GRAYSCALE,
|
||||||
|
GSD_FONT_ANTIALIASING_MODE_RGBA
|
||||||
|
} GsdFontAntialiasingMode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_FONT_HINTING_NONE,
|
||||||
|
GSD_FONT_HINTING_SLIGHT,
|
||||||
|
GSD_FONT_HINTING_MEDIUM,
|
||||||
|
GSD_FONT_HINTING_FULL
|
||||||
|
} GsdFontHinting;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_FONT_RGBA_ORDER_RGBA,
|
||||||
|
GSD_FONT_RGBA_ORDER_RGB,
|
||||||
|
GSD_FONT_RGBA_ORDER_BGR,
|
||||||
|
GSD_FONT_RGBA_ORDER_VRGB,
|
||||||
|
GSD_FONT_RGBA_ORDER_VBGR
|
||||||
|
} GsdFontRgbaOrder;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_SMARTCARD_REMOVAL_ACTION_NONE,
|
||||||
|
GSD_SMARTCARD_REMOVAL_ACTION_LOCK_SCREEN,
|
||||||
|
GSD_SMARTCARD_REMOVAL_ACTION_FORCE_LOGOUT
|
||||||
|
} GsdSmartcardRemovalAction;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_TOUCHPAD_SCROLL_METHOD_DISABLED,
|
||||||
|
GSD_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING,
|
||||||
|
GSD_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING
|
||||||
|
} GsdTouchpadScrollMethod;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_BELL_MODE_ON,
|
||||||
|
GSD_BELL_MODE_OFF,
|
||||||
|
GSD_BELL_MODE_CUSTOM
|
||||||
|
} GsdBellMode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_TOUCHPAD_HANDEDNESS_RIGHT,
|
||||||
|
GSD_TOUCHPAD_HANDEDNESS_LEFT,
|
||||||
|
GSD_TOUCHPAD_HANDEDNESS_MOUSE
|
||||||
|
} GsdTouchpadHandedness;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_WACOM_ROTATION_NONE,
|
||||||
|
GSD_WACOM_ROTATION_CW,
|
||||||
|
GSD_WACOM_ROTATION_CCW,
|
||||||
|
GSD_WACOM_ROTATION_HALF
|
||||||
|
} GsdWacomRotation;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_WACOM_ACTION_TYPE_NONE,
|
||||||
|
GSD_WACOM_ACTION_TYPE_CUSTOM,
|
||||||
|
GSD_WACOM_ACTION_TYPE_SWITCH_MONITOR,
|
||||||
|
GSD_WACOM_ACTION_TYPE_HELP
|
||||||
|
} GsdWacomActionType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_POWER_ACTION_BLANK,
|
||||||
|
GSD_POWER_ACTION_SUSPEND,
|
||||||
|
GSD_POWER_ACTION_SHUTDOWN,
|
||||||
|
GSD_POWER_ACTION_HIBERNATE,
|
||||||
|
GSD_POWER_ACTION_INTERACTIVE,
|
||||||
|
GSD_POWER_ACTION_NOTHING,
|
||||||
|
GSD_POWER_ACTION_LOGOUT
|
||||||
|
} GsdPowerActionType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_POWER_BUTTON_ACTION_NOTHING,
|
||||||
|
GSD_POWER_BUTTON_ACTION_SUSPEND,
|
||||||
|
GSD_POWER_BUTTON_ACTION_HIBERNATE,
|
||||||
|
GSD_POWER_BUTTON_ACTION_INTERACTIVE
|
||||||
|
} GsdPowerButtonActionType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_UPDATE_TYPE_ALL,
|
||||||
|
GSD_UPDATE_TYPE_SECURITY,
|
||||||
|
GSD_UPDATE_TYPE_NONE
|
||||||
|
} GsdUpdateType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSD_NUM_LOCK_STATE_UNKNOWN,
|
||||||
|
GSD_NUM_LOCK_STATE_ON,
|
||||||
|
GSD_NUM_LOCK_STATE_OFF
|
||||||
|
} GsdNumLockState;
|
||||||
|
|
||||||
|
#endif /* __gsd_enums_h__ */
|
76
data/meson.build
Normal file
76
data/meson.build
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
schemas = [
|
||||||
|
'org.gnome.settings-daemon.global-shortcuts.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.peripherals.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.peripherals.wacom.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.color.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.housekeeping.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.media-keys.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.power.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.sharing.gschema.xml',
|
||||||
|
'org.gnome.settings-daemon.plugins.xsettings.gschema.xml'
|
||||||
|
]
|
||||||
|
|
||||||
|
if enable_wwan
|
||||||
|
schemas += 'org.gnome.settings-daemon.plugins.wwan.gschema.xml'
|
||||||
|
endif
|
||||||
|
|
||||||
|
schema_conf = configuration_data()
|
||||||
|
schema_conf.set('GETTEXT_PACKAGE', meson.project_name())
|
||||||
|
|
||||||
|
schemas_xml = []
|
||||||
|
foreach schema: schemas
|
||||||
|
schemas_xml += [configure_file(
|
||||||
|
input: schema + '.in',
|
||||||
|
output: schema,
|
||||||
|
configuration: schema_conf,
|
||||||
|
install_dir: gsd_schemadir
|
||||||
|
)]
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
enums_header = files('gnome-settings-daemon' / 'gsd-enums.h')
|
||||||
|
|
||||||
|
mkenums = gnome.mkenums(
|
||||||
|
'org.gnome.settings-daemon.enums.xml',
|
||||||
|
sources: enums_header,
|
||||||
|
comments: '<!-- @comment@ -->',
|
||||||
|
fhead: '<schemalist>',
|
||||||
|
vhead: ' <@type@ id="org.gnome.settings-daemon.@EnumName@">',
|
||||||
|
vprod: ' <value nick="@valuenick@" value="@valuenum@"/>',
|
||||||
|
vtail: ' </@type@>',
|
||||||
|
ftail: '</schemalist>',
|
||||||
|
install_header: true,
|
||||||
|
install_dir: gsd_schemadir
|
||||||
|
)
|
||||||
|
|
||||||
|
install_data(
|
||||||
|
enums_header,
|
||||||
|
install_dir: join_paths(gsd_pkgincludedir, meson.project_name())
|
||||||
|
)
|
||||||
|
|
||||||
|
install_data(
|
||||||
|
'gnome-settings-daemon.convert',
|
||||||
|
install_dir: join_paths(gsd_datadir, 'GConf', 'gsettings')
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg.generate(
|
||||||
|
version: gsd_version,
|
||||||
|
name: meson.project_name(),
|
||||||
|
description: meson.project_name() + ' specific enumerations',
|
||||||
|
filebase: meson.project_name(),
|
||||||
|
subdirs: gsd_api_name
|
||||||
|
)
|
||||||
|
|
||||||
|
gsd_enums_dep = declare_dependency(
|
||||||
|
include_directories: include_directories('.')
|
||||||
|
)
|
||||||
|
|
||||||
|
meson.override_dependency(meson.project_name(), gsd_enums_dep)
|
||||||
|
|
||||||
|
# for unit tests - gnome.compile_schemas() only looks in srcdir
|
||||||
|
custom_target('compile-schemas',
|
||||||
|
input: schemas_xml,
|
||||||
|
depends: mkenums,
|
||||||
|
output: 'gschemas.compiled',
|
||||||
|
command: [find_program('glib-compile-schemas'), meson.current_build_dir()],
|
||||||
|
build_by_default: true)
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.global-shortcuts" path="/org/gnome/settings-daemon/global-shortcuts/">
|
||||||
|
<key name="applications" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>Applications</summary>
|
||||||
|
<description>Applications that have defined global shortcuts</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.global-shortcuts.application">
|
||||||
|
<key name="shortcuts" type="a(sa{sv})">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>Shortcuts</summary>
|
||||||
|
<description>Keyboard shortcut definitions</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
152
data/org.gnome.settings-daemon.peripherals.gschema.xml.in
Normal file
152
data/org.gnome.settings-daemon.peripherals.gschema.xml.in
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals" path="/org/gnome/settings-daemon/peripherals/">
|
||||||
|
<child name="smartcard" schema="org.gnome.settings-daemon.peripherals.smartcard"/>
|
||||||
|
<child name="keyboard" schema="org.gnome.settings-daemon.peripherals.keyboard"/>
|
||||||
|
<child name="touchscreen" schema="org.gnome.settings-daemon.peripherals.touchscreen"/>
|
||||||
|
</schema>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.smartcard" path="/org/gnome/settings-daemon/peripherals/smartcard/">
|
||||||
|
<key name="removal-action" enum="org.gnome.settings-daemon.GsdSmartcardRemovalAction">
|
||||||
|
<default>'none'</default>
|
||||||
|
<summary>Smartcard removal action</summary>
|
||||||
|
<description>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.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.keyboard" path="/org/gnome/settings-daemon/peripherals/keyboard/">
|
||||||
|
<key name="click" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
</key>
|
||||||
|
<key name="click-volume" type="i">
|
||||||
|
<default>0</default>
|
||||||
|
</key>
|
||||||
|
<key name="bell-mode" enum="org.gnome.settings-daemon.GsdBellMode">
|
||||||
|
<default>'on'</default>
|
||||||
|
<description>Possible values are “on”, “off”, and “custom”.</description>
|
||||||
|
</key>
|
||||||
|
<key name="bell-pitch" type="i">
|
||||||
|
<default>400</default>
|
||||||
|
</key>
|
||||||
|
<key name="bell-duration" type="i">
|
||||||
|
<default>100</default>
|
||||||
|
</key>
|
||||||
|
<key name="bell-custom-file" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Keyboard Bell Custom Filename</summary>
|
||||||
|
<description>File name of the bell sound to be played.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.peripherals.touchscreen" path="/org/gnome/settings-daemon/peripherals/touchscreen/">
|
||||||
|
<key name="orientation-lock" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Whether the tablet’s orientation is locked, or rotated automatically.</summary>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<!-- Deprecated schemas/keys -->
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.mouse.deprecated">
|
||||||
|
<key name="left-handed" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Mouse button orientation</summary>
|
||||||
|
<description>Swap left and right mouse buttons for left-handed mice.</description>
|
||||||
|
</key>
|
||||||
|
<key name="motion-acceleration" type="d">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Single Click</summary>
|
||||||
|
<description>Acceleration multiplier for mouse motion. A value of -1 is the system default.</description>
|
||||||
|
</key>
|
||||||
|
<key name="motion-threshold" type="i">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Motion Threshold</summary>
|
||||||
|
<description>Distance in pixels the pointer must move before accelerated mouse motion is activated. A value of -1 is the system default.</description>
|
||||||
|
</key>
|
||||||
|
<key name="middle-button-enabled" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Middle button emulation</summary>
|
||||||
|
<description>Enables middle mouse button emulation through simultaneous left and right button click.</description>
|
||||||
|
</key>
|
||||||
|
<key name="double-click" type="i">
|
||||||
|
<default>400</default>
|
||||||
|
<summary>Double click time</summary>
|
||||||
|
<description> Length of a double click in milliseconds.</description>
|
||||||
|
</key>
|
||||||
|
<key name="drag-threshold" type="i">
|
||||||
|
<default>8</default>
|
||||||
|
<summary>Drag threshold</summary>
|
||||||
|
<description>Distance before a drag is started.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.keyboard.deprecated">
|
||||||
|
<key name="repeat" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
</key>
|
||||||
|
<key name="repeat-interval" type="u">
|
||||||
|
<default>30</default>
|
||||||
|
<summary>Key Repeat Interval</summary>
|
||||||
|
<description>Delay between repeats in milliseconds.</description>
|
||||||
|
</key>
|
||||||
|
<key name="delay" type="u">
|
||||||
|
<default>500</default>
|
||||||
|
<summary>Initial Key Repeat Delay</summary>
|
||||||
|
<description>Initial key repeat delay in milliseconds.</description>
|
||||||
|
</key>
|
||||||
|
<key name="remember-numlock-state" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Remember NumLock state</summary>
|
||||||
|
<description>When set to true, GNOME will remember the state of the NumLock LED between sessions.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.touchpad.deprecated">
|
||||||
|
<key name="disable-while-typing" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Disable touchpad while typing</summary>
|
||||||
|
<description>Set this to TRUE if you have problems with accidentally hitting the touchpad while typing.</description>
|
||||||
|
</key>
|
||||||
|
<key name="horiz-scroll-enabled" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable horizontal scrolling</summary>
|
||||||
|
<description>Set this to TRUE to allow horizontal scrolling by the same method selected with the scroll_method key.</description>
|
||||||
|
</key>
|
||||||
|
<key name="scroll-method" enum="org.gnome.settings-daemon.GsdTouchpadScrollMethod">
|
||||||
|
<default>'two-finger-scrolling'</default>
|
||||||
|
<summary>Select the touchpad scroll method</summary>
|
||||||
|
<description>Select the touchpad scroll method. Supported values are: “disabled”, “edge-scrolling”, “two-finger-scrolling”.</description>
|
||||||
|
</key>
|
||||||
|
<key name="tap-to-click" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Enable mouse clicks with touchpad</summary>
|
||||||
|
<description>Set this to TRUE to be able to send mouse clicks by tapping on the touchpad.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-enabled" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable touchpad</summary>
|
||||||
|
<description>Set this to TRUE to enable all touchpads.</description>
|
||||||
|
</key>
|
||||||
|
<key name="left-handed" enum="org.gnome.settings-daemon.GsdTouchpadHandedness">
|
||||||
|
<default>'mouse'</default>
|
||||||
|
<summary>Touchpad button orientation</summary>
|
||||||
|
<description>Swap left and right mouse buttons for left-handed mice with “left”, “right” for right-handed, “mouse” to follow the mouse setting.</description>
|
||||||
|
</key>
|
||||||
|
<key name="motion-acceleration" type="d">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Single Click</summary>
|
||||||
|
<description>Acceleration multiplier for mouse motion. A value of -1 is the system default.</description>
|
||||||
|
</key>
|
||||||
|
<key name="motion-threshold" type="i">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Motion Threshold</summary>
|
||||||
|
<description>Distance in pixels the pointer must move before accelerated mouse motion is activated. A value of -1 is the system default.</description>
|
||||||
|
</key>
|
||||||
|
<key name="natural-scroll" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Natural scrolling</summary>
|
||||||
|
<description>Set this to TRUE to enable natural (reverse) scrolling for touchpads.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.trackball.deprecated">
|
||||||
|
<key name="scroll-wheel-emulation-button" type="i">
|
||||||
|
<default>0</default>
|
||||||
|
<range min="0" max="24"/>
|
||||||
|
<summary>Mouse wheel emulation button. 0 to disable the feature.</summary>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.wacom.deprecated">
|
||||||
|
<child name="stylus" schema="org.gnome.settings-daemon.peripherals.wacom.stylus.deprecated"/>
|
||||||
|
<child name="eraser" schema="org.gnome.settings-daemon.peripherals.wacom.eraser.deprecated"/>
|
||||||
|
|
||||||
|
<!-- is-absolute applies to all tools but PAD, CURSOR is hard-coded -->
|
||||||
|
<key name="is-absolute" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Wacom stylus absolute mode</summary>
|
||||||
|
<description>Enable this to set the tablet to absolute mode.</description>
|
||||||
|
</key>
|
||||||
|
<key name="area" type="ai">
|
||||||
|
<default>[-1, -1, -1, -1]</default>
|
||||||
|
<summary>Wacom tablet area</summary>
|
||||||
|
<description>Set this to x1, y1 and x2, y2 of the area usable by the tools.</description>
|
||||||
|
</key>
|
||||||
|
<key name="keep-aspect" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Wacom tablet aspect ratio</summary>
|
||||||
|
<description>Enable this to restrict the Wacom tablet area to match the aspect ratio of the output.</description>
|
||||||
|
</key>
|
||||||
|
<key name="rotation" enum="org.gnome.settings-daemon.GsdWacomRotation">
|
||||||
|
<default>'none'</default>
|
||||||
|
<summary>Wacom tablet rotation</summary>
|
||||||
|
<description>Set this to “none”, “cw” for 90 degree clockwise, “half” for 180 degree, and “ccw” for 90 degree counterclockwise.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touch" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Wacom touch feature</summary>
|
||||||
|
<description>Enable this to move the cursor when the user touches the tablet.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.wacom.stylus.deprecated">
|
||||||
|
<key name="pressurecurve" type="ai">
|
||||||
|
<default>[0, 0, 100, 100]</default>
|
||||||
|
<summary>Wacom stylus pressure curve</summary>
|
||||||
|
<description>Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus.</description>
|
||||||
|
</key>
|
||||||
|
<key name="buttonmapping" type="ai">
|
||||||
|
<default>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]</default>
|
||||||
|
<summary>Wacom stylus button mapping</summary>
|
||||||
|
<description>Set this to the logical button mapping.</description>
|
||||||
|
</key>
|
||||||
|
<key name="pressurethreshold" type="i">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Wacom stylus pressure threshold</summary>
|
||||||
|
<description>Set this to the pressure value at which a stylus click event is generated.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.wacom.eraser.deprecated">
|
||||||
|
<key name="pressurecurve" type="ai">
|
||||||
|
<default>[0, 0, 100, 100]</default>
|
||||||
|
<summary>Wacom eraser pressure curve</summary>
|
||||||
|
<description>Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser.</description>
|
||||||
|
</key>
|
||||||
|
<key name="buttonmapping" type="ai">
|
||||||
|
<default>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]</default>
|
||||||
|
<summary>Wacom eraser button mapping</summary>
|
||||||
|
<description>Set this to the logical button mapping.</description>
|
||||||
|
</key>
|
||||||
|
<key name="pressurethreshold" type="i">
|
||||||
|
<default>-1</default>
|
||||||
|
<summary>Wacom eraser pressure threshold</summary>
|
||||||
|
<description>Set this to the pressure value at which an eraser click event is generated.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.peripherals.wacom.tablet-button.deprecated">
|
||||||
|
<key name="action-type" enum="org.gnome.settings-daemon.GsdWacomActionType">
|
||||||
|
<default>'none'</default>
|
||||||
|
<summary>Wacom button action type</summary>
|
||||||
|
<description>The type of action triggered by the button being pressed.</description>
|
||||||
|
</key>
|
||||||
|
<key name="custom-action" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Key combination for the custom action</summary>
|
||||||
|
<description>The keyboard shortcut generated when the button is pressed for custom actions.</description>
|
||||||
|
</key>
|
||||||
|
<key name="custom-elevator-action" type="as">
|
||||||
|
<default>['', '']</default>
|
||||||
|
<summary>Key combinations for a touchring or touchstrip custom action</summary>
|
||||||
|
<description>The keyboard shortcuts generated when a touchring or touchstrip is used for custom actions (up followed by down).</description>
|
||||||
|
</key>
|
||||||
|
<key name="oled-label" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<!-- Translators: This is the OLED display on an Intuos4 tablet:
|
||||||
|
http://eu.shop.wacom.eu/images/articles/d9abd9f2d4d88aa0649cda97a8077e2b_8.jpg -->
|
||||||
|
<summary>Button label for OLED display.</summary>
|
||||||
|
<description>Label will be rendered to OLED display belonging to the button</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.desktop.peripherals.tablet.deprecated">
|
||||||
|
<key name="display" type="as">
|
||||||
|
<default>["", "", ""]</default>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
45
data/org.gnome.settings-daemon.plugins.color.gschema.xml.in
Normal file
45
data/org.gnome.settings-daemon.plugins.color.gschema.xml.in
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.color" path="/org/gnome/settings-daemon/plugins/color/">
|
||||||
|
<key name="recalibrate-display-threshold" type="u">
|
||||||
|
<default>0</default>
|
||||||
|
<summary>The duration a display profile is valid</summary>
|
||||||
|
<description>This is the number of days after which the display color profile is considered invalid.</description>
|
||||||
|
</key>
|
||||||
|
<key name="recalibrate-printer-threshold" type="u">
|
||||||
|
<default>0</default>
|
||||||
|
<summary>The duration a printer profile is valid</summary>
|
||||||
|
<description>This is the number of days after which the printer color profile is considered invalid.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-enabled" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>If the night light mode is enabled</summary>
|
||||||
|
<description>Night light mode changes the color temperature of your display when the sun has gone down or at preset times.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-temperature" type="u">
|
||||||
|
<default>2700</default>
|
||||||
|
<summary>Temperature of the display when enabled</summary>
|
||||||
|
<description>This temperature in Kelvin is used to modify the screen tones when night light mode is enabled. Higher values are bluer, lower redder.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-schedule-automatic" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Use the sunrise and sunset</summary>
|
||||||
|
<description>Calculate the sunrise and sunset times automatically, from the current location.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-schedule-from" type="d">
|
||||||
|
<default>20.00</default>
|
||||||
|
<summary>The start time</summary>
|
||||||
|
<description>When “night-light-schedule-automatic” is disabled, use this start time in hours from midnight.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-schedule-to" type="d">
|
||||||
|
<default>6.00</default>
|
||||||
|
<summary>The end time</summary>
|
||||||
|
<description>When “night-light-schedule-automatic” is disabled, use this end time in hours from midnight.</description>
|
||||||
|
</key>
|
||||||
|
<key name="night-light-last-coordinates" type="(dd)">
|
||||||
|
<default>(91,181)</default>
|
||||||
|
<summary>The last detected position</summary>
|
||||||
|
<description>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.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
18
data/org.gnome.settings-daemon.plugins.gschema.xml.in
Normal file
18
data/org.gnome.settings-daemon.plugins.gschema.xml.in
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins" path="/org/gnome/settings-daemon/plugins/">
|
||||||
|
<key name="whitelisted-plugins" type="as">
|
||||||
|
<default>['all']</default>
|
||||||
|
<summary>List of plugins that are allowed to be loaded</summary>
|
||||||
|
<description>
|
||||||
|
A list of strings representing the plugins that are allowed to be loaded (default: “all”).
|
||||||
|
This is only evaluated on startup.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
<child name="color" schema="org.gnome.settings-daemon.plugins.color"/>
|
||||||
|
<child name="housekeeping" schema="org.gnome.settings-daemon.plugins.housekeeping"/>
|
||||||
|
<child name="media-keys" schema="org.gnome.settings-daemon.plugins.media-keys"/>
|
||||||
|
<child name="power" schema="org.gnome.settings-daemon.plugins.power"/>
|
||||||
|
<child name="xsettings" schema="org.gnome.settings-daemon.plugins.xsettings"/>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.housekeeping" path="/org/gnome/settings-daemon/plugins/housekeeping/">
|
||||||
|
<key name="ignore-paths" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>Mount paths to ignore</summary>
|
||||||
|
<description>Specify a list of mount paths to ignore when they run low on space.</description>
|
||||||
|
</key>
|
||||||
|
<key name="free-percent-notify" type="d">
|
||||||
|
<default>0.05</default>
|
||||||
|
<range min="0.0" max="1.0"/>
|
||||||
|
<summary>Free percentage notify threshold</summary>
|
||||||
|
<description>Percentage free space threshold for initial warning of low disk space. If the percentage free space drops below this, a warning will be shown.</description>
|
||||||
|
</key>
|
||||||
|
<key name="free-percent-notify-again" type="d">
|
||||||
|
<default>0.01</default>
|
||||||
|
<range min="0.0" max="1.0"/>
|
||||||
|
<summary>Subsequent free space percentage notify threshold</summary>
|
||||||
|
<description>Specify the percentage that the free disk space should reduce by before issuing a subsequent warning.</description>
|
||||||
|
</key>
|
||||||
|
<key name="free-size-gb-no-notify" type="i">
|
||||||
|
<default>1</default>
|
||||||
|
<summary>Free space notify threshold</summary>
|
||||||
|
<description>Specify an amount in GB. If the amount of free space is more than this, no warning will be shown.</description>
|
||||||
|
</key>
|
||||||
|
<key name="min-notify-period" type="i">
|
||||||
|
<default>10</default>
|
||||||
|
<summary>Minimum notify period for repeated warnings</summary>
|
||||||
|
<description>Specify a time in minutes. Subsequent warnings for a volume will not appear more often than this period.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
707
data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in
Normal file
707
data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in
Normal file
|
@ -0,0 +1,707 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys.deprecated">
|
||||||
|
<key name="calculator" type="s">
|
||||||
|
<default>'XF86Calculator'</default>
|
||||||
|
<summary>Launch calculator</summary>
|
||||||
|
<description>Binding to launch the calculator.</description>
|
||||||
|
</key>
|
||||||
|
<key name="control-center" type="s">
|
||||||
|
<default>'XF86Tools'</default>
|
||||||
|
<summary>Launch settings</summary>
|
||||||
|
<description>Binding to launch GNOME Settings.</description>
|
||||||
|
</key>
|
||||||
|
<key name="email" type="s">
|
||||||
|
<default>'XF86Mail'</default>
|
||||||
|
<summary>Launch email client</summary>
|
||||||
|
<description>Binding to launch the email client.</description>
|
||||||
|
</key>
|
||||||
|
<key name="eject" type="s">
|
||||||
|
<default>'XF86Eject'</default>
|
||||||
|
<summary>Eject</summary>
|
||||||
|
<description>Binding to eject an optical disc.</description>
|
||||||
|
</key>
|
||||||
|
<key name="help" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Launch help browser</summary>
|
||||||
|
<description>Binding to launch the help browser.</description>
|
||||||
|
</key>
|
||||||
|
<key name="home" type="s">
|
||||||
|
<default>'XF86Explorer'</default>
|
||||||
|
<summary>Home folder</summary>
|
||||||
|
<description>Binding to open the Home folder.</description>
|
||||||
|
</key>
|
||||||
|
<key name="media" type="s">
|
||||||
|
<default>'XF86AudioMedia'</default>
|
||||||
|
<summary>Launch media player</summary>
|
||||||
|
<description>Binding to launch the media player.</description>
|
||||||
|
</key>
|
||||||
|
<key name="next" type="s">
|
||||||
|
<default>'XF86AudioNext'</default>
|
||||||
|
<summary>Next track</summary>
|
||||||
|
<description>Binding to skip to next track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="pause" type="s">
|
||||||
|
<default>'XF86AudioPause'</default>
|
||||||
|
<summary>Pause playback</summary>
|
||||||
|
<description>Binding to pause playback.</description>
|
||||||
|
</key>
|
||||||
|
<key name="play" type="s">
|
||||||
|
<default>'XF86AudioPlay'</default>
|
||||||
|
<summary>Play (or play/pause)</summary>
|
||||||
|
<description>Binding to start playback (or toggle play/pause).</description>
|
||||||
|
</key>
|
||||||
|
<key name="logout" type="s">
|
||||||
|
<default>'<Control><Alt>Delete'</default>
|
||||||
|
<summary>Log out</summary>
|
||||||
|
<description>Binding to log out.</description>
|
||||||
|
</key>
|
||||||
|
<key name="previous" type="s">
|
||||||
|
<default>'XF86AudioPrev'</default>
|
||||||
|
<summary>Previous track</summary>
|
||||||
|
<description>Binding to skip to previous track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screensaver" type="s">
|
||||||
|
<default>'<Super>l'</default>
|
||||||
|
<summary>Lock screen</summary>
|
||||||
|
<description>Binding to lock the screen.</description>
|
||||||
|
</key>
|
||||||
|
<key name="search" type="s">
|
||||||
|
<default>'XF86Search'</default>
|
||||||
|
<summary>Search</summary>
|
||||||
|
<description>Binding to launch the search tool.</description>
|
||||||
|
</key>
|
||||||
|
<key name="stop" type="s">
|
||||||
|
<default>'XF86AudioStop'</default>
|
||||||
|
<summary>Stop playback</summary>
|
||||||
|
<description>Binding to stop playback.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-down" type="s">
|
||||||
|
<default>'XF86AudioLowerVolume'</default>
|
||||||
|
<summary>Volume down</summary>
|
||||||
|
<description>Binding to lower the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-mute" type="s">
|
||||||
|
<default>'XF86AudioMute'</default>
|
||||||
|
<summary>Volume mute/unmute</summary>
|
||||||
|
<description>Binding to mute/unmute the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up" type="s">
|
||||||
|
<default>'XF86AudioRaiseVolume'</default>
|
||||||
|
<summary>Volume up</summary>
|
||||||
|
<description>Binding to raise the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="mic-mute" type="s">
|
||||||
|
<default>'XF86AudioMicMute'</default>
|
||||||
|
<summary>Microphone mute/unmute</summary>
|
||||||
|
<description>Binding to mute/unmute the microphone.</description>
|
||||||
|
</key>
|
||||||
|
<key name="www" type="s">
|
||||||
|
<default>'XF86WWW'</default>
|
||||||
|
<summary>Launch web browser</summary>
|
||||||
|
<description>Binding to launch the web browser.</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier" type="s">
|
||||||
|
<default>'<Alt><Super>8'</default>
|
||||||
|
<summary>Toggle magnifier</summary>
|
||||||
|
<description>Binding to show the screen magnifier</description>
|
||||||
|
</key>
|
||||||
|
<key name="screenreader" type="s">
|
||||||
|
<default>'<Alt><Super>s'</default>
|
||||||
|
<summary>Toggle screen reader</summary>
|
||||||
|
<description>Binding to start the screen reader</description>
|
||||||
|
</key>
|
||||||
|
<key name="on-screen-keyboard" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Toggle on-screen keyboard</summary>
|
||||||
|
<description>Binding to show the on-screen keyboard</description>
|
||||||
|
</key>
|
||||||
|
<key name="increase-text-size" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Increase text size</summary>
|
||||||
|
<description>Binding to increase the text size</description>
|
||||||
|
</key>
|
||||||
|
<key name="decrease-text-size" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Decrease text size</summary>
|
||||||
|
<description>Binding to decrease the text size</description>
|
||||||
|
</key>
|
||||||
|
<key name="toggle-contrast" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Toggle contrast</summary>
|
||||||
|
<description>Binding to toggle the interface contrast</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier-zoom-in" type="s">
|
||||||
|
<default>'<Alt><Super>equal'</default>
|
||||||
|
<summary>Magnifier zoom in</summary>
|
||||||
|
<description>Binding for the magnifier to zoom in</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier-zoom-out" type="s">
|
||||||
|
<default>'<Alt><Super>minus'</default>
|
||||||
|
<summary>Magnifier zoom out</summary>
|
||||||
|
<description>Binding for the magnifier to zoom out</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys" path="/org/gnome/settings-daemon/plugins/media-keys/">
|
||||||
|
<key name="custom-keybindings" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>Custom keybindings</summary>
|
||||||
|
<description>List of custom keybindings</description>
|
||||||
|
</key>
|
||||||
|
<key name="calculator" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Launch calculator</summary>
|
||||||
|
<description>Binding to launch the calculator.</description>
|
||||||
|
</key>
|
||||||
|
<key name="control-center" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Launch settings</summary>
|
||||||
|
<description>Binding to launch GNOME Settings.</description>
|
||||||
|
</key>
|
||||||
|
<key name="email" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Launch email client</summary>
|
||||||
|
<description>Binding to launch the email client.</description>
|
||||||
|
</key>
|
||||||
|
<key name="eject" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Eject</summary>
|
||||||
|
<description>Binding to eject an optical disc.</description>
|
||||||
|
</key>
|
||||||
|
<key name="help" type="as">
|
||||||
|
<default>['', '<Super>F1']</default>
|
||||||
|
<summary>Launch help browser</summary>
|
||||||
|
<description>Binding to launch the help browser.</description>
|
||||||
|
</key>
|
||||||
|
<key name="home" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Home folder</summary>
|
||||||
|
<description>Binding to open the Home folder.</description>
|
||||||
|
</key>
|
||||||
|
<key name="media" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Launch media player</summary>
|
||||||
|
<description>Binding to launch the media player.</description>
|
||||||
|
</key>
|
||||||
|
<key name="next" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Next track</summary>
|
||||||
|
<description>Binding to skip to next track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="pause" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Pause playback</summary>
|
||||||
|
<description>Binding to pause playback.</description>
|
||||||
|
</key>
|
||||||
|
<key name="play" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Play (or play/pause)</summary>
|
||||||
|
<description>Binding to start playback (or toggle play/pause).</description>
|
||||||
|
</key>
|
||||||
|
<key name="logout" type="as">
|
||||||
|
<default>['<Control><Alt>Delete']</default>
|
||||||
|
<summary>Log out</summary>
|
||||||
|
<description>Binding to log out.</description>
|
||||||
|
</key>
|
||||||
|
<key name="reboot" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Reboot</summary>
|
||||||
|
<description>Binding to reboot.</description>
|
||||||
|
</key>
|
||||||
|
<key name="shutdown" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Shut down</summary>
|
||||||
|
<description>Binding to shut down.</description>
|
||||||
|
</key>
|
||||||
|
<key name="previous" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Previous track</summary>
|
||||||
|
<description>Binding to skip to previous track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screensaver" type="as">
|
||||||
|
<default>['<Super>l']</default>
|
||||||
|
<summary>Lock screen</summary>
|
||||||
|
<description>Binding to lock the screen.</description>
|
||||||
|
</key>
|
||||||
|
<key name="search" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Search</summary>
|
||||||
|
<description>Binding to launch the search tool.</description>
|
||||||
|
</key>
|
||||||
|
<key name="stop" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Stop playback</summary>
|
||||||
|
<description>Binding to stop playback.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume -->
|
||||||
|
<key name="volume-down" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Volume down</summary>
|
||||||
|
<description>Binding to lower the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-mute" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Volume mute/unmute</summary>
|
||||||
|
<description>Binding to mute/unmute the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Volume up</summary>
|
||||||
|
<description>Binding to raise the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-step" type="i">
|
||||||
|
<default>6</default>
|
||||||
|
<range min="1" max="20"/>
|
||||||
|
<summary>Size of volume step</summary>
|
||||||
|
<description>Size of the volume step for each volume change</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume without sound effect -->
|
||||||
|
<key name="volume-down-quiet" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Quiet volume down</summary>
|
||||||
|
<description>Binding to lower the volume without emitting a sound effect.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-mute-quiet" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Quiet volume mute/unmute</summary>
|
||||||
|
<description>Binding to mute/unmute the volume without emitting a sound effect.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up-quiet" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Quiet volume up</summary>
|
||||||
|
<description>Binding to raise the volume without emitting a sound effect.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume with high precision -->
|
||||||
|
<key name="volume-down-precise" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Precise volume down</summary>
|
||||||
|
<description>Binding to lower the volume with higher precision.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up-precise" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Precise volume up</summary>
|
||||||
|
<description>Binding to raise the volume with higher precision.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="mic-mute" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Microphone mute/unmute</summary>
|
||||||
|
<description>Binding to mute/unmute the microphone.</description>
|
||||||
|
</key>
|
||||||
|
<key name="www" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Launch web browser</summary>
|
||||||
|
<description>Binding to launch the web browser.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screenreader" type="as">
|
||||||
|
<default>['<Alt><Super>s']</default>
|
||||||
|
<summary>Toggle screen reader</summary>
|
||||||
|
<description>Binding to start the screen reader</description>
|
||||||
|
</key>
|
||||||
|
<key name="on-screen-keyboard" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle on-screen keyboard</summary>
|
||||||
|
<description>Binding to show the on-screen keyboard</description>
|
||||||
|
</key>
|
||||||
|
<key name="increase-text-size" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Increase text size</summary>
|
||||||
|
<description>Binding to increase the text size</description>
|
||||||
|
</key>
|
||||||
|
<key name="decrease-text-size" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Decrease text size</summary>
|
||||||
|
<description>Binding to decrease the text size</description>
|
||||||
|
</key>
|
||||||
|
<key name="toggle-contrast" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle contrast</summary>
|
||||||
|
<description>Binding to toggle the interface contrast</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier" type="as">
|
||||||
|
<default>['<Alt><Super>8']</default>
|
||||||
|
<summary>Toggle magnifier</summary>
|
||||||
|
<description>Binding to show the screen magnifier</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier-zoom-in" type="as">
|
||||||
|
<default>['<Alt><Super>equal']</default>
|
||||||
|
<summary>Magnifier zoom in</summary>
|
||||||
|
<description>Binding for the magnifier to zoom in</description>
|
||||||
|
</key>
|
||||||
|
<key name="magnifier-zoom-out" type="as">
|
||||||
|
<default>['<Alt><Super>minus']</default>
|
||||||
|
<summary>Magnifier zoom out</summary>
|
||||||
|
<description>Binding for the magnifier to zoom out</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-toggle" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle touchpad on/off</summary>
|
||||||
|
<description>Binding to toggle the touchpad on/off.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-on" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Switch touchpad on</summary>
|
||||||
|
<description>Binding to switch the touchpad on.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-off" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Switch touchpad off</summary>
|
||||||
|
<description>Binding to switch the touchpad off.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="playback-rewind" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Skip backward in current track</summary>
|
||||||
|
<description>Binding to skip backward in current track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-forward" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Skip forward in current track</summary>
|
||||||
|
<description>Binding to skip forward in current track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-repeat" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle repeat playback mode</summary>
|
||||||
|
<description>Binding to toggle repeat mode in media player.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-random" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle random playback mode</summary>
|
||||||
|
<description>Binding to toggle random playback mode in media player.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="rotate-video-lock" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Toggle automatic screen orientation</summary>
|
||||||
|
<description>Binding to toggle automatic screen orientation.</description>
|
||||||
|
</key>
|
||||||
|
<key name="power" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Power button</summary>
|
||||||
|
<description>Binding for power button.</description>
|
||||||
|
</key>
|
||||||
|
<key name="hibernate" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Hibernate button</summary>
|
||||||
|
<description>Binding to hibernate the machine.</description>
|
||||||
|
</key>
|
||||||
|
<key name="suspend" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Suspend button</summary>
|
||||||
|
<description>Binding to suspend the machine.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="screen-brightness-up" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Screen brightness up</summary>
|
||||||
|
<description>Binding to increase the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screen-brightness-down" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Screen brightness down</summary>
|
||||||
|
<description>Binding to decrease the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screen-brightness-cycle" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Screen brightness cycle</summary>
|
||||||
|
<description>Binding to cycle the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="keyboard-brightness-up" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Keyboard brightness up</summary>
|
||||||
|
<description>Binding to increase the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="keyboard-brightness-down" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Keyboard brightness down</summary>
|
||||||
|
<description>Binding to decrease the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="keyboard-brightness-toggle" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Keyboard brightness toggle</summary>
|
||||||
|
<description>Binding to toggle the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="battery-status" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Show battery status</summary>
|
||||||
|
<description>Binding to show current battery status.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="rfkill" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>RF kill</summary>
|
||||||
|
<description>Binding to toggle airplane mode.</description>
|
||||||
|
</key>
|
||||||
|
<key name="rfkill-bluetooth" type="as">
|
||||||
|
<default>['']</default>
|
||||||
|
<summary>Bluetooth RF kill</summary>
|
||||||
|
<description>Binding to toggle bluetooth airplane mode.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The following bindings are considered static versions of the above.
|
||||||
|
Overriding these keys will likely result in unexpected behaviour on at
|
||||||
|
least some hardware.
|
||||||
|
We assume that no user will ever modify these. It is therefore legal to
|
||||||
|
assume that an update of the default value will reach all users.
|
||||||
|
-->
|
||||||
|
<key name="calculator-static" type="as">
|
||||||
|
<default>['XF86Calculator']</default>
|
||||||
|
<summary>Launch calculator</summary>
|
||||||
|
<description>Static binding to launch the calculator.</description>
|
||||||
|
</key>
|
||||||
|
<key name="control-center-static" type="as">
|
||||||
|
<default>['XF86Tools']</default>
|
||||||
|
<summary>Launch settings</summary>
|
||||||
|
<description>Static binding to launch GNOME Settings.</description>
|
||||||
|
</key>
|
||||||
|
<key name="email-static" type="as">
|
||||||
|
<default>['XF86Mail']</default>
|
||||||
|
<summary>Launch email client</summary>
|
||||||
|
<description>Static binding to launch the email client.</description>
|
||||||
|
</key>
|
||||||
|
<key name="eject-static" type="as">
|
||||||
|
<default>['XF86Eject']</default>
|
||||||
|
<summary>Eject</summary>
|
||||||
|
<description>Static binding to eject an optical disc.</description>
|
||||||
|
</key>
|
||||||
|
<key name="home-static" type="as">
|
||||||
|
<default>['XF86Explorer']</default>
|
||||||
|
<summary>Home folder</summary>
|
||||||
|
<description>Static binding to open the Home folder.</description>
|
||||||
|
</key>
|
||||||
|
<key name="media-static" type="as">
|
||||||
|
<default>['XF86AudioMedia']</default>
|
||||||
|
<summary>Launch media player</summary>
|
||||||
|
<description>Static binding to launch the media player.</description>
|
||||||
|
</key>
|
||||||
|
<key name="next-static" type="as">
|
||||||
|
<default>['XF86AudioNext', '<Ctrl>XF86AudioNext']</default>
|
||||||
|
<summary>Next track</summary>
|
||||||
|
<description>Static binding to skip to next track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="pause-static" type="as">
|
||||||
|
<default>['XF86AudioPause']</default>
|
||||||
|
<summary>Pause playback</summary>
|
||||||
|
<description>Static binding to pause playback.</description>
|
||||||
|
</key>
|
||||||
|
<key name="play-static" type="as">
|
||||||
|
<default>['XF86AudioPlay', '<Ctrl>XF86AudioPlay']</default>
|
||||||
|
<summary>Play (or play/pause)</summary>
|
||||||
|
<description>Static binding to start playback (or toggle play/pause).</description>
|
||||||
|
</key>
|
||||||
|
<key name="previous-static" type="as">
|
||||||
|
<default>['XF86AudioPrev', '<Ctrl>XF86AudioPrev']</default>
|
||||||
|
<summary>Previous track</summary>
|
||||||
|
<description>Static binding to skip to previous track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screensaver-static" type="as">
|
||||||
|
<default>['XF86ScreenSaver']</default>
|
||||||
|
<summary>Lock screen</summary>
|
||||||
|
<description>Static binding to lock the screen.</description>
|
||||||
|
</key>
|
||||||
|
<key name="search-static" type="as">
|
||||||
|
<default>['XF86Search']</default>
|
||||||
|
<summary>Search</summary>
|
||||||
|
<description>Static binding to launch the search tool.</description>
|
||||||
|
</key>
|
||||||
|
<key name="stop-static" type="as">
|
||||||
|
<default>['XF86AudioStop']</default>
|
||||||
|
<summary>Stop playback</summary>
|
||||||
|
<description>Static binding to stop playback.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume, "Ctrl" is always emitted on some weird keyboards -->
|
||||||
|
<key name="volume-down-static" type="as">
|
||||||
|
<default>['XF86AudioLowerVolume', '<Ctrl>XF86AudioLowerVolume']</default>
|
||||||
|
<summary>Volume down</summary>
|
||||||
|
<description>Static binding to lower the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-mute-static" type="as">
|
||||||
|
<default>['XF86AudioMute']</default>
|
||||||
|
<summary>Volume mute/unmute</summary>
|
||||||
|
<description>Static binding to mute/unmute the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up-static" type="as">
|
||||||
|
<default>['XF86AudioRaiseVolume', '<Ctrl>XF86AudioRaiseVolume']</default>
|
||||||
|
<summary>Volume up</summary>
|
||||||
|
<description>Static binding to raise the volume.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume without sound effect -->
|
||||||
|
<key name="volume-down-quiet-static" type="as">
|
||||||
|
<default>['<Alt>XF86AudioLowerVolume', '<Alt><Ctrl>XF86AudioLowerVolume']</default>
|
||||||
|
<summary>Quiet volume down</summary>
|
||||||
|
<description>Static binding to lower the volume without emitting a sound effect.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-mute-quiet-static" type="as">
|
||||||
|
<default>['<Alt>XF86AudioMute']</default>
|
||||||
|
<summary>Quiet volume mute/unmute</summary>
|
||||||
|
<description>Static binding to mute/unmute the volume.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up-quiet-static" type="as">
|
||||||
|
<default>['<Alt>XF86AudioRaiseVolume', '<Alt><Ctrl>XF86AudioRaiseVolume']</default>
|
||||||
|
<summary>Quiet volume up</summary>
|
||||||
|
<description>Static binding to raise the volume without emitting a sound effect.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<!-- Change volume with high precision -->
|
||||||
|
<key name="volume-down-precise-static" type="as">
|
||||||
|
<default>['<Shift>XF86AudioLowerVolume', '<Ctrl><Shift>XF86AudioLowerVolume']</default>
|
||||||
|
<summary>Precise volume down</summary>
|
||||||
|
<description>Static binding to lower the volume with higher precision.</description>
|
||||||
|
</key>
|
||||||
|
<key name="volume-up-precise-static" type="as">
|
||||||
|
<default>['<Shift>XF86AudioRaiseVolume', '<Ctrl><Shift>XF86AudioRaiseVolume']</default>
|
||||||
|
<summary>Precise volume up</summary>
|
||||||
|
<description>Static binding to raise the volume with higher precision.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="mic-mute-static" type="as">
|
||||||
|
<default>['XF86AudioMicMute']</default>
|
||||||
|
<summary>Microphone mute/unmute</summary>
|
||||||
|
<description>Static binding to mute/unmute the microphone.</description>
|
||||||
|
</key>
|
||||||
|
<key name="www-static" type="as">
|
||||||
|
<default>['XF86WWW']</default>
|
||||||
|
<summary>Launch web browser</summary>
|
||||||
|
<description>Static binding to launch the web browser.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="touchpad-toggle-static" type="as">
|
||||||
|
<default>['XF86TouchpadToggle', '<Ctrl><Super>XF86TouchpadToggle']</default>
|
||||||
|
<summary>Magnifier zoom out</summary>
|
||||||
|
<description>Static binding to toggle the touchpad on/off.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-on-static" type="as">
|
||||||
|
<default>['XF86TouchpadOn']</default>
|
||||||
|
<summary>Switch touchpad on</summary>
|
||||||
|
<description>Static binding to switch the touchpad on.</description>
|
||||||
|
</key>
|
||||||
|
<key name="touchpad-off-static" type="as">
|
||||||
|
<default>['XF86TouchpadOff']</default>
|
||||||
|
<summary>Switch touchpad off</summary>
|
||||||
|
<description>Static binding to switch the touchpad off.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="playback-rewind-static" type="as">
|
||||||
|
<default>['XF86AudioRewind']</default>
|
||||||
|
<summary>Skip backward in current track</summary>
|
||||||
|
<description>Static binding to skip backward in current track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-forward-static" type="as">
|
||||||
|
<default>['XF86AudioForward']</default>
|
||||||
|
<summary>Skip forward in current track</summary>
|
||||||
|
<description>Static binding to skip forward in current track.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-repeat-static" type="as">
|
||||||
|
<default>['XF86AudioRepeat']</default>
|
||||||
|
<summary>Toggle repeat playback mode</summary>
|
||||||
|
<description>Static binding to toggle repeat mode in media player.</description>
|
||||||
|
</key>
|
||||||
|
<key name="playback-random-static" type="as">
|
||||||
|
<default>['XF86AudioRandomPlay']</default>
|
||||||
|
<summary>Toggle random playback mode</summary>
|
||||||
|
<description>Static binding to toggle random playback mode in media player.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="rotate-video-lock-static" type="as">
|
||||||
|
<default>['<Super>o', 'XF86RotationLockToggle']</default>
|
||||||
|
<summary>Toggle automatic screen orientation</summary>
|
||||||
|
<description>Static binding to toggle automatic screen orientation.</description>
|
||||||
|
</key>
|
||||||
|
<key name="power-static" type="as">
|
||||||
|
<default>['XF86PowerOff']</default>
|
||||||
|
<summary>Power button</summary>
|
||||||
|
<description>Static binding for power button.</description>
|
||||||
|
</key>
|
||||||
|
<key name="hibernate-static" type="as">
|
||||||
|
<default>['XF86Suspend', 'XF86Hibernate']</default>
|
||||||
|
<summary>Hibernate button</summary>
|
||||||
|
<description>Static binding to hibernate the machine.</description>
|
||||||
|
</key>
|
||||||
|
<key name="suspend-static" type="as">
|
||||||
|
<default>['XF86Sleep']</default>
|
||||||
|
<summary>Suspend button</summary>
|
||||||
|
<description>Static binding to suspend the machine.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="screen-brightness-up-static" type="as">
|
||||||
|
<default>['XF86MonBrightnessUp']</default>
|
||||||
|
<summary>Screen brightness up</summary>
|
||||||
|
<description>Static binding to increase the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screen-brightness-down-static" type="as">
|
||||||
|
<default>['XF86MonBrightnessDown']</default>
|
||||||
|
<summary>Screen brightness down</summary>
|
||||||
|
<description>Static binding to decrease the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="screen-brightness-cycle-static" type="as">
|
||||||
|
<default>['XF86MonBrightnessCycle']</default>
|
||||||
|
<summary>Screen brightness cycle</summary>
|
||||||
|
<description>Static binding to cycle the screen brightness.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="keyboard-brightness-up-static" type="as">
|
||||||
|
<default>['XF86KbdBrightnessUp']</default>
|
||||||
|
<summary>Keyboard brightness up</summary>
|
||||||
|
<description>Static binding to increase the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="keyboard-brightness-down-static" type="as">
|
||||||
|
<default>['XF86KbdBrightnessDown']</default>
|
||||||
|
<summary>Keyboard brightness down</summary>
|
||||||
|
<description>Static binding to decrease the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
<key name="keyboard-brightness-toggle-static" type="as">
|
||||||
|
<default>['XF86KbdLightOnOff']</default>
|
||||||
|
<summary>Keyboard brightness toggle</summary>
|
||||||
|
<description>Static binding to toggle the keyboard brightness.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="battery-status-static" type="as">
|
||||||
|
<default>['XF86Battery']</default>
|
||||||
|
<summary>Show battery status</summary>
|
||||||
|
<description>Static binding to show current battery status.</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="rfkill-static" type="as">
|
||||||
|
<default>['XF86WLAN', 'XF86UWB', 'XF86RFKill']</default>
|
||||||
|
<summary>RF kill</summary>
|
||||||
|
<description>Static binding to toggle airplane mode.</description>
|
||||||
|
</key>
|
||||||
|
<key name="rfkill-bluetooth-static" type="as">
|
||||||
|
<default>['XF86Bluetooth']</default>
|
||||||
|
<summary>Bluetooth RF kill</summary>
|
||||||
|
<description>Static binding to toggle bluetooth airplane mode.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys.custom-keybinding">
|
||||||
|
<key name="name" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Name</summary>
|
||||||
|
<description>Name of the custom binding</description>
|
||||||
|
</key>
|
||||||
|
<key name="binding" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Binding</summary>
|
||||||
|
<description>Binding for the custom binding</description>
|
||||||
|
</key>
|
||||||
|
<key name="command" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<summary>Command</summary>
|
||||||
|
<description>Command to run when the binding is invoked</description>
|
||||||
|
</key>
|
||||||
|
<key name="enable-in-lockscreen" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Enable in Lockscreen</summary>
|
||||||
|
<description>Whether the command can be invoked while the lockscreen is shown</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
50
data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
Normal file
50
data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.power" path="/org/gnome/settings-daemon/plugins/power/">
|
||||||
|
<key name="idle-brightness" type="i">
|
||||||
|
<default>30</default>
|
||||||
|
<summary>The brightness of the screen when idle</summary>
|
||||||
|
<description>This is the laptop panel screen brightness used when the session is idle.</description>
|
||||||
|
</key>
|
||||||
|
<key name="idle-dim" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Dim the screen after a period of inactivity</summary>
|
||||||
|
<description>If the screen should be dimmed to save power when the computer is idle.</description>
|
||||||
|
</key>
|
||||||
|
<key name="sleep-inactive-ac-timeout" type="i">
|
||||||
|
<default>900</default>
|
||||||
|
<summary>Sleep timeout computer when on AC</summary>
|
||||||
|
<description>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.</description>
|
||||||
|
</key>
|
||||||
|
<key name="sleep-inactive-ac-type" enum="org.gnome.settings-daemon.GsdPowerActionType">
|
||||||
|
<default>'suspend'</default>
|
||||||
|
<summary>Whether to hibernate, suspend or do nothing when inactive</summary>
|
||||||
|
<description>The type of sleeping that should be performed when the computer is inactive.</description>
|
||||||
|
</key>
|
||||||
|
<key name="sleep-inactive-battery-timeout" type="i">
|
||||||
|
<default>900</default>
|
||||||
|
<summary>Sleep timeout computer when on battery</summary>
|
||||||
|
<description>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.</description>
|
||||||
|
</key>
|
||||||
|
<key name="sleep-inactive-battery-type" enum="org.gnome.settings-daemon.GsdPowerActionType">
|
||||||
|
<default>'suspend'</default>
|
||||||
|
<summary>Whether to hibernate, suspend or do nothing when inactive</summary>
|
||||||
|
<description>The type of sleeping that should be performed when the computer is inactive.</description>
|
||||||
|
</key>
|
||||||
|
<key name="ambient-enabled" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable the ALS sensor</summary>
|
||||||
|
<description>If the ambient light sensor functionality is enabled.</description>
|
||||||
|
</key>
|
||||||
|
<key name="power-button-action" enum="org.gnome.settings-daemon.GsdPowerButtonActionType">
|
||||||
|
<default>'suspend'</default>
|
||||||
|
<summary>Power button action</summary>
|
||||||
|
<description>The action to take when the system power button is pressed. Virtual machines only honor the 'nothing' action, and will shutdown otherwise. Tablets always suspend, ignoring all the other action options.</description>
|
||||||
|
</key>
|
||||||
|
<key name="power-saver-profile-on-low-battery" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable power-saver profile when battery is low</summary>
|
||||||
|
<description>Automatically enable the "power-saver" profile using power-profiles-daemon if the battery is low.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.sharing.service">
|
||||||
|
<key name="enabled-connections" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>On which connections the service is enabled</summary>
|
||||||
|
<description>The list of NetworkManager connections (each one represented with its UUID) on which this service is enabled and started.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
10
data/org.gnome.settings-daemon.plugins.wwan.gschema.xml.in
Normal file
10
data/org.gnome.settings-daemon.plugins.wwan.gschema.xml.in
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.wwan" path="/org/gnome/settings-daemon/plugins/wwan/">
|
||||||
|
<key name="unlock-sim" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Unlock sim cards</summary>
|
||||||
|
<description>Unlock any sim cards right away.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<schemalist>
|
||||||
|
<schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.xsettings" path="/org/gnome/settings-daemon/plugins/xsettings/">
|
||||||
|
<key name="disabled-gtk-modules" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>List of explicitly disabled GTK+ modules</summary>
|
||||||
|
<description>A list of strings representing the GTK+ modules that will not be loaded, even if enabled by default in their configuration.</description>
|
||||||
|
</key>
|
||||||
|
<key name="enabled-gtk-modules" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<summary>List of explicitly enabled GTK+ modules</summary>
|
||||||
|
<description>A list of strings representing the GTK+ modules that will be loaded, usually in addition to conditional and forcibly disabled ones.</description>
|
||||||
|
</key>
|
||||||
|
<key type="a{sv}" name="overrides">
|
||||||
|
<default>{}</default>
|
||||||
|
<summary>A dictionary of XSETTINGS to override</summary>
|
||||||
|
<description>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).</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
<schema id="org.gnome.settings-daemon.plugins.xsettings.deprecated">
|
||||||
|
<key name="antialiasing" enum="org.gnome.settings-daemon.GsdFontAntialiasingMode">
|
||||||
|
<default>'grayscale'</default>
|
||||||
|
<summary>Antialiasing</summary>
|
||||||
|
<description>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).</description>
|
||||||
|
</key>
|
||||||
|
<key name="hinting" enum="org.gnome.settings-daemon.GsdFontHinting">
|
||||||
|
<default>'slight'</default>
|
||||||
|
<summary>Hinting</summary>
|
||||||
|
<description>The type of hinting to use when rendering fonts. Possible values are: “none” for no hinting and “slight” for fitting only to the Y-axis like Microsoft’s ClearType, DirectWrite and Adobe’s proprietary font rendering engine. Ignores native hinting within the font, generates hints algorithmically. Used on Ubuntu by default. Recommended. The meaning of “medium” and “full” depends on the font format (.ttf, .otf, .pfa/.pfb) and the installed version of FreeType. They usually try to fit glyphs to both the X and the Y axis (except for .otf: Y-only). This can lead to distortion and/or inconsistent rendering depending on the quality of the font, the font format and the state of FreeType’s font engines.</description>
|
||||||
|
</key>
|
||||||
|
<key name="rgba-order" enum="org.gnome.settings-daemon.GsdFontRgbaOrder">
|
||||||
|
<default>'rgb'</default>
|
||||||
|
<summary>RGBA order</summary>
|
||||||
|
<description>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.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
40
gnome-settings-daemon.doap
Normal file
40
gnome-settings-daemon.doap
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||||
|
xmlns:foaf="http://xmlns.com/foaf/0.1/"
|
||||||
|
xmlns:gnome="http://api.gnome.org/doap-extensions#"
|
||||||
|
xmlns="http://usefulinc.com/ns/doap#">
|
||||||
|
|
||||||
|
<name xml:lang="en">gnome-settings-daemon</name>
|
||||||
|
<shortdesc xml:lang="en">GNOME Settings Daemon</shortdesc>
|
||||||
|
<description xml:lang="en">The GNOME Settings Daemon is responsible for setting various parameters of a
|
||||||
|
GNOME Session and the applications that run under it.</description>
|
||||||
|
<homepage rdf:resource="https://www.gnome.org/" />
|
||||||
|
<developer-forum rdf:resource="https://discourse.gnome.org/c/platform/5" />
|
||||||
|
<download-page rdf:resource="https://download.gnome.org/sources/gnome-settings-daemon/" />
|
||||||
|
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/gnome-settings-daemon/issues/" />
|
||||||
|
|
||||||
|
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||||
|
<programming-language>C</programming-language>
|
||||||
|
|
||||||
|
<maintainer>
|
||||||
|
<foaf:Person>
|
||||||
|
<foaf:name>Carlos Garnacho</foaf:name>
|
||||||
|
<foaf:mbox rdf:resource="mailto:carlosg@gnome.org" />
|
||||||
|
<gnome:userid>carlosg</gnome:userid>
|
||||||
|
</foaf:Person>
|
||||||
|
</maintainer>
|
||||||
|
<maintainer>
|
||||||
|
<foaf:Person>
|
||||||
|
<foaf:name>Benjamin Berg</foaf:name>
|
||||||
|
<foaf:mbox rdf:resource="mailto:bberg@gnome.org" />
|
||||||
|
<gnome:userid>bberg</gnome:userid>
|
||||||
|
</foaf:Person>
|
||||||
|
</maintainer>
|
||||||
|
<author>
|
||||||
|
<foaf:Person>
|
||||||
|
<foaf:name>Bastien Nocera</foaf:name>
|
||||||
|
<foaf:mbox rdf:resource="mailto:hadess@hadess.net" />
|
||||||
|
<gnome:userid>hadess</gnome:userid>
|
||||||
|
</foaf:Person>
|
||||||
|
</author>
|
||||||
|
</Project>
|
224
gnome-settings-daemon/gnome-settings-bus.c
Normal file
224
gnome-settings-daemon/gnome-settings-bus.c
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2011 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#if HAVE_WAYLAND
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gnome-settings-bus.h"
|
||||||
|
|
||||||
|
#define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager"
|
||||||
|
#define GNOME_SESSION_DBUS_OBJECT "/org/gnome/SessionManager"
|
||||||
|
|
||||||
|
#define GNOME_SCREENSAVER_DBUS_NAME "org.gnome.ScreenSaver"
|
||||||
|
#define GNOME_SCREENSAVER_DBUS_OBJECT "/org/gnome/ScreenSaver"
|
||||||
|
|
||||||
|
#define GNOME_SHELL_DBUS_NAME "org.gnome.Shell"
|
||||||
|
#define GNOME_SHELL_DBUS_OBJECT "/org/gnome/Shell"
|
||||||
|
|
||||||
|
#define MUTTER_DISPLAY_CONFIG_DBUS_NAME "org.gnome.Mutter.DisplayConfig"
|
||||||
|
#define MUTTER_DISPLAY_CONFIG_DBUS_OBJECT "/org/gnome/Mutter/DisplayConfig"
|
||||||
|
|
||||||
|
GsdSessionManager *
|
||||||
|
gnome_settings_bus_get_session_proxy (void)
|
||||||
|
{
|
||||||
|
static GsdSessionManager *session_proxy;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (session_proxy != NULL) {
|
||||||
|
g_object_ref (session_proxy);
|
||||||
|
} else {
|
||||||
|
session_proxy = gsd_session_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
GNOME_SESSION_DBUS_NAME,
|
||||||
|
GNOME_SESSION_DBUS_OBJECT,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdScreenSaver *
|
||||||
|
gnome_settings_bus_get_screen_saver_proxy (void)
|
||||||
|
{
|
||||||
|
static GsdScreenSaver *screen_saver_proxy;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (screen_saver_proxy != NULL) {
|
||||||
|
g_object_ref (screen_saver_proxy);
|
||||||
|
} else {
|
||||||
|
screen_saver_proxy = gsd_screen_saver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||||
|
GNOME_SCREENSAVER_DBUS_NAME,
|
||||||
|
GNOME_SCREENSAVER_DBUS_OBJECT,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (error) {
|
||||||
|
g_warning ("Failed to connect to the screen saver: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
} else {
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (screen_saver_proxy), (gpointer*)&screen_saver_proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return screen_saver_proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdShell *
|
||||||
|
gnome_settings_bus_get_shell_proxy (void)
|
||||||
|
{
|
||||||
|
static GsdShell *shell_proxy = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (shell_proxy != NULL) {
|
||||||
|
g_object_ref (shell_proxy);
|
||||||
|
} else {
|
||||||
|
shell_proxy = gsd_shell_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||||
|
GNOME_SHELL_DBUS_NAME,
|
||||||
|
GNOME_SHELL_DBUS_OBJECT,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (error) {
|
||||||
|
g_warning ("Failed to connect to the shell: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
} else {
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (shell_proxy), (gpointer*)&shell_proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shell_proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdDisplayConfig *
|
||||||
|
gnome_settings_bus_get_display_config_proxy (void)
|
||||||
|
{
|
||||||
|
static GsdDisplayConfig *display_config_proxy = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
if (display_config_proxy != NULL) {
|
||||||
|
g_object_ref (display_config_proxy);
|
||||||
|
} else {
|
||||||
|
display_config_proxy =
|
||||||
|
gsd_display_config_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||||
|
MUTTER_DISPLAY_CONFIG_DBUS_NAME,
|
||||||
|
MUTTER_DISPLAY_CONFIG_DBUS_OBJECT,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (error) {
|
||||||
|
g_warning ("Failed to connect to display config: %s", error->message);
|
||||||
|
} else {
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (display_config_proxy),
|
||||||
|
(gpointer*)&display_config_proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return display_config_proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
gnome_settings_get_chassis_type (void)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
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.hostname1",
|
||||||
|
"/org/freedesktop/hostname1",
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"Get",
|
||||||
|
g_variant_new ("(ss)",
|
||||||
|
"org.freedesktop.hostname1",
|
||||||
|
"Chassis"),
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (variant == NULL) {
|
||||||
|
g_debug ("Failed to get property '%s': %s", "Chassis", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_get (variant, "(v)", &inner);
|
||||||
|
ret = g_variant_dup_string (inner, NULL);
|
||||||
|
g_variant_unref (inner);
|
||||||
|
out:
|
||||||
|
g_clear_object (&connection);
|
||||||
|
g_clear_pointer (&variant, g_variant_unref);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
is_wayland_session (gpointer user_data)
|
||||||
|
{
|
||||||
|
#if HAVE_WAYLAND
|
||||||
|
struct wl_display *display;
|
||||||
|
|
||||||
|
display = wl_display_connect (NULL);
|
||||||
|
if (!display)
|
||||||
|
return GUINT_TO_POINTER(FALSE);
|
||||||
|
wl_display_disconnect (display);
|
||||||
|
return GUINT_TO_POINTER(TRUE);
|
||||||
|
#else
|
||||||
|
return GUINT_TO_POINTER(FALSE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnome_settings_is_wayland (void)
|
||||||
|
{
|
||||||
|
static GOnce wayland_once = G_ONCE_INIT;
|
||||||
|
|
||||||
|
g_once (&wayland_once, is_wayland_session, NULL);
|
||||||
|
|
||||||
|
return GPOINTER_TO_UINT(wayland_once.retval);
|
||||||
|
}
|
42
gnome-settings-daemon/gnome-settings-bus.h
Normal file
42
gnome-settings-daemon/gnome-settings-bus.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* 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 __GNOME_SETTINGS_BUS_H
|
||||||
|
#define __GNOME_SETTINGS_BUS_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include "gsd-session-manager-glue.h"
|
||||||
|
#include "gsd-screen-saver-glue.h"
|
||||||
|
#include "gsd-shell-glue.h"
|
||||||
|
#include "gsd-display-config-glue.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
GsdSessionManager *gnome_settings_bus_get_session_proxy (void);
|
||||||
|
GsdScreenSaver *gnome_settings_bus_get_screen_saver_proxy (void);
|
||||||
|
GsdShell *gnome_settings_bus_get_shell_proxy (void);
|
||||||
|
GsdDisplayConfig *gnome_settings_bus_get_display_config_proxy (void);
|
||||||
|
gboolean gnome_settings_is_wayland (void);
|
||||||
|
char * gnome_settings_get_chassis_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GNOME_SETTINGS_BUS_H */
|
164
gnome-settings-daemon/gnome-settings-module.c
Normal file
164
gnome-settings-daemon/gnome-settings-module.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - Paolo Maggi
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gnome-settings-module.h"
|
||||||
|
|
||||||
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
typedef struct _GnomeSettingsModuleClass GnomeSettingsModuleClass;
|
||||||
|
|
||||||
|
struct _GnomeSettingsModuleClass
|
||||||
|
{
|
||||||
|
GTypeModuleClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GnomeSettingsModule
|
||||||
|
{
|
||||||
|
GTypeModule parent_instance;
|
||||||
|
|
||||||
|
GModule *library;
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
GType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef GType (*GnomeSettingsModuleRegisterFunc) (GTypeModule *);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GnomeSettingsModule, gnome_settings_module, G_TYPE_TYPE_MODULE)
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gnome_settings_module_load (GTypeModule *gmodule)
|
||||||
|
{
|
||||||
|
GnomeSettingsModule *module;
|
||||||
|
GnomeSettingsModuleRegisterFunc register_func;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
module = GNOME_SETTINGS_MODULE (gmodule);
|
||||||
|
|
||||||
|
g_debug ("Loading %s", module->path);
|
||||||
|
|
||||||
|
module->library = g_module_open (module->path, 0);
|
||||||
|
|
||||||
|
if (module->library == NULL) {
|
||||||
|
g_warning ("%s", g_module_error ());
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extract symbols from the lib */
|
||||||
|
res = g_module_symbol (module->library, "register_gnome_settings_plugin", (void *) ®ister_func);
|
||||||
|
if (! res) {
|
||||||
|
g_warning ("%s", g_module_error ());
|
||||||
|
g_module_close (module->library);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (register_func);
|
||||||
|
|
||||||
|
module->type = register_func (gmodule);
|
||||||
|
|
||||||
|
if (module->type == 0) {
|
||||||
|
g_warning ("Invalid gnome settings plugin in module %s", module->path);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_module_unload (GTypeModule *gmodule)
|
||||||
|
{
|
||||||
|
GnomeSettingsModule *module = GNOME_SETTINGS_MODULE (gmodule);
|
||||||
|
|
||||||
|
g_debug ("Unloading %s", module->path);
|
||||||
|
|
||||||
|
g_module_close (module->library);
|
||||||
|
|
||||||
|
module->library = NULL;
|
||||||
|
module->type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
gnome_settings_module_get_path (GnomeSettingsModule *module)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_MODULE (module), NULL);
|
||||||
|
|
||||||
|
return module->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
gnome_settings_module_new_object (GnomeSettingsModule *module)
|
||||||
|
{
|
||||||
|
g_debug ("Creating object of type %s", g_type_name (module->type));
|
||||||
|
|
||||||
|
if (module->type == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_object_new (module->type, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_module_init (GnomeSettingsModule *module)
|
||||||
|
{
|
||||||
|
g_debug ("GnomeSettingsModule %p initialising", module);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_module_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GnomeSettingsModule *module = GNOME_SETTINGS_MODULE (object);
|
||||||
|
|
||||||
|
g_debug ("GnomeSettingsModule %p finalizing", module);
|
||||||
|
|
||||||
|
g_free (module->path);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gnome_settings_module_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_module_class_init (GnomeSettingsModuleClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
|
||||||
|
|
||||||
|
object_class->finalize = gnome_settings_module_finalize;
|
||||||
|
|
||||||
|
module_class->load = gnome_settings_module_load;
|
||||||
|
module_class->unload = gnome_settings_module_unload;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnomeSettingsModule *
|
||||||
|
gnome_settings_module_new (const char *path)
|
||||||
|
{
|
||||||
|
GnomeSettingsModule *result;
|
||||||
|
|
||||||
|
if (path == NULL || path[0] == '\0') {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = g_object_new (GNOME_TYPE_SETTINGS_MODULE, NULL);
|
||||||
|
|
||||||
|
g_type_module_set_name (G_TYPE_MODULE (result), path);
|
||||||
|
result->path = g_strdup (path);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
45
gnome-settings-daemon/gnome-settings-module.h
Normal file
45
gnome-settings-daemon/gnome-settings-module.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 - Paolo Maggi
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNOME_SETTINGS_MODULE_H
|
||||||
|
#define GNOME_SETTINGS_MODULE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GNOME_TYPE_SETTINGS_MODULE (gnome_settings_module_get_type ())
|
||||||
|
#define GNOME_SETTINGS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_SETTINGS_MODULE, GnomeSettingsModule))
|
||||||
|
#define GNOME_SETTINGS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_SETTINGS_MODULE, GnomeSettingsModuleClass))
|
||||||
|
#define GNOME_IS_SETTINGS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_SETTINGS_MODULE))
|
||||||
|
#define GNOME_IS_SETTINGS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GNOME_TYPE_SETTINGS_MODULE))
|
||||||
|
#define GNOME_SETTINGS_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNOME_TYPE_SETTINGS_MODULE, GnomeSettingsModuleClass))
|
||||||
|
|
||||||
|
typedef struct _GnomeSettingsModule GnomeSettingsModule;
|
||||||
|
|
||||||
|
GType gnome_settings_module_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GnomeSettingsModule *gnome_settings_module_new (const gchar *path);
|
||||||
|
|
||||||
|
const char *gnome_settings_module_get_path (GnomeSettingsModule *module);
|
||||||
|
|
||||||
|
GObject *gnome_settings_module_new_object (GnomeSettingsModule *module);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
471
gnome-settings-daemon/gnome-settings-plugin-info.c
Normal file
471
gnome-settings-daemon/gnome-settings-plugin-info.c
Normal file
|
@ -0,0 +1,471 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gnome-settings-plugin-info.h"
|
||||||
|
#include "gnome-settings-module.h"
|
||||||
|
#include "gnome-settings-plugin.h"
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
|
||||||
|
#define PLUGIN_GROUP "GNOME Settings Plugin"
|
||||||
|
|
||||||
|
#define PLUGIN_PRIORITY_MAX 1
|
||||||
|
#define PLUGIN_PRIORITY_DEFAULT 100
|
||||||
|
|
||||||
|
struct GnomeSettingsPluginInfoPrivate
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
GSettings *settings;
|
||||||
|
|
||||||
|
char *location;
|
||||||
|
GTypeModule *module;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
char *desc;
|
||||||
|
char **authors;
|
||||||
|
char *copyright;
|
||||||
|
char *website;
|
||||||
|
|
||||||
|
GnomeSettingsPlugin *plugin;
|
||||||
|
|
||||||
|
int active : 1;
|
||||||
|
|
||||||
|
/* A plugin is unavailable if it is not possible to activate it
|
||||||
|
due to an error loading the plugin module (e.g. for Python plugins
|
||||||
|
when the interpreter has not been correctly initializated) */
|
||||||
|
int available : 1;
|
||||||
|
|
||||||
|
/* Priority determines the order in which plugins are started and
|
||||||
|
* stopped. A lower number means higher priority. */
|
||||||
|
guint priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ACTIVATED,
|
||||||
|
DEACTIVATED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals [LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (GnomeSettingsPluginInfo, gnome_settings_plugin_info, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_plugin_info_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GnomeSettingsPluginInfo *info;
|
||||||
|
|
||||||
|
g_return_if_fail (object != NULL);
|
||||||
|
g_return_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (object));
|
||||||
|
|
||||||
|
info = GNOME_SETTINGS_PLUGIN_INFO (object);
|
||||||
|
|
||||||
|
g_return_if_fail (info->priv != NULL);
|
||||||
|
|
||||||
|
if (info->priv->plugin != NULL) {
|
||||||
|
g_debug ("Unref plugin %s", info->priv->name);
|
||||||
|
|
||||||
|
g_object_unref (info->priv->plugin);
|
||||||
|
|
||||||
|
/* info->priv->module must not be unref since it is not possible to finalize
|
||||||
|
* a type module */
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (info->priv->file);
|
||||||
|
g_free (info->priv->location);
|
||||||
|
g_free (info->priv->name);
|
||||||
|
g_free (info->priv->desc);
|
||||||
|
g_free (info->priv->website);
|
||||||
|
g_free (info->priv->copyright);
|
||||||
|
g_strfreev (info->priv->authors);
|
||||||
|
|
||||||
|
if (info->priv->settings != NULL) {
|
||||||
|
g_object_unref (info->priv->settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gnome_settings_plugin_info_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_plugin_info_class_init (GnomeSettingsPluginInfoClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gnome_settings_plugin_info_finalize;
|
||||||
|
|
||||||
|
signals [ACTIVATED] =
|
||||||
|
g_signal_new ("activated",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GnomeSettingsPluginInfoClass, activated),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
0);
|
||||||
|
signals [DEACTIVATED] =
|
||||||
|
g_signal_new ("deactivated",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GnomeSettingsPluginInfoClass, deactivated),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnome_settings_plugin_info_init (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
info->priv = gnome_settings_plugin_info_get_instance_private (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
debug_info (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_debug ("GnomeSettingsPluginInfo: name='%s' file='%s' location='%s'",
|
||||||
|
info->priv->name,
|
||||||
|
info->priv->file,
|
||||||
|
info->priv->location);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gnome_settings_plugin_info_fill_from_file (GnomeSettingsPluginInfo *info,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
GKeyFile *plugin_file = NULL;
|
||||||
|
char *str;
|
||||||
|
int priority;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
gnome_settings_profile_start ("%s", filename);
|
||||||
|
|
||||||
|
ret = FALSE;
|
||||||
|
|
||||||
|
info->priv->file = g_strdup (filename);
|
||||||
|
|
||||||
|
plugin_file = g_key_file_new ();
|
||||||
|
if (! g_key_file_load_from_file (plugin_file, filename, G_KEY_FILE_NONE, NULL)) {
|
||||||
|
g_warning ("Bad plugin file: %s", filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! g_key_file_has_key (plugin_file, PLUGIN_GROUP, "IAge", NULL)) {
|
||||||
|
g_debug ("IAge key does not exist in file: %s", filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check IAge=2 */
|
||||||
|
if (g_key_file_get_integer (plugin_file, PLUGIN_GROUP, "IAge", NULL) != 0) {
|
||||||
|
g_debug ("Wrong IAge in file: %s", filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Location */
|
||||||
|
str = g_key_file_get_string (plugin_file, PLUGIN_GROUP, "Module", NULL);
|
||||||
|
|
||||||
|
if ((str != NULL) && (*str != '\0')) {
|
||||||
|
info->priv->location = str;
|
||||||
|
} else {
|
||||||
|
g_free (str);
|
||||||
|
g_warning ("Could not find 'Module' in %s", filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Name */
|
||||||
|
str = g_key_file_get_locale_string (plugin_file, PLUGIN_GROUP, "Name", NULL, NULL);
|
||||||
|
if (str != NULL) {
|
||||||
|
info->priv->name = str;
|
||||||
|
} else {
|
||||||
|
g_warning ("Could not find 'Name' in %s", filename);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Description */
|
||||||
|
str = g_key_file_get_locale_string (plugin_file, PLUGIN_GROUP, "Description", NULL, NULL);
|
||||||
|
if (str != NULL) {
|
||||||
|
info->priv->desc = str;
|
||||||
|
} else {
|
||||||
|
g_debug ("Could not find 'Description' in %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Authors */
|
||||||
|
info->priv->authors = g_key_file_get_string_list (plugin_file, PLUGIN_GROUP, "Authors", NULL, NULL);
|
||||||
|
if (info->priv->authors == NULL) {
|
||||||
|
g_debug ("Could not find 'Authors' in %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Copyright */
|
||||||
|
str = g_key_file_get_string (plugin_file, PLUGIN_GROUP, "Copyright", NULL);
|
||||||
|
if (str != NULL) {
|
||||||
|
info->priv->copyright = str;
|
||||||
|
} else {
|
||||||
|
g_debug ("Could not find 'Copyright' in %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Website */
|
||||||
|
str = g_key_file_get_string (plugin_file, PLUGIN_GROUP, "Website", NULL);
|
||||||
|
if (str != NULL) {
|
||||||
|
info->priv->website = str;
|
||||||
|
} else {
|
||||||
|
g_debug ("Could not find 'Website' in %s", filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Priority */
|
||||||
|
priority = g_key_file_get_integer (plugin_file, PLUGIN_GROUP, "Priority", NULL);
|
||||||
|
if (priority >= PLUGIN_PRIORITY_MAX) {
|
||||||
|
info->priv->priority = priority;
|
||||||
|
} else {
|
||||||
|
info->priv->priority = PLUGIN_PRIORITY_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_file_free (plugin_file);
|
||||||
|
|
||||||
|
debug_info (info);
|
||||||
|
|
||||||
|
/* If we know nothing about the availability of the plugin,
|
||||||
|
set it as available */
|
||||||
|
info->priv->available = TRUE;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
out:
|
||||||
|
gnome_settings_profile_end ("%s", filename);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
GnomeSettingsPluginInfo *
|
||||||
|
gnome_settings_plugin_info_new_from_file (const char *filename)
|
||||||
|
{
|
||||||
|
GnomeSettingsPluginInfo *info;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
info = g_object_new (GNOME_TYPE_SETTINGS_PLUGIN_INFO, NULL);
|
||||||
|
|
||||||
|
res = gnome_settings_plugin_info_fill_from_file (info, filename);
|
||||||
|
if (! res) {
|
||||||
|
g_object_unref (info);
|
||||||
|
info = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_deactivate_plugin (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
gnome_settings_plugin_deactivate (info->priv->plugin);
|
||||||
|
g_signal_emit (info, signals [DEACTIVATED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnome_settings_plugin_info_deactivate (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), FALSE);
|
||||||
|
|
||||||
|
if (!info->priv->active || !info->priv->available) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_deactivate_plugin (info);
|
||||||
|
|
||||||
|
/* Update plugin state */
|
||||||
|
info->priv->active = FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
load_plugin_module (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
char *dirname;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
ret = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), FALSE);
|
||||||
|
g_return_val_if_fail (info->priv->file != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (info->priv->location != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (info->priv->plugin == NULL, FALSE);
|
||||||
|
g_return_val_if_fail (info->priv->available, FALSE);
|
||||||
|
|
||||||
|
gnome_settings_profile_start ("%s", info->priv->location);
|
||||||
|
|
||||||
|
dirname = g_path_get_dirname (info->priv->file);
|
||||||
|
g_return_val_if_fail (dirname != NULL, FALSE);
|
||||||
|
|
||||||
|
path = g_module_build_path (dirname, info->priv->location);
|
||||||
|
g_free (dirname);
|
||||||
|
g_return_val_if_fail (path != NULL, FALSE);
|
||||||
|
|
||||||
|
info->priv->module = G_TYPE_MODULE (gnome_settings_module_new (path));
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
if (!g_type_module_use (info->priv->module)) {
|
||||||
|
g_warning ("Cannot load plugin '%s' since file '%s' cannot be read.",
|
||||||
|
info->priv->name,
|
||||||
|
gnome_settings_module_get_path (GNOME_SETTINGS_MODULE (info->priv->module)));
|
||||||
|
|
||||||
|
g_object_unref (G_OBJECT (info->priv->module));
|
||||||
|
info->priv->module = NULL;
|
||||||
|
|
||||||
|
/* Mark plugin as unavailable and fails */
|
||||||
|
info->priv->available = FALSE;
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->priv->plugin = GNOME_SETTINGS_PLUGIN (gnome_settings_module_new_object (GNOME_SETTINGS_MODULE (info->priv->module)));
|
||||||
|
|
||||||
|
g_type_module_unuse (info->priv->module);
|
||||||
|
ret = TRUE;
|
||||||
|
out:
|
||||||
|
gnome_settings_profile_end ("%s", info->priv->location);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_activate_plugin (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
|
||||||
|
if (!info->priv->available) {
|
||||||
|
/* Plugin is not available, don't try to activate/load it */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->priv->plugin == NULL) {
|
||||||
|
res = load_plugin_module (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
gnome_settings_plugin_activate (info->priv->plugin);
|
||||||
|
g_signal_emit (info, signals [ACTIVATED], 0);
|
||||||
|
} else {
|
||||||
|
g_warning ("Error activating plugin '%s'", info->priv->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnome_settings_plugin_info_activate (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), FALSE);
|
||||||
|
|
||||||
|
if (! info->priv->available) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->priv->active) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_activate_plugin (info)) {
|
||||||
|
info->priv->active = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnome_settings_plugin_info_is_active (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), FALSE);
|
||||||
|
|
||||||
|
return (info->priv->available && info->priv->active);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnome_settings_plugin_info_is_available (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), FALSE);
|
||||||
|
|
||||||
|
return (info->priv->available != FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gnome_settings_plugin_info_get_name (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), NULL);
|
||||||
|
|
||||||
|
return info->priv->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gnome_settings_plugin_info_get_description (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), NULL);
|
||||||
|
|
||||||
|
return info->priv->desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **
|
||||||
|
gnome_settings_plugin_info_get_authors (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), (const char **)NULL);
|
||||||
|
|
||||||
|
return (const char **)info->priv->authors;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gnome_settings_plugin_info_get_website (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), NULL);
|
||||||
|
|
||||||
|
return info->priv->website;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gnome_settings_plugin_info_get_copyright (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), NULL);
|
||||||
|
|
||||||
|
return info->priv->copyright;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gnome_settings_plugin_info_get_location (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), NULL);
|
||||||
|
|
||||||
|
return info->priv->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gnome_settings_plugin_info_get_priority (GnomeSettingsPluginInfo *info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GNOME_IS_SETTINGS_PLUGIN_INFO (info), PLUGIN_PRIORITY_DEFAULT);
|
||||||
|
|
||||||
|
return info->priv->priority;
|
||||||
|
}
|
69
gnome-settings-daemon/gnome-settings-plugin-info.h
Normal file
69
gnome-settings-daemon/gnome-settings-plugin-info.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/* -*- 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GNOME_SETTINGS_PLUGIN_INFO_H__
|
||||||
|
#define __GNOME_SETTINGS_PLUGIN_INFO_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
#define GNOME_TYPE_SETTINGS_PLUGIN_INFO (gnome_settings_plugin_info_get_type())
|
||||||
|
#define GNOME_SETTINGS_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNOME_TYPE_SETTINGS_PLUGIN_INFO, GnomeSettingsPluginInfo))
|
||||||
|
#define GNOME_SETTINGS_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNOME_TYPE_SETTINGS_PLUGIN_INFO, GnomeSettingsPluginInfoClass))
|
||||||
|
#define GNOME_IS_SETTINGS_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNOME_TYPE_SETTINGS_PLUGIN_INFO))
|
||||||
|
#define GNOME_IS_SETTINGS_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_SETTINGS_PLUGIN_INFO))
|
||||||
|
#define GNOME_SETTINGS_PLUGIN_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNOME_TYPE_SETTINGS_PLUGIN_INFO, GnomeSettingsPluginInfoClass))
|
||||||
|
|
||||||
|
typedef struct GnomeSettingsPluginInfoPrivate GnomeSettingsPluginInfoPrivate;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
GnomeSettingsPluginInfoPrivate *priv;
|
||||||
|
} GnomeSettingsPluginInfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* activated) (GnomeSettingsPluginInfo *info);
|
||||||
|
void (* deactivated) (GnomeSettingsPluginInfo *info);
|
||||||
|
} GnomeSettingsPluginInfoClass;
|
||||||
|
|
||||||
|
GType gnome_settings_plugin_info_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GnomeSettingsPluginInfo *gnome_settings_plugin_info_new_from_file (const char *filename);
|
||||||
|
|
||||||
|
gboolean gnome_settings_plugin_info_activate (GnomeSettingsPluginInfo *info);
|
||||||
|
gboolean gnome_settings_plugin_info_deactivate (GnomeSettingsPluginInfo *info);
|
||||||
|
|
||||||
|
gboolean gnome_settings_plugin_info_is_active (GnomeSettingsPluginInfo *info);
|
||||||
|
gboolean gnome_settings_plugin_info_is_available (GnomeSettingsPluginInfo *info);
|
||||||
|
|
||||||
|
const char *gnome_settings_plugin_info_get_name (GnomeSettingsPluginInfo *info);
|
||||||
|
const char *gnome_settings_plugin_info_get_description (GnomeSettingsPluginInfo *info);
|
||||||
|
const char **gnome_settings_plugin_info_get_authors (GnomeSettingsPluginInfo *info);
|
||||||
|
const char *gnome_settings_plugin_info_get_website (GnomeSettingsPluginInfo *info);
|
||||||
|
const char *gnome_settings_plugin_info_get_copyright (GnomeSettingsPluginInfo *info);
|
||||||
|
const char *gnome_settings_plugin_info_get_location (GnomeSettingsPluginInfo *info);
|
||||||
|
int gnome_settings_plugin_info_get_priority (GnomeSettingsPluginInfo *info);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GNOME_SETTINGS_PLUGIN_INFO_H__ */
|
64
gnome-settings-daemon/gnome-settings-profile.c
Normal file
64
gnome-settings-daemon/gnome-settings-profile.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors: William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
_gnome_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);
|
||||||
|
}
|
52
gnome-settings-daemon/gnome-settings-profile.h
Normal file
52
gnome-settings-daemon/gnome-settings-profile.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors: William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GNOME_SETTINGS_PROFILE_H
|
||||||
|
#define __GNOME_SETTINGS_PROFILE_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#ifdef ENABLE_PROFILING
|
||||||
|
#ifdef G_HAVE_ISO_VARARGS
|
||||||
|
#define gnome_settings_profile_start(...) _gnome_settings_profile_log (G_STRFUNC, "start", __VA_ARGS__)
|
||||||
|
#define gnome_settings_profile_end(...) _gnome_settings_profile_log (G_STRFUNC, "end", __VA_ARGS__)
|
||||||
|
#define gnome_settings_profile_msg(...) _gnome_settings_profile_log (NULL, NULL, __VA_ARGS__)
|
||||||
|
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||||
|
#define gnome_settings_profile_start(format...) _gnome_settings_profile_log (G_STRFUNC, "start", format)
|
||||||
|
#define gnome_settings_profile_end(format...) _gnome_settings_profile_log (G_STRFUNC, "end", format)
|
||||||
|
#define gnome_settings_profile_msg(format...) _gnome_settings_profile_log (NULL, NULL, format)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define gnome_settings_profile_start(...)
|
||||||
|
#define gnome_settings_profile_end(...)
|
||||||
|
#define gnome_settings_profile_msg(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _gnome_settings_profile_log (const char *func,
|
||||||
|
const char *note,
|
||||||
|
const char *format,
|
||||||
|
...) G_GNUC_PRINTF (3, 4);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GNOME_SETTINGS_PROFILE_H */
|
50
gnome-settings-daemon/meson.build
Normal file
50
gnome-settings-daemon/meson.build
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
sources = files(
|
||||||
|
'gnome-settings-bus.c',
|
||||||
|
'gnome-settings-profile.c'
|
||||||
|
)
|
||||||
|
|
||||||
|
dbus_ifaces = [
|
||||||
|
['SessionManager', 'gsd-session-manager-glue', 'SessionManager'],
|
||||||
|
['ScreenSaver', 'gsd-screen-saver-glue', 'ScreenSaver'],
|
||||||
|
['Shell', 'gsd-shell-glue', 'Shell'],
|
||||||
|
['Mutter.DisplayConfig', 'gsd-display-config-glue', 'DisplayConfig'],
|
||||||
|
]
|
||||||
|
|
||||||
|
dbus_headers = []
|
||||||
|
|
||||||
|
foreach iface: dbus_ifaces
|
||||||
|
name = 'org.gnome.' + iface[0]
|
||||||
|
c_name = iface[2]
|
||||||
|
|
||||||
|
dbus_sources = gnome.gdbus_codegen(
|
||||||
|
iface[1],
|
||||||
|
name + '.xml',
|
||||||
|
interface_prefix: name + '.',
|
||||||
|
namespace: 'Gsd',
|
||||||
|
annotations: [name, 'org.gtk.GDBus.C.Name', iface[2]]
|
||||||
|
)
|
||||||
|
|
||||||
|
sources += dbus_sources[0]
|
||||||
|
dbus_headers += dbus_sources[1]
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
deps = [gio_unix_dep]
|
||||||
|
|
||||||
|
if enable_wayland
|
||||||
|
deps += wayland_client_dep
|
||||||
|
endif
|
||||||
|
|
||||||
|
libgsd = shared_library(
|
||||||
|
'gsd',
|
||||||
|
sources: sources + dbus_headers,
|
||||||
|
include_directories: top_inc,
|
||||||
|
dependencies: deps,
|
||||||
|
install: true,
|
||||||
|
install_dir: gsd_pkglibdir
|
||||||
|
)
|
||||||
|
|
||||||
|
libgsd_dep = declare_dependency(
|
||||||
|
sources: dbus_headers,
|
||||||
|
include_directories: include_directories('.'),
|
||||||
|
link_with: libgsd
|
||||||
|
)
|
536
gnome-settings-daemon/org.gnome.Mutter.DisplayConfig.xml
Normal file
536
gnome-settings-daemon/org.gnome.Mutter.DisplayConfig.xml
Normal file
|
@ -0,0 +1,536 @@
|
||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||||
|
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||||
|
<node>
|
||||||
|
<!--
|
||||||
|
org.gnome.Mutter.DisplayConfig:
|
||||||
|
@short_description: display configuration interface
|
||||||
|
|
||||||
|
This interface is used by mutter and gnome-settings-daemon
|
||||||
|
to apply multiple monitor configuration.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<interface name="org.gnome.Mutter.DisplayConfig">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
GetResources:
|
||||||
|
@serial: configuration serial
|
||||||
|
@crtcs: available CRTCs
|
||||||
|
@outputs: available outputs
|
||||||
|
@modes: available modes
|
||||||
|
@max_screen_width:
|
||||||
|
@max_screen_height:
|
||||||
|
|
||||||
|
Retrieves the current layout of the hardware.
|
||||||
|
|
||||||
|
@serial is an unique identifier representing the current state
|
||||||
|
of the screen. It must be passed back to ApplyConfiguration()
|
||||||
|
and will be increased for every configuration change (so that
|
||||||
|
mutter can detect that the new configuration is based on old
|
||||||
|
state).
|
||||||
|
|
||||||
|
A CRTC (CRT controller) is a logical monitor, ie a portion
|
||||||
|
of the compositor coordinate space. It might correspond
|
||||||
|
to multiple monitors, when in clone mode, but not that
|
||||||
|
it is possible to implement clone mode also by setting different
|
||||||
|
CRTCs to the same coordinates.
|
||||||
|
|
||||||
|
The number of CRTCs represent the maximum number of monitors
|
||||||
|
that can be set to expand and it is a HW constraint; if more
|
||||||
|
monitors are connected, then necessarily some will clone. This
|
||||||
|
is complementary to the concept of the encoder (not exposed in
|
||||||
|
the API), which groups outputs that necessarily will show the
|
||||||
|
same image (again a HW constraint).
|
||||||
|
|
||||||
|
A CRTC is represented by a DBus structure with the following
|
||||||
|
layout:
|
||||||
|
* u ID: the ID in the API of this CRTC
|
||||||
|
* x winsys_id: the low-level ID of this CRTC (which might
|
||||||
|
be a XID, a KMS handle or something entirely
|
||||||
|
different)
|
||||||
|
* i x, y, width, height: the geometry of this CRTC
|
||||||
|
(might be invalid if the CRTC is not in
|
||||||
|
use)
|
||||||
|
* i current_mode: the current mode of the CRTC, or -1 if this
|
||||||
|
CRTC is not used
|
||||||
|
Note: the size of the mode will always correspond
|
||||||
|
to the width and height of the CRTC
|
||||||
|
* u current_transform: the current transform (espressed according
|
||||||
|
to the wayland protocol)
|
||||||
|
* au transforms: all possible transforms
|
||||||
|
* a{sv} properties: other high-level properties that affect this
|
||||||
|
CRTC; they are not necessarily reflected in
|
||||||
|
the hardware.
|
||||||
|
No property is specified in this version of the API.
|
||||||
|
|
||||||
|
Note: all geometry information refers to the untransformed
|
||||||
|
display.
|
||||||
|
|
||||||
|
An output represents a physical screen, connected somewhere to
|
||||||
|
the computer. Floating connectors are not exposed in the API.
|
||||||
|
An output is a DBus struct with the following fields:
|
||||||
|
* u ID: the ID in the API
|
||||||
|
* x winsys_id: the low-level ID of this output (XID or KMS handle)
|
||||||
|
* i current_crtc: the CRTC that is currently driving this output,
|
||||||
|
or -1 if the output is disabled
|
||||||
|
* au possible_crtcs: all CRTCs that can control this output
|
||||||
|
* s name: the name of the connector to which the output is attached
|
||||||
|
(like VGA1 or HDMI)
|
||||||
|
* au modes: valid modes for this output
|
||||||
|
* au clones: valid clones for this output, ie other outputs that
|
||||||
|
can be assigned the same CRTC as this one; if you
|
||||||
|
want to mirror two outputs that don't have each other
|
||||||
|
in the clone list, you must configure two different
|
||||||
|
CRTCs for the same geometry
|
||||||
|
* a{sv} properties: other high-level properties that affect this
|
||||||
|
output; they are not necessarily reflected in
|
||||||
|
the hardware.
|
||||||
|
Known properties:
|
||||||
|
- "vendor" (s): (readonly) the human readable name
|
||||||
|
of the manufacturer
|
||||||
|
- "product" (s): (readonly) the human readable name
|
||||||
|
of the display model
|
||||||
|
- "serial" (s): (readonly) the serial number of this
|
||||||
|
particular hardware part
|
||||||
|
- "display-name" (s): (readonly) a human readable name
|
||||||
|
of this output, to be shown in the UI
|
||||||
|
- "backlight" (i): (readonly, use the specific interface)
|
||||||
|
the backlight value as a percentage
|
||||||
|
(-1 if not supported)
|
||||||
|
- "primary" (b): whether this output is primary
|
||||||
|
or not
|
||||||
|
- "presentation" (b): whether this output is
|
||||||
|
for presentation only
|
||||||
|
Note: properties might be ignored if not consistently
|
||||||
|
applied to all outputs in the same clone group. In
|
||||||
|
general, it's expected that presentation or primary
|
||||||
|
outputs will not be cloned.
|
||||||
|
|
||||||
|
A mode represents a set of parameters that are applied to
|
||||||
|
each output, such as resolution and refresh rate. It is a separate
|
||||||
|
object so that it can be referenced by CRTCs and outputs.
|
||||||
|
Multiple outputs in the same CRTCs must all have the same mode.
|
||||||
|
A mode is exposed as:
|
||||||
|
* u ID: the ID in the API
|
||||||
|
* x winsys_id: the low-level ID of this mode
|
||||||
|
* u width, height: the resolution
|
||||||
|
* d frequency: refresh rate
|
||||||
|
* u flags: mode flags as defined in xf86drmMode.h and randr.h
|
||||||
|
|
||||||
|
Output and modes are read-only objects (except for output properties),
|
||||||
|
they can change only in accordance to HW changes (such as hotplugging
|
||||||
|
a monitor), while CRTCs can be changed with ApplyConfiguration().
|
||||||
|
|
||||||
|
XXX: actually, if you insist enough, you can add new modes
|
||||||
|
through xrandr command line or the KMS API, overriding what the
|
||||||
|
kernel driver and the EDID say.
|
||||||
|
Usually, it only matters with old cards with broken drivers, or
|
||||||
|
old monitors with broken EDIDs, but it happens more often with
|
||||||
|
projectors (if for example the kernel driver doesn't add the
|
||||||
|
640x480 - 800x600 - 1024x768 default modes). Probably something
|
||||||
|
that we need to handle in mutter anyway.
|
||||||
|
-->
|
||||||
|
<method name="GetResources">
|
||||||
|
<arg name="serial" direction="out" type="u" />
|
||||||
|
<arg name="crtcs" direction="out" type="a(uxiiiiiuaua{sv})" />
|
||||||
|
<arg name="outputs" direction="out" type="a(uxiausauaua{sv})" />
|
||||||
|
<arg name="modes" direction="out" type="a(uxuudu)" />
|
||||||
|
<arg name="max_screen_width" direction="out" type="i" />
|
||||||
|
<arg name="max_screen_height" direction="out" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ApplyConfiguration:
|
||||||
|
@serial: configuration serial
|
||||||
|
@persistent: whether this configuration should be saved on disk
|
||||||
|
@crtcs: new data for CRTCs
|
||||||
|
@outputs: new data for outputs
|
||||||
|
|
||||||
|
Applies the requested configuration changes.
|
||||||
|
|
||||||
|
@serial must match the serial from the last GetResources() call,
|
||||||
|
or org.freedesktop.DBus.AccessDenied will be generated.
|
||||||
|
|
||||||
|
If @persistent is true, mutter will attempt to replicate this
|
||||||
|
configuration the next time this HW layout appears.
|
||||||
|
|
||||||
|
@crtcs represents the new logical configuration, as a list
|
||||||
|
of structures containing:
|
||||||
|
- u ID: the API ID from the corresponding GetResources() call
|
||||||
|
- i new_mode: the API ID of the new mode to configure the CRTC
|
||||||
|
with, or -1 if the CRTC should be disabled
|
||||||
|
- i x, y: the new coordinates of the top left corner
|
||||||
|
the geometry will be completed with the size information
|
||||||
|
from @new_mode
|
||||||
|
- u transform: the desired transform
|
||||||
|
- au outputs: the API ID of outputs that should be assigned to
|
||||||
|
this CRTC
|
||||||
|
- a{sv} properties: properties whose value should be changed
|
||||||
|
|
||||||
|
Note: CRTCs not referenced in the array will be disabled.
|
||||||
|
|
||||||
|
@outputs represent the output property changes as:
|
||||||
|
- u ID: the API ID of the output to change
|
||||||
|
- a{sv} properties: properties whose value should be changed
|
||||||
|
|
||||||
|
Note: both for CRTCs and outputs, properties not included in
|
||||||
|
the dictionary will not be changed.
|
||||||
|
|
||||||
|
Note: unrecognized properties will have no effect, but if the
|
||||||
|
configuration change succeeds the property will be reported
|
||||||
|
by the next GetResources() call, and if @persistent is true,
|
||||||
|
it will also be saved to disk.
|
||||||
|
|
||||||
|
If the configuration is invalid according to the previous
|
||||||
|
GetResources() call, for example because a CRTC references
|
||||||
|
an output it cannot drive, or not all outputs support the
|
||||||
|
chosen mode, the error org.freedesktop.DBus.InvalidArgs will
|
||||||
|
be generated.
|
||||||
|
|
||||||
|
If the configuration cannot be applied for any other reason
|
||||||
|
(eg. the screen size would exceed texture limits), the error
|
||||||
|
org.freedesktop.DBus.Error.LimitsExceeded will be generated.
|
||||||
|
-->
|
||||||
|
<method name="ApplyConfiguration">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="persistent" direction="in" type="b" />
|
||||||
|
<arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" />
|
||||||
|
<arg name="outputs" direction="in" type="a(ua{sv})" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ChangeBacklight:
|
||||||
|
@serial: configuration serial
|
||||||
|
@output: the API id of the output
|
||||||
|
@value: the new backlight value
|
||||||
|
|
||||||
|
Changes the backlight of @output to @value, which is
|
||||||
|
expressed as a percentage and rounded to the HW limits.
|
||||||
|
|
||||||
|
Returns the new value after rounding.
|
||||||
|
-->
|
||||||
|
<method name="ChangeBacklight">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="output" direction="in" type="u" />
|
||||||
|
<arg name="value" direction="in" type="i" />
|
||||||
|
<arg name="new_value" direction="out" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SetBacklight:
|
||||||
|
@serial: configuration serial
|
||||||
|
@connector: the connector name
|
||||||
|
@value: the new backlight value
|
||||||
|
|
||||||
|
Changes the backlight of @output to @value.
|
||||||
|
-->
|
||||||
|
<method name="SetBacklight">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="connector" direction="in" type="s" />
|
||||||
|
<arg name="value" direction="in" type="i" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Backlight:
|
||||||
|
|
||||||
|
A set of backlights. Each backlight is a dictionary with the following
|
||||||
|
entries. If an entry is only a connector, it means there is no way to
|
||||||
|
control it via this D-Bus interface.
|
||||||
|
|
||||||
|
* 'connector' (s) - An associated monitor connector
|
||||||
|
* 'active' (s) - True if the monitor is active
|
||||||
|
* 'min_step' (i) - Minimum step amount (optional)
|
||||||
|
* 'value' (i) - Current value (optional)
|
||||||
|
|
||||||
|
The initial 'u' is a serial number used when setting the backlight.
|
||||||
|
-->
|
||||||
|
<property name="Backlight" type="(uaa{sv})" access="read" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
GetCrtcGamma:
|
||||||
|
@serial: configuration serial
|
||||||
|
@crtc: API id of the crtc
|
||||||
|
@red: red gamma ramp
|
||||||
|
@green: green gamma ramp
|
||||||
|
@blue: blue gamma ramp
|
||||||
|
|
||||||
|
Requests the current gamma ramps of @crtc.
|
||||||
|
-->
|
||||||
|
<method name="GetCrtcGamma">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="crtc" direction="in" type="u" />
|
||||||
|
<arg name="red" direction="out" type="aq" />
|
||||||
|
<arg name="green" direction="out" type="aq" />
|
||||||
|
<arg name="blue" direction="out" type="aq" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SetCrtcGamma:
|
||||||
|
@serial: configuration serial
|
||||||
|
@crtc: API id of the crtc
|
||||||
|
@red: red gamma ramp
|
||||||
|
@green: green gamma ramp
|
||||||
|
@blue: blue gamma ramp
|
||||||
|
|
||||||
|
Changes the gamma ramps of @crtc.
|
||||||
|
-->
|
||||||
|
<method name="SetCrtcGamma">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="crtc" direction="in" type="u" />
|
||||||
|
<arg name="red" direction="in" type="aq" />
|
||||||
|
<arg name="green" direction="in" type="aq" />
|
||||||
|
<arg name="blue" direction="in" type="aq" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
PowerSaveMode:
|
||||||
|
|
||||||
|
Contains the current power saving mode for the screen, and
|
||||||
|
allows changing it.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
- 0: on
|
||||||
|
- 1: standby
|
||||||
|
- 2: suspend
|
||||||
|
- 3: off
|
||||||
|
- -1: unknown (unsupported)
|
||||||
|
|
||||||
|
A client should not attempt to change the powersave mode
|
||||||
|
from -1 (unknown) to any other value, and viceversa.
|
||||||
|
Note that the actual effects of the different values
|
||||||
|
depend on the hardware and the kernel driver in use, and
|
||||||
|
it's perfectly possible that all values different than on
|
||||||
|
have the same effect.
|
||||||
|
Also, setting the PowerSaveMode to 3 (off) may or may
|
||||||
|
not have the same effect as disabling all outputs by
|
||||||
|
setting no CRTC on them with ApplyConfiguration(), and
|
||||||
|
may or may not cause a configuration change.
|
||||||
|
|
||||||
|
Also note that this property might become out of date
|
||||||
|
if changed through different means (for example using the
|
||||||
|
XRandR interface directly).
|
||||||
|
-->
|
||||||
|
<property name="PowerSaveMode" type="i" access="readwrite" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
PanelOrientationManaged:
|
||||||
|
|
||||||
|
Whether the built-in panel orientation is automatically managed
|
||||||
|
by mutter.
|
||||||
|
-->
|
||||||
|
<property name="PanelOrientationManaged" type="b" access="read" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ApplyMonitorsConfigAllowed:
|
||||||
|
|
||||||
|
Whether calling the ApplyMonitorsConfig method is allowed.
|
||||||
|
-->
|
||||||
|
<property name="ApplyMonitorsConfigAllowed" type="b" access="read" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NightLightSupported:
|
||||||
|
|
||||||
|
Whether night light is supported by this system.
|
||||||
|
-->
|
||||||
|
<property name="NightLightSupported" type="b" access="read" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
MonitorsChanged:
|
||||||
|
|
||||||
|
The signal is emitted every time the screen configuration
|
||||||
|
changes.
|
||||||
|
The client should then call GetResources() to read the new layout.
|
||||||
|
-->
|
||||||
|
<signal name="MonitorsChanged" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
GetCurrentState:
|
||||||
|
@serial: configuration serial
|
||||||
|
@monitors: available monitors
|
||||||
|
@logical_monitors: current logical monitor configuration
|
||||||
|
@properties: display configuration properties
|
||||||
|
|
||||||
|
@monitors represent connected physical monitors
|
||||||
|
|
||||||
|
* s connector: connector name (e.g. HDMI-1, DP-1, etc)
|
||||||
|
* s vendor: vendor name
|
||||||
|
* s product: product name
|
||||||
|
* s serial: product serial
|
||||||
|
* a(siiddada{sv}) modes: available modes
|
||||||
|
* s id: mode ID
|
||||||
|
* i width: width in physical pixels
|
||||||
|
* i height: height in physical pixels
|
||||||
|
* d refresh rate: refresh rate
|
||||||
|
* d preferred scale: scale preferred as per calculations
|
||||||
|
* ad supported scales: scales supported by this mode
|
||||||
|
* a{sv} properties: optional properties, including:
|
||||||
|
- "is-current" (b): the mode is currently active mode
|
||||||
|
- "is-preferred" (b): the mode is the preferred mode
|
||||||
|
- "is-interlaced" (b): the mode is an interlaced mode
|
||||||
|
- "refresh-rate-mode" (s): the refresh rate mode, either
|
||||||
|
"variable" or "fixed" (absence
|
||||||
|
of this means "fixed")
|
||||||
|
* a{sv} properties: optional properties, including:
|
||||||
|
- "width-mm" (i): physical width of monitor in millimeters
|
||||||
|
- "height-mm" (i): physical height of monitor in millimeters
|
||||||
|
- "is-underscanning" (b): whether underscanning is enabled
|
||||||
|
(absence of this means underscanning
|
||||||
|
not being supported)
|
||||||
|
- "max-screen-size" (ii): the maximum size a screen may have
|
||||||
|
(absence of this means unlimited screen
|
||||||
|
size)
|
||||||
|
- "is-builtin" (b): whether the monitor is built in, e.g. a
|
||||||
|
laptop panel (absence of this means it is
|
||||||
|
not built in)
|
||||||
|
- "display-name" (s): a human readable display name of the monitor
|
||||||
|
- "privacy-screen-state" (bb): the state of the privacy screen
|
||||||
|
(absence of this means it is not being
|
||||||
|
supported) first value indicates whether
|
||||||
|
it's enabled and second value whether it's
|
||||||
|
hardware locked (and so can't be changed
|
||||||
|
via gsettings)
|
||||||
|
- "min-refresh-rate" (i): minimum refresh rate of monitor when
|
||||||
|
Variable Refresh Rate is active (absence
|
||||||
|
of this means unknown)
|
||||||
|
|
||||||
|
Possible mode flags:
|
||||||
|
1 : preferred mode
|
||||||
|
2 : current mode
|
||||||
|
|
||||||
|
|
||||||
|
@logical_monitors represent current logical monitor configuration
|
||||||
|
|
||||||
|
* i x: x position
|
||||||
|
* i y: y position
|
||||||
|
* d scale: scale
|
||||||
|
* u transform: transform (see below)
|
||||||
|
* b primary: true if this is the primary logical monitor
|
||||||
|
* a(sss) monitors: monitors displaying this logical monitor
|
||||||
|
* connector: name of the connector (e.g. DP-1, eDP-1 etc)
|
||||||
|
* vendor: vendor name
|
||||||
|
* product: product name
|
||||||
|
* serial: product serial
|
||||||
|
* a{sv} properties: possibly other properties
|
||||||
|
|
||||||
|
Posisble transform values:
|
||||||
|
0: normal
|
||||||
|
1: 90°
|
||||||
|
2: 180°
|
||||||
|
3: 270°
|
||||||
|
4: flipped
|
||||||
|
5: 90° flipped
|
||||||
|
6: 180° flipped
|
||||||
|
7: 270° flipped
|
||||||
|
|
||||||
|
|
||||||
|
@layout_mode current layout mode represents the way logical monitors
|
||||||
|
are laid out on the screen. Possible modes include:
|
||||||
|
|
||||||
|
1 : logical
|
||||||
|
2 : physical
|
||||||
|
|
||||||
|
With physical layout mode, each logical monitor has the same dimensions
|
||||||
|
as the monitor modes of the associated monitors assigned to it, no
|
||||||
|
matter what scale is in use.
|
||||||
|
|
||||||
|
With logical mode, the dimension of a logical monitor is the dimension
|
||||||
|
of the monitor mode, divided by the logical monitor scale.
|
||||||
|
|
||||||
|
|
||||||
|
Possible @properties are:
|
||||||
|
|
||||||
|
* "layout-mode" (u): Represents in what way logical monitors are laid
|
||||||
|
out on the screen. The layout mode can be either
|
||||||
|
of the ones listed below. Absence of this property
|
||||||
|
means the layout mode cannot be changed, and that
|
||||||
|
"logical" mode is assumed to be used.
|
||||||
|
* 1 : logical - the dimension of a logical monitor is derived from
|
||||||
|
the monitor modes associated with it, then scaled
|
||||||
|
using the logical monitor scale.
|
||||||
|
* 2 : physical - the dimension of a logical monitor is derived from
|
||||||
|
the monitor modes associated with it.
|
||||||
|
* "supports-changing-layout-mode" (b): True if the layout mode can be
|
||||||
|
changed. Absence of this means the
|
||||||
|
layout mode cannot be changed.
|
||||||
|
* "global-scale-required" (b): True if all the logical monitors must
|
||||||
|
always use the same scale. Absence of
|
||||||
|
this means logical monitor scales can
|
||||||
|
differ.
|
||||||
|
* "legacy-ui-scaling-factor" (i): The legacy scaling factor traditionally
|
||||||
|
used to scale X11 clients (commonly
|
||||||
|
communicated via the
|
||||||
|
Gdk/WindowScalingFactor XSetting entry).
|
||||||
|
-->
|
||||||
|
<method name="GetCurrentState">
|
||||||
|
<arg name="serial" direction="out" type="u" />
|
||||||
|
<arg name="monitors" direction="out" type="a((ssss)a(siiddada{sv})a{sv})" />
|
||||||
|
<arg name="logical_monitors" direction="out" type="a(iiduba(ssss)a{sv})" />
|
||||||
|
<arg name="properties" direction="out" type="a{sv}" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ApplyMonitorsConfig:
|
||||||
|
@serial: configuration serial
|
||||||
|
@method: configuration method
|
||||||
|
@logical_monitors: monitors configuration
|
||||||
|
@properties: properties
|
||||||
|
|
||||||
|
@method represents the way the configuration should be handled.
|
||||||
|
|
||||||
|
Possible methods:
|
||||||
|
0: verify
|
||||||
|
1: temporary
|
||||||
|
2: persistent
|
||||||
|
|
||||||
|
@logical_monitors consists of a list of logical monitor configurations.
|
||||||
|
Each logical monitor configuration consists of:
|
||||||
|
|
||||||
|
* i: layout x position
|
||||||
|
* i: layout y position
|
||||||
|
* d: scale
|
||||||
|
* u: transform (see GetCurrentState)
|
||||||
|
* b primary: true if this is the primary logical monitor
|
||||||
|
* a(ssa{sv}): a list of monitors, each consisting of:
|
||||||
|
* s: connector
|
||||||
|
* s: monitor mode ID
|
||||||
|
* a{sv}: monitor properties, including:
|
||||||
|
- "enable_underscanning" (b): enable monitor underscanning;
|
||||||
|
may only be set when underscanning
|
||||||
|
is supported (see GetCurrentState).
|
||||||
|
|
||||||
|
@properties may effect the global monitor configuration state. Possible
|
||||||
|
properties are:
|
||||||
|
|
||||||
|
* "layout-mode" (u): layout mode the passed configuration is in; may
|
||||||
|
only be set when changing the layout mode is
|
||||||
|
supported (see GetCurrentState).
|
||||||
|
-->
|
||||||
|
<method name="ApplyMonitorsConfig">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="method" direction="in" type="u" />
|
||||||
|
<arg name="logical_monitors" direction="in" type="a(iiduba(ssa{sv}))" />
|
||||||
|
<arg name="properties" direction="in" type="a{sv}" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SetOutputCTM:
|
||||||
|
@serial: configuration serial
|
||||||
|
@output: API id of the output
|
||||||
|
@ctm: 3x3 matrix in fixed-point sign-magnitude S31.32
|
||||||
|
|
||||||
|
Changes the color transform matrix of @output
|
||||||
|
-->
|
||||||
|
<method name="SetOutputCTM">
|
||||||
|
<arg name="serial" direction="in" type="u" />
|
||||||
|
<arg name="output" direction="in" type="u" />
|
||||||
|
<arg name="ctm" direction="in" type="(ttttttttt)" />
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
HasExternalmonitor:
|
||||||
|
|
||||||
|
True if there is an external monitor connected and activated.
|
||||||
|
-->
|
||||||
|
<property name="HasExternalMonitor" type="b" access="read" />
|
||||||
|
</interface>
|
||||||
|
</node>
|
43
gnome-settings-daemon/org.gnome.ScreenSaver.xml
Normal file
43
gnome-settings-daemon/org.gnome.ScreenSaver.xml
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2013 Red Hat, Inc.
|
||||||
|
|
||||||
|
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, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||||
|
<!--
|
||||||
|
org.gnome.ScreenSaver:
|
||||||
|
|
||||||
|
An interface used for managing the lock screen.
|
||||||
|
-->
|
||||||
|
<interface name="org.gnome.ScreenSaver">
|
||||||
|
<method name="Lock" />
|
||||||
|
<method name="GetActive">
|
||||||
|
<arg name="active" direction="out" type="b" />
|
||||||
|
</method>
|
||||||
|
<method name="SetActive">
|
||||||
|
<arg name="value" direction="in" type="b" />
|
||||||
|
</method>
|
||||||
|
<method name="GetActiveTime">
|
||||||
|
<arg name="value" direction="out" type="u" />
|
||||||
|
</method>
|
||||||
|
<signal name="ActiveChanged">
|
||||||
|
<arg name="new_value" type="b" />
|
||||||
|
</signal>
|
||||||
|
</interface>
|
||||||
|
</node>
|
451
gnome-settings-daemon/org.gnome.SessionManager.xml
Normal file
451
gnome-settings-daemon/org.gnome.SessionManager.xml
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||||
|
<interface name="org.gnome.SessionManager">
|
||||||
|
|
||||||
|
<!-- Initialization phase interfaces -->
|
||||||
|
|
||||||
|
<method name="Setenv">
|
||||||
|
<arg name="variable" type="s" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The variable name</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg name="value" type="s" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The value</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetLocale">
|
||||||
|
<arg name="category" type="i" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The locale category</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg name="value" type="s" direction="out">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The value</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Reads the current state of the specific locale category.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="InitializationError">
|
||||||
|
<arg name="message" type="s" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The error message</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg name="fatal" type="b" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>Whether the error should be treated as fatal</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>May be used by applications launched during the Session Manager initialization phase to indicate there was a problem.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!-- Running phase interfaces -->
|
||||||
|
|
||||||
|
<method name="RegisterClient">
|
||||||
|
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||||
|
<arg type="s" name="app_id" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The application identifier</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="s" name="client_startup_id" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>Client startup identifier</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="o" name="client_id" direction="out">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path of the newly registered client</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Register the caller as a Session Management client.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="UnregisterClient">
|
||||||
|
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||||
|
<arg type="o" name="client_id" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path of the client</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Unregister the specified client from Session Management.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Inhibit">
|
||||||
|
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||||
|
<arg type="s" name="app_id" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The application identifier</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="toplevel_xid" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The toplevel X window identifier</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="s" name="reason" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The reason for the inhibit</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="flags" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>Flags that specify what should be inhibited</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="u" name="inhibit_cookie" direction="out">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The cookie</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>
|
||||||
|
Proactively indicates that the calling application is performing an action that should not be interrupted and sets a reason to be displayed to the user when an interruption is about to take placea.
|
||||||
|
</doc:summary>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Applications should invoke this method when they begin an operation that
|
||||||
|
should not be interrupted, such as creating a CD or DVD. The types of actions
|
||||||
|
that may be blocked are specified by the flags parameter. When the application
|
||||||
|
completes the operation it should call <doc:ref type="method" to="org.gnome.SessionManager.Uninhibit">Uninhibit()</doc:ref>
|
||||||
|
or disconnect from the session bus.
|
||||||
|
</doc:para>
|
||||||
|
<doc:para>
|
||||||
|
Applications should not expect that they will always be able to block the
|
||||||
|
action. In most cases, users will be given the option to force the action
|
||||||
|
to take place.
|
||||||
|
</doc:para>
|
||||||
|
<doc:para>
|
||||||
|
Reasons should be short and to the point.
|
||||||
|
</doc:para>
|
||||||
|
<doc:para>
|
||||||
|
The flags parameter must include at least one of the following:
|
||||||
|
<doc:list>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>1</doc:term>
|
||||||
|
<doc:definition>Inhibit logging out</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>2</doc:term>
|
||||||
|
<doc:definition>Inhibit user switching</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>4</doc:term>
|
||||||
|
<doc:definition>Inhibit suspending the session or computer</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>8</doc:term>
|
||||||
|
<doc:definition>Inhibit the session being marked as idle</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>16</doc:term>
|
||||||
|
<doc:definition>Inhibit auto-mounting removable media for the session</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
</doc:list>
|
||||||
|
Values for flags may be bitwise or'ed together.
|
||||||
|
</doc:para>
|
||||||
|
<doc:para>
|
||||||
|
The returned cookie is used to uniquely identify this request. It should be used
|
||||||
|
as an argument to <doc:ref type="method" to="org.gnome.SessionManager.Uninhibit">Uninhibit()</doc:ref> in
|
||||||
|
order to remove the request.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Uninhibit">
|
||||||
|
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||||
|
<arg type="u" name="inhibit_cookie" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The cookie</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Cancel a previous call to <doc:ref type="method" to="org.gnome.SessionManager.Inhibit">Inhibit()</doc:ref> identified by the cookie.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="IsInhibited">
|
||||||
|
<arg type="u" name="flags" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>Flags that spefify what should be inhibited</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg type="b" name="is_inhibited" direction="out">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>Returns TRUE if any of the operations in the bitfield flags are inhibited</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Determine if operation(s) specified by the flags
|
||||||
|
are currently inhibited. Flags are same as those accepted
|
||||||
|
by the
|
||||||
|
<doc:ref type="method" to="org.gnome.SessionManager.Inhibit">Inhibit()</doc:ref>
|
||||||
|
method.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetClients">
|
||||||
|
<arg name="clients" direction="out" type="ao">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>an array of client IDs</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>This gets a list of all the <doc:ref type="interface" to="org.gnome.SessionManager.Client">Clients</doc:ref>
|
||||||
|
that are currently known to the session manager.</doc:para>
|
||||||
|
<doc:para>Each Client ID is an D-Bus object path for the object that implements the
|
||||||
|
<doc:ref type="interface" to="org.gnome.SessionManager.Client">Client</doc:ref> interface.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
<doc:seealso><doc:ref type="interface" to="org.gnome.SessionManager.Client">org.gnome.SessionManager.Client</doc:ref></doc:seealso>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="GetInhibitors">
|
||||||
|
<arg name="inhibitors" direction="out" type="ao">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>an array of inhibitor IDs</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>This gets a list of all the <doc:ref type="interface" to="org.gnome.SessionManager.Inhibitor">Inhibitors</doc:ref>
|
||||||
|
that are currently known to the session manager.</doc:para>
|
||||||
|
<doc:para>Each Inhibitor ID is an D-Bus object path for the object that implements the
|
||||||
|
<doc:ref type="interface" to="org.gnome.SessionManager.Inhibitor">Inhibitor</doc:ref> interface.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
<doc:seealso><doc:ref type="interface" to="org.gnome.SessionManager.Inhibitor">org.gnome.SessionManager.Inhibitor</doc:ref></doc:seealso>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
|
||||||
|
<method name="IsAutostartConditionHandled">
|
||||||
|
<arg name="condition" direction="in" type="s">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The autostart condition string</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<arg name="handled" direction="out" type="b">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>True if condition is handled, false otherwise</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Allows the caller to determine whether the session manager is
|
||||||
|
handling changes to the specified autostart condition.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Shutdown">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Request a shutdown dialog.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Reboot">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Request a reboot dialog.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="CanShutdown">
|
||||||
|
<arg name="is_available" direction="out" type="b">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>True if shutdown is available to the user, false otherwise</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Allows the caller to determine whether or not it's okay to show
|
||||||
|
a shutdown option in the UI</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="Logout">
|
||||||
|
<arg name="mode" type="u" direction="in">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The type of logout that is being requested</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Request a logout dialog</doc:para>
|
||||||
|
<doc:para>
|
||||||
|
Allowed values for the mode parameter are:
|
||||||
|
<doc:list>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>0</doc:term>
|
||||||
|
<doc:definition>Normal.</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>1</doc:term>
|
||||||
|
<doc:definition>No confirmation inferface should be shown.</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
<doc:item>
|
||||||
|
<doc:term>2</doc:term>
|
||||||
|
<doc:definition>Forcefully logout. No confirmation will be shown and any inhibitors will be ignored.</doc:definition>
|
||||||
|
</doc:item>
|
||||||
|
</doc:list>
|
||||||
|
Values for flags may be bitwise or'ed together.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="IsSessionRunning">
|
||||||
|
<arg name="running" direction="out" type="b">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>True if the session has entered the Running phase, false otherwise</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Allows the caller to determine whether the session manager
|
||||||
|
has entered the Running phase, in case the client missed the
|
||||||
|
SessionRunning signal.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!-- Signals -->
|
||||||
|
|
||||||
|
<signal name="ClientAdded">
|
||||||
|
<arg name="id" type="o">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path for the added client</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Emitted when a client has been added to the session manager.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
<signal name="ClientRemoved">
|
||||||
|
<arg name="id" type="o">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path for the removed client</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Emitted when a client has been removed from the session manager.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<signal name="InhibitorAdded">
|
||||||
|
<arg name="id" type="o">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path for the added inhibitor</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Emitted when an inhibitor has been added to the session manager.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
<signal name="InhibitorRemoved">
|
||||||
|
<arg name="id" type="o">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:summary>The object path for the removed inhibitor</doc:summary>
|
||||||
|
</doc:doc>
|
||||||
|
</arg>
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Emitted when an inhibitor has been removed from the session manager.
|
||||||
|
</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<signal name="SessionRunning">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Indicates the session has entered the Running phase.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<signal name="SessionOver">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>Indicates the session is about to end.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</signal>
|
||||||
|
|
||||||
|
<!-- Properties -->
|
||||||
|
|
||||||
|
<property name="SessionName" type="s" access="read">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>The name of the session that has been loaded.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="SessionIsActive" type="b" access="read">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>If true, the session is currently in the
|
||||||
|
foreground and available for user input.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="InhibitedActions" type="u" access="read">
|
||||||
|
<doc:doc>
|
||||||
|
<doc:description>
|
||||||
|
<doc:para>A bitmask of flags to indicate which actions
|
||||||
|
are inhibited. See the Inhibit() function's description
|
||||||
|
for a list of possible values.</doc:para>
|
||||||
|
</doc:description>
|
||||||
|
</doc:doc>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
34
gnome-settings-daemon/org.gnome.Shell.xml
Normal file
34
gnome-settings-daemon/org.gnome.Shell.xml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2013 Red Hat, Inc.
|
||||||
|
|
||||||
|
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, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||||
|
<!--
|
||||||
|
org.gnome.Shell:
|
||||||
|
|
||||||
|
An interface used to request shell features.
|
||||||
|
-->
|
||||||
|
<interface name="org.gnome.Shell">
|
||||||
|
<method name="FocusSearch"/>
|
||||||
|
<method name="ShowOSD">
|
||||||
|
<arg type="a{sv}" direction="in" name="params"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
301
meson.build
Normal file
301
meson.build
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
project(
|
||||||
|
'gnome-settings-daemon', 'c',
|
||||||
|
version: '48.1',
|
||||||
|
license: [ 'GPL2+', 'LGPLv2+' ],
|
||||||
|
meson_version: '>= 0.57.0'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure the version always has a trailing N.0 so that
|
||||||
|
# it can be sorted properly when comparing to N.alpha and so on.
|
||||||
|
#
|
||||||
|
# See https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/-/issues/66
|
||||||
|
assert(meson.project_version().split('.').length() > 1)
|
||||||
|
|
||||||
|
gsd_version = meson.project_version()
|
||||||
|
version_array = gsd_version.split('.')
|
||||||
|
gsd_major_version = version_array[0].to_int()
|
||||||
|
|
||||||
|
gsd_api_name = '@0@-@1@'.format(meson.project_name(), gsd_major_version)
|
||||||
|
|
||||||
|
glib_min_version = '2.70'
|
||||||
|
|
||||||
|
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
|
||||||
|
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
|
||||||
|
|
||||||
|
gsd_prefix = get_option('prefix')
|
||||||
|
gsd_bindir = join_paths(gsd_prefix, get_option('bindir'))
|
||||||
|
gsd_datadir = join_paths(gsd_prefix, get_option('datadir'))
|
||||||
|
gsd_includedir = join_paths(gsd_prefix, get_option('includedir'))
|
||||||
|
gsd_libdir = join_paths(gsd_prefix, get_option('libdir'))
|
||||||
|
gsd_libexecdir = join_paths(gsd_prefix, get_option('libexecdir'))
|
||||||
|
gsd_localedir = join_paths(gsd_prefix, get_option('localedir'))
|
||||||
|
gsd_sysconfdir = join_paths(gsd_prefix, get_option('sysconfdir'))
|
||||||
|
|
||||||
|
gsd_pkgdatadir = join_paths(gsd_datadir, meson.project_name())
|
||||||
|
gsd_pkgincludedir = join_paths(gsd_includedir, gsd_api_name)
|
||||||
|
gsd_pkglibdir = join_paths(gsd_libdir, gsd_api_name)
|
||||||
|
|
||||||
|
gsd_schemadir = join_paths(gsd_datadir, 'glib-2.0', 'schemas')
|
||||||
|
|
||||||
|
gsd_xdg_autostart = join_paths(gsd_sysconfdir, 'xdg', 'autostart')
|
||||||
|
|
||||||
|
gsd_3_0_api_name = '@0@-@1@'.format(meson.project_name(), '3.0')
|
||||||
|
gsd_gtk_modules_directory = join_paths(gsd_libdir, gsd_3_0_api_name, 'gtk-modules')
|
||||||
|
|
||||||
|
gsd_buildtype = get_option('buildtype')
|
||||||
|
|
||||||
|
host_is_darwin = host_machine.system().contains('darwin')
|
||||||
|
host_is_linux = host_machine.system().contains('linux')
|
||||||
|
host_is_linux_not_s390 = host_is_linux and not host_machine.cpu().contains('s390')
|
||||||
|
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
config_h = configuration_data()
|
||||||
|
|
||||||
|
# defines
|
||||||
|
set_defines = [
|
||||||
|
['PACKAGE_NAME', meson.project_name()],
|
||||||
|
['PACKAGE_VERSION', gsd_version],
|
||||||
|
# i18n
|
||||||
|
['GETTEXT_PACKAGE', meson.project_name()]
|
||||||
|
]
|
||||||
|
|
||||||
|
foreach define: set_defines
|
||||||
|
config_h.set_quoted(define[0], define[1])
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
# compiler flags
|
||||||
|
common_flags = ['-DHAVE_CONFIG_H']
|
||||||
|
compiler_flags = []
|
||||||
|
|
||||||
|
if gsd_buildtype.contains('debug')
|
||||||
|
common_flags += ['-DG_ENABLE_DEBUG']
|
||||||
|
|
||||||
|
test_cflags = [
|
||||||
|
'-Wcast-align',
|
||||||
|
'-Wmissing-declarations',
|
||||||
|
'-Wmissing-prototypes',
|
||||||
|
'-Wnested-externs',
|
||||||
|
'-Wno-strict-aliasing',
|
||||||
|
'-Wno-sign-compare',
|
||||||
|
'-Wpointer-arith',
|
||||||
|
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
|
||||||
|
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
|
||||||
|
]
|
||||||
|
|
||||||
|
compiler_flags = cc.get_supported_arguments(test_cflags)
|
||||||
|
elif gsd_buildtype.contains('release')
|
||||||
|
common_flags += ['-DG_DISABLE_CAST_CHECKS']
|
||||||
|
endif
|
||||||
|
|
||||||
|
if get_option('b_ndebug') == 'true'
|
||||||
|
common_flags += ['-DG_DISABLE_ASSERT']
|
||||||
|
endif
|
||||||
|
|
||||||
|
add_project_arguments(common_flags + compiler_flags, language: 'c')
|
||||||
|
|
||||||
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
|
geocode_glib_dep = dependency('geocode-glib-2.0', version: '>= 3.26.3', required: false)
|
||||||
|
if not geocode_glib_dep.found()
|
||||||
|
geocode_glib_dep = dependency('geocode-glib-1.0', version: '>= 3.10.0')
|
||||||
|
endif
|
||||||
|
gio_dep = dependency('gio-2.0', version: '>= 2.53.0')
|
||||||
|
gio_unix_dep = dependency('gio-unix-2.0')
|
||||||
|
gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>= 3.37.1')
|
||||||
|
gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 46.beta')
|
||||||
|
gtk_dep = dependency('gtk+-3.0', version: '>= 3.15.3')
|
||||||
|
gtk_x11_dep = dependency('gtk+-x11-3.0')
|
||||||
|
gweather_dep = dependency('gweather4')
|
||||||
|
libcanberra_gtk_dep = dependency('libcanberra-gtk3')
|
||||||
|
libgeoclue_dep = dependency('libgeoclue-2.0', version: '>= 2.3.1')
|
||||||
|
libnotify_dep = dependency('libnotify', version: '>= 0.7.3')
|
||||||
|
libpulse_mainloop_glib_dep = dependency('libpulse-mainloop-glib', version: '>= 2.0')
|
||||||
|
pango_dep = dependency('pango', version: '>= 1.20.0')
|
||||||
|
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.114')
|
||||||
|
upower_glib_dep = dependency('upower-glib', version: '>= 0.99.12')
|
||||||
|
x11_dep = dependency('x11')
|
||||||
|
xfixes_dep = dependency('xfixes', version: '>= 6.0')
|
||||||
|
|
||||||
|
enable_systemd = get_option('systemd')
|
||||||
|
enable_elogind = get_option('elogind')
|
||||||
|
|
||||||
|
if enable_systemd and enable_elogind
|
||||||
|
error('Only systemd or elogind support should be activated')
|
||||||
|
elif enable_systemd
|
||||||
|
systemd_dep = dependency('systemd', version: '>= 243', required: true)
|
||||||
|
libsystemd_dep = dependency('libsystemd', version: '>= 243', required: true)
|
||||||
|
systemd_userunitdir = systemd_dep.get_variable(pkgconfig: 'systemduserunitdir',
|
||||||
|
pkgconfig_define: ['prefix', gsd_prefix])
|
||||||
|
elif enable_elogind
|
||||||
|
elogind_dep = dependency('libelogind', version: '>= 209', required: true)
|
||||||
|
endif
|
||||||
|
|
||||||
|
config_h.set10('HAVE_SYSTEMD_LIB', enable_systemd or enable_elogind)
|
||||||
|
|
||||||
|
m_dep = cc.find_library('m')
|
||||||
|
|
||||||
|
# ALSA integration (default enabled)
|
||||||
|
enable_alsa = get_option('alsa')
|
||||||
|
assert(enable_alsa or not host_is_linux, 'ALSA is not optional on Linux platforms')
|
||||||
|
|
||||||
|
libgvc = subproject(
|
||||||
|
'gvc',
|
||||||
|
default_options: [
|
||||||
|
'static=true',
|
||||||
|
'alsa=' + enable_alsa.to_string()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
libgvc_dep = libgvc.get_variable('libgvc_dep')
|
||||||
|
|
||||||
|
# GUdev integration (default enabled)
|
||||||
|
enable_gudev = get_option('gudev')
|
||||||
|
if enable_gudev
|
||||||
|
gudev_dep = dependency('gudev-1.0')
|
||||||
|
endif
|
||||||
|
config_h.set10('HAVE_GUDEV', enable_gudev)
|
||||||
|
if host_is_linux
|
||||||
|
assert(enable_gudev, 'GUdev is not optional on Linux platforms')
|
||||||
|
endif
|
||||||
|
|
||||||
|
has_timerfd_create = cc.has_function('timerfd_create')
|
||||||
|
config_h.set10('HAVE_TIMERFD', has_timerfd_create)
|
||||||
|
|
||||||
|
# Check for wayland dependencies
|
||||||
|
enable_wayland = get_option('wayland')
|
||||||
|
if enable_wayland
|
||||||
|
assert(enable_gudev, 'GUDev support is required for wayland support.')
|
||||||
|
wayland_client_dep = dependency('wayland-client')
|
||||||
|
wayland_gdk_dep = dependency('gdk-wayland-3.0')
|
||||||
|
endif
|
||||||
|
config_h.set10('HAVE_WAYLAND', enable_wayland)
|
||||||
|
|
||||||
|
# wacom (disabled for s390/s390x and non Linux platforms)
|
||||||
|
enable_wacom = host_is_linux_not_s390
|
||||||
|
if enable_wacom
|
||||||
|
assert(enable_gudev, 'GUDev support is required for wacom support.')
|
||||||
|
libwacom_dep = dependency('libwacom', version: '>= 0.7')
|
||||||
|
endif
|
||||||
|
config_h.set10('HAVE_WACOM', enable_wacom)
|
||||||
|
|
||||||
|
# smartcard section
|
||||||
|
enable_smartcard = get_option('smartcard')
|
||||||
|
if enable_smartcard
|
||||||
|
if get_option('gcr3')
|
||||||
|
smartcard_deps = dependency('gck-1', version: '>= 3.36')
|
||||||
|
else
|
||||||
|
smartcard_deps = dependency('gck-2')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
enable_usb_protection = get_option('usb-protection')
|
||||||
|
|
||||||
|
# CUPS
|
||||||
|
enable_cups = get_option('cups')
|
||||||
|
if enable_cups
|
||||||
|
cups_dep = dependency('cups', version : '>= 1.4', required: false)
|
||||||
|
assert(cups_dep.found(), 'CUPS 1.4 or newer not found')
|
||||||
|
|
||||||
|
# FIXME: 1.6 cflags generate a lot of errors
|
||||||
|
'''
|
||||||
|
cups_cflags = []
|
||||||
|
if cups_dep.version().version_compare('>= 1.6')
|
||||||
|
cups_cflags += '-D_PPD_DEPRECATED=""'
|
||||||
|
endif
|
||||||
|
|
||||||
|
cups_dep = declare_dependency(
|
||||||
|
dependencies: cups_dep,
|
||||||
|
compile_args: cups_cflags
|
||||||
|
)
|
||||||
|
'''
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Rfkill
|
||||||
|
enable_rfkill = get_option('rfkill')
|
||||||
|
assert(enable_rfkill or not host_is_linux, 'rfkill is not optional on Linux platforms')
|
||||||
|
if enable_rfkill
|
||||||
|
assert(cc.has_header('linux/rfkill.h'), 'rfkill support requested but RFKill headers not found')
|
||||||
|
assert(enable_gudev, 'GUdev is required for rfkill support')
|
||||||
|
|
||||||
|
udev_dir = get_option('udev_dir')
|
||||||
|
if udev_dir == ''
|
||||||
|
udev_dir = dependency('udev').get_variable(pkgconfig: 'udevdir')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# wwan
|
||||||
|
enable_wwan = get_option('wwan')
|
||||||
|
if enable_wwan
|
||||||
|
if get_option('gcr3')
|
||||||
|
gcr_dep = dependency('gcr-base-3', version: '>= 3.7.5')
|
||||||
|
config_h.set10('HAVE_GCR3', 1)
|
||||||
|
else
|
||||||
|
gcr_dep = dependency('gcr-4', version: '>= 3.90.0')
|
||||||
|
endif
|
||||||
|
mm_glib_dep = dependency('mm-glib', version: '>= 1.18')
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Sharing plugin
|
||||||
|
enable_network_manager = get_option('network_manager')
|
||||||
|
assert(enable_network_manager or not host_is_linux, 'NetworkManager support is not optional on Linux platforms')
|
||||||
|
if enable_network_manager
|
||||||
|
# network manager
|
||||||
|
libnm_dep = dependency('libnm', version: '>= 1.0')
|
||||||
|
endif
|
||||||
|
config_h.set10('HAVE_NETWORK_MANAGER', enable_network_manager)
|
||||||
|
|
||||||
|
# colord
|
||||||
|
enable_colord = get_option('colord')
|
||||||
|
if enable_colord
|
||||||
|
colord_dep = dependency('colord', version: '>= 1.4.5')
|
||||||
|
endif
|
||||||
|
|
||||||
|
gnome = import('gnome')
|
||||||
|
i18n = import('i18n')
|
||||||
|
pkg = import('pkgconfig')
|
||||||
|
|
||||||
|
po_dir = join_paths(meson.project_source_root(), 'po')
|
||||||
|
|
||||||
|
top_inc = include_directories('.')
|
||||||
|
|
||||||
|
subdir('gnome-settings-daemon')
|
||||||
|
subdir('data')
|
||||||
|
subdir('plugins')
|
||||||
|
subdir('po')
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
output: 'config.h',
|
||||||
|
configuration: config_h
|
||||||
|
)
|
||||||
|
|
||||||
|
gnome.post_install(
|
||||||
|
glib_compile_schemas: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
output = '\n ' + meson.project_name() + ' ' + meson.project_version() +'\n'
|
||||||
|
output += ' =============================\n\n'
|
||||||
|
output += ' prefix: ' + gsd_prefix + '\n'
|
||||||
|
output += ' exec_prefix: ' + gsd_prefix + '\n'
|
||||||
|
output += ' libdir: ' + gsd_libdir + '\n'
|
||||||
|
output += ' libexecdir: ' + gsd_libexecdir + '\n'
|
||||||
|
output += ' bindir: ' + gsd_bindir + '\n'
|
||||||
|
output += ' sysconfdir: ' + gsd_sysconfdir + '\n'
|
||||||
|
output += ' datadir: ' + gsd_datadir + '\n\n'
|
||||||
|
output += ' gtk modules dir: ' + gsd_gtk_modules_directory + '\n\n'
|
||||||
|
output += ' source code location: ' + meson.project_source_root() + '\n'
|
||||||
|
output += ' compiler: ' + cc.get_id() + '\n'
|
||||||
|
output += ' cflags: ' + ' '.join(compiler_flags) + '\n\n'
|
||||||
|
output += ' ALSA support: ' + enable_alsa.to_string() + '\n'
|
||||||
|
output += ' NetworkManager support: ' + enable_network_manager.to_string() + '\n'
|
||||||
|
output += ' Smartcard support: ' + enable_smartcard.to_string() + '\n'
|
||||||
|
output += ' USB Protection support: ' + enable_usb_protection.to_string() + '\n'
|
||||||
|
output += ' Cups support: ' + enable_cups.to_string() + '\n'
|
||||||
|
output += ' Wayland support: ' + enable_wayland.to_string() + '\n'
|
||||||
|
output += ' Wacom support: ' + enable_wacom.to_string() + '\n'
|
||||||
|
output += ' RFKill support: ' + enable_rfkill.to_string() + '\n'
|
||||||
|
if enable_systemd
|
||||||
|
output += ' Systemd user unit dir: ' + systemd_userunitdir + '\n'
|
||||||
|
endif
|
||||||
|
if enable_rfkill
|
||||||
|
output += ' udev dir: ' + udev_dir + '\n'
|
||||||
|
endif
|
||||||
|
message(output)
|
14
meson_options.txt
Normal file
14
meson_options.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
option('udev_dir', type: 'string', value: '', description: 'Absolute path of the udev base directory')
|
||||||
|
option('systemd', type: 'boolean', value: true, description: 'Enable systemd integration')
|
||||||
|
option('elogind', type: 'boolean', value: false, description: 'Use elogind')
|
||||||
|
option('alsa', type: 'boolean', value: true, description: 'build with ALSA support (not optional on Linux platforms)')
|
||||||
|
option('gudev', type: 'boolean', value: true, description: 'build with gudev device support (not optional on Linux platforms)')
|
||||||
|
option('cups', type: 'boolean', value: true, description: 'build with CUPS support')
|
||||||
|
option('network_manager', type: 'boolean', value: true, description: 'build with NetworkManager support (not optional on Linux platforms)')
|
||||||
|
option('rfkill', type: 'boolean', value: true, description: 'build with rfkill support (not optional on Linux platforms)')
|
||||||
|
option('smartcard', type: 'boolean', value: true, description: 'build with smartcard support')
|
||||||
|
option('usb-protection', type: 'boolean', value: true, description: 'build with usb-protection support')
|
||||||
|
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
|
||||||
|
option('wwan', type: 'boolean', value: true, description: 'build with WWAN support')
|
||||||
|
option('gcr3', type: 'boolean', value: false, description: 'build with gcr3, otherwise gcr4 is used')
|
||||||
|
option('colord', type: 'boolean', value: true, description: 'build with colord support')
|
141
plugins/a11y-settings/gsd-a11y-settings-manager.c
Normal file
141
plugins/a11y-settings/gsd-a11y-settings-manager.c
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
#include "gsd-a11y-settings-manager.h"
|
||||||
|
|
||||||
|
struct _GsdA11ySettingsManager
|
||||||
|
{
|
||||||
|
GsdApplication parent;
|
||||||
|
|
||||||
|
GSettings *interface_settings;
|
||||||
|
GSettings *a11y_apps_settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_a11y_settings_manager_class_init (GsdA11ySettingsManagerClass *klass);
|
||||||
|
static void gsd_a11y_settings_manager_init (GsdA11ySettingsManager *a11y_settings_manager);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdA11ySettingsManager, gsd_a11y_settings_manager, GSD_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
static void
|
||||||
|
apps_settings_changed (GSettings *settings,
|
||||||
|
const char *key,
|
||||||
|
GsdA11ySettingsManager *manager)
|
||||||
|
{
|
||||||
|
gboolean screen_reader, keyboard, magnifier;
|
||||||
|
|
||||||
|
if (g_str_equal (key, "screen-reader-enabled") == FALSE &&
|
||||||
|
g_str_equal (key, "screen-keyboard-enabled") == FALSE &&
|
||||||
|
g_str_equal (key, "screen-magnifier-enabled") == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_debug ("screen reader, OSK or magnifier enablement changed");
|
||||||
|
|
||||||
|
screen_reader = g_settings_get_boolean (manager->a11y_apps_settings, "screen-reader-enabled");
|
||||||
|
keyboard = g_settings_get_boolean (manager->a11y_apps_settings, "screen-keyboard-enabled");
|
||||||
|
magnifier = g_settings_get_boolean (manager->a11y_apps_settings, "screen-magnifier-enabled");
|
||||||
|
|
||||||
|
if (screen_reader || keyboard || magnifier) {
|
||||||
|
g_debug ("Enabling toolkit-accessibility, screen reader, OSK or magnifier enabled");
|
||||||
|
g_settings_set_boolean (manager->interface_settings, "toolkit-accessibility", TRUE);
|
||||||
|
} else if (screen_reader == FALSE && keyboard == FALSE && magnifier == FALSE) {
|
||||||
|
g_debug ("Disabling toolkit-accessibility, screen reader, OSK and magnifier disabled");
|
||||||
|
g_settings_set_boolean (manager->interface_settings, "toolkit-accessibility", FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_a11y_settings_manager_startup (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdA11ySettingsManager *manager = GSD_A11Y_SETTINGS_MANAGER (app);
|
||||||
|
|
||||||
|
g_debug ("Starting a11y_settings manager");
|
||||||
|
gnome_settings_profile_start (NULL);
|
||||||
|
|
||||||
|
manager->interface_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||||
|
manager->a11y_apps_settings = g_settings_new ("org.gnome.desktop.a11y.applications");
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (manager->a11y_apps_settings), "changed",
|
||||||
|
G_CALLBACK (apps_settings_changed), manager);
|
||||||
|
|
||||||
|
/* If any of the screen reader, on-screen keyboard or magnifier 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->a11y_apps_settings, "screen-keyboard-enabled") ||
|
||||||
|
g_settings_get_boolean (manager->a11y_apps_settings, "screen-reader-enabled") ||
|
||||||
|
g_settings_get_boolean (manager->a11y_apps_settings, "screen-magnifier-enabled"))
|
||||||
|
g_settings_set_boolean (manager->interface_settings, "toolkit-accessibility", TRUE);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_a11y_settings_manager_parent_class)->startup (app);
|
||||||
|
|
||||||
|
gnome_settings_profile_end (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_a11y_settings_manager_shutdown (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdA11ySettingsManager *manager = GSD_A11Y_SETTINGS_MANAGER (app);
|
||||||
|
|
||||||
|
if (manager->interface_settings) {
|
||||||
|
g_object_unref (manager->interface_settings);
|
||||||
|
manager->interface_settings = NULL;
|
||||||
|
}
|
||||||
|
if (manager->a11y_apps_settings) {
|
||||||
|
g_object_unref (manager->a11y_apps_settings);
|
||||||
|
manager->a11y_apps_settings = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_a11y_settings_manager_parent_class)->shutdown (app);
|
||||||
|
|
||||||
|
g_debug ("Stopping a11y_settings manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_a11y_settings_manager_class_init (GsdA11ySettingsManagerClass *klass)
|
||||||
|
{
|
||||||
|
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
||||||
|
|
||||||
|
application_class->startup = gsd_a11y_settings_manager_startup;
|
||||||
|
application_class->shutdown = gsd_a11y_settings_manager_shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_a11y_settings_manager_init (GsdA11ySettingsManager *manager)
|
||||||
|
{
|
||||||
|
}
|
32
plugins/a11y-settings/gsd-a11y-settings-manager.h
Normal file
32
plugins/a11y-settings/gsd-a11y-settings-manager.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_A11Y_SETTINGS_MANAGER_H
|
||||||
|
#define __GSD_A11Y_SETTINGS_MANAGER_H
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_A11Y_SETTINGS_MANAGER gsd_a11y_settings_manager_get_type ()
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdA11ySettingsManager, gsd_a11y_settings_manager, GSD, A11Y_SETTINGS_MANAGER, GsdApplication)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_A11Y_SETTINGS_MANAGER_H */
|
9
plugins/a11y-settings/main.c
Normal file
9
plugins/a11y-settings/main.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "gsd-main-helper.h"
|
||||||
|
#include "gsd-a11y-settings-manager.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return gsd_main_helper (GSD_TYPE_A11Y_SETTINGS_MANAGER, argc, argv);
|
||||||
|
}
|
||||||
|
|
21
plugins/a11y-settings/meson.build
Normal file
21
plugins/a11y-settings/meson.build
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
sources = files(
|
||||||
|
'gsd-a11y-settings-manager.c',
|
||||||
|
'main.c'
|
||||||
|
)
|
||||||
|
sources += main_helper_sources
|
||||||
|
|
||||||
|
deps = plugins_deps + [
|
||||||
|
gio_dep,
|
||||||
|
gsettings_desktop_dep
|
||||||
|
]
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'gsd-' + plugin_name,
|
||||||
|
sources,
|
||||||
|
include_directories: [top_inc, common_inc],
|
||||||
|
dependencies: deps,
|
||||||
|
c_args: cflags,
|
||||||
|
install: true,
|
||||||
|
install_rpath: gsd_pkglibdir,
|
||||||
|
install_dir: gsd_libexecdir
|
||||||
|
)
|
360
plugins/color/gcm-self-test.c
Normal file
360
plugins/color/gcm-self-test.c
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* 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 <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "gsd-color-state.h"
|
||||||
|
#include "gsd-night-light.h"
|
||||||
|
#include "gsd-night-light-common.h"
|
||||||
|
|
||||||
|
GMainLoop *mainloop;
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_notify (GsdNightLight *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
|
||||||
|
gcm_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(GsdNightLight) nlight = NULL;
|
||||||
|
g_autoptr(GSettings) settings = NULL;
|
||||||
|
|
||||||
|
nlight = gsd_night_light_new ();
|
||||||
|
g_assert (GSD_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
|
||||||
|
/* do not start geoclue */
|
||||||
|
gsd_night_light_set_geoclue_enabled (nlight, FALSE);
|
||||||
|
|
||||||
|
/* do not smooth the transition */
|
||||||
|
gsd_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-enabled", FALSE);
|
||||||
|
g_settings_set_uint (settings, "night-light-temperature", 4000);
|
||||||
|
|
||||||
|
/* check default values */
|
||||||
|
g_assert (!gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint ((gint) gsd_night_light_get_sunrise (nlight), ==, -1);
|
||||||
|
g_assert_cmpint ((gint) gsd_night_light_get_sunset (nlight), ==, -1);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
g_assert (!gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
|
||||||
|
/* start module, disabled */
|
||||||
|
ret = gsd_night_light_start (nlight, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert (ret);
|
||||||
|
g_assert (!gsd_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 (gsd_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) gsd_night_light_get_sunrise (nlight), ==, 7);
|
||||||
|
g_assert_cmpint ((gint) gsd_night_light_get_sunset (nlight), ==, 17);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, 4000);
|
||||||
|
g_assert (!gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
|
||||||
|
/* disable for one day */
|
||||||
|
gsd_night_light_set_disabled_until_tmw (nlight, TRUE);
|
||||||
|
gsd_night_light_set_disabled_until_tmw (nlight, TRUE);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
g_assert (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert (gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
g_assert_cmpint (temperature_cnt, ==, 2);
|
||||||
|
g_assert_cmpint (disabled_until_tmw_cnt, ==, 1);
|
||||||
|
|
||||||
|
/* change our mind */
|
||||||
|
gsd_night_light_set_disabled_until_tmw (nlight, FALSE);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, 4000);
|
||||||
|
g_assert (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert (!gsd_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 (!gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint ((gint) gsd_night_light_get_sunrise (nlight), ==, 7);
|
||||||
|
g_assert_cmpint ((gint) gsd_night_light_get_sunset (nlight), ==, 17);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
g_assert (!gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
|
||||||
|
/* disable, with no changes */
|
||||||
|
g_settings_set_boolean (settings, "night-light-enabled", FALSE);
|
||||||
|
g_assert (!gsd_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 */
|
||||||
|
gsd_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 (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_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 (!gsd_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 (gsd_night_light_get_temperature (nlight), ==, GSD_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);
|
||||||
|
gsd_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_true (gsd_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_false (gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
|
||||||
|
gsd_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_false (gsd_night_light_get_disabled_until_tmw (nlight));
|
||||||
|
|
||||||
|
|
||||||
|
/* Check that we are always in night mode if from/to are equal. */
|
||||||
|
gsd_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, 4000);
|
||||||
|
|
||||||
|
datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 0, 0);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, 4000);
|
||||||
|
|
||||||
|
datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 10, 0);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_false (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
|
||||||
|
/* Not enabled >10 minutes after sunrise */
|
||||||
|
datetime_override = g_date_time_new_utc (2017, 2, 10, 6, 20, 0);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_false (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), ==, GSD_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_true (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), <=, (GSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 + 20);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), >=, (GSD_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);
|
||||||
|
gsd_night_light_set_date_time_now (nlight, datetime_override);
|
||||||
|
g_assert_true (gsd_night_light_get_active (nlight));
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), <=, (GSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 + 20);
|
||||||
|
g_assert_cmpint (gsd_night_light_get_temperature (nlight), >=, (GSD_COLOR_TEMPERATURE_DEFAULT + 4000) / 2 - 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_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 */
|
||||||
|
gsd_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
|
||||||
|
gcm_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_identifier ("+01:30");
|
||||||
|
g_assert_nonnull (tz);
|
||||||
|
dt = g_date_time_new (tz, 2007, 2, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
/* get for our made up timezone, today */
|
||||||
|
gsd_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
|
||||||
|
gcm_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 = gsd_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 (gsd_night_light_frac_day_is_between (12, 6, 20));
|
||||||
|
g_assert_false (gsd_night_light_frac_day_is_between (5, 6, 20));
|
||||||
|
g_assert_true (gsd_night_light_frac_day_is_between (12, 0, 24));
|
||||||
|
g_assert_true (gsd_night_light_frac_day_is_between (12, -1, 25));
|
||||||
|
|
||||||
|
/* test rollover to next day */
|
||||||
|
g_assert_true (gsd_night_light_frac_day_is_between (23, 20, 6));
|
||||||
|
g_assert_false (gsd_night_light_frac_day_is_between (12, 20, 6));
|
||||||
|
|
||||||
|
/* test rollover to the previous day */
|
||||||
|
g_assert_true (gsd_night_light_frac_day_is_between (5, 16, 8));
|
||||||
|
|
||||||
|
/* test equality */
|
||||||
|
g_assert_true (gsd_night_light_frac_day_is_between (12, 0.5, 24.5));
|
||||||
|
g_assert_true (gsd_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/sunset-sunrise", gcm_test_sunset_sunrise);
|
||||||
|
g_test_add_func ("/color/sunset-sunrise/fractional-timezone", gcm_test_sunset_sunrise_fractional_timezone);
|
||||||
|
g_test_add_func ("/color/fractional-day", gcm_test_frac_day);
|
||||||
|
g_test_add_func ("/color/night-light", gcm_test_night_light);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
||||||
|
|
286
plugins/color/gnome-datetime-source.c
Normal file
286
plugins/color/gnome-datetime-source.c
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
/* -*- 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 <walters@verbum.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||||
|
#include "gnome-datetime-source.h"
|
||||||
|
|
||||||
|
#if HAVE_TIMERFD
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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.
|
||||||
|
*
|
||||||
|
* <note><para>This function currently does not detect time zone
|
||||||
|
* changes. On Linux, your program should also monitor the
|
||||||
|
* <literal>/etc/timezone</literal> file using
|
||||||
|
* #GFileMonitor.</para></note>
|
||||||
|
*
|
||||||
|
* <example id="gdatetime-example-watch"><title>Clock example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../glib/tests/glib-clock.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
38
plugins/color/gnome-datetime-source.h
Normal file
38
plugins/color/gnome-datetime-source.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* 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 <walters@verbum.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <glib.h>
|
||||||
|
|
||||||
|
GSource *_gnome_datetime_source_new (GDateTime *now,
|
||||||
|
GDateTime *expiry,
|
||||||
|
gboolean cancel_on_set);
|
||||||
|
|
||||||
|
#endif /* GNOME_DATETIME_SOURCE_H */
|
412
plugins/color/gsd-color-calibrate.c
Normal file
412
plugins/color/gsd-color-calibrate.c
Normal file
|
@ -0,0 +1,412 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011-2013 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <colord.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
#include <canberra-gtk.h>
|
||||||
|
|
||||||
|
#include "gsd-color-calibrate.h"
|
||||||
|
|
||||||
|
#define GCM_SESSION_NOTIFY_TIMEOUT 30000 /* ms */
|
||||||
|
#define GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD "recalibrate-printer-threshold"
|
||||||
|
#define GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD "recalibrate-display-threshold"
|
||||||
|
|
||||||
|
struct _GsdColorCalibrate
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
CdClient *client;
|
||||||
|
GSettings *settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_color_calibrate_class_init (GsdColorCalibrateClass *klass);
|
||||||
|
static void gsd_color_calibrate_init (GsdColorCalibrate *color_calibrate);
|
||||||
|
static void gsd_color_calibrate_finalize (GObject *object);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdColorCalibrate, gsd_color_calibrate, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GsdColorCalibrate *calibrate;
|
||||||
|
CdProfile *profile;
|
||||||
|
CdDevice *device;
|
||||||
|
guint32 output_id;
|
||||||
|
} GcmSessionAsyncHelper;
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_session_async_helper_free (GcmSessionAsyncHelper *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
|
||||||
|
gcm_session_exec_control_center (GsdColorCalibrate *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
|
||||||
|
gcm_session_notify_cb (NotifyNotification *notification,
|
||||||
|
gchar *action,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorCalibrate *calibrate = GSD_COLOR_CALIBRATE (user_data);
|
||||||
|
|
||||||
|
if (g_strcmp0 (action, "recalibrate") == 0) {
|
||||||
|
notify_notification_close (notification, NULL);
|
||||||
|
gcm_session_exec_control_center (calibrate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
closed_cb (NotifyNotification *notification, gpointer data)
|
||||||
|
{
|
||||||
|
g_object_unref (notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gcm_session_notify_recalibrate (GsdColorCalibrate *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, NULL);
|
||||||
|
notify_notification_set_timeout (notification, GCM_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 GCM */
|
||||||
|
_("Recalibrate now"),
|
||||||
|
gcm_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 *
|
||||||
|
gcm_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
|
||||||
|
gcm_session_notify_device (GsdColorCalibrate *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 = gcm_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,
|
||||||
|
GCM_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,
|
||||||
|
GCM_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)
|
||||||
|
gcm_session_notify_recalibrate (calibrate, title, message, kind);
|
||||||
|
g_free (device_title);
|
||||||
|
g_free (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_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);
|
||||||
|
GcmSessionAsyncHelper *helper = (GcmSessionAsyncHelper *) user_data;
|
||||||
|
GsdColorCalibrate *calibrate = GSD_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, "GCM")) {
|
||||||
|
g_debug ("not a GCM 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 */
|
||||||
|
gcm_session_notify_device (calibrate, helper->device);
|
||||||
|
out:
|
||||||
|
gcm_session_async_helper_free (helper);
|
||||||
|
g_free (basename);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_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);
|
||||||
|
GsdColorCalibrate *calibrate = GSD_COLOR_CALIBRATE (user_data);
|
||||||
|
GcmSessionAsyncHelper *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 (GcmSessionAsyncHelper, 1);
|
||||||
|
helper->calibrate = g_object_ref (calibrate);
|
||||||
|
helper->device = g_object_ref (device);
|
||||||
|
cd_profile_connect (profile,
|
||||||
|
NULL,
|
||||||
|
gcm_session_profile_connect_cb,
|
||||||
|
helper);
|
||||||
|
out:
|
||||||
|
if (profile != NULL)
|
||||||
|
g_object_unref (profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_session_device_added_notify_cb (CdClient *client,
|
||||||
|
CdDevice *device,
|
||||||
|
GsdColorCalibrate *calibrate)
|
||||||
|
{
|
||||||
|
/* connect to the device to get properties */
|
||||||
|
cd_device_connect (device,
|
||||||
|
NULL,
|
||||||
|
gcm_session_device_connect_cb,
|
||||||
|
calibrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_session_sensor_added_cb (CdClient *client,
|
||||||
|
CdSensor *sensor,
|
||||||
|
GsdColorCalibrate *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, _("GNOME 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 */
|
||||||
|
gcm_session_exec_control_center (calibrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcm_session_sensor_removed_cb (CdClient *client,
|
||||||
|
CdSensor *sensor,
|
||||||
|
GsdColorCalibrate *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, _("GNOME Settings Daemon Color Plugin"),
|
||||||
|
/* TRANSLATORS: this is a sound description */
|
||||||
|
CA_PROP_EVENT_DESCRIPTION, _("Color calibration device removed"), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_calibrate_class_init (GsdColorCalibrateClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gsd_color_calibrate_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_calibrate_init (GsdColorCalibrate *calibrate)
|
||||||
|
{
|
||||||
|
calibrate->settings = g_settings_new ("org.gnome.settings-daemon.plugins.color");
|
||||||
|
calibrate->client = cd_client_new ();
|
||||||
|
g_signal_connect (calibrate->client, "device-added",
|
||||||
|
G_CALLBACK (gcm_session_device_added_notify_cb),
|
||||||
|
calibrate);
|
||||||
|
g_signal_connect (calibrate->client, "sensor-added",
|
||||||
|
G_CALLBACK (gcm_session_sensor_added_cb),
|
||||||
|
calibrate);
|
||||||
|
g_signal_connect (calibrate->client, "sensor-removed",
|
||||||
|
G_CALLBACK (gcm_session_sensor_removed_cb),
|
||||||
|
calibrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_calibrate_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GsdColorCalibrate *calibrate;
|
||||||
|
|
||||||
|
g_return_if_fail (object != NULL);
|
||||||
|
g_return_if_fail (GSD_IS_COLOR_CALIBRATE (object));
|
||||||
|
|
||||||
|
calibrate = GSD_COLOR_CALIBRATE (object);
|
||||||
|
|
||||||
|
g_clear_object (&calibrate->settings);
|
||||||
|
g_clear_object (&calibrate->client);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gsd_color_calibrate_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdColorCalibrate *
|
||||||
|
gsd_color_calibrate_new (void)
|
||||||
|
{
|
||||||
|
GsdColorCalibrate *calibrate;
|
||||||
|
calibrate = g_object_new (GSD_TYPE_COLOR_CALIBRATE, NULL);
|
||||||
|
return GSD_COLOR_CALIBRATE (calibrate);
|
||||||
|
}
|
38
plugins/color/gsd-color-calibrate.h
Normal file
38
plugins/color/gsd-color-calibrate.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011-2013 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_COLOR_CALIBRATE_H
|
||||||
|
#define __GSD_COLOR_CALIBRATE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_COLOR_CALIBRATE (gsd_color_calibrate_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdColorCalibrate, gsd_color_calibrate, GSD, COLOR_CALIBRATE, GObject)
|
||||||
|
|
||||||
|
GType gsd_color_calibrate_get_type (void);
|
||||||
|
GQuark gsd_color_calibrate_error_quark (void);
|
||||||
|
|
||||||
|
GsdColorCalibrate * gsd_color_calibrate_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_COLOR_CALIBRATE_H */
|
454
plugins/color/gsd-color-manager.c
Normal file
454
plugins/color/gsd-color-manager.c
Normal file
|
@ -0,0 +1,454 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011-2013 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
#include "gsd-color-calibrate.h"
|
||||||
|
#include "gsd-color-manager.h"
|
||||||
|
#include "gsd-color-state.h"
|
||||||
|
#include "gsd-night-light.h"
|
||||||
|
|
||||||
|
#define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
|
||||||
|
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
|
||||||
|
#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon"
|
||||||
|
|
||||||
|
#define GSD_COLOR_DBUS_NAME GSD_DBUS_NAME ".Color"
|
||||||
|
#define GSD_COLOR_DBUS_PATH GSD_DBUS_PATH "/Color"
|
||||||
|
#define GSD_COLOR_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Color"
|
||||||
|
|
||||||
|
static const gchar introspection_xml[] =
|
||||||
|
"<node>"
|
||||||
|
" <interface name='org.gnome.SettingsDaemon.Color'>"
|
||||||
|
" <method name='NightLightPreview'>"
|
||||||
|
" <arg type='u' name='duration' direction='in'/>"
|
||||||
|
" </method>"
|
||||||
|
" <property name='NightLightActive' type='b' access='read'/>"
|
||||||
|
" <property name='Temperature' type='u' access='readwrite'/>"
|
||||||
|
" <property name='DisabledUntilTomorrow' type='b' access='readwrite'/>"
|
||||||
|
" <property name='Sunrise' type='d' access='read'/>"
|
||||||
|
" <property name='Sunset' type='d' access='read'/>"
|
||||||
|
" </interface>"
|
||||||
|
"</node>";
|
||||||
|
|
||||||
|
struct _GsdColorManager
|
||||||
|
{
|
||||||
|
GsdApplication parent;
|
||||||
|
|
||||||
|
/* D-Bus */
|
||||||
|
GDBusNodeInfo *introspection_data;
|
||||||
|
|
||||||
|
GsdColorCalibrate *calibrate;
|
||||||
|
GsdColorState *state;
|
||||||
|
GsdNightLight *nlight;
|
||||||
|
|
||||||
|
guint nlight_forced_timeout_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_color_manager_class_init (GsdColorManagerClass *klass);
|
||||||
|
static void gsd_color_manager_init (GsdColorManager *color_manager);
|
||||||
|
static void gsd_color_manager_finalize (GObject *object);
|
||||||
|
static gboolean gsd_color_manager_dbus_register (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path,
|
||||||
|
GError **error);
|
||||||
|
static void gsd_color_manager_dbus_unregister (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdColorManager, gsd_color_manager, GSD_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_manager_startup (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (app);
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
|
g_debug ("Starting color manager");
|
||||||
|
gnome_settings_profile_start (NULL);
|
||||||
|
|
||||||
|
/* start the device probing */
|
||||||
|
gsd_color_state_start (manager->state);
|
||||||
|
|
||||||
|
/* setup night light module */
|
||||||
|
if (!gsd_night_light_start (manager->nlight, &error))
|
||||||
|
g_warning ("Could not start night light module: %s", error->message);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_color_manager_parent_class)->startup (app);
|
||||||
|
|
||||||
|
gnome_settings_profile_end (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_manager_shutdown (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (app);
|
||||||
|
|
||||||
|
g_debug ("Stopping color manager");
|
||||||
|
gsd_color_state_stop (manager->state);
|
||||||
|
|
||||||
|
g_clear_pointer (&manager->introspection_data, g_dbus_node_info_unref);
|
||||||
|
|
||||||
|
g_clear_handle_id (&manager->nlight_forced_timeout_id, g_source_remove);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_color_manager_parent_class)->shutdown (app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_manager_class_init (GsdColorManagerClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gsd_color_manager_finalize;
|
||||||
|
|
||||||
|
application_class->startup = gsd_color_manager_startup;
|
||||||
|
application_class->shutdown = gsd_color_manager_shutdown;
|
||||||
|
application_class->dbus_register = gsd_color_manager_dbus_register;
|
||||||
|
application_class->dbus_unregister = gsd_color_manager_dbus_unregister;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_property_changed (GsdColorManager *manager,
|
||||||
|
const gchar *property_name,
|
||||||
|
GVariant *property_value)
|
||||||
|
{
|
||||||
|
GVariantBuilder builder;
|
||||||
|
GVariantBuilder invalidated_builder;
|
||||||
|
GDBusConnection *connection = g_application_get_dbus_connection (G_APPLICATION (manager));
|
||||||
|
|
||||||
|
/* not yet connected */
|
||||||
|
if (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 (connection,
|
||||||
|
NULL,
|
||||||
|
GSD_COLOR_DBUS_PATH,
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"PropertiesChanged",
|
||||||
|
g_variant_new ("(sa{sv}as)",
|
||||||
|
GSD_COLOR_DBUS_INTERFACE,
|
||||||
|
&builder,
|
||||||
|
&invalidated_builder),
|
||||||
|
NULL);
|
||||||
|
g_variant_builder_clear (&builder);
|
||||||
|
g_variant_builder_clear (&invalidated_builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_active_notify (GsdNightLight *nlight,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
emit_property_changed (manager, "NightLightActive",
|
||||||
|
g_variant_new_boolean (gsd_night_light_get_active (manager->nlight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_sunset_notify (GsdNightLight *nlight,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
emit_property_changed (manager, "Sunset",
|
||||||
|
g_variant_new_double (gsd_night_light_get_sunset (manager->nlight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_sunrise_notify (GsdNightLight *nlight,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
emit_property_changed (manager, "Sunrise",
|
||||||
|
g_variant_new_double (gsd_night_light_get_sunrise (manager->nlight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_disabled_until_tmw_notify (GsdNightLight *nlight,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
emit_property_changed (manager, "DisabledUntilTomorrow",
|
||||||
|
g_variant_new_boolean (gsd_night_light_get_disabled_until_tmw (manager->nlight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_temperature_notify (GsdNightLight *nlight,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
gdouble temperature = gsd_night_light_get_temperature (manager->nlight);
|
||||||
|
gsd_color_state_set_temperature (manager->state, temperature);
|
||||||
|
emit_property_changed (manager, "Temperature",
|
||||||
|
g_variant_new_uint32 (roundf (temperature)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_manager_init (GsdColorManager *manager)
|
||||||
|
{
|
||||||
|
/* setup calibration features */
|
||||||
|
manager->calibrate = gsd_color_calibrate_new ();
|
||||||
|
manager->state = gsd_color_state_new ();
|
||||||
|
|
||||||
|
/* night light features */
|
||||||
|
manager->nlight = gsd_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
|
||||||
|
gsd_color_manager_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager;
|
||||||
|
|
||||||
|
g_return_if_fail (object != NULL);
|
||||||
|
g_return_if_fail (GSD_IS_COLOR_MANAGER (object));
|
||||||
|
|
||||||
|
manager = GSD_COLOR_MANAGER (object);
|
||||||
|
|
||||||
|
g_clear_object (&manager->calibrate);
|
||||||
|
g_clear_object (&manager->state);
|
||||||
|
g_clear_object (&manager->nlight);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gsd_color_manager_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nlight_forced_timeout_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
|
||||||
|
manager->nlight_forced_timeout_id = 0;
|
||||||
|
gsd_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)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_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);
|
||||||
|
|
||||||
|
gsd_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)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
|
||||||
|
if (g_strcmp0 (interface_name, GSD_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 (gsd_night_light_get_active (manager->nlight));
|
||||||
|
|
||||||
|
if (g_strcmp0 (property_name, "Temperature") == 0) {
|
||||||
|
guint temperature;
|
||||||
|
temperature = gsd_color_state_get_temperature (manager->state);
|
||||||
|
return g_variant_new_uint32 (temperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (property_name, "DisabledUntilTomorrow") == 0)
|
||||||
|
return g_variant_new_boolean (gsd_night_light_get_disabled_until_tmw (manager->nlight));
|
||||||
|
|
||||||
|
if (g_strcmp0 (property_name, "Sunrise") == 0)
|
||||||
|
return g_variant_new_double (gsd_night_light_get_sunrise (manager->nlight));
|
||||||
|
|
||||||
|
if (g_strcmp0 (property_name, "Sunset") == 0)
|
||||||
|
return g_variant_new_double (gsd_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)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (user_data);
|
||||||
|
|
||||||
|
if (g_strcmp0 (interface_name, GSD_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 < GSD_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, GSD_COLOR_TEMPERATURE_MIN);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (temperature > GSD_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, GSD_COLOR_TEMPERATURE_MAX);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
gsd_color_state_set_temperature (manager->state, temperature);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (property_name, "DisabledUntilTomorrow") == 0) {
|
||||||
|
gsd_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 gboolean
|
||||||
|
gsd_color_manager_dbus_register (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (app);
|
||||||
|
|
||||||
|
if (!G_APPLICATION_CLASS (gsd_color_manager_parent_class)->dbus_register (app,
|
||||||
|
connection,
|
||||||
|
object_path,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
manager->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
|
||||||
|
g_assert (manager->introspection_data != NULL);
|
||||||
|
|
||||||
|
g_dbus_connection_register_object (connection,
|
||||||
|
GSD_COLOR_DBUS_PATH,
|
||||||
|
manager->introspection_data->interfaces[0],
|
||||||
|
&interface_vtable,
|
||||||
|
manager,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_manager_dbus_unregister (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path)
|
||||||
|
{
|
||||||
|
GsdColorManager *manager = GSD_COLOR_MANAGER (app);
|
||||||
|
|
||||||
|
g_clear_pointer (&manager->introspection_data, g_dbus_node_info_unref);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_color_manager_parent_class)->dbus_unregister (app,
|
||||||
|
connection,
|
||||||
|
object_path);
|
||||||
|
}
|
33
plugins/color/gsd-color-manager.h
Normal file
33
plugins/color/gsd-color-manager.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_COLOR_MANAGER_H
|
||||||
|
#define __GSD_COLOR_MANAGER_H
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_COLOR_MANAGER (gsd_color_manager_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdColorManager, gsd_color_manager, GSD, COLOR_MANAGER, GsdApplication)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_COLOR_MANAGER_H */
|
82
plugins/color/gsd-color-state.c
Normal file
82
plugins/color/gsd-color-state.c
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011-2013 Richard Hughes <richard@hughsie.com>
|
||||||
|
* Copyright (C) 2020 NVIDIA CORPORATION
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gsd-color-manager.h"
|
||||||
|
#include "gsd-color-state.h"
|
||||||
|
|
||||||
|
struct _GsdColorState
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
guint color_temperature;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_color_state_class_init (GsdColorStateClass *klass);
|
||||||
|
static void gsd_color_state_init (GsdColorState *color_state);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdColorState, gsd_color_state, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_color_state_set_temperature (GsdColorState *state, guint temperature)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GSD_IS_COLOR_STATE (state));
|
||||||
|
|
||||||
|
state->color_temperature = temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
gsd_color_state_get_temperature (GsdColorState *state)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GSD_IS_COLOR_STATE (state), 0);
|
||||||
|
return state->color_temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_color_state_start (GsdColorState *state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_color_state_stop (GsdColorState *state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_state_class_init (GsdColorStateClass *klass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_color_state_init (GsdColorState *state)
|
||||||
|
{
|
||||||
|
/* default color temperature */
|
||||||
|
state->color_temperature = GSD_COLOR_TEMPERATURE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdColorState *
|
||||||
|
gsd_color_state_new (void)
|
||||||
|
{
|
||||||
|
GsdColorState *state;
|
||||||
|
state = g_object_new (GSD_TYPE_COLOR_STATE, NULL);
|
||||||
|
return GSD_COLOR_STATE (state);
|
||||||
|
}
|
45
plugins/color/gsd-color-state.h
Normal file
45
plugins/color/gsd-color-state.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||||
|
* Copyright (C) 2011-2013 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_COLOR_STATE_H
|
||||||
|
#define __GSD_COLOR_STATE_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_COLOR_STATE (gsd_color_state_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdColorState, gsd_color_state, GSD, COLOR_STATE, GObject)
|
||||||
|
|
||||||
|
#define GSD_COLOR_TEMPERATURE_MIN 1000 /* Kelvin */
|
||||||
|
#define GSD_COLOR_TEMPERATURE_DEFAULT 6500 /* Kelvin, is RGB [1.0,1.0,1.0] */
|
||||||
|
#define GSD_COLOR_TEMPERATURE_MAX 10000 /* Kelvin */
|
||||||
|
|
||||||
|
GsdColorState * gsd_color_state_new (void);
|
||||||
|
void gsd_color_state_start (GsdColorState *state);
|
||||||
|
void gsd_color_state_stop (GsdColorState *state);
|
||||||
|
void gsd_color_state_set_temperature (GsdColorState *state,
|
||||||
|
guint temperature);
|
||||||
|
guint gsd_color_state_get_temperature (GsdColorState *state);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_COLOR_STATE_H */
|
137
plugins/color/gsd-night-light-common.c
Normal file
137
plugins/color/gsd-night-light-common.c
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "gsd-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
|
||||||
|
gsd_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
|
||||||
|
gsd_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsd_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;
|
||||||
|
}
|
39
plugins/color/gsd-night-light-common.h
Normal file
39
plugins/color/gsd-night-light-common.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_NIGHT_LIGHT_COMMON_H
|
||||||
|
#define __GSD_NIGHT_LIGHT_COMMON_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
gboolean gsd_night_light_get_sunrise_sunset (GDateTime *dt,
|
||||||
|
gdouble pos_lat,
|
||||||
|
gdouble pos_long,
|
||||||
|
gdouble *sunrise,
|
||||||
|
gdouble *sunset);
|
||||||
|
gdouble gsd_night_light_frac_day_from_dt (GDateTime *dt);
|
||||||
|
gboolean gsd_night_light_frac_day_is_between (gdouble value,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_NIGHT_LIGHT_COMMON_H */
|
807
plugins/color/gsd-night-light.c
Normal file
807
plugins/color/gsd-night-light.c
Normal file
|
@ -0,0 +1,807 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* 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 <geoclue.h>
|
||||||
|
|
||||||
|
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||||
|
#include "gnome-datetime-source.h"
|
||||||
|
|
||||||
|
#include "gsd-color-state.h"
|
||||||
|
|
||||||
|
#include "gsd-night-light.h"
|
||||||
|
#include "gsd-night-light-common.h"
|
||||||
|
|
||||||
|
struct _GsdNightLight {
|
||||||
|
GObject parent;
|
||||||
|
GSettings *settings;
|
||||||
|
gboolean forced;
|
||||||
|
gboolean disabled_until_tmw;
|
||||||
|
GDateTime *disabled_until_tmw_dt;
|
||||||
|
gboolean geoclue_enabled;
|
||||||
|
GSource *source;
|
||||||
|
guint validate_id;
|
||||||
|
GClueClient *geoclue_client;
|
||||||
|
GClueSimple *geoclue_simple;
|
||||||
|
GSettings *location_settings;
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GSD_NIGHT_LIGHT_SCHEDULE_TIMEOUT 5 /* seconds */
|
||||||
|
#define GSD_NIGHT_LIGHT_POLL_TIMEOUT 60 /* seconds */
|
||||||
|
#define GSD_NIGHT_LIGHT_POLL_SMEAR 1 /* hours */
|
||||||
|
#define GSD_NIGHT_LIGHT_SMOOTH_SMEAR 5.f /* seconds */
|
||||||
|
|
||||||
|
#define GSD_FRAC_DAY_MAX_DELTA (1.f/60.f) /* 1 minute */
|
||||||
|
#define GSD_TEMPERATURE_MAX_DELTA (10.f) /* Kelvin */
|
||||||
|
|
||||||
|
#define DESKTOP_ID "gnome-color-panel"
|
||||||
|
|
||||||
|
static void poll_timeout_destroy (GsdNightLight *self);
|
||||||
|
static void poll_timeout_create (GsdNightLight *self);
|
||||||
|
static void night_light_recheck (GsdNightLight *self);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdNightLight, gsd_night_light, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static GDateTime *
|
||||||
|
gsd_night_light_get_date_time_now (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
if (self->datetime_override != NULL)
|
||||||
|
return g_date_time_ref (self->datetime_override);
|
||||||
|
return g_date_time_new_now_local ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_night_light_set_date_time_now (GsdNightLight *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 (GsdNightLight *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
|
||||||
|
gsd_night_light_set_smooth_enabled (GsdNightLight *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 (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
gdouble latitude;
|
||||||
|
gdouble longitude;
|
||||||
|
gdouble sunrise;
|
||||||
|
gdouble sunset;
|
||||||
|
g_autoptr(GVariant) tmp = NULL;
|
||||||
|
g_autoptr(GDateTime) dt_now = gsd_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 (!gsd_night_light_get_sunrise_sunset (dt_now, latitude, longitude,
|
||||||
|
&sunrise, &sunset)) {
|
||||||
|
g_warning ("failed to get sunset/sunrise for %.3f,%.3f",
|
||||||
|
longitude, longitude);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* anything changed */
|
||||||
|
if (ABS (self->cached_sunrise - sunrise) > GSD_FRAC_DAY_MAX_DELTA) {
|
||||||
|
self->cached_sunrise = sunrise;
|
||||||
|
g_object_notify (G_OBJECT (self), "sunrise");
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
if (ABS (self->cached_sunset - sunset) > GSD_FRAC_DAY_MAX_DELTA) {
|
||||||
|
self->cached_sunset = sunset;
|
||||||
|
g_object_notify (G_OBJECT (self), "sunset");
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_set_temperature_internal (GsdNightLight *self, gdouble temperature, gboolean force)
|
||||||
|
{
|
||||||
|
if (!force && ABS (self->cached_temperature - temperature) <= GSD_TEMPERATURE_MAX_DELTA)
|
||||||
|
return;
|
||||||
|
if (self->cached_temperature == temperature)
|
||||||
|
return;
|
||||||
|
self->cached_temperature = temperature;
|
||||||
|
g_object_notify (G_OBJECT (self), "temperature");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gsd_night_light_smooth_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
|
||||||
|
gdouble tmp;
|
||||||
|
gdouble frac;
|
||||||
|
|
||||||
|
/* find fraction */
|
||||||
|
frac = g_timer_elapsed (self->smooth_timer, NULL) / GSD_NIGHT_LIGHT_SMOOTH_SMEAR;
|
||||||
|
if (frac >= 1.f) {
|
||||||
|
gsd_night_light_set_temperature_internal (self,
|
||||||
|
self->smooth_target_temperature,
|
||||||
|
TRUE);
|
||||||
|
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;
|
||||||
|
gsd_night_light_set_temperature_internal (self, tmp, FALSE);
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poll_smooth_create (GsdNightLight *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, gsd_night_light_smooth_cb, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_set_temperature (GsdNightLight *self, gdouble temperature)
|
||||||
|
{
|
||||||
|
/* immediate */
|
||||||
|
if (!self->smooth_enabled) {
|
||||||
|
gsd_night_light_set_temperature_internal (self, temperature, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy any smooth transition, it will be recreated if neccessary */
|
||||||
|
poll_smooth_destroy (self);
|
||||||
|
|
||||||
|
/* small jump */
|
||||||
|
if (ABS (temperature - self->cached_temperature) < GSD_TEMPERATURE_MAX_DELTA) {
|
||||||
|
gsd_night_light_set_temperature_internal (self, temperature, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* smooth out the transition */
|
||||||
|
poll_smooth_create (self, temperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_set_active (GsdNightLight *self, gboolean active)
|
||||||
|
{
|
||||||
|
if (self->cached_active == active)
|
||||||
|
return;
|
||||||
|
self->cached_active = active;
|
||||||
|
|
||||||
|
/* ensure set to unity temperature */
|
||||||
|
if (!active)
|
||||||
|
gsd_night_light_set_temperature (self, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "active");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
night_light_recheck (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
gdouble frac_day;
|
||||||
|
gdouble schedule_from = -1.f;
|
||||||
|
gdouble schedule_to = -1.f;
|
||||||
|
gdouble smear = GSD_NIGHT_LIGHT_POLL_SMEAR; /* hours */
|
||||||
|
guint temperature;
|
||||||
|
guint temp_smeared;
|
||||||
|
g_autoptr(GDateTime) dt_now = gsd_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");
|
||||||
|
gsd_night_light_set_temperature (self, temperature);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enabled */
|
||||||
|
if (!g_settings_get_boolean (self->settings, "night-light-enabled")) {
|
||||||
|
g_debug ("night light disabled, resetting");
|
||||||
|
gsd_night_light_set_active (self, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the position of the sun */
|
||||||
|
if (g_settings_get_boolean (self->settings, "night-light-schedule-automatic")) {
|
||||||
|
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 = gsd_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 = gsd_night_light_frac_day_from_dt (self->disabled_until_tmw_dt);
|
||||||
|
if (frac_disabled != frac_day &&
|
||||||
|
gsd_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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (!gsd_night_light_frac_day_is_between (frac_day,
|
||||||
|
schedule_from - smear,
|
||||||
|
schedule_to)) {
|
||||||
|
g_debug ("not time for night-light");
|
||||||
|
gsd_night_light_set_active (self, FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsd_night_light_set_active (self, TRUE);
|
||||||
|
|
||||||
|
if (self->disabled_until_tmw) {
|
||||||
|
g_debug ("night light still day-disabled");
|
||||||
|
gsd_night_light_set_temperature (self, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
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 (gsd_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 (GSD_COLOR_TEMPERATURE_DEFAULT,
|
||||||
|
temperature, factor);
|
||||||
|
} else if (gsd_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 (GSD_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);
|
||||||
|
gsd_night_light_set_temperature (self, temp_smeared);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
night_light_recheck_schedule_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
|
||||||
|
night_light_recheck (self);
|
||||||
|
self->validate_id = 0;
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called when something changed */
|
||||||
|
static void
|
||||||
|
night_light_recheck_schedule (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
if (self->validate_id != 0)
|
||||||
|
g_source_remove (self->validate_id);
|
||||||
|
self->validate_id =
|
||||||
|
g_timeout_add_seconds (GSD_NIGHT_LIGHT_SCHEDULE_TIMEOUT,
|
||||||
|
night_light_recheck_schedule_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called when the time may have changed */
|
||||||
|
static gboolean
|
||||||
|
night_light_recheck_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_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 (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
g_autoptr(GDateTime) dt_now = NULL;
|
||||||
|
g_autoptr(GDateTime) dt_expiry = NULL;
|
||||||
|
|
||||||
|
if (self->source != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* It is not a good idea to make this overridable, it just creates
|
||||||
|
* an infinite loop as a fixed date for testing just doesn't work. */
|
||||||
|
dt_now = g_date_time_new_now_local ();
|
||||||
|
dt_expiry = g_date_time_add_seconds (dt_now, GSD_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 (GsdNightLight *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)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
|
||||||
|
g_debug ("settings changed");
|
||||||
|
night_light_recheck (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_location_notify (GClueSimple *simple,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
|
||||||
|
GClueLocation *location;
|
||||||
|
gdouble latitude, longitude;
|
||||||
|
|
||||||
|
location = gclue_simple_get_location (simple);
|
||||||
|
latitude = gclue_location_get_latitude (location);
|
||||||
|
longitude = gclue_location_get_longitude (location);
|
||||||
|
|
||||||
|
g_settings_set_value (self->settings,
|
||||||
|
"night-light-last-coordinates",
|
||||||
|
g_variant_new ("(dd)", latitude, longitude));
|
||||||
|
|
||||||
|
g_debug ("got geoclue latitude %f, longitude %f", latitude, longitude);
|
||||||
|
|
||||||
|
/* recheck the levels if the location changed significantly */
|
||||||
|
if (update_cached_sunrise_sunset (self))
|
||||||
|
night_light_recheck_schedule (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_geoclue_simple_ready (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
|
||||||
|
GClueSimple *geoclue_simple;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
geoclue_simple = gclue_simple_new_finish (res, &error);
|
||||||
|
if (geoclue_simple == NULL) {
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to connect to GeoClue2 service: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->geoclue_simple = geoclue_simple;
|
||||||
|
self->geoclue_client = gclue_simple_get_client (self->geoclue_simple);
|
||||||
|
g_object_set (G_OBJECT (self->geoclue_client),
|
||||||
|
"time-threshold", 60*60, NULL); /* 1 hour */
|
||||||
|
|
||||||
|
g_signal_connect (self->geoclue_simple, "notify::location",
|
||||||
|
G_CALLBACK (on_location_notify), user_data);
|
||||||
|
|
||||||
|
on_location_notify (self->geoclue_simple, NULL, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_geoclue (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
self->cancellable = g_cancellable_new ();
|
||||||
|
gclue_simple_new (DESKTOP_ID,
|
||||||
|
GCLUE_ACCURACY_LEVEL_CITY,
|
||||||
|
self->cancellable,
|
||||||
|
on_geoclue_simple_ready,
|
||||||
|
self);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_geoclue (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (self->cancellable);
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
|
||||||
|
if (self->geoclue_client != NULL) {
|
||||||
|
gclue_client_call_stop (self->geoclue_client, NULL, NULL, NULL);
|
||||||
|
self->geoclue_client = NULL;
|
||||||
|
}
|
||||||
|
g_clear_object (&self->geoclue_simple);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_location_settings (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
if (g_settings_get_boolean (self->location_settings, "enabled") && self->geoclue_enabled)
|
||||||
|
start_geoclue (self);
|
||||||
|
else
|
||||||
|
stop_geoclue (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_night_light_set_disabled_until_tmw (GsdNightLight *self, gboolean value)
|
||||||
|
{
|
||||||
|
g_autoptr(GDateTime) dt = gsd_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
|
||||||
|
gsd_night_light_get_disabled_until_tmw (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->disabled_until_tmw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_night_light_set_forced (GsdNightLight *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)
|
||||||
|
gsd_night_light_set_temperature (self, GSD_COLOR_TEMPERATURE_DEFAULT);
|
||||||
|
|
||||||
|
night_light_recheck (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsd_night_light_get_forced (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->forced;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsd_night_light_get_active (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->cached_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gsd_night_light_get_sunrise (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->cached_sunrise;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gsd_night_light_get_sunset (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->cached_sunset;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gsd_night_light_get_temperature (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
return self->cached_temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_night_light_set_geoclue_enabled (GsdNightLight *self, gboolean enabled)
|
||||||
|
{
|
||||||
|
self->geoclue_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsd_night_light_start (GsdNightLight *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);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (self->location_settings, "changed::enabled",
|
||||||
|
G_CALLBACK (check_location_settings), self);
|
||||||
|
check_location_settings (self);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_NIGHT_LIGHT (object);
|
||||||
|
|
||||||
|
stop_geoclue (self);
|
||||||
|
|
||||||
|
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_clear_object (&self->location_settings);
|
||||||
|
G_OBJECT_CLASS (gsd_night_light_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_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:
|
||||||
|
gsd_night_light_set_disabled_until_tmw (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_FORCED:
|
||||||
|
gsd_night_light_set_forced (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GsdNightLight *self = GSD_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_sunset);
|
||||||
|
break;
|
||||||
|
case PROP_TEMPERATURE:
|
||||||
|
g_value_set_double (value, self->cached_temperature);
|
||||||
|
break;
|
||||||
|
case PROP_DISABLED_UNTIL_TMW:
|
||||||
|
g_value_set_boolean (value, gsd_night_light_get_disabled_until_tmw (self));
|
||||||
|
break;
|
||||||
|
case PROP_FORCED:
|
||||||
|
g_value_set_boolean (value, gsd_night_light_get_forced (self));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_night_light_class_init (GsdNightLightClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
object_class->finalize = gsd_night_light_finalize;
|
||||||
|
|
||||||
|
object_class->set_property = gsd_night_light_set_property;
|
||||||
|
object_class->get_property = gsd_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",
|
||||||
|
GSD_COLOR_TEMPERATURE_MIN,
|
||||||
|
GSD_COLOR_TEMPERATURE_MAX,
|
||||||
|
GSD_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
|
||||||
|
gsd_night_light_init (GsdNightLight *self)
|
||||||
|
{
|
||||||
|
self->geoclue_enabled = TRUE;
|
||||||
|
self->smooth_enabled = TRUE;
|
||||||
|
self->cached_sunrise = -1.f;
|
||||||
|
self->cached_sunset = -1.f;
|
||||||
|
self->cached_temperature = GSD_COLOR_TEMPERATURE_DEFAULT;
|
||||||
|
self->settings = g_settings_new ("org.gnome.settings-daemon.plugins.color");
|
||||||
|
self->location_settings = g_settings_new ("org.gnome.system.location");
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdNightLight *
|
||||||
|
gsd_night_light_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (GSD_TYPE_NIGHT_LIGHT, NULL);
|
||||||
|
}
|
58
plugins/color/gsd-night-light.h
Normal file
58
plugins/color/gsd-night-light.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* 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 __GSD_NIGHT_LIGHT_H__
|
||||||
|
#define __GSD_NIGHT_LIGHT_H__
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_NIGHT_LIGHT (gsd_night_light_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdNightLight, gsd_night_light, GSD, NIGHT_LIGHT, GObject)
|
||||||
|
|
||||||
|
GsdNightLight *gsd_night_light_new (void);
|
||||||
|
gboolean gsd_night_light_start (GsdNightLight *self,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean gsd_night_light_get_active (GsdNightLight *self);
|
||||||
|
gdouble gsd_night_light_get_sunrise (GsdNightLight *self);
|
||||||
|
gdouble gsd_night_light_get_sunset (GsdNightLight *self);
|
||||||
|
gdouble gsd_night_light_get_temperature (GsdNightLight *self);
|
||||||
|
|
||||||
|
gboolean gsd_night_light_get_disabled_until_tmw (GsdNightLight *self);
|
||||||
|
void gsd_night_light_set_disabled_until_tmw (GsdNightLight *self,
|
||||||
|
gboolean value);
|
||||||
|
|
||||||
|
gboolean gsd_night_light_get_forced (GsdNightLight *self);
|
||||||
|
void gsd_night_light_set_forced (GsdNightLight *self,
|
||||||
|
gboolean value);
|
||||||
|
|
||||||
|
/* only for the self test program */
|
||||||
|
void gsd_night_light_set_geoclue_enabled (GsdNightLight *self,
|
||||||
|
gboolean enabled);
|
||||||
|
void gsd_night_light_set_date_time_now (GsdNightLight *self,
|
||||||
|
GDateTime *datetime);
|
||||||
|
void gsd_night_light_set_smooth_enabled (GsdNightLight *self,
|
||||||
|
gboolean smooth_enabled);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
9
plugins/color/main.c
Normal file
9
plugins/color/main.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "gsd-main-helper.h"
|
||||||
|
#include "gsd-color-manager.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return gsd_main_helper (GSD_TYPE_COLOR_MANAGER, argc, argv);
|
||||||
|
}
|
||||||
|
|
53
plugins/color/meson.build
Normal file
53
plugins/color/meson.build
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
sources = files(
|
||||||
|
'gnome-datetime-source.c',
|
||||||
|
'gsd-color-calibrate.c',
|
||||||
|
'gsd-color-manager.c',
|
||||||
|
'gsd-color-state.c',
|
||||||
|
'gsd-night-light.c',
|
||||||
|
'gsd-night-light-common.c',
|
||||||
|
'main.c'
|
||||||
|
)
|
||||||
|
sources += main_helper_sources
|
||||||
|
|
||||||
|
deps = plugins_deps + [
|
||||||
|
colord_dep,
|
||||||
|
libcanberra_gtk_dep,
|
||||||
|
libgeoclue_dep,
|
||||||
|
libnotify_dep,
|
||||||
|
libcommon_dep,
|
||||||
|
m_dep,
|
||||||
|
]
|
||||||
|
|
||||||
|
cflags += ['-DBINDIR="@0@"'.format(gsd_bindir)]
|
||||||
|
cflags += ['-DUSE_GTK=1']
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'gsd-' + plugin_name,
|
||||||
|
sources,
|
||||||
|
include_directories: [top_inc, common_inc],
|
||||||
|
dependencies: deps,
|
||||||
|
c_args: cflags,
|
||||||
|
install: true,
|
||||||
|
install_rpath: gsd_pkglibdir,
|
||||||
|
install_dir: gsd_libexecdir
|
||||||
|
)
|
||||||
|
|
||||||
|
sources = files(
|
||||||
|
'gcm-self-test.c',
|
||||||
|
'gnome-datetime-source.c',
|
||||||
|
'gsd-night-light.c',
|
||||||
|
'gsd-night-light-common.c'
|
||||||
|
)
|
||||||
|
|
||||||
|
test_unit = 'gcm-self-test'
|
||||||
|
|
||||||
|
exe = executable(
|
||||||
|
test_unit,
|
||||||
|
sources,
|
||||||
|
include_directories: top_inc,
|
||||||
|
dependencies: deps,
|
||||||
|
c_args: '-DTESTDATADIR="@0@"'.format(join_paths(meson.current_source_dir(), 'test-data'))
|
||||||
|
)
|
||||||
|
|
||||||
|
envs = ['GSETTINGS_SCHEMA_DIR=@0@'.format(join_paths(meson.project_build_root(), 'data'))]
|
||||||
|
test(test_unit, exe, env: envs)
|
BIN
plugins/color/test-data/LG-L225W-External.bin
Normal file
BIN
plugins/color/test-data/LG-L225W-External.bin
Normal file
Binary file not shown.
BIN
plugins/color/test-data/Lenovo-T61-Internal.bin
Normal file
BIN
plugins/color/test-data/Lenovo-T61-Internal.bin
Normal file
Binary file not shown.
46
plugins/common/gsd-application.c
Normal file
46
plugins/common/gsd-application.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdApplication, gsd_application, G_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_application_real_pre_shutdown (GsdApplication *app)
|
||||||
|
{
|
||||||
|
g_application_release (G_APPLICATION (app));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_application_class_init (GsdApplicationClass *klass)
|
||||||
|
{
|
||||||
|
klass->pre_shutdown = gsd_application_real_pre_shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_application_init (GsdApplication *app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_application_pre_shutdown (GsdApplication *app)
|
||||||
|
{
|
||||||
|
GSD_APPLICATION_GET_CLASS (app)->pre_shutdown (app);
|
||||||
|
}
|
41
plugins/common/gsd-application.h
Normal file
41
plugins/common/gsd-application.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_APPLICATION_H__
|
||||||
|
#define __GSD_APPLICATION_H__
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#define GSD_TYPE_APPLICATION gsd_application_get_type ()
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (GsdApplication,
|
||||||
|
gsd_application,
|
||||||
|
GSD, APPLICATION,
|
||||||
|
GApplication)
|
||||||
|
|
||||||
|
struct _GsdApplicationClass
|
||||||
|
{
|
||||||
|
GApplicationClass parent_class;
|
||||||
|
|
||||||
|
void (* pre_shutdown) (GsdApplication *app);
|
||||||
|
};
|
||||||
|
|
||||||
|
void gsd_application_pre_shutdown (GsdApplication *app);
|
||||||
|
|
||||||
|
#endif /* __GSD_APPLICATION_H__ */
|
79
plugins/common/gsd-input-helper.c
Normal file
79
plugins/common/gsd-input-helper.c
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/XInput2.h>
|
||||||
|
|
||||||
|
#include "gsd-input-helper.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
33
plugins/common/gsd-input-helper.h
Normal file
33
plugins/common/gsd-input-helper.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_INPUT_HELPER_H
|
||||||
|
#define __GSD_INPUT_HELPER_H
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <X11/extensions/XInput.h>
|
||||||
|
#include <X11/extensions/XIproto.h>
|
||||||
|
|
||||||
|
char * xdevice_get_device_node (int deviceid);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_INPUT_HELPER_H */
|
300
plugins/common/gsd-main-helper.c
Normal file
300
plugins/common/gsd-main-helper.c
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
/**
|
||||||
|
* Create a gnome-settings-daemon helper easily
|
||||||
|
*
|
||||||
|
* #include "gsd-main-helper.h"
|
||||||
|
* #include "gsd-media-keys-manager.h"
|
||||||
|
*
|
||||||
|
* int
|
||||||
|
* main (int argc, char **argv)
|
||||||
|
* {
|
||||||
|
* return gsd_main_helper (GSD_TYPE_MEDIA_KEYS_MANAGER, argc, argv);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
#include "gsd-main-helper.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#ifdef USE_GTK
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gnome-settings-bus.h"
|
||||||
|
|
||||||
|
#ifdef USE_GTK
|
||||||
|
#include "gsd-resources.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PLUGIN_NAME
|
||||||
|
#error Include PLUGIN_CFLAGS in the daemon s CFLAGS
|
||||||
|
#endif /* !PLUGIN_NAME */
|
||||||
|
|
||||||
|
#ifndef PLUGIN_DBUS_NAME
|
||||||
|
#error Include PLUGIN_DBUS_NAME in the daemon s CFLAGS
|
||||||
|
#endif /* !PLUGIN_DBUS_NAME */
|
||||||
|
|
||||||
|
#define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager"
|
||||||
|
#define GNOME_SESSION_CLIENT_PRIVATE_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate"
|
||||||
|
|
||||||
|
static int timeout = -1;
|
||||||
|
static char *dummy_name = NULL;
|
||||||
|
static gboolean verbose = FALSE;
|
||||||
|
|
||||||
|
static GOptionEntry entries[] = {
|
||||||
|
{ "exit-time", 0, 0, G_OPTION_ARG_INT, &timeout, "Exit after n seconds time", NULL },
|
||||||
|
{ "dummy-name", 0, 0, G_OPTION_ARG_STRING, &dummy_name, "Name when using the dummy daemon", NULL },
|
||||||
|
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose", NULL },
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_activate (GApplication *manager)
|
||||||
|
{
|
||||||
|
g_debug ("Daemon activated");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_activate (GApplication *manager)
|
||||||
|
{
|
||||||
|
g_signal_connect (manager, "activate", G_CALLBACK (on_activate), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_timeout (GApplication *manager)
|
||||||
|
{
|
||||||
|
if (timeout > 0) {
|
||||||
|
guint id;
|
||||||
|
id = g_timeout_add_seconds (timeout, (GSourceFunc) gsd_application_pre_shutdown, manager);
|
||||||
|
g_source_set_name_by_id (id, "[gnome-settings-daemon] gsd_application_pre_shutdown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_sigterm (gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdApplication *manager = user_data;
|
||||||
|
|
||||||
|
g_debug ("Got SIGTERM; shutting down ...");
|
||||||
|
|
||||||
|
gsd_application_pre_shutdown (manager);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
install_signal_handler (GApplication *manager)
|
||||||
|
{
|
||||||
|
g_autoptr (GSource) source = NULL;
|
||||||
|
|
||||||
|
source = g_unix_signal_source_new (SIGTERM);
|
||||||
|
|
||||||
|
g_source_set_callback (source, handle_sigterm, manager, NULL);
|
||||||
|
g_source_attach (source, 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)
|
||||||
|
{
|
||||||
|
GsdApplication *manager = 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");
|
||||||
|
gsd_application_pre_shutdown (manager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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_DBUS_INTERFACE,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (!client_proxy) {
|
||||||
|
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), user_data);
|
||||||
|
|
||||||
|
g_free (object_path);
|
||||||
|
g_variant_unref (variant);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_with_gnome_session (GApplication *manager)
|
||||||
|
{
|
||||||
|
GDBusProxy *proxy;
|
||||||
|
const char *startup_id;
|
||||||
|
|
||||||
|
proxy = G_DBUS_PROXY (gnome_settings_bus_get_session_proxy ());
|
||||||
|
startup_id = g_getenv ("DESKTOP_AUTOSTART_ID");
|
||||||
|
g_dbus_proxy_call (proxy,
|
||||||
|
"RegisterClient",
|
||||||
|
g_variant_new ("(ss)", dummy_name ? dummy_name : PLUGIN_NAME, startup_id ? startup_id : ""),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) on_client_registered,
|
||||||
|
manager);
|
||||||
|
|
||||||
|
/* DESKTOP_AUTOSTART_ID must not leak into child processes, because
|
||||||
|
* it can't be reused. Child processes will not know whether this is
|
||||||
|
* a genuine value or erroneous already-used value. */
|
||||||
|
g_unsetenv ("DESKTOP_AUTOSTART_ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GTK
|
||||||
|
static void
|
||||||
|
set_empty_gtk_theme (gboolean set)
|
||||||
|
{
|
||||||
|
static char *old_gtk_theme = NULL;
|
||||||
|
|
||||||
|
if (set) {
|
||||||
|
/* Override GTK_THEME to reduce overhead of CSS engine. By using
|
||||||
|
* GTK_THEME environment variable, GtkSettings is not allowed to
|
||||||
|
* initially parse the Adwaita theme.
|
||||||
|
*
|
||||||
|
* https://bugzilla.gnome.org/show_bug.cgi?id=780555 */
|
||||||
|
old_gtk_theme = g_strdup (g_getenv ("GTK_THEME"));
|
||||||
|
g_setenv ("GTK_THEME", "Disabled", TRUE);
|
||||||
|
} else {
|
||||||
|
/* GtkSettings has loaded, so we can drop GTK_THEME used to initialize
|
||||||
|
* our internal theme. Only the main thread accesses the GTK_THEME
|
||||||
|
* environment variable, so this is safe to release. */
|
||||||
|
if (old_gtk_theme != NULL)
|
||||||
|
g_setenv ("GTK_THEME", old_gtk_theme, TRUE);
|
||||||
|
else
|
||||||
|
g_unsetenv ("GTK_THEME");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
start (GApplication *manager,
|
||||||
|
int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
|
if (G_IS_INITABLE (manager) &&
|
||||||
|
!g_initable_init (G_INITABLE (manager), NULL, &error)) {
|
||||||
|
g_printerr ("Failed to start: %s\n", error->message);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_application_hold (manager);
|
||||||
|
|
||||||
|
return g_application_run (manager, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gsd_main_helper (GType manager_type,
|
||||||
|
int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
g_autoptr (GOptionContext) context = NULL;
|
||||||
|
g_autoptr (GApplication) manager = NULL;
|
||||||
|
|
||||||
|
bindtextdomain (GETTEXT_PACKAGE, GNOME_SETTINGS_LOCALEDIR);
|
||||||
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
|
textdomain (GETTEXT_PACKAGE);
|
||||||
|
setlocale (LC_ALL, "");
|
||||||
|
|
||||||
|
#ifdef USE_GTK
|
||||||
|
/* Ensure we don't lose resources during linkage */
|
||||||
|
g_resources_register (gsd_get_resource ());
|
||||||
|
|
||||||
|
set_empty_gtk_theme (TRUE);
|
||||||
|
|
||||||
|
if (! gtk_init_with_args (&argc, &argv, PLUGIN_NAME, entries, NULL, &error)) {
|
||||||
|
if (error != NULL) {
|
||||||
|
g_printerr ("%s\n", error->message);
|
||||||
|
}
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_empty_gtk_theme (FALSE);
|
||||||
|
#else
|
||||||
|
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)) {
|
||||||
|
g_printerr ("%s\n", error->message);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||||
|
/* Work around GLib not flushing the output for us by explicitly
|
||||||
|
* setting buffering to a sane behaviour. This is important
|
||||||
|
* during testing when the output is not going to a TTY and
|
||||||
|
* we are reading messages from g_debug on stdout.
|
||||||
|
*
|
||||||
|
* See also
|
||||||
|
* https://bugzilla.gnome.org/show_bug.cgi?id=792432
|
||||||
|
*/
|
||||||
|
setlinebuf (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
manager = g_object_new (manager_type,
|
||||||
|
"application-id", PLUGIN_DBUS_NAME,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
register_activate (manager);
|
||||||
|
register_timeout (manager);
|
||||||
|
install_signal_handler (manager);
|
||||||
|
register_with_gnome_session (manager);
|
||||||
|
|
||||||
|
return start (manager, argc, argv);
|
||||||
|
}
|
31
plugins/common/gsd-main-helper.h
Normal file
31
plugins/common/gsd-main-helper.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SUSE Software Solutions Germany GmbH
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Joan Torres <joan.torres@suse.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_MAIN_HELPER_H
|
||||||
|
#define __GSD_MAIN_HELPER_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
int gsd_main_helper (GType manager_type,
|
||||||
|
int argc,
|
||||||
|
char **argv);
|
||||||
|
|
||||||
|
#endif /* __GSD_MAIN_HELPER_H */
|
74
plugins/common/gsd-settings-migrate.c
Normal file
74
plugins/common/gsd-settings-migrate.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* -*- 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 <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gsd-settings-migrate.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
gsd_settings_migrate_check (const gchar *origin_schema,
|
||||||
|
const gchar *origin_path,
|
||||||
|
const gchar *dest_schema,
|
||||||
|
const gchar *dest_path,
|
||||||
|
GsdSettingsMigrateEntry 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;
|
||||||
|
|
||||||
|
g_settings_reset (origin_settings, entries[i].origin_key);
|
||||||
|
|
||||||
|
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, 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_object_unref (origin_settings);
|
||||||
|
g_object_unref (dest_settings);
|
||||||
|
}
|
43
plugins/common/gsd-settings-migrate.h
Normal file
43
plugins/common/gsd-settings-migrate.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- 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 <carlosg@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_SETTINGS_MIGRATE_H__
|
||||||
|
#define __GSD_SETTINGS_MIGRATE_H__
|
||||||
|
|
||||||
|
typedef struct _GsdSettingsMigrateEntry GsdSettingsMigrateEntry;
|
||||||
|
|
||||||
|
typedef GVariant * (* GsdSettingsMigrateFunc) (GVariant *variant, GVariant *old_default, GVariant *new_default);
|
||||||
|
|
||||||
|
struct _GsdSettingsMigrateEntry
|
||||||
|
{
|
||||||
|
const gchar *origin_key;
|
||||||
|
const gchar *dest_key;
|
||||||
|
GsdSettingsMigrateFunc func;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gsd_settings_migrate_check (const gchar *origin_schema,
|
||||||
|
const gchar *origin_path,
|
||||||
|
const gchar *dest_schema,
|
||||||
|
const gchar *dest_path,
|
||||||
|
GsdSettingsMigrateEntry entries[],
|
||||||
|
guint n_entries);
|
||||||
|
|
||||||
|
#endif /* __GSD_SETTINGS_MIGRATE_H__ */
|
66
plugins/common/gsd-shell-helper.c
Normal file
66
plugins/common/gsd-shell-helper.c
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "gsd-shell-helper.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_show_osd (GsdShell *shell,
|
||||||
|
const gchar *icon_name,
|
||||||
|
const gchar *label,
|
||||||
|
double level,
|
||||||
|
const gchar *connector)
|
||||||
|
{
|
||||||
|
shell_show_osd_with_max_level (shell, icon_name, label, level, -1, connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_show_osd_with_max_level (GsdShell *shell,
|
||||||
|
const gchar *icon_name,
|
||||||
|
const gchar *label,
|
||||||
|
double level,
|
||||||
|
double max_level,
|
||||||
|
const gchar *connector)
|
||||||
|
{
|
||||||
|
GVariantBuilder builder;
|
||||||
|
|
||||||
|
g_return_if_fail (GSD_IS_SHELL (shell));
|
||||||
|
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
|
||||||
|
if (icon_name)
|
||||||
|
g_variant_builder_add (&builder, "{sv}",
|
||||||
|
"icon", g_variant_new_string (icon_name));
|
||||||
|
if (label)
|
||||||
|
g_variant_builder_add (&builder, "{sv}",
|
||||||
|
"label", g_variant_new_string (label));
|
||||||
|
if (level >= 0.0)
|
||||||
|
g_variant_builder_add (&builder, "{sv}",
|
||||||
|
"level", g_variant_new_double (level));
|
||||||
|
if (max_level > 1.0)
|
||||||
|
g_variant_builder_add (&builder, "{sv}",
|
||||||
|
"max_level", g_variant_new_double (max_level));
|
||||||
|
if (connector)
|
||||||
|
g_variant_builder_add (&builder, "{sv}",
|
||||||
|
"connector", g_variant_new_string (connector));
|
||||||
|
|
||||||
|
gsd_shell_call_show_osd (shell,
|
||||||
|
g_variant_builder_end (&builder),
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
42
plugins/common/gsd-shell-helper.h
Normal file
42
plugins/common/gsd-shell-helper.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Carlos Garnacho <carlosg@gnome.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_SHELL_HELPER_H__
|
||||||
|
#define __GSD_SHELL_HELPER_H__
|
||||||
|
|
||||||
|
#include "gsd-shell-glue.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void shell_show_osd (GsdShell *shell,
|
||||||
|
const gchar *icon_name,
|
||||||
|
const gchar *label,
|
||||||
|
double level,
|
||||||
|
const gchar *connector);
|
||||||
|
|
||||||
|
void shell_show_osd_with_max_level (GsdShell *shell,
|
||||||
|
const gchar *icon_name,
|
||||||
|
const gchar *label,
|
||||||
|
double level,
|
||||||
|
double max_level,
|
||||||
|
const gchar *connector);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_SHELL_HELPER_H__ */
|
6
plugins/common/gsd.gresources.xml
Normal file
6
plugins/common/gsd.gresources.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/org/gtk/libgtk/theme/Disabled">
|
||||||
|
<file>gtk.css</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
0
plugins/common/gtk.css
Normal file
0
plugins/common/gtk.css
Normal file
48
plugins/common/meson.build
Normal file
48
plugins/common/meson.build
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
common_inc = include_directories('.')
|
||||||
|
|
||||||
|
sources = files(
|
||||||
|
'gsd-input-helper.c',
|
||||||
|
'gsd-settings-migrate.c',
|
||||||
|
'gsd-shell-helper.c'
|
||||||
|
)
|
||||||
|
|
||||||
|
main_helper_sources = files(
|
||||||
|
'gsd-application.c',
|
||||||
|
'gsd-main-helper.c',
|
||||||
|
)
|
||||||
|
|
||||||
|
resource_data = files('gtk.css')
|
||||||
|
|
||||||
|
sources += gnome.compile_resources(
|
||||||
|
'gsd-resources',
|
||||||
|
'gsd.gresources.xml',
|
||||||
|
c_name: 'gsd',
|
||||||
|
dependencies: resource_data
|
||||||
|
)
|
||||||
|
|
||||||
|
deps = plugins_deps + [
|
||||||
|
gnome_desktop_dep,
|
||||||
|
gtk_x11_dep,
|
||||||
|
x11_dep,
|
||||||
|
dependency('kbproto'),
|
||||||
|
dependency('xi')
|
||||||
|
]
|
||||||
|
|
||||||
|
ldflags = []
|
||||||
|
if host_is_darwin
|
||||||
|
ldflags += ['-Wl,-bundle_loader,@0@'.format(join_paths(), meson.project_build_root(), meson.project_name(), meson.project_name())]
|
||||||
|
endif
|
||||||
|
|
||||||
|
libcommon = static_library(
|
||||||
|
plugin_name,
|
||||||
|
sources: sources,
|
||||||
|
include_directories: top_inc,
|
||||||
|
dependencies: deps,
|
||||||
|
c_args: cflags,
|
||||||
|
link_args: ldflags
|
||||||
|
)
|
||||||
|
|
||||||
|
libcommon_dep = declare_dependency(
|
||||||
|
include_directories: common_inc,
|
||||||
|
link_with: libcommon
|
||||||
|
)
|
118
plugins/datetime/backward
Normal file
118
plugins/datetime/backward
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
# <pre>
|
||||||
|
# @(#)backward 8.9
|
||||||
|
# This file is in the public domain, so clarified as of
|
||||||
|
# 2009-05-17 by Arthur David Olson.
|
||||||
|
|
||||||
|
# This file provides links between current names for time zones
|
||||||
|
# and their old names. Many names changed in late 1993.
|
||||||
|
|
||||||
|
Link Africa/Asmara Africa/Asmera
|
||||||
|
Link Africa/Bamako Africa/Timbuktu
|
||||||
|
Link America/Argentina/Catamarca America/Argentina/ComodRivadavia
|
||||||
|
Link America/Adak America/Atka
|
||||||
|
Link America/Argentina/Buenos_Aires America/Buenos_Aires
|
||||||
|
Link America/Argentina/Catamarca America/Catamarca
|
||||||
|
Link America/Atikokan America/Coral_Harbour
|
||||||
|
Link America/Argentina/Cordoba America/Cordoba
|
||||||
|
Link America/Tijuana America/Ensenada
|
||||||
|
Link America/Indiana/Indianapolis America/Fort_Wayne
|
||||||
|
Link America/Indiana/Indianapolis America/Indianapolis
|
||||||
|
Link America/Argentina/Jujuy America/Jujuy
|
||||||
|
Link America/Indiana/Knox America/Knox_IN
|
||||||
|
Link America/Kentucky/Louisville America/Louisville
|
||||||
|
Link America/Argentina/Mendoza America/Mendoza
|
||||||
|
Link America/Rio_Branco America/Porto_Acre
|
||||||
|
Link America/Argentina/Cordoba America/Rosario
|
||||||
|
Link America/St_Thomas America/Virgin
|
||||||
|
Link Asia/Ashgabat Asia/Ashkhabad
|
||||||
|
Link Asia/Chongqing Asia/Chungking
|
||||||
|
Link Asia/Dhaka Asia/Dacca
|
||||||
|
Link Asia/Kathmandu Asia/Katmandu
|
||||||
|
Link Asia/Kolkata Asia/Calcutta
|
||||||
|
Link Asia/Macau Asia/Macao
|
||||||
|
Link Asia/Jerusalem Asia/Tel_Aviv
|
||||||
|
Link Asia/Ho_Chi_Minh Asia/Saigon
|
||||||
|
Link Asia/Thimphu Asia/Thimbu
|
||||||
|
Link Asia/Makassar Asia/Ujung_Pandang
|
||||||
|
Link Asia/Ulaanbaatar Asia/Ulan_Bator
|
||||||
|
Link Atlantic/Faroe Atlantic/Faeroe
|
||||||
|
Link Europe/Oslo Atlantic/Jan_Mayen
|
||||||
|
Link Australia/Sydney Australia/ACT
|
||||||
|
Link Australia/Sydney Australia/Canberra
|
||||||
|
Link Australia/Lord_Howe Australia/LHI
|
||||||
|
Link Australia/Sydney Australia/NSW
|
||||||
|
Link Australia/Darwin Australia/North
|
||||||
|
Link Australia/Brisbane Australia/Queensland
|
||||||
|
Link Australia/Adelaide Australia/South
|
||||||
|
Link Australia/Hobart Australia/Tasmania
|
||||||
|
Link Australia/Melbourne Australia/Victoria
|
||||||
|
Link Australia/Perth Australia/West
|
||||||
|
Link Australia/Broken_Hill Australia/Yancowinna
|
||||||
|
Link America/Rio_Branco Brazil/Acre
|
||||||
|
Link America/Noronha Brazil/DeNoronha
|
||||||
|
Link America/Sao_Paulo Brazil/East
|
||||||
|
Link America/Manaus Brazil/West
|
||||||
|
Link America/Halifax Canada/Atlantic
|
||||||
|
Link America/Winnipeg Canada/Central
|
||||||
|
Link America/Regina Canada/East-Saskatchewan
|
||||||
|
Link America/Toronto Canada/Eastern
|
||||||
|
Link America/Edmonton Canada/Mountain
|
||||||
|
Link America/St_Johns Canada/Newfoundland
|
||||||
|
Link America/Vancouver Canada/Pacific
|
||||||
|
Link America/Regina Canada/Saskatchewan
|
||||||
|
Link America/Whitehorse Canada/Yukon
|
||||||
|
Link America/Santiago Chile/Continental
|
||||||
|
Link Pacific/Easter Chile/EasterIsland
|
||||||
|
Link America/Havana Cuba
|
||||||
|
Link Africa/Cairo Egypt
|
||||||
|
Link Europe/Dublin Eire
|
||||||
|
Link Europe/London Europe/Belfast
|
||||||
|
Link Europe/Chisinau Europe/Tiraspol
|
||||||
|
Link Europe/London GB
|
||||||
|
Link Europe/London GB-Eire
|
||||||
|
Link Etc/GMT GMT+0
|
||||||
|
Link Etc/GMT GMT-0
|
||||||
|
Link Etc/GMT GMT0
|
||||||
|
Link Etc/GMT Greenwich
|
||||||
|
Link Asia/Hong_Kong Hongkong
|
||||||
|
Link Atlantic/Reykjavik Iceland
|
||||||
|
Link Asia/Tehran Iran
|
||||||
|
Link Asia/Jerusalem Israel
|
||||||
|
Link America/Jamaica Jamaica
|
||||||
|
Link Asia/Tokyo Japan
|
||||||
|
Link Pacific/Kwajalein Kwajalein
|
||||||
|
Link Africa/Tripoli Libya
|
||||||
|
Link America/Tijuana Mexico/BajaNorte
|
||||||
|
Link America/Mazatlan Mexico/BajaSur
|
||||||
|
Link America/Mexico_City Mexico/General
|
||||||
|
Link Pacific/Auckland NZ
|
||||||
|
Link Pacific/Chatham NZ-CHAT
|
||||||
|
Link America/Denver Navajo
|
||||||
|
Link Asia/Shanghai PRC
|
||||||
|
Link Pacific/Pago_Pago Pacific/Samoa
|
||||||
|
Link Pacific/Chuuk Pacific/Yap
|
||||||
|
Link Pacific/Chuuk Pacific/Truk
|
||||||
|
Link Pacific/Pohnpei Pacific/Ponape
|
||||||
|
Link Europe/Warsaw Poland
|
||||||
|
Link Europe/Lisbon Portugal
|
||||||
|
Link Asia/Taipei ROC
|
||||||
|
Link Asia/Seoul ROK
|
||||||
|
Link Asia/Singapore Singapore
|
||||||
|
Link Europe/Istanbul Turkey
|
||||||
|
Link Etc/UCT UCT
|
||||||
|
Link America/Anchorage US/Alaska
|
||||||
|
Link America/Adak US/Aleutian
|
||||||
|
Link America/Phoenix US/Arizona
|
||||||
|
Link America/Chicago US/Central
|
||||||
|
Link America/Indiana/Indianapolis US/East-Indiana
|
||||||
|
Link America/New_York US/Eastern
|
||||||
|
Link Pacific/Honolulu US/Hawaii
|
||||||
|
Link America/Indiana/Knox US/Indiana-Starke
|
||||||
|
Link America/Detroit US/Michigan
|
||||||
|
Link America/Denver US/Mountain
|
||||||
|
Link America/Los_Angeles US/Pacific
|
||||||
|
Link Pacific/Pago_Pago US/Samoa
|
||||||
|
Link Etc/UTC UTC
|
||||||
|
Link Etc/UTC Universal
|
||||||
|
Link Europe/Moscow W-SU
|
||||||
|
Link Etc/UTC Zulu
|
201
plugins/datetime/gsd-datetime-manager.c
Normal file
201
plugins/datetime/gsd-datetime-manager.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
|
||||||
|
#include "gsd-datetime-manager.h"
|
||||||
|
#include "gsd-timezone-monitor.h"
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
|
||||||
|
#define DATETIME_SCHEMA "org.gnome.desktop.datetime"
|
||||||
|
#define AUTO_TIMEZONE_KEY "automatic-timezone"
|
||||||
|
|
||||||
|
struct _GsdDatetimeManager
|
||||||
|
{
|
||||||
|
GsdApplication parent;
|
||||||
|
|
||||||
|
GSettings *settings;
|
||||||
|
GsdTimezoneMonitor *timezone_monitor;
|
||||||
|
NotifyNotification *notification;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_datetime_manager_class_init (GsdDatetimeManagerClass *klass);
|
||||||
|
static void gsd_datetime_manager_init (GsdDatetimeManager *manager);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdDatetimeManager, gsd_datetime_manager, GSD_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
static void
|
||||||
|
notification_closed_cb (NotifyNotification *n,
|
||||||
|
GsdDatetimeManager *self)
|
||||||
|
{
|
||||||
|
g_clear_object (&self->notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_settings_cb (NotifyNotification *n,
|
||||||
|
const char *action,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
const gchar *argv[] = { "gnome-control-center", "datetime", NULL };
|
||||||
|
|
||||||
|
g_debug ("Running gnome-control-center datetime");
|
||||||
|
g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
notify_notification_close (n, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timezone_changed_cb (GsdTimezoneMonitor *timezone_monitor,
|
||||||
|
const gchar *timezone_id,
|
||||||
|
GsdDatetimeManager *self)
|
||||||
|
{
|
||||||
|
GDateTime *datetime;
|
||||||
|
GTimeZone *tz;
|
||||||
|
gchar *notification_summary;
|
||||||
|
gchar *timezone_name;
|
||||||
|
gchar *utc_offset;
|
||||||
|
|
||||||
|
tz = g_time_zone_new_identifier (timezone_id);
|
||||||
|
if (tz == NULL) {
|
||||||
|
g_warning ("Failed to parse new timezone identifier ‘%s’. Ignoring.", timezone_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
datetime = g_date_time_new_now (tz);
|
||||||
|
g_time_zone_unref (tz);
|
||||||
|
|
||||||
|
/* Translators: UTC here means the Coordinated Universal Time.
|
||||||
|
* %:::z will be replaced by the offset from UTC e.g. UTC+02 */
|
||||||
|
utc_offset = g_date_time_format (datetime, _("UTC%:::z"));
|
||||||
|
timezone_name = g_strdup (g_date_time_get_timezone_abbreviation (datetime));
|
||||||
|
g_date_time_unref (datetime);
|
||||||
|
|
||||||
|
notification_summary = g_strdup_printf (_("Time Zone Updated to %s (%s)"),
|
||||||
|
timezone_name,
|
||||||
|
utc_offset);
|
||||||
|
g_free (timezone_name);
|
||||||
|
g_free (utc_offset);
|
||||||
|
|
||||||
|
if (self->notification == NULL) {
|
||||||
|
self->notification = notify_notification_new (notification_summary, NULL, NULL);
|
||||||
|
g_signal_connect (self->notification,
|
||||||
|
"closed",
|
||||||
|
G_CALLBACK (notification_closed_cb),
|
||||||
|
self);
|
||||||
|
|
||||||
|
notify_notification_add_action (self->notification,
|
||||||
|
"settings",
|
||||||
|
_("Settings"),
|
||||||
|
(NotifyActionCallback) open_settings_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
} else {
|
||||||
|
notify_notification_update (self->notification,
|
||||||
|
notification_summary, NULL, NULL);
|
||||||
|
}
|
||||||
|
g_free (notification_summary);
|
||||||
|
|
||||||
|
notify_notification_set_app_name (self->notification, _("Date & Time Settings"));
|
||||||
|
notify_notification_set_hint_string (self->notification, "desktop-entry", "gnome-datetime-panel");
|
||||||
|
notify_notification_set_urgency (self->notification, NOTIFY_URGENCY_NORMAL);
|
||||||
|
notify_notification_set_timeout (self->notification, NOTIFY_EXPIRES_NEVER);
|
||||||
|
|
||||||
|
if (!notify_notification_show (self->notification, NULL)) {
|
||||||
|
g_warning ("Failed to send timezone notification");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
auto_timezone_settings_changed_cb (GSettings *settings,
|
||||||
|
const char *key,
|
||||||
|
GsdDatetimeManager *self)
|
||||||
|
{
|
||||||
|
gboolean enabled;
|
||||||
|
|
||||||
|
enabled = g_settings_get_boolean (settings, key);
|
||||||
|
if (enabled && self->timezone_monitor == NULL) {
|
||||||
|
g_debug ("Automatic timezone enabled");
|
||||||
|
self->timezone_monitor = gsd_timezone_monitor_new ();
|
||||||
|
|
||||||
|
g_signal_connect (self->timezone_monitor, "timezone-changed",
|
||||||
|
G_CALLBACK (timezone_changed_cb), self);
|
||||||
|
} else {
|
||||||
|
g_debug ("Automatic timezone disabled");
|
||||||
|
g_clear_object (&self->timezone_monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_datetime_manager_startup (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdDatetimeManager *self = GSD_DATETIME_MANAGER (app);
|
||||||
|
|
||||||
|
g_debug ("Starting datetime manager");
|
||||||
|
gnome_settings_profile_start (NULL);
|
||||||
|
|
||||||
|
self->settings = g_settings_new (DATETIME_SCHEMA);
|
||||||
|
|
||||||
|
g_signal_connect (self->settings, "changed::" AUTO_TIMEZONE_KEY,
|
||||||
|
G_CALLBACK (auto_timezone_settings_changed_cb), self);
|
||||||
|
auto_timezone_settings_changed_cb (self->settings, AUTO_TIMEZONE_KEY, self);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_datetime_manager_parent_class)->startup (app);
|
||||||
|
|
||||||
|
gnome_settings_profile_end (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_datetime_manager_shutdown (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdDatetimeManager *self = GSD_DATETIME_MANAGER (app);
|
||||||
|
|
||||||
|
g_debug ("Stopping datetime manager");
|
||||||
|
|
||||||
|
g_clear_object (&self->settings);
|
||||||
|
g_clear_object (&self->timezone_monitor);
|
||||||
|
|
||||||
|
if (self->notification != NULL) {
|
||||||
|
g_signal_handlers_disconnect_by_func (self->notification,
|
||||||
|
G_CALLBACK (notification_closed_cb),
|
||||||
|
self);
|
||||||
|
g_clear_object (&self->notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_datetime_manager_parent_class)->shutdown (app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_datetime_manager_class_init (GsdDatetimeManagerClass *klass)
|
||||||
|
{
|
||||||
|
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
||||||
|
|
||||||
|
application_class->startup = gsd_datetime_manager_startup;
|
||||||
|
application_class->shutdown = gsd_datetime_manager_shutdown;
|
||||||
|
|
||||||
|
notify_init ("gnome-settings-daemon");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_datetime_manager_init (GsdDatetimeManager *manager)
|
||||||
|
{
|
||||||
|
}
|
32
plugins/datetime/gsd-datetime-manager.h
Normal file
32
plugins/datetime/gsd-datetime-manager.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_DATETIME_MANAGER_H
|
||||||
|
#define __GSD_DATETIME_MANAGER_H
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_DATETIME_MANAGER (gsd_datetime_manager_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdDatetimeManager, gsd_datetime_manager, GSD, DATETIME_MANAGER, GsdApplication)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_DATETIME_MANAGER_H */
|
472
plugins/datetime/gsd-timezone-monitor.c
Normal file
472
plugins/datetime/gsd-timezone-monitor.c
Normal file
|
@ -0,0 +1,472 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gsd-timezone-monitor.h"
|
||||||
|
|
||||||
|
#include "timedated.h"
|
||||||
|
#include "tz.h"
|
||||||
|
#include "weather-tz.h"
|
||||||
|
|
||||||
|
#include <geoclue.h>
|
||||||
|
#include <geocode-glib/geocode-glib.h>
|
||||||
|
#include <polkit/polkit.h>
|
||||||
|
|
||||||
|
#define DESKTOP_ID "gnome-datetime-panel"
|
||||||
|
#define SET_TIMEZONE_PERMISSION "org.freedesktop.timedate1.set-timezone"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TIMEZONE_CHANGED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GCancellable *cancellable;
|
||||||
|
GPermission *permission;
|
||||||
|
Timedate1 *dtm;
|
||||||
|
|
||||||
|
GClueClient *geoclue_client;
|
||||||
|
GClueSimple *geoclue_simple;
|
||||||
|
GCancellable *geoclue_cancellable;
|
||||||
|
|
||||||
|
gchar *current_timezone;
|
||||||
|
|
||||||
|
GSettings *location_settings;
|
||||||
|
} GsdTimezoneMonitorPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (GsdTimezoneMonitor, gsd_timezone_monitor, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_timezone_cb (GObject *source,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitorPrivate *priv;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!timedate1_call_set_timezone_finish (TIMEDATE1 (source),
|
||||||
|
res,
|
||||||
|
&error)) {
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Could not set system timezone: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = gsd_timezone_monitor_get_instance_private (user_data);
|
||||||
|
g_signal_emit (G_OBJECT (user_data),
|
||||||
|
signals[TIMEZONE_CHANGED],
|
||||||
|
0, priv->current_timezone);
|
||||||
|
|
||||||
|
g_debug ("Successfully changed timezone to '%s'",
|
||||||
|
priv->current_timezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_set_timezone (GsdTimezoneMonitor *self,
|
||||||
|
const gchar *new_timezone)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
|
||||||
|
g_debug ("Changing timezone to '%s'", new_timezone);
|
||||||
|
|
||||||
|
timedate1_call_set_timezone (priv->dtm,
|
||||||
|
new_timezone,
|
||||||
|
TRUE,
|
||||||
|
priv->cancellable,
|
||||||
|
set_timezone_cb,
|
||||||
|
self);
|
||||||
|
|
||||||
|
g_free (priv->current_timezone);
|
||||||
|
priv->current_timezone = g_strdup (new_timezone);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare_locations (TzLocation *a,
|
||||||
|
TzLocation *b)
|
||||||
|
{
|
||||||
|
if (a->dist > b->dist)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a->dist < b->dist)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
sort_by_closest_to (GList *locations,
|
||||||
|
GeocodeLocation *location)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = locations; l; l = l->next) {
|
||||||
|
GeocodeLocation *loc;
|
||||||
|
TzLocation *tz_location = l->data;
|
||||||
|
|
||||||
|
loc = geocode_location_new (tz_location->latitude,
|
||||||
|
tz_location->longitude,
|
||||||
|
GEOCODE_LOCATION_ACCURACY_UNKNOWN);
|
||||||
|
tz_location->dist = geocode_location_get_distance_from (loc, location);
|
||||||
|
g_object_unref (loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_list_sort (locations, (GCompareFunc) compare_locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
ptr_array_to_list (GPtrArray *array)
|
||||||
|
{
|
||||||
|
GList *l = NULL;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < array->len; i++)
|
||||||
|
l = g_list_prepend (l, g_ptr_array_index (array, i));
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
find_by_country (GList *locations,
|
||||||
|
const gchar *country_code)
|
||||||
|
{
|
||||||
|
GList *l, *found = NULL;
|
||||||
|
gchar *c1;
|
||||||
|
gchar *c2;
|
||||||
|
|
||||||
|
c1 = g_ascii_strdown (country_code, -1);
|
||||||
|
|
||||||
|
for (l = locations; l; l = l->next) {
|
||||||
|
TzLocation *loc = l->data;
|
||||||
|
|
||||||
|
c2 = g_ascii_strdown (loc->country, -1);
|
||||||
|
if (g_strcmp0 (c1, c2) == 0)
|
||||||
|
found = g_list_prepend (found, loc);
|
||||||
|
g_free (c2);
|
||||||
|
}
|
||||||
|
g_free (c1);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
find_timezone (GsdTimezoneMonitor *self,
|
||||||
|
GeocodeLocation *location,
|
||||||
|
const gchar *country_code)
|
||||||
|
{
|
||||||
|
TzDB *tzdb;
|
||||||
|
gchar *res;
|
||||||
|
GList *filtered;
|
||||||
|
GList *weather_locations;
|
||||||
|
GList *locations;
|
||||||
|
TzLocation *closest_tz_location;
|
||||||
|
|
||||||
|
tzdb = tz_load_db ();
|
||||||
|
|
||||||
|
/* First load locations from Olson DB */
|
||||||
|
locations = ptr_array_to_list (tz_get_locations (tzdb));
|
||||||
|
g_return_val_if_fail (locations != NULL, NULL);
|
||||||
|
|
||||||
|
/* ... and then add libgweather's locations as well */
|
||||||
|
weather_locations = weather_tz_db_get_locations (country_code);
|
||||||
|
locations = g_list_concat (locations,
|
||||||
|
g_list_copy (weather_locations));
|
||||||
|
|
||||||
|
/* Filter tz locations by country */
|
||||||
|
filtered = find_by_country (locations, country_code);
|
||||||
|
if (filtered != NULL) {
|
||||||
|
g_list_free (locations);
|
||||||
|
locations = filtered;
|
||||||
|
} else {
|
||||||
|
g_debug ("No match for country code '%s' in tzdb", country_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the closest tz location */
|
||||||
|
locations = sort_by_closest_to (locations, location);
|
||||||
|
closest_tz_location = (TzLocation *) locations->data;
|
||||||
|
|
||||||
|
res = g_strdup (closest_tz_location->zone);
|
||||||
|
|
||||||
|
g_list_free (locations);
|
||||||
|
g_list_free_full (weather_locations, (GDestroyNotify) tz_location_free);
|
||||||
|
tz_db_free (tzdb);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_location (GsdTimezoneMonitor *self,
|
||||||
|
GeocodePlace *place)
|
||||||
|
{
|
||||||
|
GeocodeLocation *location;
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
const gchar *country_code;
|
||||||
|
g_autofree gchar *new_timezone = NULL;
|
||||||
|
|
||||||
|
country_code = geocode_place_get_country_code (place);
|
||||||
|
location = geocode_place_get_location (place);
|
||||||
|
|
||||||
|
new_timezone = find_timezone (self, location, country_code);
|
||||||
|
|
||||||
|
if (g_strcmp0 (priv->current_timezone, new_timezone) != 0) {
|
||||||
|
g_debug ("Found updated timezone '%s' for country '%s'",
|
||||||
|
new_timezone, country_code);
|
||||||
|
queue_set_timezone (self, new_timezone);
|
||||||
|
} else {
|
||||||
|
g_debug ("Timezone didn't change from '%s' for country '%s'",
|
||||||
|
new_timezone, country_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_reverse_geocoding_ready (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GeocodePlace *place;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
place = geocode_reverse_resolve_finish (GEOCODE_REVERSE (source_object),
|
||||||
|
res,
|
||||||
|
&error);
|
||||||
|
if (error != NULL) {
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_debug ("Reverse geocoding failed: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_debug ("Geocode lookup resolved country to '%s'",
|
||||||
|
geocode_place_get_country (place));
|
||||||
|
|
||||||
|
process_location (user_data, place);
|
||||||
|
g_object_unref (place);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_reverse_geocoding (GsdTimezoneMonitor *self,
|
||||||
|
gdouble latitude,
|
||||||
|
gdouble longitude)
|
||||||
|
{
|
||||||
|
GeocodeLocation *location;
|
||||||
|
GeocodeReverse *reverse;
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
|
||||||
|
location = geocode_location_new (latitude,
|
||||||
|
longitude,
|
||||||
|
GEOCODE_LOCATION_ACCURACY_CITY);
|
||||||
|
|
||||||
|
reverse = geocode_reverse_new_for_location (location);
|
||||||
|
geocode_reverse_resolve_async (reverse,
|
||||||
|
priv->geoclue_cancellable,
|
||||||
|
on_reverse_geocoding_ready,
|
||||||
|
self);
|
||||||
|
|
||||||
|
g_object_unref (location);
|
||||||
|
g_object_unref (reverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_location_notify (GClueSimple *simple,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitor *self = user_data;
|
||||||
|
GClueLocation *location;
|
||||||
|
gdouble latitude, longitude;
|
||||||
|
|
||||||
|
location = gclue_simple_get_location (simple);
|
||||||
|
|
||||||
|
latitude = gclue_location_get_latitude (location);
|
||||||
|
longitude = gclue_location_get_longitude (location);
|
||||||
|
|
||||||
|
g_debug ("Got location %lf,%lf", latitude, longitude);
|
||||||
|
|
||||||
|
start_reverse_geocoding (self, latitude, longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_geoclue_simple_ready (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GsdTimezoneMonitorPrivate *priv;
|
||||||
|
GClueSimple *geoclue_simple;
|
||||||
|
|
||||||
|
geoclue_simple = gclue_simple_new_finish (res, &error);
|
||||||
|
if (geoclue_simple == NULL) {
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to connect to GeoClue2 service: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("Geoclue now available");
|
||||||
|
|
||||||
|
priv = gsd_timezone_monitor_get_instance_private (user_data);
|
||||||
|
priv->geoclue_simple = geoclue_simple;
|
||||||
|
priv->geoclue_client = gclue_simple_get_client (priv->geoclue_simple);
|
||||||
|
gclue_client_set_distance_threshold (priv->geoclue_client,
|
||||||
|
GEOCODE_LOCATION_ACCURACY_CITY);
|
||||||
|
|
||||||
|
g_signal_connect (priv->geoclue_simple, "notify::location",
|
||||||
|
G_CALLBACK (on_location_notify), user_data);
|
||||||
|
|
||||||
|
on_location_notify (priv->geoclue_simple, NULL, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_geoclue (GsdTimezoneMonitor *self)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
|
||||||
|
g_debug ("Timezone monitor enabled, starting geoclue");
|
||||||
|
|
||||||
|
priv->geoclue_cancellable = g_cancellable_new ();
|
||||||
|
gclue_simple_new (DESKTOP_ID,
|
||||||
|
GCLUE_ACCURACY_LEVEL_CITY,
|
||||||
|
priv->geoclue_cancellable,
|
||||||
|
on_geoclue_simple_ready,
|
||||||
|
self);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_geoclue (GsdTimezoneMonitor *self)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
|
||||||
|
g_debug ("Timezone monitor disabled, stopping geoclue");
|
||||||
|
|
||||||
|
g_cancellable_cancel (priv->geoclue_cancellable);
|
||||||
|
g_clear_object (&priv->geoclue_cancellable);
|
||||||
|
|
||||||
|
if (priv->geoclue_client) {
|
||||||
|
gclue_client_call_stop (priv->geoclue_client, NULL, NULL, NULL);
|
||||||
|
priv->geoclue_client = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&priv->geoclue_simple);
|
||||||
|
}
|
||||||
|
|
||||||
|
GsdTimezoneMonitor *
|
||||||
|
gsd_timezone_monitor_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (GSD_TYPE_TIMEZONE_MONITOR, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_timezone_monitor_finalize (GObject *obj)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitor *monitor = GSD_TIMEZONE_MONITOR (obj);
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (monitor);
|
||||||
|
|
||||||
|
g_debug ("Stopping timezone monitor");
|
||||||
|
|
||||||
|
stop_geoclue (monitor);
|
||||||
|
|
||||||
|
if (priv->cancellable) {
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_clear_object (&priv->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&priv->dtm);
|
||||||
|
g_clear_object (&priv->permission);
|
||||||
|
g_clear_pointer (&priv->current_timezone, g_free);
|
||||||
|
|
||||||
|
g_clear_object (&priv->location_settings);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gsd_timezone_monitor_parent_class)->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_timezone_monitor_class_init (GsdTimezoneMonitorClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = gsd_timezone_monitor_finalize;
|
||||||
|
|
||||||
|
signals[TIMEZONE_CHANGED] =
|
||||||
|
g_signal_new ("timezone-changed",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GsdTimezoneMonitorClass, timezone_changed),
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_location_settings (GsdTimezoneMonitor *self)
|
||||||
|
{
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
if (g_settings_get_boolean (priv->location_settings, "enabled"))
|
||||||
|
start_geoclue (self);
|
||||||
|
else
|
||||||
|
stop_geoclue (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_timezone_monitor_init (GsdTimezoneMonitor *self)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
|
||||||
|
|
||||||
|
g_debug ("Starting timezone monitor");
|
||||||
|
|
||||||
|
priv->permission = polkit_permission_new_sync (SET_TIMEZONE_PERMISSION,
|
||||||
|
NULL, NULL,
|
||||||
|
&error);
|
||||||
|
if (priv->permission == NULL) {
|
||||||
|
g_warning ("Could not get '%s' permission: %s",
|
||||||
|
SET_TIMEZONE_PERMISSION,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_permission_get_allowed (priv->permission)) {
|
||||||
|
g_debug ("No permission to set timezone");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
|
priv->dtm = timedate1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
"org.freedesktop.timedate1",
|
||||||
|
"/org/freedesktop/timedate1",
|
||||||
|
priv->cancellable,
|
||||||
|
&error);
|
||||||
|
if (priv->dtm == NULL) {
|
||||||
|
g_warning ("Could not get proxy for DateTimeMechanism: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->current_timezone = timedate1_dup_timezone (priv->dtm);
|
||||||
|
|
||||||
|
priv->location_settings = g_settings_new ("org.gnome.system.location");
|
||||||
|
g_signal_connect_swapped (priv->location_settings, "changed::enabled",
|
||||||
|
G_CALLBACK (check_location_settings), self);
|
||||||
|
check_location_settings (self);
|
||||||
|
}
|
55
plugins/datetime/gsd-timezone-monitor.h
Normal file
55
plugins/datetime/gsd-timezone-monitor.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_TIMEZONE_MONITOR_H
|
||||||
|
#define __GSD_TIMEZONE_MONITOR_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_TIMEZONE_MONITOR (gsd_timezone_monitor_get_type ())
|
||||||
|
#define GSD_TIMEZONE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_TIMEZONE_MONITOR, GsdTimezoneMonitor))
|
||||||
|
#define GSD_IS_TIMEZONE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_TIMEZONE_MONITOR))
|
||||||
|
#define GSD_TIMEZONE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_TIMEZONE_MONITOR, GsdTimezoneMonitorClass))
|
||||||
|
#define GSD_IS_TIMEZONE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_TIMEZONE_MONITOR))
|
||||||
|
#define GSD_TIMEZONE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_TIMEZONE_MONITOR, GsdTimezoneMonitorClass))
|
||||||
|
|
||||||
|
typedef struct _GsdTimezoneMonitor GsdTimezoneMonitor;
|
||||||
|
typedef struct _GsdTimezoneMonitorClass GsdTimezoneMonitorClass;
|
||||||
|
|
||||||
|
struct _GsdTimezoneMonitor
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GsdTimezoneMonitorClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (*timezone_changed) (GsdTimezoneMonitor *monitor, gchar *timezone_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gsd_timezone_monitor_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GsdTimezoneMonitor *gsd_timezone_monitor_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_TIMEZONE_MONITOR_H */
|
9
plugins/datetime/main.c
Normal file
9
plugins/datetime/main.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "gsd-main-helper.h"
|
||||||
|
#include "gsd-datetime-manager.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
return gsd_main_helper (GSD_TYPE_DATETIME_MANAGER, argc, argv);
|
||||||
|
}
|
||||||
|
|
42
plugins/datetime/meson.build
Normal file
42
plugins/datetime/meson.build
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
install_data(
|
||||||
|
'backward',
|
||||||
|
install_dir: join_paths(gsd_pkgdatadir, 'datetime')
|
||||||
|
)
|
||||||
|
|
||||||
|
sources = files(
|
||||||
|
'gsd-datetime-manager.c',
|
||||||
|
'gsd-timezone-monitor.c',
|
||||||
|
'main.c',
|
||||||
|
'tz.c',
|
||||||
|
'weather-tz.c'
|
||||||
|
)
|
||||||
|
|
||||||
|
sources += gnome.gdbus_codegen(
|
||||||
|
'timedated',
|
||||||
|
'timedated1-interface.xml',
|
||||||
|
interface_prefix: 'org.freedesktop.'
|
||||||
|
)
|
||||||
|
|
||||||
|
sources += main_helper_sources
|
||||||
|
|
||||||
|
deps = plugins_deps + [
|
||||||
|
geocode_glib_dep,
|
||||||
|
gweather_dep,
|
||||||
|
libgeoclue_dep,
|
||||||
|
libnotify_dep,
|
||||||
|
m_dep,
|
||||||
|
polkit_gobject_dep
|
||||||
|
]
|
||||||
|
|
||||||
|
cflags += ['-DGNOMECC_DATA_DIR="@0@"'.format(gsd_pkgdatadir)]
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'gsd-' + plugin_name,
|
||||||
|
sources,
|
||||||
|
include_directories: [top_inc, common_inc],
|
||||||
|
dependencies: deps,
|
||||||
|
c_args: cflags,
|
||||||
|
install: true,
|
||||||
|
install_rpath: gsd_pkglibdir,
|
||||||
|
install_dir: gsd_libexecdir
|
||||||
|
)
|
28
plugins/datetime/timedated1-interface.xml
Normal file
28
plugins/datetime/timedated1-interface.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
|
<node>
|
||||||
|
<interface name="org.freedesktop.timedate1">
|
||||||
|
<property name="Timezone" type="s" access="read"/>
|
||||||
|
<property name="LocalRTC" type="b" access="read"/>
|
||||||
|
<property name="CanNTP" type="b" access="read"/>
|
||||||
|
<property name="NTP" type="b" access="read"/>
|
||||||
|
<method name="SetTime">
|
||||||
|
<arg name="usec_utc" type="x" direction="in"/>
|
||||||
|
<arg name="relative" type="b" direction="in"/>
|
||||||
|
<arg name="user_interaction" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="SetTimezone">
|
||||||
|
<arg name="timezone" type="s" direction="in"/>
|
||||||
|
<arg name="user_interaction" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="SetLocalRTC">
|
||||||
|
<arg name="local_rtc" type="b" direction="in"/>
|
||||||
|
<arg name="fix_system" type="b" direction="in"/>
|
||||||
|
<arg name="user_interaction" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<method name="SetNTP">
|
||||||
|
<arg name="use_ntp" type="b" direction="in"/>
|
||||||
|
<arg name="user_interaction" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
482
plugins/datetime/tz.c
Normal file
482
plugins/datetime/tz.c
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||||
|
/* Generic timezone utilities.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||||
|
*
|
||||||
|
* Authors: Hans Petter Jansson <hpj@ximian.com>
|
||||||
|
*
|
||||||
|
* Largely based on Michael Fulbright's work on Anaconda.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "tz.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward declarations for private functions */
|
||||||
|
|
||||||
|
static float convert_pos (gchar *pos, int digits);
|
||||||
|
static int compare_country_names (const void *a, const void *b);
|
||||||
|
static void sort_locations_by_country (GPtrArray *locations);
|
||||||
|
static gchar * tz_data_file_get (void);
|
||||||
|
static void load_backward_tz (TzDB *tz_db);
|
||||||
|
|
||||||
|
/* ---------------- *
|
||||||
|
* Public interface *
|
||||||
|
* ---------------- */
|
||||||
|
TzDB *
|
||||||
|
tz_load_db (void)
|
||||||
|
{
|
||||||
|
gchar *tz_data_file;
|
||||||
|
TzDB *tz_db;
|
||||||
|
FILE *tzfile;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
tz_data_file = tz_data_file_get ();
|
||||||
|
if (!tz_data_file) {
|
||||||
|
g_warning ("Could not get the TimeZone data file name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tzfile = fopen (tz_data_file, "r");
|
||||||
|
if (!tzfile) {
|
||||||
|
g_warning ("Could not open *%s*\n", tz_data_file);
|
||||||
|
g_free (tz_data_file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tz_db = g_new0 (TzDB, 1);
|
||||||
|
tz_db->locations = g_ptr_array_new ();
|
||||||
|
|
||||||
|
while (fgets (buf, sizeof(buf), tzfile))
|
||||||
|
{
|
||||||
|
gchar **tmpstrarr;
|
||||||
|
gchar *latstr, *lngstr, *p;
|
||||||
|
TzLocation *loc;
|
||||||
|
|
||||||
|
if (*buf == '#') continue;
|
||||||
|
|
||||||
|
g_strchomp(buf);
|
||||||
|
tmpstrarr = g_strsplit(buf,"\t", 6);
|
||||||
|
|
||||||
|
latstr = g_strdup (tmpstrarr[1]);
|
||||||
|
p = latstr + 1;
|
||||||
|
while (*p != '-' && *p != '+') p++;
|
||||||
|
lngstr = g_strdup (p);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
loc = g_new0 (TzLocation, 1);
|
||||||
|
loc->country = g_strdup (tmpstrarr[0]);
|
||||||
|
loc->zone = g_strdup (tmpstrarr[2]);
|
||||||
|
loc->latitude = convert_pos (latstr, 2);
|
||||||
|
loc->longitude = convert_pos (lngstr, 3);
|
||||||
|
|
||||||
|
#ifdef __sun
|
||||||
|
if (tmpstrarr[3] && *tmpstrarr[3] == '-' && tmpstrarr[4])
|
||||||
|
loc->comment = g_strdup (tmpstrarr[4]);
|
||||||
|
|
||||||
|
if (tmpstrarr[3] && *tmpstrarr[3] != '-' && !islower(loc->zone)) {
|
||||||
|
TzLocation *locgrp;
|
||||||
|
|
||||||
|
/* duplicate entry */
|
||||||
|
locgrp = g_new0 (TzLocation, 1);
|
||||||
|
locgrp->country = g_strdup (tmpstrarr[0]);
|
||||||
|
locgrp->zone = g_strdup (tmpstrarr[3]);
|
||||||
|
locgrp->latitude = convert_pos (latstr, 2);
|
||||||
|
locgrp->longitude = convert_pos (lngstr, 3);
|
||||||
|
locgrp->comment = (tmpstrarr[4]) ? g_strdup (tmpstrarr[4]) : NULL;
|
||||||
|
|
||||||
|
g_ptr_array_add (tz_db->locations, (gpointer) locgrp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
loc->comment = (tmpstrarr[3]) ? g_strdup(tmpstrarr[3]) : NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_ptr_array_add (tz_db->locations, (gpointer) loc);
|
||||||
|
|
||||||
|
g_free (latstr);
|
||||||
|
g_free (lngstr);
|
||||||
|
g_strfreev (tmpstrarr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (tzfile);
|
||||||
|
|
||||||
|
/* now sort by country */
|
||||||
|
sort_locations_by_country (tz_db->locations);
|
||||||
|
|
||||||
|
g_free (tz_data_file);
|
||||||
|
|
||||||
|
/* Load up the hashtable of backward links */
|
||||||
|
load_backward_tz (tz_db);
|
||||||
|
|
||||||
|
return tz_db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tz_location_free (TzLocation *loc)
|
||||||
|
{
|
||||||
|
g_free (loc->country);
|
||||||
|
g_free (loc->zone);
|
||||||
|
g_free (loc->comment);
|
||||||
|
|
||||||
|
g_free (loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tz_db_free (TzDB *db)
|
||||||
|
{
|
||||||
|
g_ptr_array_foreach (db->locations, (GFunc) tz_location_free, NULL);
|
||||||
|
g_ptr_array_free (db->locations, TRUE);
|
||||||
|
g_hash_table_destroy (db->backward);
|
||||||
|
g_free (db);
|
||||||
|
}
|
||||||
|
|
||||||
|
GPtrArray *
|
||||||
|
tz_get_locations (TzDB *db)
|
||||||
|
{
|
||||||
|
return db->locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
tz_location_get_country (TzLocation *loc)
|
||||||
|
{
|
||||||
|
return loc->country;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
tz_location_get_zone (TzLocation *loc)
|
||||||
|
{
|
||||||
|
return loc->zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
tz_location_get_comment (TzLocation *loc)
|
||||||
|
{
|
||||||
|
return loc->comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
tz_location_get_position (TzLocation *loc, double *longitude, double *latitude)
|
||||||
|
{
|
||||||
|
*longitude = loc->longitude;
|
||||||
|
*latitude = loc->latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
glong
|
||||||
|
tz_location_get_utc_offset (TzLocation *loc)
|
||||||
|
{
|
||||||
|
TzInfo *tz_info;
|
||||||
|
glong offset;
|
||||||
|
|
||||||
|
tz_info = tz_info_from_location (loc);
|
||||||
|
offset = tz_info->utc_offset;
|
||||||
|
tz_info_free (tz_info);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
TzInfo *
|
||||||
|
tz_info_from_location (TzLocation *loc)
|
||||||
|
{
|
||||||
|
TzInfo *tzinfo;
|
||||||
|
time_t curtime;
|
||||||
|
struct tm *curzone;
|
||||||
|
gchar *tz_env_value;
|
||||||
|
|
||||||
|
g_return_val_if_fail (loc != NULL, NULL);
|
||||||
|
g_return_val_if_fail (loc->zone != NULL, NULL);
|
||||||
|
|
||||||
|
tz_env_value = g_strdup (getenv ("TZ"));
|
||||||
|
setenv ("TZ", loc->zone, 1);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
tzset ();
|
||||||
|
#endif
|
||||||
|
tzinfo = g_new0 (TzInfo, 1);
|
||||||
|
|
||||||
|
curtime = time (NULL);
|
||||||
|
curzone = localtime (&curtime);
|
||||||
|
|
||||||
|
#ifndef __sun
|
||||||
|
/* Currently this solution doesnt seem to work - I get that */
|
||||||
|
/* America/Phoenix uses daylight savings, which is wrong */
|
||||||
|
tzinfo->tzname_normal = g_strdup (curzone->tm_zone);
|
||||||
|
if (curzone->tm_isdst)
|
||||||
|
tzinfo->tzname_daylight =
|
||||||
|
g_strdup (&curzone->tm_zone[curzone->tm_isdst]);
|
||||||
|
else
|
||||||
|
tzinfo->tzname_daylight = NULL;
|
||||||
|
|
||||||
|
tzinfo->utc_offset = curzone->tm_gmtoff;
|
||||||
|
#else
|
||||||
|
tzinfo->tzname_normal = NULL;
|
||||||
|
tzinfo->tzname_daylight = NULL;
|
||||||
|
tzinfo->utc_offset = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tzinfo->daylight = curzone->tm_isdst;
|
||||||
|
|
||||||
|
if (tz_env_value)
|
||||||
|
setenv ("TZ", tz_env_value, 1);
|
||||||
|
else
|
||||||
|
unsetenv ("TZ");
|
||||||
|
|
||||||
|
g_free (tz_env_value);
|
||||||
|
|
||||||
|
return tzinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
tz_info_free (TzInfo *tzinfo)
|
||||||
|
{
|
||||||
|
g_return_if_fail (tzinfo != NULL);
|
||||||
|
|
||||||
|
if (tzinfo->tzname_normal) g_free (tzinfo->tzname_normal);
|
||||||
|
if (tzinfo->tzname_daylight) g_free (tzinfo->tzname_daylight);
|
||||||
|
g_free (tzinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *orig;
|
||||||
|
const char *dest;
|
||||||
|
} aliases[] = {
|
||||||
|
{ "Asia/Istanbul", "Europe/Istanbul" }, /* Istanbul is in both Europe and Asia */
|
||||||
|
{ "Europe/Nicosia", "Asia/Nicosia" }, /* Ditto */
|
||||||
|
{ "EET", "Europe/Istanbul" }, /* Same tz as the 2 above */
|
||||||
|
{ "HST", "Pacific/Honolulu" },
|
||||||
|
{ "WET", "Europe/Brussels" }, /* Other name for the mainland Europe tz */
|
||||||
|
{ "CET", "Europe/Brussels" }, /* ditto */
|
||||||
|
{ "MET", "Europe/Brussels" },
|
||||||
|
{ "Etc/Zulu", "Etc/GMT" },
|
||||||
|
{ "Etc/UTC", "Etc/GMT" },
|
||||||
|
{ "GMT", "Etc/GMT" },
|
||||||
|
{ "Greenwich", "Etc/GMT" },
|
||||||
|
{ "Etc/UCT", "Etc/GMT" },
|
||||||
|
{ "Etc/GMT0", "Etc/GMT" },
|
||||||
|
{ "Etc/GMT+0", "Etc/GMT" },
|
||||||
|
{ "Etc/GMT-0", "Etc/GMT" },
|
||||||
|
{ "Etc/Universal", "Etc/GMT" },
|
||||||
|
{ "PST8PDT", "America/Los_Angeles" }, /* Other name for the Atlantic tz */
|
||||||
|
{ "EST", "America/New_York" }, /* Other name for the Eastern tz */
|
||||||
|
{ "EST5EDT", "America/New_York" }, /* ditto */
|
||||||
|
{ "CST6CDT", "America/Chicago" }, /* Other name for the Central tz */
|
||||||
|
{ "MST", "America/Denver" }, /* Other name for the mountain tz */
|
||||||
|
{ "MST7MDT", "America/Denver" }, /* ditto */
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
compare_timezones (const char *a,
|
||||||
|
const char *b)
|
||||||
|
{
|
||||||
|
if (g_str_equal (a, b))
|
||||||
|
return TRUE;
|
||||||
|
if (strchr (b, '/') == NULL) {
|
||||||
|
char *prefixed;
|
||||||
|
|
||||||
|
prefixed = g_strdup_printf ("/%s", b);
|
||||||
|
if (g_str_has_suffix (a, prefixed)) {
|
||||||
|
g_free (prefixed);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
g_free (prefixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
tz_info_get_clean_name (TzDB *tz_db,
|
||||||
|
const char *tz)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
const char *timezone;
|
||||||
|
guint i;
|
||||||
|
gboolean replaced;
|
||||||
|
|
||||||
|
/* Remove useless prefixes */
|
||||||
|
if (g_str_has_prefix (tz, "right/"))
|
||||||
|
tz = tz + strlen ("right/");
|
||||||
|
else if (g_str_has_prefix (tz, "posix/"))
|
||||||
|
tz = tz + strlen ("posix/");
|
||||||
|
|
||||||
|
/* Here start the crazies */
|
||||||
|
replaced = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (aliases); i++) {
|
||||||
|
if (compare_timezones (tz, aliases[i].orig)) {
|
||||||
|
replaced = TRUE;
|
||||||
|
timezone = aliases[i].dest;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try again! */
|
||||||
|
if (!replaced) {
|
||||||
|
/* Ignore crazy solar times from the '80s */
|
||||||
|
if (g_str_has_prefix (tz, "Asia/Riyadh") ||
|
||||||
|
g_str_has_prefix (tz, "Mideast/Riyadh")) {
|
||||||
|
timezone = "Asia/Riyadh";
|
||||||
|
replaced = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!replaced)
|
||||||
|
timezone = tz;
|
||||||
|
|
||||||
|
ret = g_hash_table_lookup (tz_db->backward, timezone);
|
||||||
|
if (ret == NULL)
|
||||||
|
return g_strdup (timezone);
|
||||||
|
return g_strdup (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------- *
|
||||||
|
* Private functions *
|
||||||
|
* ----------------- */
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
tz_data_file_get (void)
|
||||||
|
{
|
||||||
|
gchar *file;
|
||||||
|
|
||||||
|
file = g_strdup (TZ_DATA_FILE);
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
convert_pos (gchar *pos, int digits)
|
||||||
|
{
|
||||||
|
gchar whole[10];
|
||||||
|
gchar *fraction;
|
||||||
|
gint i;
|
||||||
|
float t1, t2;
|
||||||
|
|
||||||
|
if (!pos || strlen(pos) < 4 || digits > 9) return 0.0;
|
||||||
|
|
||||||
|
for (i = 0; i < digits + 1; i++) whole[i] = pos[i];
|
||||||
|
whole[i] = '\0';
|
||||||
|
fraction = pos + digits + 1;
|
||||||
|
|
||||||
|
t1 = g_strtod (whole, NULL);
|
||||||
|
t2 = g_strtod (fraction, NULL);
|
||||||
|
|
||||||
|
if (t1 >= 0.0) return t1 + t2/pow (10.0, strlen(fraction));
|
||||||
|
else return t1 - t2/pow (10.0, strlen(fraction));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* Currently not working */
|
||||||
|
static void
|
||||||
|
free_tzdata (TzLocation *tz)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (tz->country)
|
||||||
|
g_free(tz->country);
|
||||||
|
if (tz->zone)
|
||||||
|
g_free(tz->zone);
|
||||||
|
if (tz->comment)
|
||||||
|
g_free(tz->comment);
|
||||||
|
|
||||||
|
g_free(tz);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_country_names (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const TzLocation *tza = * (TzLocation **) a;
|
||||||
|
const TzLocation *tzb = * (TzLocation **) b;
|
||||||
|
|
||||||
|
return strcmp (tza->zone, tzb->zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
sort_locations_by_country (GPtrArray *locations)
|
||||||
|
{
|
||||||
|
qsort (locations->pdata, locations->len, sizeof (gpointer),
|
||||||
|
compare_country_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_backward_tz (TzDB *tz_db)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
char **lines, *contents;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
tz_db->backward = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
|
if (g_file_get_contents (GNOMECC_DATA_DIR "/datetime/backward", &contents, NULL, &error) == FALSE)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to load 'backward' file: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lines = g_strsplit (contents, "\n", -1);
|
||||||
|
g_free (contents);
|
||||||
|
for (i = 0; lines[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
char **items;
|
||||||
|
guint j;
|
||||||
|
char *real, *alias;
|
||||||
|
|
||||||
|
if (g_ascii_strncasecmp (lines[i], "Link\t", 5) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
items = g_strsplit (lines[i], "\t", -1);
|
||||||
|
real = NULL;
|
||||||
|
alias = NULL;
|
||||||
|
/* Skip the "Link<tab>" part */
|
||||||
|
for (j = 1; items[j] != NULL; j++)
|
||||||
|
{
|
||||||
|
if (items[j][0] == '\0')
|
||||||
|
continue;
|
||||||
|
if (real == NULL)
|
||||||
|
{
|
||||||
|
real = items[j];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
alias = items[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (real == NULL || alias == NULL)
|
||||||
|
g_warning ("Could not parse line: %s", lines[i]);
|
||||||
|
|
||||||
|
/* We don't need more than one name for it */
|
||||||
|
if (g_str_equal (real, "Etc/UTC") ||
|
||||||
|
g_str_equal (real, "Etc/UCT"))
|
||||||
|
real = "Etc/GMT";
|
||||||
|
|
||||||
|
g_hash_table_insert (tz_db->backward, g_strdup (alias), g_strdup (real));
|
||||||
|
g_strfreev (items);
|
||||||
|
}
|
||||||
|
g_strfreev (lines);
|
||||||
|
}
|
||||||
|
|
89
plugins/datetime/tz.h
Normal file
89
plugins/datetime/tz.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||||
|
/* Generic timezone utilities.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2001 Ximian, Inc.
|
||||||
|
*
|
||||||
|
* Authors: Hans Petter Jansson <hpj@ximian.com>
|
||||||
|
*
|
||||||
|
* Largely based on Michael Fulbright's work on Anaconda.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _E_TZ_H
|
||||||
|
#define _E_TZ_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#ifndef __sun
|
||||||
|
# define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
|
||||||
|
#else
|
||||||
|
# define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _TzDB TzDB;
|
||||||
|
typedef struct _TzLocation TzLocation;
|
||||||
|
typedef struct _TzInfo TzInfo;
|
||||||
|
|
||||||
|
|
||||||
|
struct _TzDB
|
||||||
|
{
|
||||||
|
GPtrArray *locations;
|
||||||
|
GHashTable *backward;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TzLocation
|
||||||
|
{
|
||||||
|
gchar *country;
|
||||||
|
gdouble latitude;
|
||||||
|
gdouble longitude;
|
||||||
|
gchar *zone;
|
||||||
|
gchar *comment;
|
||||||
|
|
||||||
|
gdouble dist; /* distance to clicked point for comparison */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* see the glibc info page information on time zone information */
|
||||||
|
/* tzname_normal is the default name for the timezone */
|
||||||
|
/* tzname_daylight is the name of the zone when in daylight savings */
|
||||||
|
/* utc_offset is offset in seconds from utc */
|
||||||
|
/* daylight if non-zero then location obeys daylight savings */
|
||||||
|
|
||||||
|
struct _TzInfo
|
||||||
|
{
|
||||||
|
gchar *tzname_normal;
|
||||||
|
gchar *tzname_daylight;
|
||||||
|
glong utc_offset;
|
||||||
|
gint daylight;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TzDB *tz_load_db (void);
|
||||||
|
void tz_db_free (TzDB *db);
|
||||||
|
char * tz_info_get_clean_name (TzDB *tz_db,
|
||||||
|
const char *tz);
|
||||||
|
GPtrArray *tz_get_locations (TzDB *db);
|
||||||
|
void tz_location_get_position (TzLocation *loc,
|
||||||
|
double *longitude, double *latitude);
|
||||||
|
void tz_location_free (TzLocation *loc);
|
||||||
|
char *tz_location_get_country (TzLocation *loc);
|
||||||
|
gchar *tz_location_get_zone (TzLocation *loc);
|
||||||
|
gchar *tz_location_get_comment (TzLocation *loc);
|
||||||
|
glong tz_location_get_utc_offset (TzLocation *loc);
|
||||||
|
gint tz_location_set_locally (TzLocation *loc);
|
||||||
|
TzInfo *tz_info_from_location (TzLocation *loc);
|
||||||
|
void tz_info_free (TzInfo *tz_info);
|
||||||
|
|
||||||
|
#endif
|
118
plugins/datetime/weather-tz.c
Normal file
118
plugins/datetime/weather-tz.c
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "weather-tz.h"
|
||||||
|
#include "tz.h"
|
||||||
|
|
||||||
|
#include <libgweather/gweather.h>
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
location_get_cities (GWeatherLocation *parent_location)
|
||||||
|
{
|
||||||
|
GList *cities = NULL;
|
||||||
|
GWeatherLocation *child = NULL;
|
||||||
|
|
||||||
|
while ((child = gweather_location_next_child (parent_location, child))) {
|
||||||
|
if (gweather_location_get_level (child) == GWEATHER_LOCATION_CITY) {
|
||||||
|
cities = g_list_prepend (cities, g_object_ref (child));
|
||||||
|
} else {
|
||||||
|
cities = g_list_concat (cities,
|
||||||
|
location_get_cities (child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cities;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
weather_location_has_timezone (GWeatherLocation *loc)
|
||||||
|
{
|
||||||
|
return gweather_location_get_timezone (loc) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load_timezones:
|
||||||
|
* @cities: a list of #GWeatherLocation
|
||||||
|
*
|
||||||
|
* Returns: a list of #TzLocation
|
||||||
|
*/
|
||||||
|
static GList *
|
||||||
|
load_timezones (GList *cities)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
GList *tz_locations = NULL;
|
||||||
|
|
||||||
|
for (l = cities; l; l = l->next) {
|
||||||
|
TzLocation *loc;
|
||||||
|
const gchar *country;
|
||||||
|
const gchar *timezone_id;
|
||||||
|
GTimeZone *tz;
|
||||||
|
gdouble latitude;
|
||||||
|
gdouble longitude;
|
||||||
|
|
||||||
|
if (!gweather_location_has_coords (l->data) ||
|
||||||
|
!weather_location_has_timezone (l->data)) {
|
||||||
|
g_debug ("Incomplete GWeather location entry: (%s) %s",
|
||||||
|
gweather_location_get_country (l->data),
|
||||||
|
gweather_location_get_city_name (l->data));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
country = gweather_location_get_country (l->data);
|
||||||
|
tz = gweather_location_get_timezone (l->data);
|
||||||
|
timezone_id = g_time_zone_get_identifier (tz);
|
||||||
|
gweather_location_get_coords (l->data,
|
||||||
|
&latitude,
|
||||||
|
&longitude);
|
||||||
|
|
||||||
|
loc = g_new0 (TzLocation, 1);
|
||||||
|
loc->country = g_strdup (country);
|
||||||
|
loc->latitude = latitude;
|
||||||
|
loc->longitude = longitude;
|
||||||
|
loc->zone = g_strdup (timezone_id);
|
||||||
|
loc->comment = NULL;
|
||||||
|
|
||||||
|
tz_locations = g_list_prepend (tz_locations, loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tz_locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
weather_tz_db_get_locations (const gchar *country_code)
|
||||||
|
{
|
||||||
|
g_autoptr(GWeatherLocation) world = NULL;
|
||||||
|
g_autoptr(GWeatherLocation) country = NULL;
|
||||||
|
g_autolist(GWeatherLocation) cities = NULL;
|
||||||
|
GList *tz_locations;
|
||||||
|
|
||||||
|
world = gweather_location_get_world ();
|
||||||
|
|
||||||
|
country = gweather_location_find_by_country_code (world, country_code);
|
||||||
|
|
||||||
|
if (!country)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cities = location_get_cities (country);
|
||||||
|
tz_locations = load_timezones (cities);
|
||||||
|
|
||||||
|
return tz_locations;
|
||||||
|
}
|
27
plugins/datetime/weather-tz.h
Normal file
27
plugins/datetime/weather-tz.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Kalev Lember <kalevlember@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WEATHER_TZ_H
|
||||||
|
#define __WEATHER_TZ_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
GList *weather_tz_db_get_locations (const char *country);
|
||||||
|
|
||||||
|
#endif /* __WEATHER_TZ_H */
|
26
plugins/gsd.service.in
Normal file
26
plugins/gsd.service.in
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[Unit]
|
||||||
|
Description=@description@ service
|
||||||
|
CollectMode=inactive-or-failed
|
||||||
|
RefuseManualStart=true
|
||||||
|
RefuseManualStop=true
|
||||||
|
|
||||||
|
After=gnome-session-initialized.target
|
||||||
|
|
||||||
|
# Requisite/PartOf means the dependency is not loaded automatically.
|
||||||
|
# The ordering here also implies Before=gnome-session.target
|
||||||
|
Requisite=@plugin_dbus_name@.target
|
||||||
|
PartOf=@plugin_dbus_name@.target
|
||||||
|
Before=@plugin_dbus_name@.target
|
||||||
|
|
||||||
|
@plugin_gate_units_section@
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Slice=session.slice
|
||||||
|
Type=dbus
|
||||||
|
ExecStart=@libexecdir@/gsd-@plugin_name@
|
||||||
|
Restart=on-failure
|
||||||
|
BusName=@plugin_dbus_name@
|
||||||
|
TimeoutStopSec=5
|
||||||
|
# We cannot use OnFailure as e.g. dependency failures are normal
|
||||||
|
# https://github.com/systemd/systemd/issues/12352
|
||||||
|
ExecStopPost=@libexecdir@/gnome-session-ctl --exec-stop-check
|
12
plugins/gsd.target.in
Normal file
12
plugins/gsd.target.in
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[Unit]
|
||||||
|
Description=@description@ target
|
||||||
|
CollectMode=inactive-or-failed
|
||||||
|
|
||||||
|
# Pull in the service
|
||||||
|
Wants=@plugin_dbus_name@.service
|
||||||
|
|
||||||
|
# Require GNOME session and specify startup ordering
|
||||||
|
Requisite=gnome-session-initialized.target
|
||||||
|
After=gnome-session-initialized.target
|
||||||
|
PartOf=gnome-session-initialized.target
|
||||||
|
Before=gnome-session.target
|
159
plugins/housekeeping/gsd-disk-space-helper.c
Normal file
159
plugins/housekeeping/gsd-disk-space-helper.c
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/* -*- 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 <vuntz@gnome.org>
|
||||||
|
* Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gsd-disk-space-helper.h"
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsd_should_ignore_unix_mount (GUnixMountEntry *mount)
|
||||||
|
{
|
||||||
|
const char *fs, *device;
|
||||||
|
g_autofree char *label = NULL;
|
||||||
|
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 */
|
||||||
|
#if !GLIB_CHECK_VERSION(2, 56, 0)
|
||||||
|
const gchar *ignore_fs[] = {
|
||||||
|
"adfs",
|
||||||
|
"afs",
|
||||||
|
"auto",
|
||||||
|
"autofs",
|
||||||
|
"autofs4",
|
||||||
|
"cgroup",
|
||||||
|
"configfs",
|
||||||
|
"cxfs",
|
||||||
|
"debugfs",
|
||||||
|
"devfs",
|
||||||
|
"devpts",
|
||||||
|
"devtmpfs",
|
||||||
|
"ecryptfs",
|
||||||
|
"fdescfs",
|
||||||
|
"fusectl",
|
||||||
|
"gfs",
|
||||||
|
"gfs2",
|
||||||
|
"gpfs",
|
||||||
|
"hugetlbfs",
|
||||||
|
"kernfs",
|
||||||
|
"linprocfs",
|
||||||
|
"linsysfs",
|
||||||
|
"lustre",
|
||||||
|
"lustre_lite",
|
||||||
|
"mfs",
|
||||||
|
"mqueue",
|
||||||
|
"ncpfs",
|
||||||
|
"nfsd",
|
||||||
|
"nullfs",
|
||||||
|
"ocfs2",
|
||||||
|
"overlay",
|
||||||
|
"proc",
|
||||||
|
"procfs",
|
||||||
|
"pstore",
|
||||||
|
"ptyfs",
|
||||||
|
"rootfs",
|
||||||
|
"rpc_pipefs",
|
||||||
|
"securityfs",
|
||||||
|
"selinuxfs",
|
||||||
|
"sysfs",
|
||||||
|
"tmpfs",
|
||||||
|
"usbfs",
|
||||||
|
"zfs",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
#endif /* GLIB < 2.56.0 */
|
||||||
|
const gchar *ignore_network_fs[] = {
|
||||||
|
"cifs",
|
||||||
|
"nfs",
|
||||||
|
"nfs4",
|
||||||
|
"smbfs",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const gchar *ignore_devices[] = {
|
||||||
|
"none",
|
||||||
|
"sunrpc",
|
||||||
|
"devpts",
|
||||||
|
"nfsd",
|
||||||
|
"/dev/loop",
|
||||||
|
"/dev/vn",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
const gchar *ignore_labels[] = {
|
||||||
|
"RETRODE",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
fs = g_unix_mount_get_fs_type (mount);
|
||||||
|
#if GLIB_CHECK_VERSION(2, 56, 0)
|
||||||
|
if (g_unix_is_system_fs_type (fs))
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
for (i = 0; ignore_fs[i] != NULL; i++)
|
||||||
|
if (g_str_equal (ignore_fs[i], fs))
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
for (i = 0; ignore_network_fs[i] != NULL; i++)
|
||||||
|
if (g_str_equal (ignore_network_fs[i], fs))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
device = g_unix_mount_get_device_path (mount);
|
||||||
|
for (i = 0; ignore_devices[i] != NULL; i++)
|
||||||
|
if (g_str_equal (ignore_devices[i], device))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
label = g_unix_mount_guess_name (mount);
|
||||||
|
for (i = 0; ignore_labels[i] != NULL; i++)
|
||||||
|
if (g_str_equal (ignore_labels[i], label))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used in gnome-control-center's info panel */
|
||||||
|
gboolean
|
||||||
|
gsd_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;
|
||||||
|
}
|
38
plugins/housekeeping/gsd-disk-space-helper.h
Normal file
38
plugins/housekeeping/gsd-disk-space-helper.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*- 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 <vuntz@gnome.org>
|
||||||
|
* Bastien Nocera <hadess@hadess.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_DISK_SPACE_HELPER_H
|
||||||
|
#define __GSD_DISK_SPACE_HELPER_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gunixmounts.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
gboolean gsd_should_ignore_unix_mount (GUnixMountEntry *mount);
|
||||||
|
gboolean gsd_is_removable_mount (GUnixMountEntry *mount);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_DISK_SPACE_HELPER_H */
|
48
plugins/housekeeping/gsd-disk-space-test.c
Normal file
48
plugins/housekeeping/gsd-disk-space-test.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* -*- 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 <vuntz@gnome.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
#include "gsd-disk-space.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
GMainLoop *loop;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
notify_init ("gsd-disk-space-test");
|
||||||
|
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
gsd_ldsm_setup (TRUE);
|
||||||
|
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
|
gsd_ldsm_clean ();
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
1083
plugins/housekeeping/gsd-disk-space.c
Normal file
1083
plugins/housekeeping/gsd-disk-space.c
Normal file
File diff suppressed because it is too large
Load diff
64
plugins/housekeeping/gsd-disk-space.h
Normal file
64
plugins/housekeeping/gsd-disk-space.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* -*- 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 <vuntz@gnome.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_DISK_SPACE_H
|
||||||
|
#define __GSD_DISK_SPACE_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
grefcount ref_count;
|
||||||
|
GFile *file;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
GDateTime *old;
|
||||||
|
gboolean dry_run;
|
||||||
|
gboolean trash;
|
||||||
|
gchar *name;
|
||||||
|
gchar *filesystem;
|
||||||
|
gint depth;
|
||||||
|
} DeleteData;
|
||||||
|
|
||||||
|
void delete_data_unref (DeleteData *data);
|
||||||
|
DeleteData *delete_data_new (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GDateTime *old,
|
||||||
|
gboolean dry_run,
|
||||||
|
gboolean trash,
|
||||||
|
gint depth,
|
||||||
|
const char *filesystem);
|
||||||
|
char* get_filesystem (GFile *file);
|
||||||
|
|
||||||
|
void delete_recursively_by_age (DeleteData *data);
|
||||||
|
|
||||||
|
void gsd_ldsm_setup (gboolean check_now);
|
||||||
|
void gsd_ldsm_clean (void);
|
||||||
|
|
||||||
|
/* for the test */
|
||||||
|
void gsd_ldsm_show_empty_trash (void);
|
||||||
|
void gsd_ldsm_purge_trash (GDateTime *old);
|
||||||
|
void gsd_ldsm_purge_temp_files (GDateTime *old);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_DISK_SPACE_H */
|
44
plugins/housekeeping/gsd-empty-trash-test.c
Normal file
44
plugins/housekeeping/gsd-empty-trash-test.c
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/* -*- 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 <cosimoc@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "gsd-disk-space.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
GMainLoop *loop;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
gsd_ldsm_show_empty_trash ();
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
501
plugins/housekeeping/gsd-housekeeping-manager.c
Normal file
501
plugins/housekeeping/gsd-housekeeping-manager.c
Normal file
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Michael J. Chudobiak <mjc@avtechpulse.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
|
||||||
|
#include "gnome-settings-profile.h"
|
||||||
|
#include "gsd-housekeeping-manager.h"
|
||||||
|
#include "gsd-disk-space.h"
|
||||||
|
#include "gsd-systemd-notify.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* General */
|
||||||
|
#define INTERVAL_ONCE_A_DAY 24*60*60
|
||||||
|
#define INTERVAL_TWO_MINUTES 2*60
|
||||||
|
|
||||||
|
/* Thumbnail cleaner */
|
||||||
|
#define THUMB_PREFIX "org.gnome.desktop.thumbnail-cache"
|
||||||
|
|
||||||
|
#define THUMB_AGE_KEY "maximum-age"
|
||||||
|
#define THUMB_SIZE_KEY "maximum-size"
|
||||||
|
|
||||||
|
#define GSD_HOUSEKEEPING_DBUS_PATH "/org/gnome/SettingsDaemon/Housekeeping"
|
||||||
|
|
||||||
|
static const gchar introspection_xml[] =
|
||||||
|
"<node>"
|
||||||
|
" <interface name='org.gnome.SettingsDaemon.Housekeeping'>"
|
||||||
|
" <method name='EmptyTrash'/>"
|
||||||
|
" <method name='RemoveTempFiles'/>"
|
||||||
|
" </interface>"
|
||||||
|
"</node>";
|
||||||
|
|
||||||
|
struct _GsdHousekeepingManager {
|
||||||
|
GsdApplication parent;
|
||||||
|
|
||||||
|
GSettings *settings;
|
||||||
|
guint long_term_cb;
|
||||||
|
guint short_term_cb;
|
||||||
|
|
||||||
|
GDBusNodeInfo *introspection_data;
|
||||||
|
|
||||||
|
GsdSystemdNotify *systemd_notify;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gsd_housekeeping_manager_class_init (GsdHousekeepingManagerClass *klass);
|
||||||
|
static void gsd_housekeeping_manager_init (GsdHousekeepingManager *housekeeping_manager);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdHousekeepingManager, gsd_housekeeping_manager, GSD_TYPE_APPLICATION)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDateTime *now; /* (owned) */
|
||||||
|
GTimeSpan max_age_us;
|
||||||
|
goffset total_size;
|
||||||
|
goffset max_size;
|
||||||
|
} PurgeData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDateTime *time; /* (owned) (nullable) */
|
||||||
|
char *path;
|
||||||
|
glong size;
|
||||||
|
} ThumbData;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
thumb_data_free (gpointer data)
|
||||||
|
{
|
||||||
|
ThumbData *info = data;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
g_clear_pointer (&info->time, g_date_time_unref);
|
||||||
|
g_free (info->path);
|
||||||
|
g_free (info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
read_dir_for_purge (const char *path, GList *files)
|
||||||
|
{
|
||||||
|
GFile *read_path;
|
||||||
|
GFileEnumerator *enum_dir;
|
||||||
|
int cannot_get_time = 0;
|
||||||
|
|
||||||
|
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_ACCESS ","
|
||||||
|
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;
|
||||||
|
GDateTime *time = NULL;
|
||||||
|
|
||||||
|
entry = g_file_get_child (read_path, name);
|
||||||
|
entry_path = g_file_get_path (entry);
|
||||||
|
g_object_unref (entry);
|
||||||
|
|
||||||
|
// If atime is available, it should be no worse than mtime.
|
||||||
|
// - Even if the file system is mounted with noatime, the atime and
|
||||||
|
// mtime will be set to the same value on file creation.
|
||||||
|
// - Since the thumbnailer never edits thumbnails, and instead swaps
|
||||||
|
// in newly created temp files, atime will always be >= mtime.
|
||||||
|
|
||||||
|
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS)) {
|
||||||
|
time = g_file_info_get_access_date_time (info);
|
||||||
|
} else if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) {
|
||||||
|
time = g_file_info_get_modification_date_time (info);
|
||||||
|
} else {
|
||||||
|
// Unlikely to get here, but be defensive
|
||||||
|
cannot_get_time += 1;
|
||||||
|
time = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
td = g_new0 (ThumbData, 1);
|
||||||
|
td->path = entry_path;
|
||||||
|
td->time = g_steal_pointer (&time);
|
||||||
|
td->size = g_file_info_get_size (info);
|
||||||
|
|
||||||
|
files = g_list_prepend (files, td);
|
||||||
|
}
|
||||||
|
g_object_unref (info);
|
||||||
|
}
|
||||||
|
g_object_unref (enum_dir);
|
||||||
|
|
||||||
|
if (cannot_get_time > 0) {
|
||||||
|
g_warning ("Could not read atime or mtime on %d files in %s", cannot_get_time, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_object_unref (read_path);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
purge_old_thumbnails (ThumbData *info, PurgeData *purge_data)
|
||||||
|
{
|
||||||
|
if (info->time != NULL &&
|
||||||
|
g_date_time_difference (purge_data->now, info->time) > purge_data->max_age_us) {
|
||||||
|
g_unlink (info->path);
|
||||||
|
info->size = 0;
|
||||||
|
} else {
|
||||||
|
purge_data->total_size += info->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sort_file_time (ThumbData *file1, ThumbData *file2)
|
||||||
|
{
|
||||||
|
if (file1->time == NULL && file2->time == NULL)
|
||||||
|
return 0;
|
||||||
|
else if (file1->time == NULL)
|
||||||
|
return 1;
|
||||||
|
else if (file2->time == NULL)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return g_date_time_difference (file1->time, file2->time);
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
"x-large",
|
||||||
|
NULL);
|
||||||
|
g_ptr_array_add (array, path);
|
||||||
|
|
||||||
|
path = g_build_filename (g_get_user_cache_dir (),
|
||||||
|
"thumbnails",
|
||||||
|
"xx-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 (GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
|
||||||
|
char **paths;
|
||||||
|
GList *files;
|
||||||
|
PurgeData purge_data;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_debug ("housekeeping: checking thumbnail cache size and freshness");
|
||||||
|
|
||||||
|
purge_data.max_age_us = (GTimeSpan) g_settings_get_int (manager->settings, THUMB_AGE_KEY) * 24 * 60 * 60 * G_USEC_PER_SEC;
|
||||||
|
purge_data.max_size = (goffset) g_settings_get_int (manager->settings, THUMB_SIZE_KEY) * 1024 * 1024;
|
||||||
|
|
||||||
|
/* if both are set to -1, we don't need to read anything */
|
||||||
|
if ((purge_data.max_age_us < 0) && (purge_data.max_size < 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
paths = get_thumbnail_dirs ();
|
||||||
|
files = NULL;
|
||||||
|
for (i = 0; paths[i] != NULL; i++)
|
||||||
|
files = read_dir_for_purge (paths[i], files);
|
||||||
|
g_strfreev (paths);
|
||||||
|
|
||||||
|
purge_data.now = g_date_time_new_now_utc ();
|
||||||
|
purge_data.total_size = 0;
|
||||||
|
|
||||||
|
if (purge_data.max_age_us >= 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_time);
|
||||||
|
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);
|
||||||
|
g_date_time_unref (purge_data.now);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_cleanup (GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
purge_thumbnail_cache (manager);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_cleanup_once (GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
do_cleanup (manager);
|
||||||
|
manager->short_term_cb = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_cleanup_soon (GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
if (manager->short_term_cb == 0) {
|
||||||
|
g_debug ("housekeeping: will tidy up in 2 minutes");
|
||||||
|
manager->short_term_cb = g_timeout_add_seconds (INTERVAL_TWO_MINUTES,
|
||||||
|
(GSourceFunc) do_cleanup_once,
|
||||||
|
manager);
|
||||||
|
g_source_set_name_by_id (manager->short_term_cb, "[gnome-settings-daemon] do_cleanup_once");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
settings_changed_callback (GSettings *settings,
|
||||||
|
const char *key,
|
||||||
|
GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
do_cleanup_soon (manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GDateTime *now;
|
||||||
|
now = g_date_time_new_now_local ();
|
||||||
|
if (g_strcmp0 (method_name, "EmptyTrash") == 0) {
|
||||||
|
gsd_ldsm_purge_trash (now);
|
||||||
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0 (method_name, "RemoveTempFiles") == 0) {
|
||||||
|
gsd_ldsm_purge_temp_files (now);
|
||||||
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
|
}
|
||||||
|
g_date_time_unref (now);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GDBusInterfaceVTable interface_vtable =
|
||||||
|
{
|
||||||
|
handle_method_call,
|
||||||
|
NULL, /* Get Property */
|
||||||
|
NULL, /* Set Property */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_housekeeping_manager_startup (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdHousekeepingManager *manager = GSD_HOUSEKEEPING_MANAGER (app);
|
||||||
|
gchar *dir;
|
||||||
|
|
||||||
|
g_debug ("Starting housekeeping manager");
|
||||||
|
gnome_settings_profile_start (NULL);
|
||||||
|
|
||||||
|
/* Create ~/.local/ as early as possible */
|
||||||
|
(void) g_mkdir_with_parents(g_get_user_data_dir (), 0700);
|
||||||
|
|
||||||
|
/* Create ~/.local/share/applications/, see
|
||||||
|
* https://bugzilla.gnome.org/show_bug.cgi?id=703048 */
|
||||||
|
dir = g_build_filename (g_get_user_data_dir (), "applications", NULL);
|
||||||
|
(void) g_mkdir (dir, 0700);
|
||||||
|
g_free (dir);
|
||||||
|
|
||||||
|
gsd_ldsm_setup (FALSE);
|
||||||
|
|
||||||
|
manager->settings = g_settings_new (THUMB_PREFIX);
|
||||||
|
g_signal_connect (G_OBJECT (manager->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->long_term_cb = g_timeout_add_seconds (INTERVAL_ONCE_A_DAY,
|
||||||
|
(GSourceFunc) do_cleanup,
|
||||||
|
manager);
|
||||||
|
g_source_set_name_by_id (manager->long_term_cb, "[gnome-settings-daemon] do_cleanup");
|
||||||
|
|
||||||
|
manager->systemd_notify = g_object_new (GSD_TYPE_SYSTEMD_NOTIFY, NULL);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_housekeeping_manager_parent_class)->startup (app);
|
||||||
|
|
||||||
|
gnome_settings_profile_end (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_housekeeping_manager_shutdown (GApplication *app)
|
||||||
|
{
|
||||||
|
GsdHousekeepingManager *manager = GSD_HOUSEKEEPING_MANAGER (app);
|
||||||
|
|
||||||
|
g_debug ("Stopping housekeeping manager");
|
||||||
|
|
||||||
|
g_clear_object (&manager->systemd_notify);
|
||||||
|
|
||||||
|
if (manager->short_term_cb) {
|
||||||
|
g_source_remove (manager->short_term_cb);
|
||||||
|
manager->short_term_cb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager->long_term_cb) {
|
||||||
|
g_source_remove (manager->long_term_cb);
|
||||||
|
manager->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 (manager->settings, THUMB_AGE_KEY) == 0) ||
|
||||||
|
(g_settings_get_int (manager->settings, THUMB_SIZE_KEY) == 0)) {
|
||||||
|
do_cleanup (manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&manager->settings);
|
||||||
|
gsd_ldsm_clean ();
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_housekeeping_manager_parent_class)->shutdown (app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gsd_housekeeping_manager_dbus_register (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GsdHousekeepingManager *manager = GSD_HOUSEKEEPING_MANAGER (app);
|
||||||
|
GDBusInterfaceInfo **infos;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!G_APPLICATION_CLASS (gsd_housekeeping_manager_parent_class)->dbus_register (app,
|
||||||
|
connection,
|
||||||
|
object_path,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
manager->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
|
||||||
|
g_assert (manager->introspection_data != NULL);
|
||||||
|
|
||||||
|
infos = manager->introspection_data->interfaces;
|
||||||
|
for (i = 0; infos[i] != NULL; i++) {
|
||||||
|
g_dbus_connection_register_object (connection,
|
||||||
|
GSD_HOUSEKEEPING_DBUS_PATH,
|
||||||
|
infos[i],
|
||||||
|
&interface_vtable,
|
||||||
|
manager,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_housekeeping_manager_dbus_unregister (GApplication *app,
|
||||||
|
GDBusConnection *connection,
|
||||||
|
const char *object_path)
|
||||||
|
{
|
||||||
|
GsdHousekeepingManager *manager = GSD_HOUSEKEEPING_MANAGER (app);
|
||||||
|
|
||||||
|
g_clear_pointer (&manager->introspection_data, g_dbus_node_info_unref);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (gsd_housekeeping_manager_parent_class)->dbus_unregister (app,
|
||||||
|
connection,
|
||||||
|
object_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_housekeeping_manager_class_init (GsdHousekeepingManagerClass *klass)
|
||||||
|
{
|
||||||
|
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
|
||||||
|
|
||||||
|
application_class->startup = gsd_housekeeping_manager_startup;
|
||||||
|
application_class->shutdown = gsd_housekeeping_manager_shutdown;
|
||||||
|
application_class->dbus_register = gsd_housekeeping_manager_dbus_register;
|
||||||
|
application_class->dbus_unregister = gsd_housekeeping_manager_dbus_unregister;
|
||||||
|
|
||||||
|
notify_init ("gnome-settings-daemon");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_housekeeping_manager_init (GsdHousekeepingManager *manager)
|
||||||
|
{
|
||||||
|
}
|
33
plugins/housekeeping/gsd-housekeeping-manager.h
Normal file
33
plugins/housekeeping/gsd-housekeeping-manager.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Michael J. Chudobiak <mjc@avtechpulse.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSD_HOUSEKEEPING_MANAGER_H
|
||||||
|
#define __GSD_HOUSEKEEPING_MANAGER_H
|
||||||
|
|
||||||
|
#include "gsd-application.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GSD_TYPE_HOUSEKEEPING_MANAGER (gsd_housekeeping_manager_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (GsdHousekeepingManager, gsd_housekeeping_manager, GSD, HOUSEKEEPING_MANAGER, GsdApplication)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSD_HOUSEKEEPING_MANAGER_H */
|
62
plugins/housekeeping/gsd-purge-temp-test.c
Normal file
62
plugins/housekeeping/gsd-purge-temp-test.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/* -*- 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 <vuntz@gnome.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
#include "gsd-disk-space.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
DeleteData *data;
|
||||||
|
GDateTime *old;
|
||||||
|
GMainLoop *loop;
|
||||||
|
g_autofree char *filesystem = NULL;
|
||||||
|
|
||||||
|
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
notify_init ("gsd-purge-temp-test");
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
file = g_file_new_for_path ("/tmp/gsd-purge-temp-test");
|
||||||
|
if (!g_file_query_exists (file, NULL)) {
|
||||||
|
g_warning ("Create /tmp/gsd-purge-temp-test and add some files to it to test deletion by date");
|
||||||
|
g_object_unref (file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = g_date_time_new_now_local ();
|
||||||
|
filesystem = get_filesystem (file);
|
||||||
|
data = delete_data_new (file, NULL, old, FALSE, FALSE, 0, filesystem);
|
||||||
|
delete_recursively_by_age (data);
|
||||||
|
delete_data_unref (data);
|
||||||
|
g_object_unref (file);
|
||||||
|
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
277
plugins/housekeeping/gsd-systemd-notify.c
Normal file
277
plugins/housekeeping/gsd-systemd-notify.c
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Benjamin Berg <bberg@redhat.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gsd-systemd-notify.h"
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <gio/gdesktopappinfo.h>
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
|
||||||
|
struct _GsdSystemdNotify {
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
GDBusConnection *session;
|
||||||
|
guint sub_service;
|
||||||
|
guint sub_scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GsdSystemdNotify, gsd_systemd_notify, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
notify_oom_kill (char *unit)
|
||||||
|
{
|
||||||
|
g_autoptr(GDesktopAppInfo) app = NULL;
|
||||||
|
g_autofree char *unit_copy = NULL;
|
||||||
|
g_autofree char *app_id = NULL;
|
||||||
|
g_autofree char *desktop_id = NULL;
|
||||||
|
g_autofree char *summary = NULL;
|
||||||
|
g_autofree char *message = NULL;
|
||||||
|
NotifyNotification *notification = NULL;
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
unit_copy = g_strdup (unit);
|
||||||
|
|
||||||
|
if (g_str_has_suffix (unit_copy, ".service")) {
|
||||||
|
/* Find (first) @ character */
|
||||||
|
pos = strchr (unit_copy, '@');
|
||||||
|
if (pos)
|
||||||
|
*pos = '\0';
|
||||||
|
} else if (g_str_has_suffix (unit_copy, ".scope")) {
|
||||||
|
/* Find last - character */
|
||||||
|
pos = strrchr (unit_copy, '-');
|
||||||
|
if (pos)
|
||||||
|
*pos = '\0';
|
||||||
|
} else {
|
||||||
|
/* This cannot happen, because we only subscribe to the Scope
|
||||||
|
* and Service DBus interfaces.
|
||||||
|
*/
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pos = strrchr (unit_copy, '-');
|
||||||
|
if (pos) {
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
app_id = g_strcompress (pos);
|
||||||
|
desktop_id = g_strjoin (NULL, app_id, ".desktop", NULL);
|
||||||
|
|
||||||
|
app = g_desktop_app_info_new (desktop_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app) {
|
||||||
|
/* TRANSLATORS: %s is the application name. */
|
||||||
|
summary = g_strdup_printf (_("%s Stopped"),
|
||||||
|
g_app_info_get_name (G_APP_INFO (app)));
|
||||||
|
/* TRANSLATORS: %s is the application name. */
|
||||||
|
message = g_strdup_printf (_("Device memory is nearly full. %s was using a lot of memory and was forced to stop."),
|
||||||
|
g_app_info_get_name (G_APP_INFO (app)));
|
||||||
|
} else if (g_str_has_prefix (unit, "vte-spawn-")) {
|
||||||
|
/* TRANSLATORS: A terminal tab/window was killed. */
|
||||||
|
summary = g_strdup_printf (_("Virtual Terminal Stopped"));
|
||||||
|
/* TRANSLATORS: A terminal tab/window was killed. */
|
||||||
|
message = g_strdup_printf (_("Device memory is nearly full. Virtual terminal processes were using a lot of memory and were forced to stop."));
|
||||||
|
} else {
|
||||||
|
/* TRANSLATORS: We don't have a good description of what was killed. */
|
||||||
|
summary = g_strdup_printf (_("Application Stopped"));
|
||||||
|
/* TRANSLATORS: We don't have a good description of what was killed. */
|
||||||
|
message = g_strdup_printf (_("Device memory is nearly full. An application was using a lot of memory and was forced to stop."));
|
||||||
|
}
|
||||||
|
|
||||||
|
notification = notify_notification_new (summary, message, NULL);
|
||||||
|
|
||||||
|
if (app) {
|
||||||
|
notify_notification_set_hint_string (notification, "desktop-entry", desktop_id);
|
||||||
|
notify_notification_set_app_name (notification, g_app_info_get_name (G_APP_INFO (app)));
|
||||||
|
}
|
||||||
|
notify_notification_set_hint (notification, "image-path", g_variant_new_string ("dialog-warning-symbolic"));
|
||||||
|
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);
|
||||||
|
|
||||||
|
notify_notification_show (notification, NULL);
|
||||||
|
g_object_unref (notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Taken from hexdecoct.c in systemd, LGPL-2.1-or-later */
|
||||||
|
static int
|
||||||
|
unhexchar (char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
|
||||||
|
if (c >= 'a' && c <= 'f')
|
||||||
|
return c - 'a' + 10;
|
||||||
|
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
unescape_dbus_path (const char *path)
|
||||||
|
{
|
||||||
|
g_autofree char *res = g_malloc (strlen (path) + 1);
|
||||||
|
char *r;
|
||||||
|
|
||||||
|
for (r = res; *path; path += 1, r += 1) {
|
||||||
|
int c1, c2;
|
||||||
|
if (*path != '_') {
|
||||||
|
*r = *path;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Read next two hex characters */
|
||||||
|
path += 1;
|
||||||
|
c1 = unhexchar (*path);
|
||||||
|
if (c1 < 0)
|
||||||
|
return NULL;
|
||||||
|
path += 1;
|
||||||
|
c2 = unhexchar (*path);
|
||||||
|
if (c2 < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*r = (c1 << 4) | c2;
|
||||||
|
}
|
||||||
|
*r = '\0';
|
||||||
|
|
||||||
|
return g_steal_pointer (&res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_unit_properties_changed (GDBusConnection *connection,
|
||||||
|
const char *sender_name,
|
||||||
|
const char *object_path,
|
||||||
|
const char *interface_name,
|
||||||
|
const char *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GVariant) dict = NULL;
|
||||||
|
const char *result = NULL;
|
||||||
|
const char *unit_escaped = NULL;
|
||||||
|
g_autofree char *unit = NULL;
|
||||||
|
|
||||||
|
g_assert (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)")));
|
||||||
|
|
||||||
|
dict = g_variant_get_child_value (parameters, 1);
|
||||||
|
g_assert (dict);
|
||||||
|
|
||||||
|
unit_escaped = strrchr (object_path, '/');
|
||||||
|
g_assert (unit_escaped);
|
||||||
|
unit_escaped += 1;
|
||||||
|
|
||||||
|
unit = unescape_dbus_path (unit_escaped);
|
||||||
|
g_assert (unit);
|
||||||
|
|
||||||
|
if (g_variant_lookup (dict, "Result", "&s", &result)) {
|
||||||
|
if (g_strcmp0 (result, "oom-kill") == 0)
|
||||||
|
notify_oom_kill (unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_bus_gotten (GDBusConnection *obj,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GsdSystemdNotify *self)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
GDBusConnection *con;
|
||||||
|
|
||||||
|
con = g_bus_get_finish (res, &error);
|
||||||
|
if (!con) {
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to get session bus: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->session = con;
|
||||||
|
|
||||||
|
/* Subscribe to systemd events by calling Subscribe on
|
||||||
|
* org.freedesktop.systemd1.Manager.
|
||||||
|
*/
|
||||||
|
g_dbus_connection_call (self->session,
|
||||||
|
"org.freedesktop.systemd1",
|
||||||
|
"/org/freedesktop/systemd1",
|
||||||
|
"org.freedesktop.systemd1.Manager",
|
||||||
|
"Subscribe",
|
||||||
|
NULL,
|
||||||
|
G_VARIANT_TYPE ("()"),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
self->sub_service = g_dbus_connection_signal_subscribe (self->session,
|
||||||
|
"org.freedesktop.systemd1",
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"PropertiesChanged",
|
||||||
|
NULL,
|
||||||
|
"org.freedesktop.systemd1.Service",
|
||||||
|
G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE,
|
||||||
|
on_unit_properties_changed,
|
||||||
|
self,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
self->sub_scope = g_dbus_connection_signal_subscribe (self->session,
|
||||||
|
"org.freedesktop.systemd1",
|
||||||
|
"org.freedesktop.DBus.Properties",
|
||||||
|
"PropertiesChanged",
|
||||||
|
NULL,
|
||||||
|
"org.freedesktop.systemd1.Scope",
|
||||||
|
G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE,
|
||||||
|
on_unit_properties_changed,
|
||||||
|
self,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_systemd_notify_init (GsdSystemdNotify *self)
|
||||||
|
{
|
||||||
|
g_bus_get (G_BUS_TYPE_SESSION, NULL, (GAsyncReadyCallback) on_bus_gotten, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_systemd_notify_dispose (GObject *obj)
|
||||||
|
{
|
||||||
|
GsdSystemdNotify *self = GSD_SYSTEMD_NOTIFY (obj);
|
||||||
|
|
||||||
|
if (self->sub_service) {
|
||||||
|
g_dbus_connection_signal_unsubscribe (self->session, self->sub_service);
|
||||||
|
g_dbus_connection_signal_unsubscribe (self->session, self->sub_scope);
|
||||||
|
}
|
||||||
|
self->sub_service = 0;
|
||||||
|
self->sub_scope = 0;
|
||||||
|
g_clear_object (&self->session);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gsd_systemd_notify_parent_class)->dispose (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsd_systemd_notify_class_init (GsdSystemdNotifyClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = gsd_systemd_notify_dispose;
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue