1
0
Fork 0

Adding upstream version 48.1.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
Daniel Baumann 2025-06-22 20:20:27 +02:00
parent d8950f2d0b
commit 18b565039d
Signed by: daniel.baumann
GPG key ID: BCC918A2ABD66424
371 changed files with 405983 additions and 0 deletions

120
.gitignore vendored Normal file
View 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
View 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"

View 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
View 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
View file

@ -0,0 +1,2 @@
Jonathan Blandford <jrb@redhat.com>
William Jon McCann <mccann@jhu.edu>

340
COPYING Normal file
View 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
View 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!

3913
ChangeLog Normal file

File diff suppressed because it is too large Load diff

1
MAINTAINERS Normal file
View file

@ -0,0 +1 @@
See gnome-settings-daemon.doap

5047
NEWS Normal file

File diff suppressed because it is too large Load diff

65
README Normal file
View 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
View 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

View 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

View 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
View 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)

View file

@ -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>

View 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 tablets 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>

View file

@ -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>

View 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>

View 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>

View file

@ -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>

View 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>'&lt;Control&gt;&lt;Alt&gt;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>'&lt;Super&gt;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>'&lt;Alt&gt;&lt;Super&gt;8'</default>
<summary>Toggle magnifier</summary>
<description>Binding to show the screen magnifier</description>
</key>
<key name="screenreader" type="s">
<default>'&lt;Alt&gt;&lt;Super&gt;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>'&lt;Alt&gt;&lt;Super&gt;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>'&lt;Alt&gt;&lt;Super&gt;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>['', '&lt;Super&gt;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>['&lt;Control&gt;&lt;Alt&gt;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>['&lt;Super&gt;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>['&lt;Alt&gt;&lt;Super&gt;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>['&lt;Alt&gt;&lt;Super&gt;8']</default>
<summary>Toggle magnifier</summary>
<description>Binding to show the screen magnifier</description>
</key>
<key name="magnifier-zoom-in" type="as">
<default>['&lt;Alt&gt;&lt;Super&gt;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>['&lt;Alt&gt;&lt;Super&gt;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', '&lt;Ctrl&gt;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', '&lt;Ctrl&gt;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', '&lt;Ctrl&gt;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', '&lt;Ctrl&gt;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', '&lt;Ctrl&gt;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>['&lt;Alt&gt;XF86AudioLowerVolume', '&lt;Alt&gt;&lt;Ctrl&gt;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>['&lt;Alt&gt;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>['&lt;Alt&gt;XF86AudioRaiseVolume', '&lt;Alt&gt;&lt;Ctrl&gt;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>['&lt;Shift&gt;XF86AudioLowerVolume', '&lt;Ctrl&gt;&lt;Shift&gt;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>['&lt;Shift&gt;XF86AudioRaiseVolume', '&lt;Ctrl&gt;&lt;Shift&gt;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', '&lt;Ctrl&gt;&lt;Super&gt;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>['&lt;Super&gt;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>

View 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>

View file

@ -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>

View 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>

View file

@ -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 Microsofts ClearType, DirectWrite and Adobes 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 FreeTypes 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>

View 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>

View 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);
}

View 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 */

View 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 *) &register_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;
}

View 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

View 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;
}

View 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__ */

View 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);
}

View 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 */

View 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
)

View 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>

View 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>

View 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>

View 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
View 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
View 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')

View 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)
{
}

View 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 */

View 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);
}

View 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
)

View 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 ();
}

View 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;
}

View 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 */

View 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);
}

View 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 */

View 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);
}

View 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 */

View 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);
}

View 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 */

View 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;
}

View 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 */

View 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);
}

View 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
View 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
View 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)

Binary file not shown.

Binary file not shown.

View 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);
}

View 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__ */

View 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;
}

View 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 */

View 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);
}

View 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 */

View 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);
}

View 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__ */

View 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);
}

View 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__ */

View 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
View file

View 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
View 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

View 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)
{
}

View 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 */

View 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);
}

View 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
View 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);
}

View 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
)

View 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
View 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
View 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

View 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;
}

View 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
View 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
View 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

View 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;
}

View 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 */

View 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;
}

File diff suppressed because it is too large Load diff

View 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 */

View 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;
}

View 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)
{
}

View 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 */

View 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;
}

View 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