initial commit

This commit is contained in:
David Zeuthen 2008-05-08 22:29:38 -04:00
commit 37f9df9b05
42 changed files with 4941 additions and 0 deletions

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
David Zeuthen <davidz@redhat.com>

353
COPYING Normal file
View file

@ -0,0 +1,353 @@
Copyright (C) 2008 David Zeuthen <david@fubar.dk>
All Rights Reserved.
The DeviceKit-power source code is licensed to you under the GNU
General Public License. Either version 2 of the License, or (at your
option) any later version. The license is included below.
-- BEGIN GPLv2+ License ---
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, 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 St, 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.
-- END GPLv2+ License ---

93
HACKING Normal file
View file

@ -0,0 +1,93 @@
SCM
===
- anonymous checkouts
$ git clone git://git.freedesktop.org/git/DeviceKit-disks.git
- checkouts if you got an ssh account on fd.o (username@ is optional)
$ git clone ssh://[username@]git.freedesktop.org/git/DeviceKit-disks.git
- commit to local repository
$ git commit -a
- push local repository to master repository at fd.o (remember most patches
requires review at the mailing list)
$ git push
- pull changes from master repository at fd.o
$ git pull
- diff of working tree versus local repository
$ git diff
- diff of local repository vs. master repository at fd.o
synchronize with upstream repo:
$ git pull
(possibly merge changes)
generate the diff:
$ git diff origin HEAD
- influential environment variables (set these in e.g. .bash_profile)
export GIT_AUTHOR_NAME='Your Full Name'
export GIT_COMMITTER_NAME='Your Full Name'
export GIT_COMMITTER_EMAIL=youremail@domain.net
export GIT_AUTHOR_EMAIL=youremail@domain.net
- see also
http://www.kernel.org/pub/software/scm/git/docs/
Committing code
===
- Commit messages should be of the form (the five lines between the
lines starting with ===)
=== begin example commit ===
short explanation of the commit
Longer explanation explaining exactly what's changed, whether any
external or private interfaces changed, what bugs were fixed (with bug
tracker reference if applicable) and so forth. Be concise but not too brief.
=== end example commit ===
- Always add a brief description of the commit to the _first_ line of
the commit and terminate by two newlines (it will work without the
second newline, but that is not nice for the interfaces).
- First line (the brief description) must only be one sentence and
must not start with a capital letter. Don't use a trailing period
either.
- The main description (the body) is normal prose and should use normal
punctuation and capital letters where appropriate. Normally, for patches
sent to a mailing list it's copied from there.
- When committing code on behalf of others use the --author option, e.g.
git commit -a --author "Joe Coder <joe@coder.org>"
Coding Style
===
- Please follow the coding style already used.
- Write docs for all functions and structs and so on. We use gtkdoc format.
- All external interfaces (network protocols, file formats, etc.)
should have documented specifications sufficient to allow an
alternative implementation to be written. Our implementation should
be strict about specification compliance (should not for example
heuristically parse a file and accept not-well-formed
data). Avoiding heuristics is also important for security reasons;
if it looks funny, ignore it (or exit, or disconnect).

39
Makefile.am Normal file
View file

@ -0,0 +1,39 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = src doc tools policy po
# Creating ChangeLog from git log (taken from cairo/Makefile.am):
ChangeLog: $(srcdir)/ChangeLog
$(srcdir)/ChangeLog:
@if test -d "$(srcdir)/.git"; then \
(cd "$(srcdir)" && \
./missing --run git-log --stat) | fmt --split-only > $@.tmp \
&& mv -f $@.tmp $@ \
|| ($(RM) $@.tmp; \
echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \
(test -f $@ || echo git-log is required to generate this file >> $@)); \
else \
test -f $@ || \
(echo A git checkout and git-log is required to generate ChangeLog >&2 && \
echo A git checkout and git-log is required to generate this file >> $@); \
fi
EXTRA_DIST = \
HACKING \
mkinstalldirs \
ChangeLog \
intltool-extract.in \
intltool-merge.in \
intltool-update.in
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update
# xsltproc barfs on 'make distcheck'; disable for now
DISTCHECK_CONFIGURE_FLAGS=--disable-man-pages --disable-gtk-doc
clean-local :
rm -f *~

2
NEWS Normal file
View file

@ -0,0 +1,2 @@
TODO: for now see doc/TODO

2
README Normal file
View file

@ -0,0 +1,2 @@
TODO

51
acinclude.m4 Normal file
View file

@ -0,0 +1,51 @@
dnl GTK_DOC_CHECK borrowed from cairo, thanks!
dnl Usage:
dnl GTK_DOC_CHECK([minimum-gtk-doc-version])
AC_DEFUN([GTK_DOC_CHECK],
[
AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
dnl for overriding the documentation installation directory
AC_ARG_WITH(html-dir,
AC_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
[with_html_dir='${datadir}/gtk-doc/html'])
HTML_DIR="$with_html_dir"
AC_SUBST(HTML_DIR)
dnl enable/disable documentation building
AC_ARG_ENABLE(gtk-doc,
AC_HELP_STRING([--enable-gtk-doc],
[use gtk-doc to build documentation [default=yes]]),,
enable_gtk_doc=yes)
have_gtk_doc=no
if test x$enable_gtk_doc = xyes; then
if test -z "$PKG_CONFIG"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
fi
if test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists gtk-doc; then
have_gtk_doc=yes
fi
dnl do we want to do a version check?
ifelse([$1],[],,
[gtk_doc_min_version=$1
if test "$have_gtk_doc" = yes; then
AC_MSG_CHECKING([gtk-doc version >= $gtk_doc_min_version])
if $PKG_CONFIG --atleast-version $gtk_doc_min_version gtk-doc; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
have_gtk_doc=no
fi
fi
])
if test "$have_gtk_doc" != yes; then
enable_gtk_doc=no
fi
fi
AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL")
])

95
autogen.sh Executable file
View file

@ -0,0 +1,95 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
DIE=0
(test -f $srcdir/configure.in) || {
echo -n "**Error**: Directory $srcdir does not look like the"
echo " top-level package directory"
exit 1
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have autoconf installed."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have libtool installed."
echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have automake installed."
echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing aclocal. The version of automake"
echo "installed doesn't appear recent enough."
echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "**Warning**: I am going to run configure with no arguments."
echo "If you wish to pass any to it, please specify them on the"
echo $0 " command line."
echo
fi
case $CC in
xlc )
am_opt=--include-deps;;
esac
aclocalinclude="$ACLOCAL_FLAGS"
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
if test -z "$NO_LIBTOOLIZE" ; then
echo "Running libtoolize..."
libtoolize --force --copy
fi
fi
echo "Running aclocal $aclocalinclude ..."
aclocal $aclocalinclude
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
echo "Running autoheader..."
autoheader
fi
echo "Running automake --gnu -Wno-portability $am_opt ..."
automake --add-missing --gnu -Wno-portability $am_opt
echo "Running autoconf ..."
autoconf
intltoolize --copy --force --automake || exit 1
conf_flags="--enable-maintainer-mode --enable-gtk-doc"
if test x$NOCONFIGURE = x; then
echo "Running $srcdir/configure $conf_flags $@ ..."
$srcdir/configure $conf_flags "$@" \
&& echo "Now type make to compile." || exit 1
else
echo "Skipping configure process."
fi

165
configure.in Normal file
View file

@ -0,0 +1,165 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59c)
AC_INIT(DeviceKit-power, 001, david@fubar.dk)
AM_INIT_AUTOMAKE(DeviceKit-power, 001)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_ISC_POSIX
AC_PROG_CC
AM_PROG_CC_STDC
AC_HEADER_STDC
AM_PROG_LIBTOOL
AC_PROG_MAKE_SET
AC_PROG_LN_S
AC_SYS_LARGEFILE
AM_PROG_CC_C_O
# Taken from dbus
AC_ARG_ENABLE(ansi, [ --enable-ansi enable -ansi -pedantic gcc flags],enable_ansi=$enableval,enable_ansi=no)
AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode],enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE)
AC_ARG_ENABLE(man-pages, [ --enable-man-pages build manual pages],enable_man_pages=$enableval,enable_man_pages=yes)
if test "${enable_man_page}" != no; then
dnl
dnl Check for xsltproc
dnl
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
enable_man_pages=no
fi
fi
AM_CONDITIONAL(MAN_PAGES_ENABLED, test x$enable_man_pages = xyes)
GTK_DOC_CHECK([1.3])
#### gcc warning flags
if test "x$GCC" = "xyes"; then
changequote(,)dnl
case " $CFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wcast-align[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wcast-align" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
esac
if test "x$enable_ansi" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -ansi" ;;
esac
case " $CFLAGS " in
*[\ \ ]-D_POSIX_C_SOURCE*) ;;
*) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199309L" ;;
esac
case " $CFLAGS " in
*[\ \ ]-D_BSD_SOURCE[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -D_BSD_SOURCE" ;;
esac
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -pedantic" ;;
esac
fi
changequote([,])dnl
fi
PKG_CHECK_MODULES(DEVKIT, [devkit-gobject >= 002])
AC_SUBST(DEVKIT_GOBJECT_CFLAGS)
AC_SUBST(DEVKIT_GOBJECT_LIBS)
PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.6.0])
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.0])
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
PKG_CHECK_MODULES(DBUS_GLIB, [dbus-glib-1 >= 0.74])
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)
PKG_CHECK_MODULES(POLKIT_DBUS, [polkit-dbus >= 0.7])
AC_SUBST(POLKIT_DBUS_CFLAGS)
AC_SUBST(POLKIT_DBUS_LIBS)
if test "x$GCC" = "xyes"; then
LDFLAGS="-Wl,--as-needed $LDFLAGS"
fi
IT_PROG_INTLTOOL([0.36.0])
GETTEXT_PACKAGE=DeviceKit-power
AC_SUBST([GETTEXT_PACKAGE])
AM_GLIB_GNU_GETTEXT
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[gettext domain])
AC_OUTPUT([
Makefile
src/Makefile
tools/Makefile
doc/Makefile
doc/version.xml
doc/man/Makefile
doc/dbus/Makefile
policy/Makefile
po/Makefile.in
])
dnl ==========================================================================
echo "
DeviceKit-power $VERSION
=======================
prefix: ${prefix}
libdir: ${libdir}
libexecdir: ${libexecdir}
bindir: ${bindir}
sbindir: ${sbindir}
datadir: ${datadir}
sysconfdir: ${sysconfdir}
localstatedir: ${localstatedir}
docdir: ${docdir}
compiler: ${CC}
cflags: ${CFLAGS}
cppflags: ${CPPFLAGS}
xsltproc: ${XSLTPROC}
Maintainer mode: ${USE_MAINTAINER_MODE}
Building api docs: ${enable_gtk_doc}
Building man pages: ${enable_man_pages}
"

81
doc/Makefile.am Normal file
View file

@ -0,0 +1,81 @@
SUBDIRS = man dbus
NULL =
AUTOMAKE_OPTIONS = 1.7
# The name of the module.
DOC_MODULE=devkit-power
# The top-level SGML file.
DOC_MAIN_SGML_FILE=devkit-power-docs.xml
# Extra options to supply to gtkdoc-scan
SCAN_OPTIONS=--ignore-headers=config.h
# The directory containing the source code. Relative to $(srcdir)
DOC_SOURCE_DIR=../policy
# Used for dependencies
HFILE_GLOB=
#$(top_srcdir)/policy/*.h
CFILE_GLOB=
#$(top_srcdir)/policy/*.c
# Headers to ignore
IGNORE_HFILES= \
$(NULL)
# CFLAGS and LDFLAGS for compiling scan program. Only needed
# if $(DOC_MODULE).types is non-empty.
INCLUDES = \
$(DBUS_GLIB_CFLAGS) \
$(GLIB_CFLAGS) \
-I$(top_srcdir)/policy \
-I$(top_builddir)/policy \
$(NULL)
GTKDOC_LIBS = \
$(DBUS_GLIB_LIBS) \
$(NULL)
# Extra options to supply to gtkdoc-mkdb
MKDB_OPTIONS=--sgml-mode --output-format=xml
# Extra options to supply to gtkdoc-mktmpl
MKTMPL_OPTIONS=
# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE)
content_files = \
version.xml \
man/devkit-power.xml \
man/devkit-power-daemon.xml \
man/DeviceKit-power.xml \
dbus/org.freedesktop.DeviceKit.Power.ref.xml \
dbus/org.freedesktop.DeviceKit.Power.Source.ref.xml \
$(NULL)
# Images to copy into HTML directory
HTML_IMAGES = \
$(NULL)
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=
MAINTAINERCLEANFILES = \
*~ \
Makefile.in \
devkit-power.types \
devkit-power-*.txt \
$(NULL)
if ENABLE_GTK_DOC
include $(top_srcdir)/gtk-doc.make
else
EXTRA_DIST =
endif
# Version information for marking the documentation
EXTRA_DIST += version.xml.in

34
doc/TODO Normal file
View file

@ -0,0 +1,34 @@
------------------------------------------------------------------------
- Current dependencies
------------------------------------------------------------------------
- DeviceKit from git
- http://gitweb.freedesktop.org/?p=users/david/DeviceKit.git
- http://people.freedesktop.org/~david/DK/F9/src/DeviceKit-002-0.git20080506.fc9.src.rpm
- D-Bus GLib 0.74 with some patches
- necessary changes are already committed upstream
- See Fedora 9 / Rawhide package for the patches needed
- PolicyKit >= 0.8
- D-Bus >= 1.1.20
------------------------------------------------------------------------
- TODO List (TODO: this section is incomplete)
------------------------------------------------------------------------
Before (next) release:
- General project management tasks
- review licenses, NEWS, TODO, HACKING etc. file
------------------------------------------------------------------------
- Current features (TODO: this section is incomplete)
------------------------------------------------------------------------
------------------------------------------------------------------------
- Future features (TODO: this section is incomplete)
------------------------------------------------------------------------

15
doc/dbus/Makefile.am Normal file
View file

@ -0,0 +1,15 @@
all : org.freedesktop.DeviceKit.Power.ref.xml org.freedesktop.DeviceKit.Power.Source.ref.xml
org.freedesktop.DeviceKit.Power.ref.xml : $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml $(top_srcdir)/doc/dbus/spec-to-docbook.xsl
echo "<?xml version=\"1.0\"?>""<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">" > $@
$(XSLTPROC) $(top_srcdir)/doc/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@
org.freedesktop.DeviceKit.Power.Source.ref.xml : $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.Source.xml $(top_srcdir)/doc/dbus/spec-to-docbook.xsl
echo "<?xml version=\"1.0\"?>""<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">" > $@
$(XSLTPROC) $(top_srcdir)/doc/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@
EXTRA_DIST = spec-to-docbook.xsl dbus-introspect-docs.dtd
clean-local :
rm -f *~ *.ref.xml

View file

@ -0,0 +1,32 @@
<!-- DTD for D-Bus Introspection Documentation -->
<!ELEMENT doc (summary?,description?,errors?,permission?,since?,deprecated,seealso?)>
<!ELEMENT summary (#PCDATA|ref)*>
<!ELEMENT description (#PCDATA|para|example)*>
<!ELEMENT errors (error)*>
<!ELEMENT permission (#PCDATA|ref|para)*>
<!ELEMENT since EMPTY>
<!ATTLIST since version CDATA #REQUIRED>
<!ELEMENT deprecated (#PCDATA|ref)>
<!ATTLIST deprecated version CDATA #REQUIRED>
<!ATTLIST deprecated instead CDATA #REQUIRED>
<!ELEMENT seealso (ref+)>
<!ELEMENT error (#PCDATA|para)*>
<!ATTLIST error name CDATA #REQUIRED>
<!ELEMENT para (#PCDATA|example|code|list|ref)*>
<!ELEMENT example (#PCDATA|para|code|ref)*>
<!ATTLIST language (c|glib|python|shell) #REQUIRED>
<!ATTLIST title CDATA #IMPLIED>
<!ELEMENT list (item*)>
<!ATTLIST list type (bullet|number) #REQUIRED>
<!ELEMENT item (term|definition)*>
<!ELEMENT term (#PCDATA|ref)*>
<!ELEMENT definition (#PCDATA|para)*>
<!ELEMENT code (#PCDATA)>
<!ATTLIST code lang CDATA #IMPLIED>
<!ELEMENT ref CDATA>
<!ATTLIST ref type (parameter|arg|signal|method|interface) #REQUIRED>
<!ATTLIST ref to CDATA #REQUIRED>

View file

@ -0,0 +1,543 @@
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"
exclude-result-prefixes="doc">
<!--
Convert D-Bus Glib xml into DocBook refentries
Copyright (C) 2007 William Jon McCann
License: GPL
-->
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:variable name="interface" select="//interface/@name"/>
<xsl:variable name="basename">
<xsl:call-template name="interface-basename">
<xsl:with-param name="str" select="$interface"/>
</xsl:call-template>
</xsl:variable>
<refentry><xsl:attribute name="id"><xsl:value-of select="$basename"/></xsl:attribute>
<refmeta>
<refentrytitle role="top_of_page"><xsl:value-of select="//interface/@name"/></refentrytitle>
</refmeta>
<refnamediv>
<refname><xsl:value-of select="//interface/@name"/></refname>
<refpurpose><xsl:value-of select="$basename"/> interface</refpurpose>
</refnamediv>
<refsynopsisdiv role="synopsis">
<title role="synopsis.title">Methods</title>
<synopsis>
<xsl:call-template name="methods-synopsis">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</synopsis>
</refsynopsisdiv>
<xsl:choose>
<xsl:when test="count(///signal) > 0">
<refsect1 role="signal_proto">
<title role="signal_proto.title">Signals</title>
<synopsis>
<xsl:call-template name="signals-synopsis">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</synopsis>
</refsect1>
</xsl:when>
</xsl:choose>
<refsect1 role="impl_interfaces">
<title role="impl_interfaces.title">Implemented Interfaces</title>
<para>
Objects implementing <xsl:value-of select="$interface"/> also implements
org.freedesktop.DBus.Introspectable,
org.freedesktop.DBus.Properties
</para>
</refsect1>
<xsl:choose>
<xsl:when test="count(///property) > 0">
<refsect1 role="properties">
<title role="properties.title">Properties</title>
<synopsis>
<xsl:call-template name="properties-synopsis">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</synopsis>
</refsect1>
</xsl:when>
</xsl:choose>
<refsect1 role="desc">
<title role="desc.title">Description</title>
<para>
<xsl:apply-templates select="//interface/doc:doc"/>
</para>
</refsect1>
<refsect1 role="details">
<title role="details.title">Details</title>
<xsl:call-template name="method-details">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</refsect1>
<xsl:choose>
<xsl:when test="count(///signal) > 0">
<refsect1 role="signals">
<title role="signals.title">Signal Details</title>
<xsl:call-template name="signal-details">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</refsect1>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="count(///property) > 0">
<refsect1 role="property_details">
<title role="property_details.title">Property Details</title>
<xsl:call-template name="property-details">
<xsl:with-param name="basename" select="$basename"/>
</xsl:call-template>
</refsect1>
</xsl:when>
</xsl:choose>
</refentry>
</xsl:template>
<xsl:template name="property-doc">
<xsl:apply-templates select="doc:doc/doc:description"/>
<variablelist role="params">
<xsl:for-each select="arg">
<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
<xsl:apply-templates select="doc:doc/doc:since"/>
<xsl:apply-templates select="doc:doc/doc:deprecated"/>
<xsl:apply-templates select="doc:doc/doc:permission"/>
<xsl:apply-templates select="doc:doc/doc:seealso"/>
</xsl:template>
<xsl:template name="property-details">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///property">
<refsect2>
<title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute></anchor>The "<xsl:value-of select="@name"/>" property</title>
<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
<programlisting>'<xsl:value-of select="@name"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="2"/></xsl:call-template>
<xsl:call-template name="property-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/></xsl:call-template></programlisting>
</refsect2>
<xsl:call-template name="property-doc"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="signal-doc">
<xsl:apply-templates select="doc:doc/doc:description"/>
<variablelist role="params">
<xsl:for-each select="arg">
<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
<xsl:apply-templates select="doc:doc/doc:since"/>
<xsl:apply-templates select="doc:doc/doc:deprecated"/>
<xsl:apply-templates select="doc:doc/doc:permission"/>
<xsl:apply-templates select="doc:doc/doc:seealso"/>
</xsl:template>
<xsl:template name="signal-details">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///signal">
<refsect2>
<title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute></anchor>The <xsl:value-of select="@name"/> signal</title>
<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
</refsect2>
<xsl:call-template name="signal-doc"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="doc:code">
<programlisting>
<xsl:apply-templates />
</programlisting>
</xsl:template>
<xsl:template match="doc:tt">
<literal>
<xsl:apply-templates />
</literal>
</xsl:template>
<xsl:template match="doc:i">
<emphasis>
<xsl:apply-templates />
</emphasis>
</xsl:template>
<xsl:template match="doc:b">
<emphasis role="bold">
<xsl:apply-templates />
</emphasis>
</xsl:template>
<xsl:template match="doc:ulink">
<ulink>
<xsl:attribute name="url"><xsl:value-of select="@url"/></xsl:attribute>
<xsl:value-of select="."/>
</ulink>
</xsl:template>
<xsl:template match="doc:summary">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="doc:example">
<informalexample>
<xsl:apply-templates />
</informalexample>
</xsl:template>
<xsl:template name="listitems-do-term">
<xsl:param name="str"/>
<xsl:choose>
<xsl:when test="string-length($str) > 0">
<emphasis role="bold"><xsl:value-of select="$str"/>: </emphasis>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="do-listitems">
<xsl:for-each select="doc:item">
<listitem>
<xsl:call-template name="listitems-do-term"><xsl:with-param name="str" select="doc:term"/></xsl:call-template>
<xsl:apply-templates select="doc:definition"/>
</listitem>
</xsl:for-each>
</xsl:template>
<xsl:template match="doc:list">
<para>
<xsl:choose>
<xsl:when test="contains(@type,'number')">
<orderedlist>
<xsl:call-template name="do-listitems"/>
</orderedlist>
</xsl:when>
<xsl:otherwise>
<itemizedlist>
<xsl:call-template name="do-listitems"/>
</itemizedlist>
</xsl:otherwise>
</xsl:choose>
</para>
</xsl:template>
<xsl:template match="doc:para">
<para>
<xsl:apply-templates />
</para>
</xsl:template>
<xsl:template match="doc:description">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="doc:since">
<para role="since">Since <xsl:value-of select="@version"/>
</para>
</xsl:template>
<xsl:template match="doc:deprecated">
<xsl:variable name="name" select="../../@name"/>
<xsl:variable name="parent">
<xsl:call-template name="interface-basename">
<xsl:with-param name="str" select="../../../@name"/>/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type" select="name(../..)"/>
<para role="deprecated">
<warning><para><literal><xsl:value-of select="$name"/></literal> is deprecated since version <xsl:value-of select="@version"/> and should not be used in newly-written code. Use
<xsl:variable name="to">
<xsl:choose>
<xsl:when test="contains($type,'property')">
<xsl:value-of select="$parent"/>:<xsl:value-of select="@instead"/>
</xsl:when>
<xsl:when test="contains($type,'signal')">
<xsl:value-of select="$parent"/>::<xsl:value-of select="@instead"/>
</xsl:when>
<xsl:when test="contains($type,'method')">
<xsl:value-of select="$parent"/>.<xsl:value-of select="@instead"/>
</xsl:when>
<xsl:when test="contains($type,'interface')">
<xsl:value-of select="@instead"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@instead"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="create-link">
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="to" select="$to"/>
<xsl:with-param name="val" select="@instead"/>
</xsl:call-template>
instead.</para></warning>
</para>
</xsl:template>
<xsl:template match="doc:permission">
<para role="permission">
<xsl:apply-templates />
</para>
</xsl:template>
<xsl:template match="doc:errors">
<para role="errors">
<xsl:apply-templates />
</para>
</xsl:template>
<xsl:template match="doc:seealso">
<para>
See also:
<xsl:apply-templates />
</para>
</xsl:template>
<xsl:template name="create-link">
<xsl:param name="type"/>
<xsl:param name="to"/>
<xsl:param name="val"/>
<xsl:choose>
<xsl:when test="contains($type,'property')">
<link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
</xsl:when>
<xsl:when test="contains($type,'signal')">
<link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
</xsl:when>
<xsl:when test="contains($type,'method')">
<link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><function><xsl:value-of select="$val"/></function></link>
</xsl:when>
<xsl:when test="contains($type,'interface')">
<link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><xsl:value-of select="$val"/></link>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="doc:ref">
<xsl:call-template name="create-link">
<xsl:with-param name="type" select="@type"/>
<xsl:with-param name="to" select="@to"/>
<xsl:with-param name="val" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="method-doc">
<xsl:apply-templates select="doc:doc/doc:description"/>
<variablelist role="params">
<xsl:for-each select="arg">
<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
<listitem><simpara><xsl:apply-templates select="doc:doc/doc:summary"/></simpara></listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
<xsl:apply-templates select="doc:doc/doc:since"/>
<xsl:apply-templates select="doc:doc/doc:deprecated"/>
<xsl:choose>
<xsl:when test="count(doc:doc/doc:errors) > 0">
<refsect3>
<title>Errors</title>
<variablelist role="errors">
<xsl:for-each select="doc:doc/doc:errors/doc:error">
<varlistentry>
<term><parameter><xsl:value-of select="@name"/></parameter>:</term>
<listitem><simpara><xsl:apply-templates select="."/></simpara></listitem>
</varlistentry>
</xsl:for-each>
</variablelist>
</refsect3>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="count(doc:doc/doc:permission) > 0">
<refsect3>
<title>Permissions</title>
<xsl:apply-templates select="doc:doc/doc:permission"/>
</refsect3>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="doc:doc/doc:seealso"/>
</xsl:template>
<xsl:template name="method-details">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///method">
<refsect2>
<title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute></anchor><xsl:value-of select="@name"/> ()</title>
<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="method-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
</refsect2>
<xsl:call-template name="method-doc"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="properties-synopsis">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="///property/@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///property">
<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute>'<xsl:value-of select="@name"/>'</link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template> <xsl:call-template name="property-args"><xsl:with-param name="indent" select="$longest + 2"/></xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="signals-synopsis">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="///signal/@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///signal">
<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="///signal"/></xsl:call-template>)
</xsl:for-each>
</xsl:template>
<xsl:template name="methods-synopsis">
<xsl:param name="basename"/>
<xsl:variable name="longest">
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="///method/@name"/>
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="///method">
<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="method-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="///method"/></xsl:call-template>)
</xsl:for-each>
</xsl:template>
<xsl:template name="method-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg"><xsl:value-of select="@direction"/>
<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="4 - string-length(@direction)"/></xsl:call-template>'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="signal-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg">'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="property-args"><xsl:param name="indent"/>
<xsl:value-of select="@access"/><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="9 - string-length(@access) + 1"/></xsl:call-template>'<xsl:value-of select="@type"/>'
</xsl:template>
<xsl:template name="pad-spaces">
<xsl:param name="width"/>
<xsl:variable name="spaces" xml:space="preserve"> </xsl:variable>
<xsl:value-of select="substring($spaces,1,$width)"/>
</xsl:template>
<xsl:template name="find-longest">
<xsl:param name="set"/>
<xsl:param name="index" select="1"/>
<xsl:param name="longest" select="0"/>
<xsl:choose>
<xsl:when test="$index > count($set)">
<!--finished looking-->
<xsl:value-of select="$longest"/>
</xsl:when>
<xsl:when test="string-length($set[$index])>$longest">
<!--found new longest-->
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="$set"/>
<xsl:with-param name="index" select="$index + 1"/>
<xsl:with-param name="longest" select="string-length($set[$index])"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!--this isn't any longer-->
<xsl:call-template name="find-longest">
<xsl:with-param name="set" select="$set"/>
<xsl:with-param name="index" select="$index + 1"/>
<xsl:with-param name="longest" select="$longest"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="interface-basename">
<xsl:param name="str"/>
<xsl:choose>
<xsl:when test="contains($str,'.')">
<xsl:call-template name="interface-basename">
<xsl:with-param name="str" select="substring-after($str,'.')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

94
doc/devkit-power-docs.xml Normal file
View file

@ -0,0 +1,94 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<title>DeviceKit-power Reference Manual</title>
<releaseinfo>Version &version;</releaseinfo>
<authorgroup>
<author>
<firstname>David</firstname>
<surname>Zeuthen</surname>
<affiliation>
<address>
<email>david@fubar.dk</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2008</year>
<holder>The DeviceKit-power Authors</holder>
</copyright>
<legalnotice>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the <citetitle>GNU Free
Documentation License</citetitle>, Version 1.1 or any later
version published by the Free Software Foundation with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. You may obtain a copy of the <citetitle>GNU Free
Documentation License</citetitle> from the Free Software
Foundation by visiting <ulink type="http"
url="http://www.fsf.org">their Web site</ulink> or by writing
to:
<address>
The Free Software Foundation, Inc.,
<street>59 Temple Place</street> - Suite 330,
<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
<country>USA</country>
</address>
</para>
<para>
Many of the names used by companies to distinguish their
products and services are claimed as trademarks. Where those
names appear in any GNOME documentation, and those trademarks
are made aware to the members of the GNOME Documentation
Project, the names have been printed in caps or initial caps.
</para>
</legalnotice>
</bookinfo>
<reference id="ref-dbus">
<title>D-Bus API Reference</title>
<partintro>
<para>
This part documents the D-Bus interface used to access the
DeviceKit-power daemon.
</para>
</partintro>
<xi:include href="dbus/org.freedesktop.DeviceKit.Power.ref.xml"/>
<xi:include href="dbus/org.freedesktop.DeviceKit.Power.Source.ref.xml"/>
</reference>
<reference id="tools-fileformats">
<title>Manual Pages</title>
<partintro>
<para>
This part contains the manual pages distributed with DeviceKit-power.
</para>
</partintro>
<xi:include href="man/DeviceKit-power.xml"/>
<xi:include href="man/devkit-power-daemon.xml"/>
<xi:include href="man/devkit-power.xml"/>
</reference>
<index>
<title>Index</title>
</index>
<!-- License -->
<appendix id="license">
<title>License</title>
<para>
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../COPYING" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
</para>
</appendix>
</book>

View file

@ -0,0 +1,64 @@
<refentry id="DeviceKit-power.7">
<refentryinfo>
<title>DeviceKit-power</title>
<date>March 2008</date>
<productname>DeviceKit-power</productname>
</refentryinfo>
<refmeta>
<refentrytitle>DeviceKit-power</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo class="version"></refmiscinfo>
</refmeta>
<refnamediv>
<refname>DeviceKit-power</refname>
<refpurpose>System-wide Power Management</refpurpose>
</refnamediv>
<refsect1><title>DESCRIPTION</title>
<para>
DeviceKit-power provides an interface to enumerate power sources
on the system and control system-wide power management. Any
application can access
the <emphasis>org.freedesktop.DeviceKit.Power</emphasis> service
on the system message bus. Some operations (such as suspending
the system) is restricted using PolicyKit.
</para>
</refsect1>
<refsect1><title>AUTHOR</title>
<para>
Written by David Zeuthen <email>david@fubar.dk</email> with
a lot of help from many others.
</para>
</refsect1>
<refsect1>
<title>BUGS</title>
<para>
Please send bug reports to either the distribution or the
hal mailing list,
see <ulink url="http://lists.freedesktop.org/mailman/listinfo/hal"/>.
to subscribe.
</para>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>DeviceKit</refentrytitle><manvolnum>7</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>PolicyKit</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>devkit-power-daemon</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>devkit-power</refentrytitle><manvolnum>1</manvolnum>
</citerefentry>
</para>
</refsect1>
</refentry>

24
doc/man/Makefile.am Normal file
View file

@ -0,0 +1,24 @@
NULL =
if MAN_PAGES_ENABLED
man_MANS = \
devkit-power.1 \
devkit-power-daemon.8 \
DeviceKit-power.7 \
$(NULL)
%.1 %.7 %.8 : %.xml
$(XSLTPROC) -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
endif # MAN_PAGES_ENABLED
EXTRA_DIST= \
devkit-power.xml \
devkit-power-daemon.xml \
DeviceKit-power.xml \
$(NULL)
clean-local:
rm -f *~ *.[178]

View file

@ -0,0 +1,84 @@
<refentry id="devkit-power-daemon.8">
<refentryinfo>
<title>devkit-power-daemon</title>
<date>April 2008</date>
<productname>devkit-power-daemon</productname>
</refentryinfo>
<refmeta>
<refentrytitle>devkit-power-daemon</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="version"></refmiscinfo>
</refmeta>
<refnamediv>
<refname>devkit-power-daemon</refname>
<refpurpose>DeviceKit-power Daemon</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>devkit-power-daemon</command>
<arg><option>--help</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>DESCRIPTION</title>
<para>
<emphasis><refentrytitle>devkit-power-daemon</refentrytitle></emphasis> provides
the <emphasis>org.freedesktop.DeviceKit.Power</emphasis> service on the
system message bus. Users or administrators should never need to
start this daemon as it will be automatically started by
<citerefentry><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>
whenever an application calls into the <emphasis>org.freedesktop.DeviceKit.Power</emphasis>
service.
</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term><option>--help</option></term>
<listitem>
<para>
Show help options.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>AUTHOR</title>
<para>
Written by David Zeuthen <email>david@fubar.dk</email> with
a lot of help from many others.
</para>
</refsect1>
<refsect1>
<title>BUGS</title>
<para>
Please send bug reports to either the distribution or the
hal mailing list,
see <ulink url="http://lists.freedesktop.org/mailman/listinfo/hal"/>
on how to subscribe.
</para>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>DeviceKit-power</refentrytitle><manvolnum>7</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>devkit-power</refentrytitle><manvolnum>1</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum>
</citerefentry>,
</para>
</refsect1>
</refentry>

99
doc/man/devkit-power.xml Normal file
View file

@ -0,0 +1,99 @@
<refentry id="devkit-power.1">
<refentryinfo>
<title>devkit-power</title>
<date>April 2008</date>
<productname>devkit-power</productname>
</refentryinfo>
<refmeta>
<refentrytitle>devkit-power</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="version"></refmiscinfo>
</refmeta>
<refnamediv>
<refname>devkit-power</refname>
<refpurpose>DeviceKit-power command line tool</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>devkit-power</command>
<arg><option>--enumerate</option></arg>
<arg><option>--monitor</option></arg>
<arg><option>--monitor-detail</option></arg>
<arg><option>--help</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>DESCRIPTION</title>
<para>
<emphasis><refentrytitle>devkit-power</refentrytitle></emphasis> is a
simple command line client for the
<citerefentry><refentrytitle>DeviceKit-power</refentrytitle><manvolnum>7</manvolnum></citerefentry>
daemon. TODO: not fully documented.
</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term><option>--monitor</option></term>
<listitem>
<para>
Connect to the DeviceKit-power daemon and print a line
every time a power source is added, removed or changed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--monitor-detail</option></term>
<listitem>
<para>
Like <option>--monitor</option> but prints the full
details of the power source whenever an event happens.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--help</option></term>
<listitem>
<para>
Show help options.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>AUTHOR</title>
<para>
Written by David Zeuthen <email>david@fubar.dk</email> with
a lot of help from many others.
</para>
</refsect1>
<refsect1>
<title>BUGS</title>
<para>
Please send bug reports to either the distribution or the
hal mailing list,
see <ulink url="http://lists.freedesktop.org/mailman/listinfo/hal"/>
on how to subscribe.
</para>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>
<citerefentry>
<refentrytitle>devkit-power-daemon</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>DeviceKit-power</refentrytitle><manvolnum>7</manvolnum>
</citerefentry>,
</para>
</refsect1>
</refentry>

1
doc/version.xml Normal file
View file

@ -0,0 +1 @@
001

159
gtk-doc.make Normal file
View file

@ -0,0 +1,159 @@
# -*- mode: makefile -*-
####################################
# Everything below here is generic #
####################################
if GTK_DOC_USE_LIBTOOL
GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CFLAGS) $(CFLAGS)
GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS)
else
GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CFLAGS) $(CFLAGS)
GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS)
endif
# We set GPATH here; this gives us semantics for GNU make
# which are more like other make's VPATH, when it comes to
# whether a source that is a target of one rule is then
# searched for in VPATH/GPATH.
#
GPATH = $(srcdir)
TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
EXTRA_DIST = \
$(content_files) \
$(HTML_IMAGES) \
$(DOC_MAIN_SGML_FILE) \
$(DOC_MODULE)-sections.txt \
$(DOC_MODULE)-overrides.txt
DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \
$(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp
SCANOBJ_FILES = \
$(DOC_MODULE).args \
$(DOC_MODULE).hierarchy \
$(DOC_MODULE).interfaces \
$(DOC_MODULE).prerequisites \
$(DOC_MODULE).signals
CLEANFILES = $(SCANOBJ_FILES) $(DOC_MODULE)-unused.txt $(DOC_STAMPS)
if ENABLE_GTK_DOC
all-local: html-build.stamp
else
all-local:
endif
docs: html-build.stamp
#### scan ####
scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB)
@echo 'gtk-doc: Scanning header files'
@-chmod -R u+w $(srcdir)
cd $(srcdir) && \
gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \
CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
else \
cd $(srcdir) ; \
for i in $(SCANOBJ_FILES) ; do \
test -f $$i || touch $$i ; \
done \
fi
touch scan-build.stamp
$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
@true
#### templates ####
tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt
@echo 'gtk-doc: Rebuilding template files'
@-chmod -R u+w $(srcdir)
cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS)
touch tmpl-build.stamp
tmpl.stamp: tmpl-build.stamp
@true
tmpl/*.sgml:
@true
#### xml ####
sgml-build.stamp: tmpl.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files)
@echo 'gtk-doc: Building XML'
@-chmod -R u+w $(srcdir)
cd $(srcdir) && \
gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
touch sgml-build.stamp
sgml.stamp: sgml-build.stamp
@true
#### html ####
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
@echo 'gtk-doc: Building HTML'
@-chmod -R u+w $(srcdir)
rm -rf $(srcdir)/html
mkdir $(srcdir)/html
cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
@echo 'gtk-doc: Fixing cross-references'
cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
touch html-build.stamp
##############
clean-local:
rm -f *~ *.bak
rm -rf .libs
maintainer-clean-local: clean
cd $(srcdir) && rm -rf xml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
install-data-local:
installfiles=`echo $(srcdir)/html/*`; \
if test "$$installfiles" = '$(srcdir)/html/*'; \
then echo '-- Nothing to install' ; \
else \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR); \
for i in $$installfiles; do \
echo '-- Installing '$$i ; \
$(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \
done; \
echo '-- Installing $(srcdir)/html/index.sgml' ; \
$(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR) || :; \
fi
uninstall-local:
rm -f $(DESTDIR)$(TARGET_DIR)/*
#
# Require gtk-doc when making dist
#
if ENABLE_GTK_DOC
dist-check-gtkdoc:
else
dist-check-gtkdoc:
@echo "*** gtk-doc must be installed and enabled in order to make dist"
@false
endif
dist-hook: dist-check-gtkdoc dist-hook-local
mkdir $(distdir)/tmpl
mkdir $(distdir)/xml
mkdir $(distdir)/html
-cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl
-cp $(srcdir)/xml/*.xml $(distdir)/xml
cp $(srcdir)/html/* $(distdir)/html
if test -f $(srcdir)/$(DOC_MODULE).types; then \
cp $(srcdir)/$(DOC_MODULE).types $(distdir)/$(DOC_MODULE).types; \
fi
.PHONY : dist-hook-local docs

111
mkinstalldirs Executable file
View file

@ -0,0 +1,111 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# End:
# mkinstalldirs ends here

0
po/ChangeLog Normal file
View file

4
po/LINGUAS Normal file
View file

@ -0,0 +1,4 @@
# please keep this list sorted alphabetically
#

4
po/POTFILES.in Normal file
View file

@ -0,0 +1,4 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
[encoding: UTF-8]
policy/org.freedesktop.devicekit.power.policy.in

17
policy/Makefile.am Normal file
View file

@ -0,0 +1,17 @@
devkit_policydir = $(datadir)/PolicyKit/policy
dist_devkit_policy_DATA = \
org.freedesktop.devicekit.power.policy
@INTLTOOL_POLICY_RULE@
check:
polkit-policy-file-validate $(dist_devkit_policy_DATA)
clean-local :
rm -f *~
DISTCLEANFILES = $(dist_devkit_policy_DATA)
EXTRA_DIST = $(dist_devkit_policy_DATA:.policy=.policy.in)

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
<!--
Policy definitions for DeviceKit-power
Copyright (c) 2008 David Zeuthen <david@fubar.dk>
NOTE: If you make changes to this file, make sure to validate the file
using the polkit-policy-file-validate(1) tool. Changes made to this
file are instantly applied.
-->
<policyconfig>
<vendor>The DeviceKit-power Project</vendor>
<vendor_url>http://hal.freedesktop.org/docs/DeviceKit-power/</vendor_url>
<icon_name>system-suspend</icon_name>
<action id="org.freedesktop.devicekit.power.suspend">
<_description>Suspend the system to RAM</_description>
<_message>Authentication is required to suspend to system</_message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
</policyconfig>

82
src/Makefile.am Normal file
View file

@ -0,0 +1,82 @@
## Process this file with automake to produce Makefile.in
INCLUDES = \
-I$(top_builddir)/src -I$(top_srcdir)/src \
-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
-DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
$(DBUS_GLIB_CFLAGS) \
$(POLKIT_DBUS_CFLAGS) \
$(DEVKIT_CFLAGS) \
$(GLIB_CFLAGS)
BUILT_SOURCES = \
devkit-power-daemon-glue.h \
devkit-power-source-glue.h \
devkit-power-marshal.h devkit-power-marshal.c
devkit-power-marshal.h: devkit-power-marshal.list
glib-genmarshal $< --prefix=devkit_power_marshal --header > $@
devkit-power-marshal.c: devkit-power-marshal.list
echo "#include \"devkit-power-marshal.h\"" > $@ && glib-genmarshal $< --prefix=devkit_power_marshal --body >> $@
devkit-power-daemon-glue.h: org.freedesktop.DeviceKit.Power.xml Makefile.am
dbus-binding-tool --prefix=devkit_power_daemon --mode=glib-server --output=devkit-power-daemon-glue.h org.freedesktop.DeviceKit.Power.xml
devkit-power-source-glue.h: org.freedesktop.DeviceKit.Power.Source.xml Makefile.am
dbus-binding-tool --prefix=devkit_power_source --mode=glib-server --output=devkit-power-source-glue.h org.freedesktop.DeviceKit.Power.Source.xml
libexec_PROGRAMS = devkit-power-daemon
dbusifdir = $(datadir)/dbus-1/interfaces
dbusif_DATA = org.freedesktop.DeviceKit.Power.xml org.freedesktop.DeviceKit.Power.Source.xml
devkit_power_daemon_SOURCES = \
devkit-power-daemon.h devkit-power-daemon.c \
devkit-power-device.h devkit-power-device.c \
devkit-power-source.h devkit-power-source.c \
sysfs-utils.h sysfs-utils.c \
main.c \
$(BUILT_SOURCES)
devkit_power_daemon_CPPFLAGS = \
-I$(top_srcdir)/src \
-DG_LOG_DOMAIN=\"devkit-power-daemon\" \
$(DISABLE_DEPRECATED) \
$(AM_CPPFLAGS)
devkit_power_daemon_LDADD = \
$(DBUS_GLIB_LIBS) \
$(POLKIT_DBUS_LIBS) \
$(DEVKIT_LIBS)
servicedir = $(datadir)/dbus-1/system-services
service_in_files = org.freedesktop.DeviceKit.Power.service.in
service_DATA = $(service_in_files:.service.in=.service)
$(service_DATA): $(service_in_files) Makefile
@sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
dbusconfdir = $(sysconfdir)/dbus-1/system.d
dbusconf_in_files = org.freedesktop.DeviceKit.Power.conf.in
dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf)
$(dbusconf_DATA): $(dbusconf_in_files) Makefile
cp $< $@
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = org.freedesktop.DeviceKit.Power.xml \
org.freedesktop.DeviceKit.Power.Source.xml \
devkit-power-marshal.list \
$(service_in_files) \
$(dbusconf_in_files)
clean-local :
rm -f *~ $(service_DATA) $(dbusconf_DATA)

631
src/devkit-power-daemon.c Normal file
View file

@ -0,0 +1,631 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <devkit-gobject.h>
#include "devkit-power-daemon.h"
#include "devkit-power-device.h"
#include "devkit-power-daemon-glue.h"
#include "devkit-power-marshal.h"
/*--------------------------------------------------------------------------------------------------------------*/
enum
{
DEVICE_ADDED_SIGNAL,
DEVICE_REMOVED_SIGNAL,
DEVICE_CHANGED_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
struct DevkitPowerDaemonPrivate
{
DBusGConnection *system_bus_connection;
DBusGProxy *system_bus_proxy;
PolKitContext *pk_context;
PolKitTracker *pk_tracker;
GHashTable *map_native_path_to_device;
DevkitClient *devkit_client;
};
static void devkit_power_daemon_class_init (DevkitPowerDaemonClass *klass);
static void devkit_power_daemon_init (DevkitPowerDaemon *seat);
static void devkit_power_daemon_finalize (GObject *object);
G_DEFINE_TYPE (DevkitPowerDaemon, devkit_power_daemon, G_TYPE_OBJECT)
#define DEVKIT_POWER_DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVKIT_TYPE_POWER_DAEMON, DevkitPowerDaemonPrivate))
/*--------------------------------------------------------------------------------------------------------------*/
GQuark
devkit_power_daemon_error_quark (void)
{
static GQuark ret = 0;
if (ret == 0) {
ret = g_quark_from_static_string ("devkit_power_daemon_error");
}
return ret;
}
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
GType
devkit_power_daemon_error_get_type (void)
{
static GType etype = 0;
if (etype == 0)
{
static const GEnumValue values[] =
{
ENUM_ENTRY (DEVKIT_POWER_DAEMON_ERROR_GENERAL, "GeneralError"),
ENUM_ENTRY (DEVKIT_POWER_DAEMON_ERROR_NOT_SUPPORTED, "NotSupported"),
ENUM_ENTRY (DEVKIT_POWER_DAEMON_ERROR_NO_SUCH_DEVICE, "NoSuchDevice"),
{ 0, 0, 0 }
};
g_assert (DEVKIT_POWER_DAEMON_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
etype = g_enum_register_static ("DevkitPowerDaemonError", values);
}
return etype;
}
static GObject *
devkit_power_daemon_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties)
{
DevkitPowerDaemon *daemon;
DevkitPowerDaemonClass *klass;
klass = DEVKIT_POWER_DAEMON_CLASS (g_type_class_peek (DEVKIT_TYPE_POWER_DAEMON));
daemon = DEVKIT_POWER_DAEMON (
G_OBJECT_CLASS (devkit_power_daemon_parent_class)->constructor (type,
n_construct_properties,
construct_properties));
return G_OBJECT (daemon);
}
static void
devkit_power_daemon_class_init (DevkitPowerDaemonClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructor = devkit_power_daemon_constructor;
object_class->finalize = devkit_power_daemon_finalize;
g_type_class_add_private (klass, sizeof (DevkitPowerDaemonPrivate));
signals[DEVICE_ADDED_SIGNAL] =
g_signal_new ("device-added",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
signals[DEVICE_REMOVED_SIGNAL] =
g_signal_new ("device-removed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
signals[DEVICE_CHANGED_SIGNAL] =
g_signal_new ("device-changed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
dbus_g_object_type_install_info (DEVKIT_TYPE_POWER_DAEMON, &dbus_glib_devkit_power_daemon_object_info);
dbus_g_error_domain_register (DEVKIT_POWER_DAEMON_ERROR,
NULL,
DEVKIT_POWER_DAEMON_TYPE_ERROR);
}
static void
devkit_power_daemon_init (DevkitPowerDaemon *daemon)
{
daemon->priv = DEVKIT_POWER_DAEMON_GET_PRIVATE (daemon);
daemon->priv->map_native_path_to_device = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
}
static void
devkit_power_daemon_finalize (GObject *object)
{
DevkitPowerDaemon *daemon;
g_return_if_fail (object != NULL);
g_return_if_fail (DEVKIT_IS_POWER_DAEMON (object));
daemon = DEVKIT_POWER_DAEMON (object);
g_return_if_fail (daemon->priv != NULL);
if (daemon->priv->pk_context != NULL)
polkit_context_unref (daemon->priv->pk_context);
if (daemon->priv->pk_tracker != NULL)
polkit_tracker_unref (daemon->priv->pk_tracker);
if (daemon->priv->system_bus_proxy != NULL)
g_object_unref (daemon->priv->system_bus_proxy);
if (daemon->priv->system_bus_connection != NULL)
dbus_g_connection_unref (daemon->priv->system_bus_connection);
if (daemon->priv->devkit_client != NULL) {
g_object_unref (daemon->priv->devkit_client);
}
if (daemon->priv->map_native_path_to_device != NULL) {
g_hash_table_unref (daemon->priv->map_native_path_to_device);
}
G_OBJECT_CLASS (devkit_power_daemon_parent_class)->finalize (object);
}
static gboolean
pk_io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
{
int fd;
PolKitContext *pk_context = user_data;
fd = g_io_channel_unix_get_fd (channel);
polkit_context_io_func (pk_context, fd);
return TRUE;
}
static int
pk_io_add_watch (PolKitContext *pk_context, int fd)
{
guint id = 0;
GIOChannel *channel;
channel = g_io_channel_unix_new (fd);
if (channel == NULL)
goto out;
id = g_io_add_watch (channel, G_IO_IN, pk_io_watch_have_data, pk_context);
if (id == 0) {
g_io_channel_unref (channel);
goto out;
}
g_io_channel_unref (channel);
out:
return id;
}
static void
pk_io_remove_watch (PolKitContext *pk_context, int watch_id)
{
g_source_remove (watch_id);
}
static DBusHandlerResult
_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{
DevkitPowerDaemon *daemon = DEVKIT_POWER_DAEMON (user_data);
const char *interface;
interface = dbus_message_get_interface (message);
if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
/* pass NameOwnerChanged signals from the bus to PolKitTracker */
polkit_tracker_dbus_func (daemon->priv->pk_tracker, message);
}
if (interface != NULL && g_str_has_prefix (interface, "org.freedesktop.ConsoleKit")) {
/* pass ConsoleKit signals to PolKitTracker */
polkit_tracker_dbus_func (daemon->priv->pk_tracker, message);
}
/* other filters might want to process this message too */
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void device_add (DevkitPowerDaemon *daemon, DevkitDevice *d, gboolean emit_event);
static void device_remove (DevkitPowerDaemon *daemon, DevkitDevice *d);
static void
device_changed (DevkitPowerDaemon *daemon, DevkitDevice *d, gboolean synthesized)
{
DevkitPowerDevice *device;
const char *native_path;
native_path = devkit_device_get_native_path (d);
device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path);
if (device != NULL) {
if (!devkit_power_device_changed (device, d, synthesized)) {
g_print ("changed triggered remove on %s\n", native_path);
device_remove (daemon, d);
} else {
g_print ("changed %s\n", native_path);
}
} else {
g_print ("treating change event as add on %s\n", native_path);
device_add (daemon, d, TRUE);
}
}
static gboolean
device_went_away_remove_cb (gpointer key, gpointer value, gpointer user_data)
{
if (value == user_data) {
g_print ("removed %s\n", (char *) key);
return TRUE;
}
return FALSE;
}
static void
device_went_away (gpointer user_data, GObject *where_the_object_was)
{
DevkitPowerDaemon *daemon = DEVKIT_POWER_DAEMON (user_data);
g_hash_table_foreach_remove (daemon->priv->map_native_path_to_device,
device_went_away_remove_cb,
where_the_object_was);
}
static void
device_add (DevkitPowerDaemon *daemon, DevkitDevice *d, gboolean emit_event)
{
DevkitPowerDevice *device;
const char *native_path;
native_path = devkit_device_get_native_path (d);
device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path);
if (device != NULL) {
/* we already have the device; treat as change event */
g_print ("treating add event as change event on %s\n", native_path);
device_changed (daemon, d, FALSE);
} else {
device = devkit_power_device_new (daemon, d);
if (device != NULL) {
/* only take a weak ref; the device will stay on the bus until
* it's unreffed. So if we ref it, it'll never go away. Stupid
* dbus-glib, no cookie for you.
*/
g_object_weak_ref (G_OBJECT (device), device_went_away, daemon);
g_hash_table_insert (daemon->priv->map_native_path_to_device,
g_strdup (native_path),
device);
g_print ("added %s\n", native_path);
if (emit_event) {
g_signal_emit (daemon, signals[DEVICE_ADDED_SIGNAL], 0,
devkit_power_device_get_object_path (device));
}
} else {
g_print ("ignoring add event on %s\n", native_path);
}
}
}
static void
device_remove (DevkitPowerDaemon *daemon, DevkitDevice *d)
{
DevkitPowerDevice *device;
const char *native_path;
native_path = devkit_device_get_native_path (d);
device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path);
if (device == NULL) {
g_print ("ignoring remove event on %s\n", native_path);
} else {
devkit_power_device_removed (device);
g_signal_emit (daemon, signals[DEVICE_REMOVED_SIGNAL], 0,
devkit_power_device_get_object_path (device));
g_object_unref (device);
}
}
static void
device_event_signal_handler (DevkitClient *client,
const char *action,
DevkitDevice *device,
gpointer user_data)
{
DevkitPowerDaemon *daemon = DEVKIT_POWER_DAEMON (user_data);
if (strcmp (action, "add") == 0) {
device_add (daemon, device, TRUE);
} else if (strcmp (action, "remove") == 0) {
device_remove (daemon, device);
} else if (strcmp (action, "change") == 0) {
device_changed (daemon, device, FALSE);
} else {
g_warning ("unhandled action '%s' on %s", action, devkit_device_get_native_path (device));
}
}
static gboolean
register_power_daemon (DevkitPowerDaemon *daemon)
{
DBusConnection *connection;
DBusError dbus_error;
GError *error = NULL;
const char *subsystems[] = {"power_supply", NULL};
daemon->priv->pk_context = polkit_context_new ();
polkit_context_set_io_watch_functions (daemon->priv->pk_context, pk_io_add_watch, pk_io_remove_watch);
if (!polkit_context_init (daemon->priv->pk_context, NULL)) {
g_critical ("cannot initialize libpolkit");
goto error;
}
error = NULL;
daemon->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (daemon->priv->system_bus_connection == NULL) {
if (error != NULL) {
g_critical ("error getting system bus: %s", error->message);
g_error_free (error);
}
goto error;
}
connection = dbus_g_connection_get_connection (daemon->priv->system_bus_connection);
daemon->priv->pk_tracker = polkit_tracker_new ();
polkit_tracker_set_system_bus_connection (daemon->priv->pk_tracker, connection);
polkit_tracker_init (daemon->priv->pk_tracker);
dbus_g_connection_register_g_object (daemon->priv->system_bus_connection, "/",
G_OBJECT (daemon));
daemon->priv->system_bus_proxy = dbus_g_proxy_new_for_name (daemon->priv->system_bus_connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
/* TODO FIXME: I'm pretty sure dbus-glib blows in a way that
* we can't say we're interested in all signals from all
* members on all interfaces for a given service... So we do
* this..
*/
dbus_error_init (&dbus_error);
/* need to listen to NameOwnerChanged */
dbus_bus_add_match (connection,
"type='signal'"
",interface='"DBUS_INTERFACE_DBUS"'"
",sender='"DBUS_SERVICE_DBUS"'"
",member='NameOwnerChanged'",
&dbus_error);
if (dbus_error_is_set (&dbus_error)) {
g_warning ("Cannot add match rule: %s: %s", dbus_error.name, dbus_error.message);
dbus_error_free (&dbus_error);
goto error;
}
/* need to listen to ConsoleKit signals */
dbus_bus_add_match (connection,
"type='signal',sender='org.freedesktop.ConsoleKit'",
&dbus_error);
if (dbus_error_is_set (&dbus_error)) {
g_warning ("Cannot add match rule: %s: %s", dbus_error.name, dbus_error.message);
dbus_error_free (&dbus_error);
goto error;
}
if (!dbus_connection_add_filter (connection,
_filter,
daemon,
NULL)) {
g_warning ("Cannot add D-Bus filter: %s: %s", dbus_error.name, dbus_error.message);
goto error;
}
/* connect to the DeviceKit daemon */
daemon->priv->devkit_client = devkit_client_new (subsystems);
if (!devkit_client_connect (daemon->priv->devkit_client, &error)) {
g_warning ("Couldn't open connection to DeviceKit daemon: %s", error->message);
g_error_free (error);
goto error;
}
g_signal_connect (daemon->priv->devkit_client, "device-event",
G_CALLBACK (device_event_signal_handler), daemon);
return TRUE;
error:
return FALSE;
}
DevkitPowerDaemon *
devkit_power_daemon_new (void)
{
DevkitPowerDaemon *daemon;
GError *error = NULL;
GList *devices;
GList *l;
const char *subsystems[] = {"power_supply", NULL};
daemon = DEVKIT_POWER_DAEMON (g_object_new (DEVKIT_TYPE_POWER_DAEMON, NULL));
if (!register_power_daemon (DEVKIT_POWER_DAEMON (daemon))) {
g_object_unref (daemon);
return NULL;
}
devices = devkit_client_enumerate_by_subsystem (daemon->priv->devkit_client,
subsystems,
&error);
if (error != NULL) {
g_warning ("Cannot enumerate devices: %s", error->message);
g_error_free (error);
g_object_unref (daemon);
return NULL;
}
for (l = devices; l != NULL; l = l->next) {
DevkitDevice *device = l->data;
device_add (daemon, device, FALSE);
}
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
g_list_free (devices);
return daemon;
}
PolKitCaller *
devkit_power_damon_local_get_caller_for_context (DevkitPowerDaemon *daemon,
DBusGMethodInvocation *context)
{
const char *sender;
GError *error;
DBusError dbus_error;
PolKitCaller *pk_caller;
sender = dbus_g_method_get_sender (context);
dbus_error_init (&dbus_error);
pk_caller = polkit_tracker_get_caller_from_dbus_name (daemon->priv->pk_tracker,
sender,
&dbus_error);
if (pk_caller == NULL) {
error = g_error_new (DEVKIT_POWER_DAEMON_ERROR,
DEVKIT_POWER_DAEMON_ERROR_GENERAL,
"Error getting information about caller: %s: %s",
dbus_error.name, dbus_error.message);
dbus_error_free (&dbus_error);
dbus_g_method_return_error (context, error);
g_error_free (error);
return NULL;
}
return pk_caller;
}
gboolean
devkit_power_damon_local_check_auth (DevkitPowerDaemon *daemon,
PolKitCaller *pk_caller,
const char *action_id,
DBusGMethodInvocation *context)
{
gboolean ret;
GError *error;
DBusError d_error;
PolKitAction *pk_action;
PolKitResult pk_result;
ret = FALSE;
pk_action = polkit_action_new ();
polkit_action_set_action_id (pk_action, action_id);
pk_result = polkit_context_is_caller_authorized (daemon->priv->pk_context,
pk_action,
pk_caller,
TRUE,
NULL);
if (pk_result == POLKIT_RESULT_YES) {
ret = TRUE;
} else {
dbus_error_init (&d_error);
polkit_dbus_error_generate (pk_action, pk_result, &d_error);
error = NULL;
dbus_set_g_error (&error, &d_error);
dbus_g_method_return_error (context, error);
g_error_free (error);
dbus_error_free (&d_error);
}
polkit_action_unref (pk_action);
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
#if 0
static gboolean
throw_error (DBusGMethodInvocation *context, int error_code, const char *format, ...)
{
GError *error;
va_list args;
char *message;
va_start (args, format);
message = g_strdup_vprintf (format, args);
va_end (args);
error = g_error_new (DEVKIT_POWER_DAEMON_ERROR,
error_code,
message);
dbus_g_method_return_error (context, error);
g_error_free (error);
g_free (message);
return TRUE;
}
#endif
/*--------------------------------------------------------------------------------------------------------------*/
/* exported methods */
static void
enumerate_cb (gpointer key, gpointer value, gpointer user_data)
{
DevkitPowerDevice *device = DEVKIT_POWER_DEVICE (value);
GPtrArray *object_paths = user_data;
g_ptr_array_add (object_paths, g_strdup (devkit_power_device_get_object_path (device)));
}
gboolean
devkit_power_daemon_enumerate_devices (DevkitPowerDaemon *daemon,
DBusGMethodInvocation *context)
{
GPtrArray *object_paths;
object_paths = g_ptr_array_new ();
g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_cb, object_paths);
dbus_g_method_return (context, object_paths);
g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL);
g_ptr_array_free (object_paths, TRUE);
return TRUE;
}

84
src/devkit-power-daemon.h Normal file
View file

@ -0,0 +1,84 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __DEVKIT_POWER_DAEMON_H__
#define __DEVKIT_POWER_DAEMON_H__
#include <glib-object.h>
#include <polkit-dbus/polkit-dbus.h>
#include <dbus/dbus-glib.h>
G_BEGIN_DECLS
#define DEVKIT_TYPE_POWER_DAEMON (devkit_power_daemon_get_type ())
#define DEVKIT_POWER_DAEMON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVKIT_TYPE_POWER_DAEMON, DevkitPowerDaemon))
#define DEVKIT_POWER_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DEVKIT_TYPE_POWER_DAEMON, DevkitPowerDaemonClass))
#define DEVKIT_IS_POWER_DAEMON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVKIT_TYPE_POWER_DAEMON))
#define DEVKIT_IS_POWER_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVKIT_TYPE_POWER_DAEMON))
#define DEVKIT_POWER_DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVKIT_TYPE_POWER_DAEMON, DevkitPowerDaemonClass))
typedef struct DevkitPowerDaemonPrivate DevkitPowerDaemonPrivate;
typedef struct
{
GObject parent;
DevkitPowerDaemonPrivate *priv;
} DevkitPowerDaemon;
typedef struct
{
GObjectClass parent_class;
} DevkitPowerDaemonClass;
typedef enum
{
DEVKIT_POWER_DAEMON_ERROR_GENERAL,
DEVKIT_POWER_DAEMON_ERROR_NOT_SUPPORTED,
DEVKIT_POWER_DAEMON_ERROR_NO_SUCH_DEVICE,
DEVKIT_POWER_DAEMON_NUM_ERRORS
} DevkitPowerDaemonError;
#define DEVKIT_POWER_DAEMON_ERROR devkit_power_daemon_error_quark ()
GType devkit_power_daemon_error_get_type (void);
#define DEVKIT_POWER_DAEMON_TYPE_ERROR (devkit_power_daemon_error_get_type ())
GQuark devkit_power_daemon_error_quark (void);
GType devkit_power_daemon_get_type (void);
DevkitPowerDaemon *devkit_power_daemon_new (void);
/* local methods */
PolKitCaller *devkit_power_damon_local_get_caller_for_context (DevkitPowerDaemon *daemon,
DBusGMethodInvocation *context);
gboolean devkit_power_damon_local_check_auth (DevkitPowerDaemon *daemon,
PolKitCaller *pk_caller,
const char *action_id,
DBusGMethodInvocation *context);
/* exported methods */
gboolean devkit_power_daemon_enumerate_devices (DevkitPowerDaemon *daemon,
DBusGMethodInvocation *context);
G_END_DECLS
#endif /* __DEVKIT_POWER_DAEMON_H__ */

92
src/devkit-power-device.c Normal file
View file

@ -0,0 +1,92 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <devkit-gobject.h>
#include <polkit-dbus/polkit-dbus.h>
#include "sysfs-utils.h"
#include "devkit-power-device.h"
#include "devkit-power-source.h"
static void devkit_power_device_class_init (DevkitPowerDeviceClass *klass);
static void devkit_power_device_init (DevkitPowerDevice *seat);
G_DEFINE_TYPE (DevkitPowerDevice, devkit_power_device, G_TYPE_OBJECT)
#define DEVKIT_POWER_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVKIT_TYPE_POWER_DEVICE, DevkitPowerDevicePrivate))
static void
devkit_power_device_class_init (DevkitPowerDeviceClass *klass)
{
}
static void
devkit_power_device_init (DevkitPowerDevice *device)
{
}
void
devkit_power_device_removed (DevkitPowerDevice *device)
{
DevkitPowerDeviceClass *klass = DEVKIT_POWER_DEVICE_GET_CLASS (device);
klass->removed (device);
}
DevkitPowerDevice *
devkit_power_device_new (DevkitPowerDaemon *daemon, DevkitDevice *d)
{
const char *subsys;
DevkitPowerDevice *device;
device = NULL;
subsys = devkit_device_get_subsystem (d);
if (strcmp (subsys, "power_supply") == 0) {
device = DEVKIT_POWER_DEVICE (devkit_power_source_new (daemon, d));
}
return device;
}
gboolean
devkit_power_device_changed (DevkitPowerDevice *device, DevkitDevice *d, gboolean synthesized)
{
DevkitPowerDeviceClass *klass = DEVKIT_POWER_DEVICE_GET_CLASS (device);
return (klass->changed (device, d, synthesized));
}
const char *
devkit_power_device_get_object_path (DevkitPowerDevice *device)
{
DevkitPowerDeviceClass *klass = DEVKIT_POWER_DEVICE_GET_CLASS (device);
return (klass->get_object_path (device));
}

68
src/devkit-power-device.h Normal file
View file

@ -0,0 +1,68 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __DEVKIT_POWER_DEVICE_H__
#define __DEVKIT_POWER_DEVICE_H__
#include <glib-object.h>
#include <polkit-dbus/polkit-dbus.h>
#include <devkit-gobject.h>
#include "devkit-power-daemon.h"
G_BEGIN_DECLS
#define DEVKIT_TYPE_POWER_DEVICE (devkit_power_device_get_type ())
#define DEVKIT_POWER_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVKIT_TYPE_POWER_DEVICE, DevkitPowerDevice))
#define DEVKIT_POWER_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DEVKIT_TYPE_POWER_DEVICE, DevkitPowerDeviceClass))
#define DEVKIT_IS_POWER_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVKIT_TYPE_POWER_DEVICE))
#define DEVKIT_IS_POWER_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVKIT_TYPE_POWER_DEVICE))
#define DEVKIT_POWER_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVKIT_TYPE_POWER_DEVICE, DevkitPowerDeviceClass))
typedef struct
{
GObject parent;
} DevkitPowerDevice;
typedef struct
{
GObjectClass parent_class;
/* vtable */
gboolean (*changed) (DevkitPowerDevice *device,
DevkitDevice *d,
gboolean synthesized);
void (*removed) (DevkitPowerDevice *device);
const char *(*get_object_path) (DevkitPowerDevice *device);
} DevkitPowerDeviceClass;
GType devkit_power_device_get_type (void);
DevkitPowerDevice *devkit_power_device_new (DevkitPowerDaemon *daemon,
DevkitDevice *d);
gboolean devkit_power_device_changed (DevkitPowerDevice *device,
DevkitDevice *d,
gboolean synthesized);
void devkit_power_device_removed (DevkitPowerDevice *device);
const char *devkit_power_device_get_object_path (DevkitPowerDevice *device);
G_END_DECLS
#endif /* __DEVKIT_POWER_DEVICE_H__ */

View file

@ -0,0 +1,2 @@
VOID:BOOLEAN,STRING,BOOLEAN,INT,INT,STRING,DOUBLE
VOID:STRING,BOOLEAN,STRING,BOOLEAN,INT,INT,STRING,DOUBLE

593
src/devkit-power-source.c Normal file
View file

@ -0,0 +1,593 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <math.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <devkit-gobject.h>
#include <polkit-dbus/polkit-dbus.h>
#include "sysfs-utils.h"
#include "devkit-power-source.h"
#include "devkit-power-marshal.h"
/*--------------------------------------------------------------------------------------------------------------*/
#include "devkit-power-source-glue.h"
typedef enum {
DEVKIT_POWER_SOURCE_TYPE_LINE_POWER,
DEVKIT_POWER_SOURCE_TYPE_BATTERY,
} DevkitPowerSourceType;
struct DevkitPowerSourcePrivate
{
DBusGConnection *system_bus_connection;
DBusGProxy *system_bus_proxy;
DevkitPowerDaemon *daemon;
DevkitDevice *d;
char *object_path;
char *native_path;
guint poll_timer_id;
char *vendor;
char *model;
char *serial;
GTimeVal update_time;
DevkitPowerSourceType type;
gboolean line_power_online;
double battery_energy;
double battery_energy_empty;
double battery_energy_empty_design;
double battery_energy_full;
double battery_energy_full_design;
double battery_energy_rate;
gint64 battery_time_to_empty;
gint64 battery_time_to_full;
double battery_percentage;
char *battery_technology;
};
static void devkit_power_source_class_init (DevkitPowerSourceClass *klass);
static void devkit_power_source_init (DevkitPowerSource *seat);
static void devkit_power_source_finalize (GObject *object);
static gboolean update (DevkitPowerSource *source);
enum
{
PROP_0,
PROP_NATIVE_PATH,
PROP_VENDOR,
PROP_MODEL,
PROP_SERIAL,
PROP_UPDATE_TIME,
PROP_TYPE,
PROP_LINE_POWER_ONLINE,
PROP_BATTERY_ENERGY,
PROP_BATTERY_ENERGY_EMPTY,
PROP_BATTERY_ENERGY_EMPTY_DESIGN,
PROP_BATTERY_ENERGY_FULL,
PROP_BATTERY_ENERGY_FULL_DESIGN,
PROP_BATTERY_ENERGY_RATE,
PROP_BATTERY_TIME_TO_EMPTY,
PROP_BATTERY_TIME_TO_FULL,
PROP_BATTERY_PERCENTAGE,
PROP_BATTERY_TECHNOLOGY,
};
enum
{
CHANGED_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (DevkitPowerSource, devkit_power_source, DEVKIT_TYPE_POWER_DEVICE)
#define DEVKIT_POWER_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVKIT_TYPE_POWER_SOURCE, DevkitPowerSourcePrivate))
static const char *devkit_power_source_get_object_path (DevkitPowerDevice *device);
static void devkit_power_source_removed (DevkitPowerDevice *device);
static gboolean devkit_power_source_changed (DevkitPowerDevice *device,
DevkitDevice *d,
gboolean synthesized);
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
DevkitPowerSource *source = DEVKIT_POWER_SOURCE (object);
switch (prop_id) {
case PROP_NATIVE_PATH:
g_value_set_string (value, source->priv->native_path);
break;
case PROP_VENDOR:
g_value_set_string (value, source->priv->vendor);
break;
case PROP_MODEL:
g_value_set_string (value, source->priv->model);
break;
case PROP_SERIAL:
g_value_set_string (value, source->priv->serial);
break;
case PROP_UPDATE_TIME:
g_value_set_uint64 (value, source->priv->update_time.tv_sec);
break;
case PROP_TYPE:
g_value_set_string (value, source->priv->type == DEVKIT_POWER_SOURCE_TYPE_LINE_POWER
? "line-power" : "battery");
break;
case PROP_LINE_POWER_ONLINE:
g_value_set_boolean (value, source->priv->line_power_online);
break;
case PROP_BATTERY_ENERGY:
g_value_set_double (value, source->priv->battery_energy);
break;
case PROP_BATTERY_ENERGY_EMPTY:
g_value_set_double (value, source->priv->battery_energy_empty);
break;
case PROP_BATTERY_ENERGY_EMPTY_DESIGN:
g_value_set_double (value, source->priv->battery_energy_empty_design);
break;
case PROP_BATTERY_ENERGY_FULL:
g_value_set_double (value, source->priv->battery_energy_full);
break;
case PROP_BATTERY_ENERGY_FULL_DESIGN:
g_value_set_double (value, source->priv->battery_energy_full_design);
break;
case PROP_BATTERY_ENERGY_RATE:
g_value_set_double (value, source->priv->battery_energy_rate);
break;
case PROP_BATTERY_TIME_TO_EMPTY:
g_value_set_int64 (value, source->priv->battery_time_to_empty);
break;
case PROP_BATTERY_TIME_TO_FULL:
g_value_set_int64 (value, source->priv->battery_time_to_full);
break;
case PROP_BATTERY_PERCENTAGE:
g_value_set_double (value, source->priv->battery_percentage);
break;
case PROP_BATTERY_TECHNOLOGY:
g_value_set_string (value, source->priv->battery_technology);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
devkit_power_source_class_init (DevkitPowerSourceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
DevkitPowerDeviceClass *device_class = DEVKIT_POWER_DEVICE_CLASS (klass);
object_class->finalize = devkit_power_source_finalize;
object_class->get_property = get_property;
device_class->changed = devkit_power_source_changed;
device_class->removed = devkit_power_source_removed;
device_class->get_object_path = devkit_power_source_get_object_path;
g_type_class_add_private (klass, sizeof (DevkitPowerSourcePrivate));
signals[CHANGED_SIGNAL] =
g_signal_new ("changed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
dbus_g_object_type_install_info (DEVKIT_TYPE_POWER_SOURCE, &dbus_glib_devkit_power_source_object_info);
g_object_class_install_property (
object_class,
PROP_NATIVE_PATH,
g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_VENDOR,
g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_MODEL,
g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_SERIAL,
g_param_spec_string ("serial", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_UPDATE_TIME,
g_param_spec_uint64 ("update-time", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_TYPE,
g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_LINE_POWER_ONLINE,
g_param_spec_boolean ("line-power-online", NULL, NULL, FALSE, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY,
g_param_spec_double ("battery-energy", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY_EMPTY,
g_param_spec_double ("battery-energy-empty", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY_EMPTY_DESIGN,
g_param_spec_double ("battery-energy-empty-design", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY_FULL,
g_param_spec_double ("battery-energy-full", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY_FULL_DESIGN,
g_param_spec_double ("battery-energy-full-design", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_ENERGY_RATE,
g_param_spec_double ("battery-energy-rate", NULL, NULL, -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_TIME_TO_EMPTY,
g_param_spec_int64 ("battery-time-to-empty", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_TIME_TO_FULL,
g_param_spec_int64 ("battery-time-to-full", NULL, NULL, -1, G_MAXINT64, -1, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_PERCENTAGE,
g_param_spec_double ("battery-percentage", NULL, NULL, -1, 100, -1, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
PROP_BATTERY_TECHNOLOGY,
g_param_spec_string ("battery-technology", NULL, NULL, NULL, G_PARAM_READABLE));
}
static void
devkit_power_source_init (DevkitPowerSource *source)
{
source->priv = DEVKIT_POWER_SOURCE_GET_PRIVATE (source);
source->priv->battery_time_to_empty = -1;
source->priv->battery_time_to_full = -1;
}
static void
devkit_power_source_finalize (GObject *object)
{
DevkitPowerSource *source;
g_return_if_fail (object != NULL);
g_return_if_fail (DEVKIT_IS_POWER_SOURCE (object));
source = DEVKIT_POWER_SOURCE (object);
g_return_if_fail (source->priv != NULL);
g_object_unref (source->priv->d);
g_object_unref (source->priv->daemon);
g_free (source->priv->native_path);
g_free (source->priv->vendor);
g_free (source->priv->model);
g_free (source->priv->serial);
if (source->priv->poll_timer_id > 0)
g_source_remove (source->priv->poll_timer_id);
G_OBJECT_CLASS (devkit_power_source_parent_class)->finalize (object);
}
static char *
compute_object_path_from_basename (const char *native_path_basename)
{
char *basename;
char *object_path;
unsigned int n;
/* TODO: need to be more thorough with making proper object
* names that won't make D-Bus crash. This is just to cope
* with dm-0...
*/
basename = g_path_get_basename (native_path_basename);
for (n = 0; basename[n] != '\0'; n++)
if (basename[n] == '-')
basename[n] = '_';
object_path = g_build_filename ("/sources/", basename, NULL);
g_free (basename);
return object_path;
}
static char *
compute_object_path (const char *native_path)
{
char *basename;
char *object_path;
basename = g_path_get_basename (native_path);
object_path = compute_object_path_from_basename (basename);
g_free (basename);
return object_path;
}
static gboolean
register_power_source (DevkitPowerSource *source)
{
DBusConnection *connection;
GError *error = NULL;
source->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (source->priv->system_bus_connection == NULL) {
if (error != NULL) {
g_critical ("error getting system bus: %s", error->message);
g_error_free (error);
}
goto error;
}
connection = dbus_g_connection_get_connection (source->priv->system_bus_connection);
source->priv->object_path = compute_object_path (source->priv->native_path);
dbus_g_connection_register_g_object (source->priv->system_bus_connection,
source->priv->object_path,
G_OBJECT (source));
source->priv->system_bus_proxy = dbus_g_proxy_new_for_name (source->priv->system_bus_connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
return TRUE;
error:
return FALSE;
}
DevkitPowerSource *
devkit_power_source_new (DevkitPowerDaemon *daemon, DevkitDevice *d)
{
DevkitPowerSource *source;
const char *native_path;
source = NULL;
native_path = devkit_device_get_native_path (d);
source = DEVKIT_POWER_SOURCE (g_object_new (DEVKIT_TYPE_POWER_SOURCE, NULL));
source->priv->d = g_object_ref (d);
source->priv->daemon = g_object_ref (daemon);
source->priv->native_path = g_strdup (native_path);
if (sysfs_file_exists (native_path, "online")) {
source->priv->type = DEVKIT_POWER_SOURCE_TYPE_LINE_POWER;
} else {
source->priv->type = DEVKIT_POWER_SOURCE_TYPE_BATTERY;
}
if (!update (source)) {
g_object_unref (source);
source = NULL;
goto out;
}
if (! register_power_source (DEVKIT_POWER_SOURCE (source))) {
g_object_unref (source);
source = NULL;
goto out;
}
out:
return source;
}
static void
emit_changed (DevkitPowerSource *source)
{
g_print ("emitting changed on %s\n", source->priv->native_path);
g_signal_emit_by_name (source->priv->daemon,
"device-changed",
source->priv->object_path,
NULL);
g_signal_emit (source, signals[CHANGED_SIGNAL], 0);
}
static gboolean
devkit_power_source_changed (DevkitPowerDevice *device, DevkitDevice *d, gboolean synthesized)
{
DevkitPowerSource *source = DEVKIT_POWER_SOURCE (device);
gboolean keep_source;
g_object_unref (source->priv->d);
source->priv->d = g_object_ref (d);
keep_source = update (source);
/* this 'change' event might prompt us to remove the source */
if (!keep_source)
goto out;
/* no, it's good .. keep it */
emit_changed (source);
out:
return keep_source;
}
void
devkit_power_source_removed (DevkitPowerDevice *device)
{
}
static const char *
devkit_power_source_get_object_path (DevkitPowerDevice *device)
{
DevkitPowerSource *source = DEVKIT_POWER_SOURCE (device);
return source->priv->object_path;
}
/*--------------------------------------------------------------------------------------------------------------*/
static gboolean
update_line_power (DevkitPowerSource *source)
{
source->priv->line_power_online = sysfs_get_int (source->priv->native_path, "online");
return TRUE;
}
static gboolean
update_battery (DevkitPowerSource *source)
{
char *status;
gboolean is_charging;
gboolean is_discharging;
/* TODO: this needs to handle lots of special cases when certain
* files exist, it needs to prefer _avg to _now etc. etc. etc.
*
* This is just a very quick hack for now.
*/
status = g_strstrip (sysfs_get_string (source->priv->native_path, "status"));
is_charging = strcasecmp (status, "charging") == 0;
is_discharging = strcasecmp (status, "discharging") == 0;
source->priv->battery_energy =
sysfs_get_double (source->priv->native_path, "energy_now") / 1000000.0;
source->priv->battery_energy_full =
sysfs_get_double (source->priv->native_path, "energy_full") / 1000000.0;
source->priv->battery_energy_full_design =
sysfs_get_double (source->priv->native_path, "energy_full_design") / 1000000.0;
source->priv->battery_energy_rate =
fabs (sysfs_get_double (source->priv->native_path, "current_now") / 1000000.0);
if (is_charging)
source->priv->battery_energy_rate *= -1.0;
source->priv->battery_percentage = 100.0 * source->priv->battery_energy / source->priv->battery_energy_full;
if (source->priv->battery_percentage < 0)
source->priv->battery_percentage = 0;
if (source->priv->battery_percentage > 100.0)
source->priv->battery_percentage = 100.0;
g_free (status);
return TRUE;
}
static gboolean
_poll_battery (DevkitPowerSource *source)
{
g_warning ("No updates on source %s for 30 seconds; forcing update", source->priv->native_path);
source->priv->poll_timer_id = 0;
update (source);
emit_changed (source);
return FALSE;
}
static gboolean
update (DevkitPowerSource *source)
{
gboolean ret;
if (source->priv->poll_timer_id > 0) {
g_source_remove (source->priv->poll_timer_id);
source->priv->poll_timer_id = 0;
}
/* initial values */
if (source->priv->vendor == NULL) {
char *s;
s = g_strstrip (sysfs_get_string (source->priv->native_path, "technology"));
if (strcmp (s, "Unknown") != 0)
source->priv->battery_technology = s;
else
g_free (s);
source->priv->vendor = g_strstrip (sysfs_get_string (source->priv->native_path, "manufacturer"));
source->priv->model = g_strstrip (sysfs_get_string (source->priv->native_path, "model_name"));
source->priv->serial = g_strstrip (sysfs_get_string (source->priv->native_path, "serial_number"));
}
g_get_current_time (&(source->priv->update_time));
switch (source->priv->type) {
case DEVKIT_POWER_SOURCE_TYPE_LINE_POWER:
ret = update_line_power (source);
break;
case DEVKIT_POWER_SOURCE_TYPE_BATTERY:
ret = update_battery (source);
/* Seems that we don't get change uevents from the
* kernel; set up a timer to poll
*
* TODO: perhaps only do this if running on battery.
*/
source->priv->poll_timer_id = g_timeout_add_seconds (30, (GSourceFunc) _poll_battery, source);
break;
default:
g_assert_not_reached ();
break;
}
return ret;
}
/*--------------------------------------------------------------------------------------------------------------*/
gboolean
devkit_power_source_refresh (DevkitPowerSource *power_source,
DBusGMethodInvocation *context)
{
update (power_source);
dbus_g_method_return (context);
return TRUE;
}

64
src/devkit-power-source.h Normal file
View file

@ -0,0 +1,64 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __DEVKIT_POWER_SOURCE_H__
#define __DEVKIT_POWER_SOURCE_H__
#include <glib-object.h>
#include <polkit-dbus/polkit-dbus.h>
#include <devkit-gobject.h>
#include "devkit-power-daemon.h"
#include "devkit-power-device.h"
G_BEGIN_DECLS
#define DEVKIT_TYPE_POWER_SOURCE (devkit_power_source_get_type ())
#define DEVKIT_POWER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVKIT_TYPE_POWER_SOURCE, DevkitPowerSource))
#define DEVKIT_POWER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DEVKIT_TYPE_POWER_SOURCE, DevkitPowerSourceClass))
#define DEVKIT_IS_POWER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVKIT_TYPE_POWER_SOURCE))
#define DEVKIT_IS_POWER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVKIT_TYPE_POWER_SOURCE))
#define DEVKIT_POWER_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVKIT_TYPE_POWER_SOURCE, DevkitPowerSourceClass))
typedef struct DevkitPowerSourcePrivate DevkitPowerSourcePrivate;
typedef struct
{
DevkitPowerDevice parent;
DevkitPowerSourcePrivate *priv;
} DevkitPowerSource;
typedef struct
{
DevkitPowerDeviceClass parent_class;
} DevkitPowerSourceClass;
GType devkit_power_source_get_type (void);
DevkitPowerSource *devkit_power_source_new (DevkitPowerDaemon *daemon,
DevkitDevice *d);
/* exported methods */
gboolean devkit_power_source_refresh (DevkitPowerSource *power_source,
DBusGMethodInvocation *context);
G_END_DECLS
#endif /* __DEVKIT_POWER_SOURCE_H__ */

157
src/main.c Normal file
View file

@ -0,0 +1,157 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2007 David Zeuthen <david@fubar.dk>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <devkit-gobject.h>
#include "devkit-power-daemon.h"
#define NAME_TO_CLAIM "org.freedesktop.DeviceKit.Power"
static gboolean
acquire_name_on_proxy (DBusGProxy *bus_proxy)
{
GError *error;
guint result;
gboolean res;
gboolean ret;
ret = FALSE;
if (bus_proxy == NULL) {
goto out;
}
error = NULL;
res = dbus_g_proxy_call (bus_proxy,
"RequestName",
&error,
G_TYPE_STRING, NAME_TO_CLAIM,
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &result,
G_TYPE_INVALID);
if (! res) {
if (error != NULL) {
g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message);
g_error_free (error);
} else {
g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
}
goto out;
}
if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
if (error != NULL) {
g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message);
g_error_free (error);
} else {
g_warning ("Failed to acquire %s", NAME_TO_CLAIM);
}
goto out;
}
ret = TRUE;
out:
return ret;
}
int
main (int argc, char **argv)
{
GError *error;
GMainLoop *loop;
DevkitPowerDaemon *power_daemon;
GOptionContext *context;
DBusGProxy *bus_proxy;
DBusGConnection *bus;
int ret;
static GOptionEntry entries [] = {
{ NULL }
};
ret = 1;
g_type_init ();
context = g_option_context_new ("DeviceKit Power Daemon");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
error = NULL;
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (bus == NULL) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free (error);
goto out;
}
bus_proxy = dbus_g_proxy_new_for_name (bus,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
if (bus_proxy == NULL) {
g_warning ("Could not construct bus_proxy object; bailing out");
goto out;
}
if (!acquire_name_on_proxy (bus_proxy) ) {
g_warning ("Could not acquire name; bailing out");
goto out;
}
g_debug ("Starting devkit-power-daemon version %s", VERSION);
power_daemon = devkit_power_daemon_new ();
if (power_daemon == NULL) {
goto out;
}
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_object_unref (power_daemon);
g_main_loop_unref (loop);
ret = 0;
out:
return ret;
}

View file

@ -0,0 +1,228 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" [
<!ENTITY ERROR_GENERAL "org.freedesktop.DeviceKit.Disks.Power.Source.GeneralError">
]>
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.DeviceKit.Power.Source">
<doc:doc>
<doc:description>
<doc:para>
TODO: some explanatory text etc. etc. Mention that we
collect history to provide more precise values of
battery-time-to-empty, battery-time-to-full. Go into detail
with the algorithms.
</doc:para>
<doc:para>
TODO: do we need to export voltage and other things? Do we need to export raw data?
</doc:para>
<doc:para>
Unless otherwise noted, an empty string or the value 0 in a
property means not set.
</doc:para>
</doc:description>
</doc:doc>
<!-- ************************************************************ -->
<method name="Refresh">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<doc:doc>
<doc:description>
<doc:para>
Refreshes the data collected from the power source.
</doc:para>
</doc:description>
<doc:permission>Callers need the org.freedesktop.devicekit.power.refresh-power-source authorization</doc:permission>
<doc:errors>
<doc:error name="&ERROR_GENERAL;">if an error occured while refreshing</doc:error>
</doc:errors>
</doc:doc>
</method>
<!-- ************************************************************ -->
<signal name="Changed">
<doc:doc>
<doc:description>
<doc:para>
Some value on the power source changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<property name="native-path" type="s" access="read">
<doc:doc><doc:description><doc:para>
OS specific native path of the power source. On Linux this
is the sysfs path, for
example <doc:tt>/sys/devices/LNXSYSTM:00/device:00/PNP0C0A:00/power_supply/BAT0</doc:tt>. Is
blank if the device is being driven by a user space
driver.
</doc:para></doc:description></doc:doc>
</property>
<property name="vendor" type="s" access="read">
<doc:doc><doc:description><doc:para>
Name of the vendor of the battery.
</doc:para></doc:description></doc:doc>
</property>
<property name="model" type="s" access="read">
<doc:doc><doc:description><doc:para>
Name of the model of this battery.
</doc:para></doc:description></doc:doc>
</property>
<property name="serial" type="s" access="read">
<doc:doc><doc:description><doc:para>
Unique serial number of the battery.
</doc:para></doc:description></doc:doc>
</property>
<property name="update-time" type="t" access="read">
<doc:doc><doc:description><doc:para>
The point in time (seconds since the Epoch Jan 1, 1970
0:00 UTC) that data was read from the power source.
</doc:para></doc:description></doc:doc>
</property>
<property name="type" type="s" access="read">
<doc:doc><doc:description><doc:para>
Type of power source. Known values are "battery" and "line-power".
</doc:para></doc:description></doc:doc>
</property>
<property name="line-power-online" type="b" access="read">
<doc:doc><doc:description><doc:para>
Whether power is currently being provided through line power.
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "line-power".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy (measured in Wh) currently available in
the power source.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy-empty" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy (measured in Wh) in the power source when
it's considered to be empty.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy-empty-design" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy (measured in Wh) the power source is
designed to hold when it's considered to be empty.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy-full" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy (measured in Wh) in the power source when
it's considered full.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy-full-design" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy (measured in Wh) the power source is
designed to hold when it's considered full.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-energy-rate" type="d" access="read">
<doc:doc><doc:description><doc:para>
Amount of energy being drained from the source, measured
in W. If positive, the source is being discharged, if
negative it's being charged.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-time-to-empty" type="x" access="read">
<doc:doc><doc:description><doc:para>
Number of seconds until the power source is considered empty.
Is set to -1 if unknown.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-time-to-full" type="x" access="read">
<doc:doc><doc:description><doc:para>
Number of seconds until the power source is considered full.
Is set to -1 if unknown.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-percentage" type="d" access="read">
<doc:doc><doc:description><doc:para>
The amount of energy left in the power source expressed as
a percentage between 0 and 100. Typically this is the same as
(<doc:ref type="property" to="Source:battery-energy">battery-energy</doc:ref> -
<doc:ref type="property" to="Source:battery-energy-empty">battery-energy-empty</doc:ref>) /
(<doc:ref type="property" to="Source:battery-energy-full">battery-energy-full</doc:ref> -
<doc:ref type="property" to="Source:battery-energy-empty">battery-energy-empty</doc:ref>).
However, some primitive power sources are capable of only
reporting percentages and in this case the battery-energy-*
properties will be unset while this property is set.
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
<property name="battery-technology" type="s" access="read">
<doc:doc><doc:description><doc:para>
Technology used in the battery; known values are "Li-ion".
</doc:para><doc:para>
This property is only valid if the property
<doc:ref type="property" to="Source:type">type</doc:ref>
has the value "battery".
</doc:para></doc:description></doc:doc>
</property>
</interface>
</node>

View file

@ -0,0 +1,77 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.DeviceKit.Power">
<!-- ************************************************************ -->
<method name="EnumerateDevices">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="devices" direction="out" type="ao">
<doc:doc><doc:summary>An array of object paths for devices.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Enumerate all disks on the system.
</doc:para>
</doc:description>
</doc:doc>
</method>
<!-- ************************************************************ -->
<signal name="DeviceAdded">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was added.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device is added.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="DeviceRemoved">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was removed.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device is removed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
<signal name="DeviceChanged">
<arg name="device" type="o">
<doc:doc><doc:summary>Object path of device that was changed.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a device changed.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<!-- ************************************************************ -->
</interface>
</node>

203
src/sysfs-utils.c Normal file
View file

@ -0,0 +1,203 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include "sysfs-utils.h"
double
sysfs_get_double (const char *dir, const char *attribute)
{
double result;
char *contents;
char *filename;
result = 0.0;
filename = g_build_filename (dir, attribute, NULL);
if (g_file_get_contents (filename, &contents, NULL, NULL)) {
result = atof (contents);
g_free (contents);
}
g_free (filename);
return result;
}
gboolean
sysfs_file_contains (const char *dir, const char *attribute, const char *string)
{
gboolean result;
char *filename;
char *s;
result = FALSE;
filename = g_build_filename (dir, attribute, NULL);
if (g_file_get_contents (filename, &s, NULL, NULL)) {
result = (strstr(s, string) != NULL);
g_free (s);
}
g_free (filename);
return result;
}
char *
sysfs_get_string (const char *dir, const char *attribute)
{
char *result;
char *filename;
result = NULL;
filename = g_build_filename (dir, attribute, NULL);
if (!g_file_get_contents (filename, &result, NULL, NULL)) {
result = g_strdup ("");
}
g_free (filename);
return result;
}
int
sysfs_get_int (const char *dir, const char *attribute)
{
int result;
char *contents;
char *filename;
result = 0;
filename = g_build_filename (dir, attribute, NULL);
if (g_file_get_contents (filename, &contents, NULL, NULL)) {
result = atoi (contents);
g_free (contents);
}
g_free (filename);
return result;
}
guint64
sysfs_get_uint64 (const char *dir, const char *attribute)
{
guint64 result;
char *contents;
char *filename;
result = 0;
filename = g_build_filename (dir, attribute, NULL);
if (g_file_get_contents (filename, &contents, NULL, NULL)) {
result = atoll (contents);
g_free (contents);
}
g_free (filename);
return result;
}
gboolean
sysfs_file_exists (const char *dir, const char *attribute)
{
gboolean result;
char *filename;
result = FALSE;
filename = g_build_filename (dir, attribute, NULL);
if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
result = TRUE;
}
g_free (filename);
return result;
}
char *
_dupv8 (const char *s)
{
const char *end_valid;
if (!g_utf8_validate (s,
-1,
&end_valid)) {
g_warning ("The string '%s' is not valid UTF-8. Invalid characters begins at '%s'", s, end_valid);
return g_strndup (s, end_valid - s);
} else {
return g_strdup (s);
}
}
char *
sysfs_resolve_link (const char *dir, const char *attribute)
{
char *full_path;
char link_path[PATH_MAX];
char resolved_path[PATH_MAX];
ssize_t num;
gboolean found_it;
found_it = FALSE;
full_path = g_build_filename (dir, attribute, NULL);
//g_warning ("attribute='%s'", attribute);
//g_warning ("full_path='%s'", full_path);
num = readlink (full_path, link_path, sizeof (link_path) - 1);
if (num != -1) {
char *absolute_path;
link_path[num] = '\0';
//g_warning ("link_path='%s'", link_path);
absolute_path = g_build_filename (dir, link_path, NULL);
//g_warning ("absolute_path='%s'", absolute_path);
if (realpath (absolute_path, resolved_path) != NULL) {
//g_warning ("resolved_path='%s'", resolved_path);
found_it = TRUE;
}
g_free (absolute_path);
}
g_free (full_path);
if (found_it)
return g_strdup (resolved_path);
else
return NULL;
}

36
src/sysfs-utils.h Normal file
View file

@ -0,0 +1,36 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __SYSFS_UTILS_H__
#define __SYSFS_UTILS_H__
#include <glib.h>
double sysfs_get_double (const char *dir, const char *attribute);
gboolean sysfs_file_contains (const char *dir, const char *attribute, const char *string);
char *sysfs_get_string (const char *dir, const char *attribute);
int sysfs_get_int (const char *dir, const char *attribute);
guint64 sysfs_get_uint64 (const char *dir, const char *attribute);
gboolean sysfs_file_exists (const char *dir, const char *attribute);
char *sysfs_resolve_link (const char *dir, const char *attribute);
char *_dupv8 (const char *s);
#endif /* __SYSFS_UTILS_H__ */

49
tools/Makefile.am Normal file
View file

@ -0,0 +1,49 @@
## Process this file with automake to produce Makefile.in
INCLUDES = \
-I$(top_builddir)/src -I$(top_srcdir)/src \
-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
-DPACKAGE_BIN_DIR=\""$(bindir)"\" \
-DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
$(DBUS_GLIB_CFLAGS) \
$(POLKIT_DBUS_CFLAGS) \
$(GLIB_CFLAGS)
BUILT_SOURCES = \
devkit-power-daemon-glue.h \
devkit-power-marshal.h devkit-power-marshal.c
devkit-power-marshal.h: $(top_srcdir)/src/devkit-power-marshal.list
glib-genmarshal $< --prefix=devkit_power_marshal --header > $@
devkit-power-marshal.c: $(top_srcdir)/src/devkit-power-marshal.list
echo "#include \"devkit-power-marshal.h\"" > $@ && glib-genmarshal $< --prefix=devkit_power_marshal --body >> $@
devkit-power-daemon-glue.h: $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml Makefile.am
dbus-binding-tool --prefix=devkit_power_daemon --mode=glib-client --output=devkit-power-daemon-glue.h $(top_srcdir)/src/org.freedesktop.DeviceKit.Power.xml
bin_PROGRAMS = devkit-power
devkit_power_SOURCES = \
devkit-power.c \
$(BUILT_SOURCES)
devkit_power_CPPFLAGS = \
-DG_LOG_DOMAIN=\"devkit-power\" \
$(DISABLE_DEPRECATED) \
$(AM_CPPFLAGS)
devkit_power_LDADD = \
$(DBUS_GLIB_LIBS) \
$(POLKIT_DBUS_LIBS)
CLEANFILES = $(BUILT_SOURCES)
clean-local :
rm -f *~ $(service_DATA) $(dbusconf_DATA)

376
tools/devkit-power.c Normal file
View file

@ -0,0 +1,376 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2007 David Zeuthen <david@fubar.dk>
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <polkit-dbus/polkit-dbus.h>
#include "devkit-power-daemon-glue.h"
#include "devkit-power-marshal.h"
static DBusGConnection *bus = NULL;
static DBusGProxy *power_proxy = NULL;
static GMainLoop *loop;
static gboolean opt_enumerate = FALSE;
static gboolean opt_monitor = FALSE;
static gboolean opt_monitor_detail = FALSE;
static char *opt_show_info = FALSE;
static gboolean do_monitor (void);
static void do_show_info (const char *object_path);
static gboolean
polkit_dbus_gerror_parse (GError *error,
PolKitAction **action,
PolKitResult *result)
{
gboolean ret;
const char *name;
ret = FALSE;
if (error->domain != DBUS_GERROR || error->code != DBUS_GERROR_REMOTE_EXCEPTION)
goto out;
name = dbus_g_error_get_name (error);
ret = polkit_dbus_error_parse_from_strings (name,
error->message,
action,
result);
out:
return ret;
}
static void
device_added_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
{
g_print ("added: %s\n", object_path);
if (opt_monitor_detail) {
do_show_info (object_path);
g_print ("\n");
}
}
static void
device_changed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
{
g_print ("changed: %s\n", object_path);
if (opt_monitor_detail) {
/* TODO: would be nice to just show the diff */
do_show_info (object_path);
g_print ("\n");
}
}
static void
device_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
{
g_print ("removed: %s\n", object_path);
}
/* --- SUCKY CODE BEGIN --- */
/* This totally sucks; dbus-bindings-tool and dbus-glib should be able
* to do this for us.
*/
typedef struct
{
char *native_path;
char *vendor;
char *model;
char *serial;
guint64 update_time;
char *type;
gboolean line_power_online;
double battery_energy;
double battery_energy_empty;
double battery_energy_empty_design;
double battery_energy_full;
double battery_energy_full_design;
double battery_energy_rate;
gint64 battery_time_to_full;
gint64 battery_time_to_empty;
double battery_percentage;
char *battery_technology;
} DeviceProperties;
static void
collect_props (const char *key, const GValue *value, DeviceProperties *props)
{
gboolean handled = TRUE;
if (strcmp (key, "native-path") == 0)
props->native_path = g_strdup (g_value_get_string (value));
else if (strcmp (key, "vendor") == 0)
props->vendor = g_strdup (g_value_get_string (value));
else if (strcmp (key, "model") == 0)
props->model = g_strdup (g_value_get_string (value));
else if (strcmp (key, "serial") == 0)
props->serial = g_strdup (g_value_get_string (value));
else if (strcmp (key, "update-time") == 0)
props->update_time = g_value_get_uint64 (value);
else if (strcmp (key, "type") == 0)
props->type = g_strdup (g_value_get_string (value));
else if (strcmp (key, "line-power-online") == 0)
props->line_power_online = g_value_get_boolean (value);
else if (strcmp (key, "battery-energy") == 0)
props->battery_energy = g_value_get_double (value);
else if (strcmp (key, "battery-energy-empty") == 0)
props->battery_energy_empty = g_value_get_double (value);
else if (strcmp (key, "battery-energy-empty-design") == 0)
props->battery_energy_empty_design = g_value_get_double (value);
else if (strcmp (key, "battery-energy-full") == 0)
props->battery_energy_full = g_value_get_double (value);
else if (strcmp (key, "battery-energy-full-design") == 0)
props->battery_energy_full_design = g_value_get_double (value);
else if (strcmp (key, "battery-energy-rate") == 0)
props->battery_energy_rate = g_value_get_double (value);
else if (strcmp (key, "battery-time-to-full") == 0)
props->battery_time_to_full = g_value_get_int64 (value);
else if (strcmp (key, "battery-time-to-empty") == 0)
props->battery_time_to_empty = g_value_get_int64 (value);
else if (strcmp (key, "battery-percentage") == 0)
props->battery_percentage = g_value_get_double (value);
else if (strcmp (key, "battery-technology") == 0)
props->battery_technology = g_strdup (g_value_get_string (value));
else
handled = FALSE;
if (!handled)
g_warning ("unhandled property '%s'", key);
}
static DeviceProperties *
device_properties_get (DBusGConnection *bus,
const char *object_path)
{
DeviceProperties *props;
GError *error;
GHashTable *hash_table;
DBusGProxy *prop_proxy;
const char *ifname = "org.freedesktop.DeviceKit.Power.Device";
props = g_new0 (DeviceProperties, 1);
prop_proxy = dbus_g_proxy_new_for_name (bus,
"org.freedesktop.DeviceKit.Power",
object_path,
"org.freedesktop.DBus.Properties");
error = NULL;
if (!dbus_g_proxy_call (prop_proxy,
"GetAll",
&error,
G_TYPE_STRING,
ifname,
G_TYPE_INVALID,
dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
&hash_table,
G_TYPE_INVALID)) {
g_warning ("Couldn't call GetAll() to get properties for %s: %s", object_path, error->message);
g_error_free (error);
goto out;
}
g_hash_table_foreach (hash_table, (GHFunc) collect_props, props);
g_hash_table_unref (hash_table);
out:
g_object_unref (prop_proxy);
return props;
}
static void
device_properties_free (DeviceProperties *props)
{
g_free (props->native_path);
g_free (props->vendor);
g_free (props->model);
g_free (props->serial);
g_free (props->type);
g_free (props->battery_technology);
g_free (props);
}
/* --- SUCKY CODE END --- */
static gboolean
do_monitor (void)
{
GError *error;
g_print ("Monitoring activity from the power daemon. Press Ctrl+C to cancel.\n");
error = NULL;
dbus_g_proxy_connect_signal (power_proxy, "DeviceAdded",
G_CALLBACK (device_added_signal_handler), NULL, NULL);
dbus_g_proxy_connect_signal (power_proxy, "DeviceRemoved",
G_CALLBACK (device_removed_signal_handler), NULL, NULL);
dbus_g_proxy_connect_signal (power_proxy, "DeviceChanged",
G_CALLBACK (device_changed_signal_handler), NULL, NULL);
g_main_loop_run (loop);
return FALSE;
}
static void
do_show_info (const char *object_path)
{
DeviceProperties *props;
struct tm *time_tm;
time_t t;
char time_buf[256];
props = device_properties_get (bus, object_path);
t = (time_t) props->update_time;
time_tm = localtime (&t);
strftime (time_buf, sizeof time_buf, "%c", time_tm);
g_print ("Showing information for %s\n", object_path);
g_print (" native-path: %s\n", props->native_path);
g_print (" vendor: %s\n", props->vendor);
g_print (" model: %s\n", props->model);
g_print (" serial: %s\n", props->serial);
g_print (" updated: %s (%d seconds ago)\n", time_buf, (int) (time (NULL) - props->update_time));
if (strcmp (props->type, "battery") == 0) {
g_print (" battery\n");
g_print (" energy: %g Wh\n", props->battery_energy);
g_print (" energy-empty: %g Wh\n", props->battery_energy_empty);
g_print (" energy-empty-design: %g Wh\n", props->battery_energy_empty_design);
g_print (" energy-full: %g Wh\n", props->battery_energy_full);
g_print (" energy-full-design: %g Wh\n", props->battery_energy_full_design);
g_print (" energy-rate: %g W\n", props->battery_energy_rate);
g_print (" time to full: ");
if (props->battery_time_to_full >= 0)
g_print ("%d seconds\n", (int) props->battery_time_to_full);
else
g_print ("unknown\n");
g_print (" time to empty: ");
if (props->battery_time_to_empty >= 0)
g_print ("%d seconds\n", (int) props->battery_time_to_empty);
else
g_print ("unknown\n");
g_print (" percentage: %g%%\n", props->battery_percentage);
g_print (" technology: %s\n", props->battery_technology);
} else if (strcmp (props->type, "line-power") == 0) {
g_print (" line-power\n");
g_print (" online: %s\n", props->line_power_online ? "yes" : "no");
} else {
g_print (" unknown power source type '%s'\n", props->type);
}
device_properties_free (props);
}
int
main (int argc, char **argv)
{
int ret;
GOptionContext *context;
GError *error = NULL;
unsigned int n;
static GOptionEntry entries [] = {
{ "enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_enumerate, "Enumerate objects paths for devices", NULL },
{ "monitor", 0, 0, G_OPTION_ARG_NONE, &opt_monitor, "Monitor activity from the disk daemon", NULL },
{ "monitor-detail", 0, 0, G_OPTION_ARG_NONE, &opt_monitor_detail, "Monitor with detail", NULL },
{ "show-info", 0, 0, G_OPTION_ARG_STRING, &opt_show_info, "Show information about object path", NULL },
{ NULL }
};
ret = 1;
g_type_init ();
context = g_option_context_new ("DeviceKit-power tool");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
loop = g_main_loop_new (NULL, FALSE);
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (bus == NULL) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free (error);
goto out;
}
power_proxy = dbus_g_proxy_new_for_name (bus,
"org.freedesktop.DeviceKit.Power",
"/",
"org.freedesktop.DeviceKit.Power");
dbus_g_proxy_add_signal (power_proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (power_proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal (power_proxy, "DeviceChanged", G_TYPE_STRING, G_TYPE_INVALID);
if (opt_enumerate) {
GPtrArray *devices;
if (!org_freedesktop_DeviceKit_Power_enumerate_devices (power_proxy, &devices, &error)) {
g_warning ("Couldn't enumerate devices: %s", error->message);
g_error_free (error);
goto out;
}
for (n = 0; n < devices->len; n++) {
char *object_path = devices->pdata[n];
g_print ("%s\n", object_path);
}
g_ptr_array_foreach (devices, (GFunc) g_free, NULL);
g_ptr_array_free (devices, TRUE);
} else if (opt_monitor || opt_monitor_detail) {
if (!do_monitor ())
goto out;
} else if (opt_show_info != NULL) {
do_show_info (opt_show_info);
}
ret = 0;
out:
if (power_proxy != NULL)
g_object_unref (power_proxy);
if (bus != NULL)
dbus_g_connection_unref (bus);
return ret;
}