cinnamon-screensaver-2.8.0/0000775000175000017500000000000012610211212014551 5ustar fabiofabiocinnamon-screensaver-2.8.0/COPYING0000664000175000017500000004311012610211212015603 0ustar fabiofabio GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. cinnamon-screensaver-2.8.0/debian/0000775000175000017500000000000012610211212015773 5ustar fabiofabiocinnamon-screensaver-2.8.0/files/0000775000175000017500000000000012610211212015653 5ustar fabiofabiocinnamon-screensaver-2.8.0/files/Makefile.in0000664000175000017500000000024712610211212017723 0ustar fabiofabioall: clean: distclean: install: find -mindepth 1 -maxdepth 1 -type d -exec cp -R {} $(DESTDIR)/ \; uninstall: find -mindepth 1 -type f -exec rm $(DESTDIR)/{} \; cinnamon-screensaver-2.8.0/README.md0000664000175000017500000000025312610211212016030 0ustar fabiofabio - White big Time/date on x11 background (ala Windows 8)? Background can be shaded with opacity 0.5 using cairo. - Round GTK plug corners using cairo and paint it dark? cinnamon-screensaver-2.8.0/configure.ac0000664000175000017500000006070012610211212017042 0ustar fabiofabiodnl -*- mode: m4 -*- AC_PREREQ(2.60) AC_INIT([cinnamon-screensaver], [2.8.0], [https://github.com/linuxmint/cinnamon-screensaver/issues]) AC_CONFIG_SRCDIR(src/cinnamon-screensaver.c) AM_INIT_AUTOMAKE([1.10 no-dist-gzip dist-xz tar-ustar]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS(config.h) AM_MAINTAINER_MODE([enable]) IT_PROG_INTLTOOL([0.35.0]) AC_ISC_POSIX AC_PROG_CC AM_PROG_CC_C_O AC_STDC_HEADERS AC_PROG_LIBTOOL AC_CANONICAL_HOST AC_HEADER_STDC AC_SUBST(VERSION) # Save flags to aclocal ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS" GETTEXT_PACKAGE=cinnamon-screensaver AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Name of default gettext domain]) AM_GLIB_GNU_GETTEXT GLIB_GSETTINGS # Dependencies DBUS_REQUIRED_VERSION=0.78 GLIB_REQUIRED_VERSION=2.37.3 GTK_REQUIRED_VERSION=3.1.4 X11_REQUIRED_VERSION=1.0 CINNAMON_DESKTOP_REQUIRED_VERSION=2.6.3 LIBGNOMEKBDUI_REQUIRED_VERSION=3.6.0 AC_CHECK_HEADERS(unistd.h) AC_CHECK_HEADERS(crypt.h sys/select.h) AC_CHECK_FUNCS(select fcntl uname nice setpriority getcwd getwd putenv sbrk) AC_CHECK_FUNCS(sigaction syslog realpath setrlimit) AC_CHECK_FUNCS(getresuid) AC_TYPE_UID_T AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv]) PKG_CHECK_MODULES(CINNAMON_SCREENSAVER, x11 >= $X11_REQUIRED_VERSION gtk+-3.0 >= $GTK_REQUIRED_VERSION dbus-glib-1 >= $DBUS_REQUIRED_VERSION cinnamon-desktop >= $CINNAMON_DESKTOP_REQUIRED_VERSION) PKG_CHECK_MODULES([WEBKIT], [webkit2gtk-3.0],, [PKG_CHECK_MODULES([WEBKIT], [webkit2gtk-4.0])]) AC_SUBST(CINNAMON_SCREENSAVER_CFLAGS) AC_SUBST(CINNAMON_SCREENSAVER_LIBS) PKG_CHECK_MODULES(CINNAMON_SCREENSAVER_DIALOG, gthread-2.0 gtk+-3.0 >= $GTK_REQUIRED_VERSION) AC_SUBST(CINNAMON_SCREENSAVER_DIALOG_CFLAGS) AC_SUBST(CINNAMON_SCREENSAVER_DIALOG_LIBS) PKG_CHECK_MODULES(CINNAMON_SCREENSAVER_CAPPLET, gio-2.0 >= $GLIB_REQUIRED_VERSION gtk+-3.0 >= $GTK_REQUIRED_VERSION cinnamon-desktop >= $CINNAMON_DESKTOP_REQUIRED_VERSION) AC_SUBST(CINNAMON_SCREENSAVER_CAPPLET_CFLAGS) AC_SUBST(CINNAMON_SCREENSAVER_CAPPLET_LIBS) PKG_CHECK_MODULES(CINNAMON_SCREENSAVER_COMMAND, gio-2.0 >= $GLIB_REQUIRED_VERSION gobject-2.0 >= $GLIB_REQUIRED_VERSION) AC_SUBST(CINNAMON_SCREENSAVER_COMMAND_CFLAGS) AC_SUBST(CINNAMON_SCREENSAVER_COMMAND_LIBS) AC_PATH_XTRA ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS" SAVER_LIBS="$ALL_X_LIBS" AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) GNOME_COMPILE_WARNINGS(yes) # Optional dependencies for the theme engines SAVER_MODULES="gthread-2.0 gtk+-3.0 >= $GTK_REQUIRED_VERSION" PKG_CHECK_MODULES(CINNAMON_SCREENSAVER_SAVER, $SAVER_MODULES) AC_SUBST(CINNAMON_SCREENSAVER_SAVER_CFLAGS) AC_SUBST(CINNAMON_SCREENSAVER_SAVER_LIBS) # Find out the version of DBUS we're using dbus_version=`$PKG_CONFIG --modversion dbus-1` DBUS_VERSION_MAJOR=`echo $dbus_version | awk -F. '{print $1}'` DBUS_VERSION_MINOR=`echo $dbus_version | awk -F. '{print $2}'` DBUS_VERSION_MICRO=`echo $dbus_version | awk -F. '{print $3}'` if test "z$DBUS_VERSION_MAJOR" = "z"; then DBUS_VERSION_MAJOR="0" fi if test "z$DBUS_VERSION_MINOR" = "z"; then DBUS_VERSION_MINOR="0" fi if test "z$DBUS_VERSION_MICRO" = "z"; then DBUS_VERSION_MICRO="0" fi if test "z$DBUS_VERSION_MAJOR" = "z0" -a "z$DBUS_VERSION_MINOR" = "z0" -a "z$DBUS_VERSION_MICRO" = "z0"; then echo "Error: Couldn't determine the version of your DBUS package." echo " This is probably an error in this script, please report it" echo " along with the following information:" echo " Base DBUS version ='$dbus_version'" echo " DBUS_VERSION_MAJOR='$DBUS_VERSION_MAJOR'" echo " DBUS_VERSION_MINOR='$DBUS_VERSION_MINOR'" echo " DBUS_VERSION_MICRO='$DBUS_VERSION_MICRO'" exit 1 else echo "Your dbus version is $DBUS_VERSION_MAJOR,$DBUS_VERSION_MINOR,$DBUS_VERSION_MICRO." DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MAJOR=$DBUS_VERSION_MAJOR" DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MINOR=$DBUS_VERSION_MINOR" DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_VERSION_MICRO=$DBUS_VERSION_MICRO" AC_SUBST(DBUS_CFLAGS) fi # Find out where the session service file goes # The sad sed hack is recomended by section 27.10 of the automake manual. DBUS_SESSION_SERVICE_DIR=`$PKG_CONFIG --variable session_bus_services_dir dbus-1 | sed -e 's,/usr/share,${datarootdir},g'` AC_SUBST(DBUS_SESSION_SERVICE_DIR) dnl --------------------------------------------------------------------------- dnl - Where should we put documentation ? dnl --------------------------------------------------------------------------- AC_ARG_WITH(doc-dir, [AC_HELP_STRING([--with-doc-dir=], [directory to install documentation])]) if ! test -z "$with_doc_dir"; then DOCDIR="$with_doc_dir/cinnamon-screensaver-$VERSION" else DOCDIR="$datadir/doc/cinnamon-screensaver-$VERSION" fi AC_SUBST(DOCDIR) dnl --------------------------------------------------------------------------- dnl - DocBook Documentation dnl --------------------------------------------------------------------------- AC_ARG_ENABLE(docbook-docs, [ --enable-docbook-docs build documentation (requires xmlto)],enable_docbook_docs=$enableval,enable_docbook_docs=no) AC_PATH_PROG(XMLTO, xmlto, no) AC_MSG_CHECKING([whether to build DocBook documentation]) if test x$XMLTO = xno ; then have_docbook=no else have_docbook=yes fi if test x$enable_docbook_docs = xauto ; then if test x$have_docbook = xno ; then enable_docbook_docs=no else enable_docbook_docs=yes fi fi if test x$enable_docbook_docs = xyes; then if test x$have_docbook = xno; then AC_MSG_ERROR([Building DocBook docs explicitly required, but DocBook not found]) fi fi AM_CONDITIONAL(DOCBOOK_DOCS_ENABLED, test x$enable_docbook_docs = xyes) AC_MSG_RESULT(yes) dnl --------------------------------------------------------------------------- dnl - Some utility functions to make checking for X things easier. dnl --------------------------------------------------------------------------- # Like AC_CHECK_HEADER, but it uses the already-computed -I directories. # AC_DEFUN([AC_CHECK_X_HEADER], [ ac_save_CPPFLAGS="$CPPFLAGS" if test \! -z "$includedir" ; then CPPFLAGS="$CPPFLAGS -I$includedir" fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" AC_CHECK_HEADER([$1],[$2],[$3],[$4]) CPPFLAGS="$ac_save_CPPFLAGS"]) # Like AC_TRY_COMPILE, but it uses the already-computed -I directories. # AC_DEFUN([AC_TRY_X_COMPILE], [ ac_save_CPPFLAGS="$CPPFLAGS" if test \! -z "$includedir" ; then CPPFLAGS="$CPPFLAGS -I$includedir" fi CPPFLAGS="$CPPFLAGS $X_CFLAGS" AC_TRY_COMPILE([$1], [$2], [$3], [$4]) CPPFLAGS="$ac_save_CPPFLAGS"]) # Like AC_CHECK_LIB, but it uses the already-computed -I and -L directories. # Use this sparingly; it probably doesn't work very well on X programs. # AC_DEFUN([AC_CHECK_X_LIB], [ ac_save_CPPFLAGS="$CPPFLAGS" ac_save_LDFLAGS="$LDFLAGS" # ac_save_LIBS="$LIBS" if test \! -z "$includedir" ; then CPPFLAGS="$CPPFLAGS -I$includedir" fi # note: $X_CFLAGS includes $x_includes CPPFLAGS="$CPPFLAGS $X_CFLAGS" if test \! -z "$libdir" ; then LDFLAGS="$LDFLAGS -L$libdir" fi # note: $X_LIBS includes $x_libraries LDFLAGS="$LDFLAGS $ALL_X_LIBS" AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5]) CPPFLAGS="$ac_save_CPPFLAGS" LDFLAGS="$ac_save_LDFLAGS" # LIBS="$ac_save_LIBS" ]) # Usage: HANDLE_X_PATH_ARG([variable_name], # [--command-line-option], # [descriptive string]) # # All of the --with options take three forms: # # --with-foo (or --with-foo=yes) # --without-foo (or --with-foo=no) # --with-foo=/DIR # # This function, HANDLE_X_PATH_ARG, deals with the /DIR case. When it sees # a directory (string beginning with a slash) it checks to see whether # /DIR/include and /DIR/lib exist, and adds them to $X_CFLAGS and $X_LIBS # as appropriate. # AC_DEFUN([HANDLE_X_PATH_ARG], [ case "$[$1]" in yes) ;; no) ;; /*) AC_MSG_CHECKING([for [$3] headers]) d=$[$1]/include if test -d $d; then X_CFLAGS="-I$d $X_CFLAGS" AC_MSG_RESULT($d) else AC_MSG_RESULT(not found ($d: no such directory)) fi AC_MSG_CHECKING([for [$3] libs]) d=$[$1]/lib if test -d $d; then X_LIBS="-L$d $X_LIBS" AC_MSG_RESULT($d) else AC_MSG_RESULT(not found ($d: no such directory)) fi # replace the directory string with "yes". [$1]_req="yes" [$1]=$[$1]_req ;; *) echo "" echo "error: argument to [$2] must be \"yes\", \"no\", or a directory." echo " If it is a directory, then \`DIR/include' will be added to" echo " the -I list, and \`DIR/lib' will be added to the -L list." exit 1 ;; esac ]) dnl --------------------------------------------------------------------------- dnl - Check for shaped window extension dnl --------------------------------------------------------------------------- have_shape=no AC_CHECK_X_HEADER(X11/extensions/shape.h, [have_shape=yes],, [#include ]) if test "$have_shape" = yes; then AC_DEFINE(HAVE_SHAPE_EXT, 1, [Define if shape extension is available]) fi dnl --------------------------------------------------------------------------- dnl - Check for the MIT-SCREEN-SAVER server extension. dnl --------------------------------------------------------------------------- have_mit=no with_mit_req=unspecified AC_ARG_WITH(mit-ext, [ --with-mit-ext Include support for the MIT-SCREEN-SAVER extension.], [with_mit="$withval"; with_mit_req="$withval"],[with_mit=yes]) HANDLE_X_PATH_ARG(with_mit, --with-mit-ext, MIT-SCREEN-SAVER) if test "$with_mit" = yes; then AC_CHECK_X_HEADER(X11/extensions/scrnsaver.h, [have_mit=yes],, [#include ]) # Now check to see if it's really in the library; XF86Free-3.3 ships # scrnsaver.h, but doesn't include the code in libXext.a if test "$have_mit" = yes; then AC_CHECK_X_LIB(Xext, XScreenSaverRegister, [true], [have_mit=no], -lm) if test "$have_mit" = no; then # Looks like XF86Free-3.3 actually puts it in XExExt instead # of in Xext. AC_CHECK_X_LIB(XExExt, XScreenSaverRegister, [have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXExExt"], [true], -lX11 -lXext -lm) fi if test "$have_mit" = no; then # Looks like some versions of XFree86 (whichever version # it is that comes with RedHat Linux 2.0 -- I can't find a version # number) put this in Xss instead of Xext. AC_CHECK_X_LIB(Xss, XScreenSaverRegister, [have_mit=yes; SAVER_LIBS="$SAVER_LIBS -lXss"], [true], -lX11 -lXext -lm) fi if test "$have_mit" = yes; then AC_DEFINE(HAVE_MIT_SAVER_EXTENSION, 1, [Define if the MIT screensaver extension is available]) fi fi elif test "$with_mit" != no; then echo "error: must be yes or no: --with-mit-ext=$with_mit" exit 1 fi dnl --------------------------------------------------------------------------- dnl - Check for the XF86VMODE server extension (for gamma fading.) dnl --------------------------------------------------------------------------- have_xf86vmode=no have_xf86gamma=no have_xf86gamma_ramp=no with_xf86gamma_req=unspecified AC_ARG_WITH(xf86gamma-ext, [ --with-xf86gamma-ext Include support for XFree86 gamma fading.], [with_xf86gamma="$withval"; with_xf86gamma_req="$withval"], [with_xf86gamma=yes]) HANDLE_X_PATH_ARG(with_xf86gamma, --with-xf86gamma-ext, xf86gamma) if test "$with_xf86gamma" = yes; then # first check for xf86vmode.h, if we haven't already if test "$have_xf86vmode" = yes; then have_xf86gamma=yes else AC_CHECK_X_HEADER(X11/extensions/xf86vmode.h, [have_xf86gamma=yes],, [#include ]) fi # if that succeeded, then check for the -lXxf86vm if test "$have_xf86gamma" = yes; then have_xf86gamma=no AC_CHECK_X_LIB(Xxf86vm, XF86VidModeSetGamma, [have_xf86gamma=yes], [true], -lXext -lX11) fi # check for the Ramp versions of the functions too. if test "$have_xf86gamma" = yes; then have_xf86gamma_ramp=no AC_CHECK_X_LIB(Xxf86vm, XF86VidModeSetGammaRamp, [have_xf86gamma_ramp=yes], [true], -lXext -lX11) fi # if those tests succeeded, then we've really got the functions. if test "$have_xf86gamma" = yes; then AC_DEFINE(HAVE_XF86VMODE_GAMMA, 1, [Define if XF86VMODE Gamma is available]) fi if test "$have_xf86gamma_ramp" = yes; then AC_DEFINE(HAVE_XF86VMODE_GAMMA_RAMP, 1, [Define if XF86VMODE Gamma Ramp is available]) fi # pull in the lib, if we haven't already if test "$have_xf86gamma" = yes -a "$have_xf86vmode" = no; then SAVER_LIBS="$SAVER_LIBS -lXxf86vm" fi elif test "$with_xf86gamma" != no; then echo "error: must be yes or no: --with-xf86gamma-ext=$with_xf86vmode" exit 1 fi dnl --------------------------------------------------------------------------- dnl - Check for XF86MiscSetGrabKeysState (but only bother if we are already dnl - using other XF86 stuff.) dnl --------------------------------------------------------------------------- have_xf86miscsetgrabkeysstate=no if test "$have_xf86gamma" = yes -o "$have_xf86vmode" = yes; then AC_CHECK_X_LIB(Xxf86misc, XF86MiscSetGrabKeysState, [have_xf86miscsetgrabkeysstate=yes], [true], -lXext -lX11) if test "$have_xf86miscsetgrabkeysstate" = yes ; then SAVER_LIBS="$SAVER_LIBS -lXxf86misc" AC_DEFINE(HAVE_XF86MISCSETGRABKEYSSTATE, , [Define this if you have the XF86MiscSetGrabKeysState function]) fi fi dnl --------------------------------------------------------------------------- dnl - The --enable-locking option dnl --------------------------------------------------------------------------- AC_ARG_ENABLE(locking,[ Screen locking options: --enable-locking Compile in support for locking the display. --disable-locking Do not allow locking at all.], [enable_locking="$enableval"],[enable_locking=yes]) if test "$enable_locking" = yes; then true elif test "$enable_locking" = no; then AC_DEFINE(NO_LOCKING, 1, [Define if screen locking support is disabled]) else echo "error: must be yes or no: --enable-locking=$enable_locking" exit 1 fi # We can't lock on MacOS X, so don't compile in support for it. # if test "$ac_macosx" = yes; then if test "$enable_locking" = yes; then AC_MSG_RESULT(locking disabled: it doesn't work on MacOS X) enable_locking=no AC_DEFINE(NO_LOCKING, 1, [Define if screen locking support is disabled]) fi fi dnl --------------------------------------------------------------------------- dnl - Check for bsd_auth(3) (OpenBSD) dnl --------------------------------------------------------------------------- have_bsdauth=no with_bsdauth_req=unspecified NEED_SETUID=no case "$host" in *-openbsd*) with_bsdauth=yes AUTH_SCHEME=bsdauth NEED_SETUID=no if test "x$enable_locking" = "xyes"; then with_bsdauth_req=yes NEED_SETUID=yes fi esac if test "$with_bsdauth" = yes ; then AC_CACHE_CHECK([for BSD Authentication], ac_cv_bsdauth, [AC_TRY_X_COMPILE([#include #include #include #include ], [int ok = auth_userokay("x", 0, "x", "x");], [ac_cv_bsdauth=yes], [ac_cv_bsdauth=no])]) if test "$ac_cv_bsdauth" = yes; then have_bsdauth=yes fi fi if test "$have_bsdauth" = yes; then AC_DEFINE(HAVE_BSDAUTH, 1, [Define to 1 if using bsd_auth(3) authentication]) fi AC_SUBST(NEED_SETUID) dnl --------------------------------------------------------------------------- dnl - Check for PAM dnl --------------------------------------------------------------------------- withval="" AC_ARG_WITH(pam-prefix, AS_HELP_STRING([--with-pam-prefix=], [specify where pam files go]), [if test x$withval != x; then AC_MSG_RESULT("PAM files will be installed in prefix ${withval}.") fi]) if test x$withval != x; then PAM_PREFIX="$withval" else PAM_PREFIX='${sysconfdir}' fi AC_SUBST(PAM_PREFIX) have_pam=no if test "x$enable_locking" = "xyes" -a "x$have_bsdauth" = "xno"; then AC_CHECK_LIB(pam, pam_start, have_pam=yes) fi if test "x$have_pam" = "xyes"; then AUTH_LIBS="${AUTH_LIBS} -lpam" AUTH_SCHEME=pam # On Linux, sigtimedwait() is in libc; on Solaris, it's in librt. have_timedwait=no AC_CHECK_LIB(c, sigtimedwait, [have_timedwait=yes]) if test "$have_timedwait" = no ; then AC_CHECK_LIB(rt, sigtimedwait, [AUTH_LIBS="${AUTH_LIBS} -lrt"]) fi AC_MSG_CHECKING(how to call pam_strerror) AC_CACHE_VAL(ac_cv_pam_strerror_args, [AC_TRY_COMPILE([#include #include #include ], [pam_handle_t *pamh = 0; char *s = pam_strerror(pamh, PAM_SUCCESS);], [ac_pam_strerror_args=2], [AC_TRY_COMPILE([#include #include #include ], [char *s = pam_strerror(PAM_SUCCESS);], [ac_pam_strerror_args=1], [ac_pam_strerror_args=0])]) ac_cv_pam_strerror_args=$ac_pam_strerror_args]) ac_pam_strerror_args=$ac_cv_pam_strerror_args if test "$ac_pam_strerror_args" = 1 ; then AC_MSG_RESULT(one argument) elif test "$ac_pam_strerror_args" = 2 ; then AC_DEFINE(PAM_STRERROR_TWO_ARGS, 1, [Define if pam_strerror takes two arguments]) AC_MSG_RESULT(two arguments) else AC_MSG_RESULT(unknown) fi elif test "x$have_bsdauth" = "xno"; then AC_MSG_ERROR("PAM libraries not found") fi AC_SUBST(HAVE_PAM) AC_SUBST(AUTH_LIBS) AC_SUBST(AUTH_SCHEME) if test "x$have_pam" = "xyes"; then AC_CHECK_HEADERS([security/pam_modutil.h security/pam_ext.h]) AC_CHECK_LIB(pam, pam_syslog, [AC_DEFINE(HAVE_PAM_SYSLOG, [], [Define to 1 if you have the pam_syslog function])]) fi dnl test whether struct pam_message is const (Linux) or not (Sun) if test "x$have_pam" = "xyes"; then pam_appl_h="$ac_pam_includes/security/pam_appl.h" AC_MSG_CHECKING(for const pam_message) AC_EGREP_HEADER([struct pam_message], $pam_appl_h, [ AC_EGREP_HEADER([const struct pam_message], $pam_appl_h, [AC_MSG_RESULT(["const: Linux-type PAM"]) ], [AC_MSG_RESULT(["nonconst: Sun-type PAM"]) AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])] )], [AC_MSG_RESULT(["not found - assume const, Linux-type PAM"])] ) fi dnl --------------------------------------------------------------------------- dnl logind support dnl --------------------------------------------------------------------------- PKG_CHECK_MODULES(LOGIND, [libsystemd-login], [have_logind=yes], [have_logind=no]) if test x$have_logind = xyes ; then AC_DEFINE(HAVE_LOGIND, 1, [logind support]) fi AC_SUBST(LOGIND_CFLAGS) AC_SUBST(LOGIND_LIBS) dnl --------------------------------------------------------------------------- dnl libgnomekbd dnl --------------------------------------------------------------------------- have_libgnomekbdui=no AC_ARG_WITH(kbd-layout-indicator,[ --without-kbd-layout-indicator disable keyboard layout indicator], [with_kbd_layout_indicator="$withval"],[with_kbd_layout_indicator=yes]) if test x$with_kbd_layout_indicator != xno; then PKG_CHECK_MODULES(LIBGNOMEKBDUI, libgnomekbdui >= $LIBGNOMEKBDUI_REQUIRED_VERSION libxklavier, have_libgnomekbdui=yes, have_libgnomekbdui=no) fi if test "x$have_libgnomekbdui" = "xyes"; then AC_SUBST(LIBGNOMEKBDUI_CFLAGS) AC_SUBST(LIBGNOMEKBDUI_LIBS) AC_DEFINE(WITH_KBD_LAYOUT_INDICATOR, 1, [Define if keyboard layout indicator should be built]) fi dnl --------------------------------------------------------------------------- dnl Finish dnl --------------------------------------------------------------------------- AC_SUBST(AUTH_LIBS) AC_SUBST(SAVER_LIBS) REAL_PREFIX= if test "x$prefix" = "xNONE"; then REAL_PREFIX=$ac_default_prefix else REAL_PREFIX=$prefix fi ## temporarily change prefix and exec_prefix old_prefix=$prefix prefix=$REAL_PREFIX if test "x$exec_prefix" = xNONE ; then REAL_EXEC_PREFIX=$REAL_PREFIX else REAL_EXEC_PREFIX=$exec_prefix fi old_exec_prefix=$exec_prefix exec_prefix=$REAL_EXEC_PREFIX ## eval everything LOCALSTATEDIR_TMP="$localstatedir" EXPANDED_LOCALSTATEDIR=`eval echo $LOCALSTATEDIR_TMP` AC_SUBST(EXPANDED_LOCALSTATEDIR) SYSCONFDIR_TMP="$sysconfdir" EXPANDED_SYSCONFDIR=`eval echo $SYSCONFDIR_TMP` AC_SUBST(EXPANDED_SYSCONFDIR) BINDIR_TMP="$bindir" EXPANDED_BINDIR=`eval echo $BINDIR_TMP` AC_SUBST(EXPANDED_BINDIR) LIBDIR_TMP="$libdir" EXPANDED_LIBDIR=`eval echo $LIBDIR_TMP` AC_SUBST(EXPANDED_LIBDIR) DATADIR_TMP="$datadir" EXPANDED_DATADIR=`eval echo $DATADIR_TMP` AC_SUBST(EXPANDED_DATADIR) ## put prefix and exec_prefix back prefix=$old_prefix exec_prefix=$old_exec_prefix # Turn on the additional warnings last, so -Werror doesn't affect other tests. AC_ARG_ENABLE(more-warnings, AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]), set_more_warnings="$enableval",[ if test -d $srcdir/.git; then is_cvs_version=true set_more_warnings=yes else set_more_warnings=no fi ]) AC_MSG_CHECKING(for more warnings) if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then AC_MSG_RESULT(yes) CFLAGS="\ -Wall \ -Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \ -Wnested-externs -Wpointer-arith \ -Wcast-align -Wsign-compare \ $CFLAGS" for option in -Wno-strict-aliasing -Wno-sign-compare; do SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $option" AC_MSG_CHECKING([whether gcc understands $option]) AC_TRY_COMPILE([], [], has_option=yes, has_option=no,) if test $has_option = no; then CFLAGS="$SAVE_CFLAGS" fi AC_MSG_RESULT($has_option) unset has_option unset SAVE_CFLAGS done unset option else AC_MSG_RESULT(no) fi # # Enable Debug # AC_ARG_ENABLE(debug, [AC_HELP_STRING([--enable-debug=[no/yes]], [turn on debugging])],, enable_debug=yes) if test "$enable_debug" = "yes"; then DEBUG_CFLAGS="-DG_ENABLE_DEBUG" else if test "x$enable_debug" = "xno"; then DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS" else DEBUG_CFLAGS="" fi fi AC_SUBST(DEBUG_CFLAGS) # Flags AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) # Files AC_OUTPUT([ Makefile po/Makefile.in src/Makefile src/cinnamon-screensaver.desktop.in data/Makefile data/screensavers/Makefile data/org.cinnamon.ScreenSaver.service files/Makefile ]) echo " cinnamon-screensaver $VERSION ======================== prefix: ${prefix} exec_prefix: ${exec_prefix} libdir: ${EXPANDED_LIBDIR} bindir: ${EXPANDED_BINDIR} sysconfdir: ${EXPANDED_SYSCONFDIR} localstatedir: ${EXPANDED_LOCALSTATEDIR} datadir: ${EXPANDED_DATADIR} source code location: ${srcdir} compiler: ${CC} cflags: ${CFLAGS} Base libs: ${CINNAMON_SCREENSAVER_LIBS} Extension libs: ${SAVER_LIBS} Maintainer mode: ${USE_MAINTAINER_MODE} Docs enabled: ${enable_docbook_docs} Screen locking enabled: ${enable_locking} Show keyboard indicator: ${with_kbd_layout_indicator} logind supported: ${have_logind} " if test "x$have_pam" = "xyes" ; then echo "\ PAM prefix: ${PAM_PREFIX} " fi cinnamon-screensaver-2.8.0/src/0000775000175000017500000000000012610211212015340 5ustar fabiofabiocinnamon-screensaver-2.8.0/src/gs-monitor.c0000664000175000017500000003631512610211212017612 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include "cinnamon-screensaver.h" #include "gs-manager.h" #include "gs-watcher.h" #include "gs-fade.h" #include "gs-grab.h" #include "gs-listener-dbus.h" #include "gs-monitor.h" #include "gs-prefs.h" #include "gs-debug.h" static void gs_monitor_class_init (GSMonitorClass *klass); static void gs_monitor_init (GSMonitor *monitor); static void gs_monitor_finalize (GObject *object); #define GS_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_MONITOR, GSMonitorPrivate)) struct GSMonitorPrivate { GSWatcher *watcher; GSListener *listener; GSManager *manager; GSPrefs *prefs; GSFade *fade; GSGrab *grab; guint release_grab_id; }; #define FADE_TIMEOUT 10000 G_DEFINE_TYPE (GSMonitor, gs_monitor, G_TYPE_OBJECT) static void gs_monitor_class_init (GSMonitorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_monitor_finalize; g_type_class_add_private (klass, sizeof (GSMonitorPrivate)); } static void manager_activated_cb (GSManager *manager, GSMonitor *monitor) { } static void manager_deactivated_cb (GSManager *manager, GSMonitor *monitor) { gs_listener_set_active (monitor->priv->listener, FALSE); } static gboolean watcher_idle_cb (GSWatcher *watcher, gboolean is_idle, GSMonitor *monitor) { gboolean res; gs_debug ("Idle signal detected: %d", is_idle); res = gs_listener_set_session_idle (monitor->priv->listener, is_idle); return res; } static gboolean release_grab_timeout (GSMonitor *monitor) { gboolean manager_active; manager_active = gs_manager_get_active (monitor->priv->manager); if (! manager_active) { gs_grab_release (monitor->priv->grab); } monitor->priv->release_grab_id = 0; return FALSE; } static gboolean watcher_idle_notice_cb (GSWatcher *watcher, gboolean in_effect, GSMonitor *monitor) { gboolean activation_enabled; gboolean handled; gs_debug ("Idle notice signal detected: %d", in_effect); /* only fade if screensaver can activate */ activation_enabled = gs_listener_get_activation_enabled (monitor->priv->listener); handled = FALSE; if (in_effect) { if (activation_enabled) { /* start slow fade */ if (gs_grab_grab_offscreen (monitor->priv->grab, FALSE)) { gs_fade_async (monitor->priv->fade, FADE_TIMEOUT, NULL, NULL); } else { gs_debug ("Could not grab the keyboard so not performing idle warning fade-out"); } handled = TRUE; } } else { gboolean manager_active; manager_active = gs_manager_get_active (monitor->priv->manager); /* cancel the fade unless manager was activated */ if (! manager_active) { gs_debug ("manager not active, performing fade cancellation"); gs_fade_reset (monitor->priv->fade); /* don't release the grab immediately to prevent typing passwords into windows */ if (monitor->priv->release_grab_id != 0) { g_source_remove (monitor->priv->release_grab_id); monitor->priv->release_grab_id = 0; } monitor->priv->release_grab_id = g_timeout_add_seconds (1, (GSourceFunc)release_grab_timeout, monitor); } else { gs_debug ("manager active, skipping fade cancellation"); } handled = TRUE; } return handled; } static void gs_monitor_lock_screen (GSMonitor *monitor) { gboolean res; gboolean locked; gboolean active; /* set lock flag before trying to activate screensaver in case something tries to react to the ActiveChanged signal */ gs_manager_get_lock_active (monitor->priv->manager, &locked); gs_manager_set_lock_active (monitor->priv->manager, TRUE); active = gs_manager_get_active (monitor->priv->manager); if (! active) { res = gs_listener_set_active (monitor->priv->listener, TRUE); if (! res) { /* If we've failed then restore lock status */ gs_manager_set_lock_active (monitor->priv->manager, locked); gs_debug ("Unable to lock the screen"); } } } static void gs_monitor_simulate_user_activity (GSMonitor *monitor) { XResetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); /* request that the manager unlock - will pop up a dialog if necessary */ gs_manager_request_unlock (monitor->priv->manager); } static void listener_lock_cb (GSListener *listener, const char *message, GSMonitor *monitor) { if (! monitor->priv->prefs->lock_disabled) { gs_manager_set_away_message(monitor->priv->manager, g_strdup(message)); gs_monitor_lock_screen (monitor); } else { gs_debug ("Locking disabled by the administrator"); } } static void listener_quit_cb (GSListener *listener, GSMonitor *monitor) { gs_listener_set_active (monitor->priv->listener, FALSE); cinnamon_screensaver_quit (); } static void listener_show_message_cb (GSListener *listener, const char *summary, const char *body, const char *icon, GSMonitor *monitor) { gs_manager_show_message (monitor->priv->manager, summary, body, icon); } static gboolean listener_active_changed_cb (GSListener *listener, gboolean active, GSMonitor *monitor) { gboolean res; gboolean ret; gboolean idle_watch_enabled; res = gs_manager_set_active (monitor->priv->manager, active); if (! res) { gs_debug ("Unable to set manager active: %d", active); ret = FALSE; goto done; } ret = TRUE; done: idle_watch_enabled = gs_watcher_get_enabled (monitor->priv->watcher); if (ret && idle_watch_enabled) { res = gs_watcher_set_active (monitor->priv->watcher, !active); if (! res) { gs_debug ("Unable to set the idle watcher active: %d", !active); } } return ret; } static void listener_simulate_user_activity_cb (GSListener *listener, GSMonitor *monitor) { gs_monitor_simulate_user_activity (monitor); } static void _gs_monitor_update_from_prefs (GSMonitor *monitor, GSPrefs *prefs) { gboolean idle_detection_enabled; gboolean idle_detection_active; gboolean activate_watch; gboolean manager_active; gboolean lock_enabled; gboolean user_switch_enabled; lock_enabled = (monitor->priv->prefs->lock_enabled && !monitor->priv->prefs->lock_disabled); user_switch_enabled = (monitor->priv->prefs->user_switch_enabled && !monitor->priv->prefs->user_switch_disabled); gs_manager_set_lock_enabled (monitor->priv->manager, lock_enabled); gs_manager_set_lock_timeout (monitor->priv->manager, monitor->priv->prefs->lock_timeout); gs_manager_set_logout_enabled (monitor->priv->manager, monitor->priv->prefs->logout_enabled); gs_manager_set_user_switch_enabled (monitor->priv->manager, user_switch_enabled); gs_manager_set_keyboard_enabled (monitor->priv->manager, monitor->priv->prefs->keyboard_enabled); gs_manager_set_logout_timeout (monitor->priv->manager, monitor->priv->prefs->logout_timeout); gs_manager_set_logout_command (monitor->priv->manager, monitor->priv->prefs->logout_command); gs_manager_set_keyboard_command (monitor->priv->manager, monitor->priv->prefs->keyboard_command); /* enable activation when allowed */ gs_listener_set_activation_enabled (monitor->priv->listener, monitor->priv->prefs->idle_activation_enabled); /* idle detection always enabled */ idle_detection_enabled = TRUE; gs_watcher_set_enabled (monitor->priv->watcher, idle_detection_enabled); /* in the case where idle detection is reenabled we may need to activate the watcher too */ manager_active = gs_manager_get_active (monitor->priv->manager); idle_detection_active = gs_watcher_get_active (monitor->priv->watcher); activate_watch = (! manager_active && ! idle_detection_active && idle_detection_enabled); if (activate_watch) { gs_watcher_set_active (monitor->priv->watcher, TRUE); } } static void disconnect_listener_signals (GSMonitor *monitor) { g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_lock_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_quit_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_active_changed_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_simulate_user_activity_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_show_message_cb, monitor); } static void connect_listener_signals (GSMonitor *monitor) { g_signal_connect (monitor->priv->listener, "lock", G_CALLBACK (listener_lock_cb), monitor); g_signal_connect (monitor->priv->listener, "quit", G_CALLBACK (listener_quit_cb), monitor); g_signal_connect (monitor->priv->listener, "active-changed", G_CALLBACK (listener_active_changed_cb), monitor); g_signal_connect (monitor->priv->listener, "simulate-user-activity", G_CALLBACK (listener_simulate_user_activity_cb), monitor); g_signal_connect (monitor->priv->listener, "show-message", G_CALLBACK (listener_show_message_cb), monitor); } static void disconnect_watcher_signals (GSMonitor *monitor) { g_signal_handlers_disconnect_by_func (monitor->priv->watcher, watcher_idle_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->watcher, watcher_idle_notice_cb, monitor); } static void connect_watcher_signals (GSMonitor *monitor) { g_signal_connect (monitor->priv->watcher, "idle-changed", G_CALLBACK (watcher_idle_cb), monitor); g_signal_connect (monitor->priv->watcher, "idle-notice-changed", G_CALLBACK (watcher_idle_notice_cb), monitor); } static void disconnect_manager_signals (GSMonitor *monitor) { g_signal_handlers_disconnect_by_func (monitor->priv->manager, manager_activated_cb, monitor); g_signal_handlers_disconnect_by_func (monitor->priv->manager, manager_deactivated_cb, monitor); } static void connect_manager_signals (GSMonitor *monitor) { g_signal_connect (monitor->priv->manager, "activated", G_CALLBACK (manager_activated_cb), monitor); g_signal_connect (monitor->priv->manager, "deactivated", G_CALLBACK (manager_deactivated_cb), monitor); } static void disconnect_prefs_signals (GSMonitor *monitor) { g_signal_handlers_disconnect_by_func (monitor->priv->prefs, _gs_monitor_update_from_prefs, monitor); } static void connect_prefs_signals (GSMonitor *monitor) { g_signal_connect_swapped (monitor->priv->prefs, "changed", G_CALLBACK (_gs_monitor_update_from_prefs), monitor); } static void gs_monitor_init (GSMonitor *monitor) { monitor->priv = GS_MONITOR_GET_PRIVATE (monitor); monitor->priv->prefs = gs_prefs_new (); connect_prefs_signals (monitor); monitor->priv->listener = gs_listener_new (); connect_listener_signals (monitor); monitor->priv->fade = gs_fade_new (); monitor->priv->grab = gs_grab_new (); monitor->priv->watcher = gs_watcher_new (); connect_watcher_signals (monitor); monitor->priv->manager = gs_manager_new (); connect_manager_signals (monitor); _gs_monitor_update_from_prefs (monitor, monitor->priv->prefs); } static void gs_monitor_finalize (GObject *object) { GSMonitor *monitor; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_MONITOR (object)); monitor = GS_MONITOR (object); g_return_if_fail (monitor->priv != NULL); disconnect_watcher_signals (monitor); disconnect_listener_signals (monitor); disconnect_manager_signals (monitor); disconnect_prefs_signals (monitor); g_object_unref (monitor->priv->fade); g_object_unref (monitor->priv->grab); g_object_unref (monitor->priv->watcher); g_object_unref (monitor->priv->listener); g_object_unref (monitor->priv->manager); g_object_unref (monitor->priv->prefs); G_OBJECT_CLASS (gs_monitor_parent_class)->finalize (object); } GSMonitor * gs_monitor_new (void) { GSMonitor *monitor; monitor = g_object_new (GS_TYPE_MONITOR, NULL); return GS_MONITOR (monitor); } gboolean gs_monitor_start (GSMonitor *monitor, GError **error) { g_return_val_if_fail (GS_IS_MONITOR (monitor), FALSE); if (! gs_listener_acquire (monitor->priv->listener, error)) { return FALSE; } return TRUE; } cinnamon-screensaver-2.8.0/src/cinnamon-screensaver.desktop.in.in0000664000175000017500000000067012610211212024070 0ustar fabiofabio[Desktop Entry] Type=Application _Name=Screensaver _Comment=Launch screensaver and locker program Icon=preferences-desktop-screensaver Exec=cinnamon-screensaver OnlyShowIn=X-Cinnamon; NoDisplay=true X-GNOME-Autostart-Delay=20 X-GNOME-Autostart-Phase=Application X-GNOME-Autostart-Notify=true X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=cinnamon-screensaver X-GNOME-Bugzilla-Component=general X-GNOME-Bugzilla-Version=@VERSION@ cinnamon-screensaver-2.8.0/src/gnome-wall-clock.c0000664000175000017500000002012512610211212020637 0ustar fabiofabio/* -*- mode: C; c-file-style: "linux"; indent-tabs-mode: t -*- * gnome-wall-clock.h - monitors TZ setting files and signals changes * * Copyright (C) 2010 Red Hat, Inc. * Copyright (C) 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Author: Colin Walters */ #include "config.h" #include #define GNOME_DESKTOP_USE_UNSTABLE_API #include "gnome-wall-clock.h" #include #include "gnome-datetime-source.h" struct _GnomeWallClockPrivate { guint clock_update_id; char *clock_string; GFileMonitor *tz_monitor; GSettings *desktop_settings; GSettings *screensaver_settings; gboolean use_custom; gchar *custom_time; gchar *custom_date; gchar *font_time; gchar *font_date; gboolean use_24h; gboolean show_date; }; enum { PROP_0, PROP_CLOCK }; G_DEFINE_TYPE (GnomeWallClock, gnome_wall_clock, G_TYPE_OBJECT); static gboolean update_clock (gpointer data); static void on_tz_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent *event, gpointer user_data); static void settings_changed_cb (GSettings *settings, const gchar *key, gpointer user_data) { GnomeWallClock *self = user_data; self->priv->use_custom = g_settings_get_boolean (self->priv->screensaver_settings, "use-custom-format"); self->priv->custom_time = g_settings_get_string (self->priv->screensaver_settings, "time-format"); self->priv->custom_date = g_settings_get_string (self->priv->screensaver_settings, "date-format"); self->priv->font_time = g_settings_get_string (self->priv->screensaver_settings, "font-time"); self->priv->font_date = g_settings_get_string (self->priv->screensaver_settings, "font-date"); self->priv->show_date = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-date"); self->priv->use_24h = g_settings_get_boolean (self->priv->desktop_settings, "clock-use-24h"); } static void gnome_wall_clock_init (GnomeWallClock *self) { GFile *tz; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_WALL_CLOCK, GnomeWallClockPrivate); self->priv->clock_string = NULL; tz = g_file_new_for_path ("/etc/localtime"); self->priv->tz_monitor = g_file_monitor_file (tz, 0, NULL, NULL); g_object_unref (tz); self->priv->screensaver_settings = g_settings_new ("org.cinnamon.desktop.screensaver"); self->priv->use_custom = g_settings_get_boolean (self->priv->screensaver_settings, "use-custom-format"); self->priv->custom_time = g_settings_get_string (self->priv->screensaver_settings, "time-format"); self->priv->custom_date = g_settings_get_string (self->priv->screensaver_settings, "date-format"); self->priv->font_time = g_settings_get_string (self->priv->screensaver_settings, "font-time"); self->priv->font_date = g_settings_get_string (self->priv->screensaver_settings, "font-date"); self->priv->desktop_settings = g_settings_new ("org.cinnamon.desktop.interface"); self->priv->show_date = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-date"); self->priv->use_24h = g_settings_get_boolean (self->priv->desktop_settings, "clock-use-24h"); g_signal_connect (self->priv->screensaver_settings, "changed", G_CALLBACK (settings_changed_cb), self); g_signal_connect (self->priv->desktop_settings, "changed", G_CALLBACK (settings_changed_cb), self); g_signal_connect (self->priv->tz_monitor, "changed", G_CALLBACK (on_tz_changed), self); update_clock (self); } static void gnome_wall_clock_dispose (GObject *object) { GnomeWallClock *self = GNOME_WALL_CLOCK (object); if (self->priv->clock_update_id) { g_source_remove (self->priv->clock_update_id); self->priv->clock_update_id = 0; } if (self->priv->tz_monitor != NULL) { g_object_unref (self->priv->tz_monitor); self->priv->tz_monitor = NULL; } if (self->priv->desktop_settings != NULL) { g_object_unref (self->priv->desktop_settings); self->priv->desktop_settings = NULL; } if (self->priv->screensaver_settings != NULL) { g_object_unref (self->priv->screensaver_settings); self->priv->screensaver_settings = NULL; } G_OBJECT_CLASS (gnome_wall_clock_parent_class)->dispose (object); } static void gnome_wall_clock_finalize (GObject *object) { GnomeWallClock *self = GNOME_WALL_CLOCK (object); g_free (self->priv->clock_string); G_OBJECT_CLASS (gnome_wall_clock_parent_class)->finalize (object); } static void gnome_wall_clock_get_property (GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec) { GnomeWallClock *self = GNOME_WALL_CLOCK (gobject); switch (prop_id) { case PROP_CLOCK: g_value_set_string (value, self->priv->clock_string); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } } static void gnome_wall_clock_class_init (GnomeWallClockClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->get_property = gnome_wall_clock_get_property; gobject_class->dispose = gnome_wall_clock_dispose; gobject_class->finalize = gnome_wall_clock_finalize; /** * GnomeWallClock:clock: * * A formatted string representing the current clock display. */ g_object_class_install_property (gobject_class, PROP_CLOCK, g_param_spec_string ("clock", "", "", NULL, G_PARAM_READABLE)); g_type_class_add_private (gobject_class, sizeof (GnomeWallClockPrivate)); } static gboolean update_clock (gpointer data) { GnomeWallClock *self = data; const char *time_value; const char *date_value; GSource *source; GDateTime *now; GDateTime *expiry; now = g_date_time_new_now_local (); expiry = g_date_time_add_seconds (now, 60 - g_date_time_get_second (now)); if (self->priv->clock_update_id) { g_source_remove (self->priv->clock_update_id); self->priv->clock_update_id = 0; } source = _gnome_datetime_source_new (now, expiry, TRUE); g_source_set_priority (source, G_PRIORITY_HIGH); g_source_set_callback (source, update_clock, self, NULL); self->priv->clock_update_id = g_source_attach (source, NULL); g_source_unref (source); if (!self->priv->use_custom) { if (self->priv->show_date) { date_value = g_date_time_format (now, _("%A, %B %e")); } else { date_value = ""; } if (self->priv->use_24h) { time_value = g_strchug(g_date_time_format(now, "%H:%M")); } else { time_value = g_strchug(g_date_time_format(now, "%l:%M %p")); } } else { date_value = g_date_time_format(now, self->priv->custom_date); time_value = g_date_time_format(now, self->priv->custom_time); } g_free (self->priv->clock_string); self->priv->clock_string = g_strdup_printf ("%s\n%s", self->priv->font_time, time_value, self->priv->font_date, date_value); g_date_time_unref (now); g_date_time_unref (expiry); g_object_notify ((GObject*)self, "clock"); return FALSE; } static void on_tz_changed (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent *event, gpointer user_data) { update_clock (user_data); } const char * gnome_wall_clock_get_clock (GnomeWallClock *clock) { return clock->priv->clock_string; } cinnamon-screensaver-2.8.0/src/subprocs.h0000664000175000017500000000215112610211212017350 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * subprocs.c --- choosing, spawning, and killing screenhacks. * * xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #ifndef __GS_SUBPROCS_H #define __GS_SUBPROCS_H #include G_BEGIN_DECLS void unblock_sigchld (void); #ifdef HAVE_SIGACTION sigset_t #else /* !HAVE_SIGACTION */ int #endif /* !HAVE_SIGACTION */ block_sigchld (void); int signal_pid (int pid, int signal); void await_dying_children (int pid, gboolean debug); G_END_DECLS #endif /* __GS_SUBPROCS_H */ cinnamon-screensaver-2.8.0/src/gs-debug.h0000664000175000017500000000507612610211212017216 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_DEBUG_H #define __GS_DEBUG_H #include #include G_BEGIN_DECLS #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define gs_debug(...) gs_debug_real (__func__, __FILE__, __LINE__, __VA_ARGS__) #elif defined(__GNUC__) && __GNUC__ >= 3 #define gs_debug(...) gs_debug_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) #else #define gs_debug(...) #endif void gs_debug_init (gboolean debug, gboolean to_file); gboolean gs_debug_enabled (void); void gs_debug_shutdown (void); void gs_debug_real (const char *func, const char *file, int line, const char *format, ...); #ifdef ENABLE_PROFILING #ifdef G_HAVE_ISO_VARARGS #define gs_profile_start(...) _gs_profile_log (G_STRFUNC, "start", __VA_ARGS__) #define gs_profile_end(...) _gs_profile_log (G_STRFUNC, "end", __VA_ARGS__) #define gs_profile_msg(...) _gs_profile_log (NULL, NULL, __VA_ARGS__) #elif defined(G_HAVE_GNUC_VARARGS) #define gs_profile_start(format...) _gs_profile_log (G_STRFUNC, "start", format) #define gs_profile_end(format...) _gs_profile_log (G_STRFUNC, "end", format) #define gs_profile_msg(format...) _gs_profile_log (NULL, NULL, format) #endif #else #define gs_profile_start(...) #define gs_profile_end(...) #define gs_profile_msg(...) #endif void _gs_profile_log (const char *func, const char *note, const char *format, ...) G_GNUC_PRINTF (3, 4); G_END_DECLS #endif /* __GS_DEBUG_H */ cinnamon-screensaver-2.8.0/src/subprocs.c0000664000175000017500000001040612610211212017345 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * subprocs.c --- choosing, spawning, and killing screenhacks. * * xscreensaver, Copyright (c) 1991-2003 Jamie Zawinski * Modified: Copyright (c) 2004 William Jon McCann * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #include "config.h" #include #include #include #include #ifndef ESRCH # include #endif #include /* sys/resource.h needs this for timeval */ # include /* for waitpid() and associated macros */ #ifdef VMS # include # include /* for close */ # include /* for getpid */ # define pid_t int # define fork vfork #endif /* VMS */ #include /* for the signal names */ #include #include "subprocs.h" #if !defined(SIGCHLD) && defined(SIGCLD) # define SIGCHLD SIGCLD #endif /* Semaphore to temporarily turn the SIGCHLD handler into a no-op. Don't alter this directly -- use block_sigchld() / unblock_sigchld(). */ static int block_sigchld_handler = 0; #ifdef HAVE_SIGACTION sigset_t #else /* !HAVE_SIGACTION */ int #endif /* !HAVE_SIGACTION */ block_sigchld (void) { #ifdef HAVE_SIGACTION sigset_t child_set; sigemptyset (&child_set); sigaddset (&child_set, SIGCHLD); sigaddset (&child_set, SIGPIPE); sigprocmask (SIG_BLOCK, &child_set, 0); #endif /* HAVE_SIGACTION */ block_sigchld_handler++; #ifdef HAVE_SIGACTION return child_set; #else /* !HAVE_SIGACTION */ return 0; #endif /* !HAVE_SIGACTION */ } void unblock_sigchld (void) { #ifdef HAVE_SIGACTION sigset_t child_set; sigemptyset (&child_set); sigaddset (&child_set, SIGCHLD); sigaddset (&child_set, SIGPIPE); sigprocmask (SIG_UNBLOCK, &child_set, 0); #endif /* HAVE_SIGACTION */ block_sigchld_handler--; } int signal_pid (int pid, int signal) { int status = -1; gboolean verbose = TRUE; if (block_sigchld_handler) /* This function should not be called from the signal handler. */ abort(); block_sigchld (); /* we control the horizontal... */ status = kill (pid, signal); if (verbose && status < 0) { if (errno == ESRCH) g_message ("Child process %lu was already dead.", (unsigned long) pid); else { char buf [1024]; snprintf (buf, sizeof (buf), "Couldn't kill child process %lu", (unsigned long) pid); perror (buf); } } unblock_sigchld (); if (block_sigchld_handler < 0) abort (); return status; } #ifndef VMS void await_dying_children (int pid, gboolean debug) { while (1) { int wait_status = 0; pid_t kid; errno = 0; kid = waitpid (-1, &wait_status, WNOHANG|WUNTRACED); if (debug) { if (kid < 0 && errno) g_message ("waitpid(%d) ==> %ld (%d)", pid, (long) kid, errno); else if (kid != 0) g_message ("waitpid(%d) ==> %ld", pid, (long) kid); } /* 0 means no more children to reap. -1 means error -- except "interrupted system call" isn't a "real" error, so if we get that, we should just try again. */ if (kid < 0 && errno != EINTR) break; } } #else /* VMS */ static void await_dying_children (saver_info *si) { return; } #endif /* VMS */ cinnamon-screensaver-2.8.0/src/gs-debug.c0000664000175000017500000000765212610211212017213 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include "gs-debug.h" static gboolean debugging = FALSE; static FILE *debug_out = NULL; /* Based on rhythmbox/lib/rb-debug.c */ /* Our own funky debugging function, should only be used when something * is not going wrong, if something *is* wrong use g_warning. */ void gs_debug_real (const char *func, const char *file, const int line, const char *format, ...) { va_list args; char buffer [1025]; char *str_time; time_t the_time; if (debugging == FALSE) return; va_start (args, format); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-nonliteral" g_vsnprintf (buffer, 1024, format, args); #pragma clang diagnostic pop va_end (args); time (&the_time); str_time = g_new0 (char, 255); strftime (str_time, 254, "%H:%M:%S", localtime (&the_time)); fprintf ((debug_out ? debug_out : stderr), "[%s] %s:%d (%s):\t %s\n", func, file, line, str_time, buffer); if (debug_out) fflush (debug_out); g_free (str_time); } gboolean gs_debug_enabled (void) { return debugging; } void gs_debug_init (gboolean debug, gboolean to_file) { /* return if already initialized */ if (debugging == TRUE) { return; } debugging = debug; if (debug && to_file) { const char path [50] = "cinnamon_screensaver_debug_XXXXXX"; int fd; fd = g_file_open_tmp (path, NULL, NULL); if (fd >= 0) { debug_out = fdopen (fd, "a"); } } gs_debug ("Debugging %s", (debug) ? "enabled" : "disabled"); } void gs_debug_shutdown (void) { if (! debugging) return; gs_debug ("Shutting down debugging"); debugging = FALSE; if (debug_out != NULL) { fclose (debug_out); debug_out = NULL; } } void _gs_profile_log (const char *func, const char *note, const char *format, ...) { va_list args; char *str; char *formatted; if (format == NULL) { formatted = g_strdup (""); } else { va_start (args, format); formatted = g_strdup_vprintf (format, args); va_end (args); } if (func != NULL) { str = g_strdup_printf ("MARK: %s %s: %s %s", g_get_prgname(), func, note ? note : "", formatted); } else { str = g_strdup_printf ("MARK: %s: %s %s", g_get_prgname(), note ? note : "", formatted); } g_free (formatted); g_access (str, F_OK); g_free (str); } cinnamon-screensaver-2.8.0/src/gs-lock-plug.h0000664000175000017500000000572212610211212020023 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_LOCK_PLUG_H #define __GS_LOCK_PLUG_H #include G_BEGIN_DECLS typedef enum { GS_LOCK_PLUG_RESPONSE_NONE = -1, GS_LOCK_PLUG_RESPONSE_OK = -2, GS_LOCK_PLUG_RESPONSE_CANCEL = -3 } GSPlugResponseType; #define GS_TYPE_LOCK_PLUG (gs_lock_plug_get_type ()) #define GS_LOCK_PLUG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_LOCK_PLUG, GSLockPlug)) #define GS_LOCK_PLUG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_LOCK_PLUG, GSLockPlugClass)) #define GS_IS_LOCK_PLUG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_LOCK_PLUG)) #define GS_IS_LOCK_PLUG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_LOCK_PLUG)) #define GS_LOCK_PLUG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_LOCK_PLUG, GSLockPlugClass)) typedef struct GSLockPlugPrivate GSLockPlugPrivate; typedef struct { GtkPlug parent; GSLockPlugPrivate *priv; } GSLockPlug; typedef struct { GtkPlugClass parent_class; void (* response) (GSLockPlug *plug, gint response_id); /* Keybinding signals */ void (* close) (GSLockPlug *plug); } GSLockPlugClass; GType gs_lock_plug_get_type (void); GtkWidget * gs_lock_plug_new (void); int gs_lock_plug_run (GSLockPlug *plug); void gs_lock_plug_set_sensitive (GSLockPlug *plug, gboolean sensitive); void gs_lock_plug_enable_prompt (GSLockPlug *plug, const char *message, gboolean visible); void gs_lock_plug_disable_prompt (GSLockPlug *plug); void gs_lock_plug_set_busy (GSLockPlug *plug); void gs_lock_plug_set_ready (GSLockPlug *plug); void gs_lock_plug_get_text (GSLockPlug *plug, char **text); void gs_lock_plug_show_message (GSLockPlug *plug, const char *message); G_END_DECLS #endif /* __GS_LOCK_PLUG_H */ cinnamon-screensaver-2.8.0/src/gs-window-x11.c0000664000175000017500000024574412610211212020051 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2008 William Jon McCann * Copyright (C) 2008-2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "gnome-wall-clock.h" #include "gs-window.h" #include "gs-marshal.h" #include "subprocs.h" #include "gs-debug.h" #ifdef HAVE_SHAPE_EXT #include #endif static void gs_window_class_init (GSWindowClass *klass); static void gs_window_init (GSWindow *window); static void gs_window_finalize (GObject *object); static gboolean popup_dialog_idle (GSWindow *window); static void gs_window_dialog_finish (GSWindow *window); static void remove_command_watches (GSWindow *window); static void gs_window_show_screensaver (GSWindow *window); static void gs_window_hide_screensaver (GSWindow *window); static void screensaver_command_finish (GSWindow *window); static gboolean spawn_on_window (GSWindow *window, char *command, int *pid, GIOFunc watch_func, gpointer user_data, gint *watch_id); enum { DIALOG_RESPONSE_CANCEL, DIALOG_RESPONSE_OK }; #define MAX_QUEUED_EVENTS 16 #define INFO_BAR_SECONDS 30 #define SCREENSAVER_NAME_KEY "screensaver-name" #define GS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_WINDOW, GSWindowPrivate)) struct GSWindowPrivate { int monitor; GDBusConnection *session_bus; GdkRectangle geometry; guint obscured : 1; guint dialog_up : 1; guint lock_enabled : 1; guint user_switch_enabled : 1; guint logout_enabled : 1; guint keyboard_enabled : 1; guint64 logout_timeout; char *logout_command; char *keyboard_command; GtkWidget *stack; GtkWidget *vbox; GtkWidget *panel; GtkWidget *clock; GtkWidget *name_label; GtkWidget *lock_box; GtkWidget *lock_socket; GtkWidget *keyboard_socket; GtkWidget *info_bar; GtkWidget *info_content; GtkWidget *lock_screen; GtkWidget *screensaver; gint screensaver_pid; gint screensaver_watch_id; cairo_surface_t *background_surface; guint popup_dialog_idle_id; guint dialog_map_signal_id; guint dialog_unmap_signal_id; guint dialog_response_signal_id; guint watchdog_timer_id; guint info_bar_timer_id; gint lock_pid; gint lock_watch_id; gint dialog_response; gboolean dialog_quit_requested; gboolean dialog_shake_in_progress; gint keyboard_pid; gint keyboard_watch_id; GList *key_events; gdouble last_x; gdouble last_y; GTimer *timer; GnomeWallClock *clock_tracker; GSettings *settings; gchar *font_message; char *away_message; char *default_message; #ifdef HAVE_SHAPE_EXT int shape_event_base; #endif }; enum { ACTIVITY, DEACTIVATED, LAST_SIGNAL }; enum { PROP_0, PROP_OBSCURED, PROP_DIALOG_UP, PROP_LOCK_ENABLED, PROP_LOGOUT_ENABLED, PROP_KEYBOARD_ENABLED, PROP_KEYBOARD_COMMAND, PROP_LOGOUT_COMMAND, PROP_LOGOUT_TIMEOUT, PROP_MONITOR }; static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSWindow, gs_window, GTK_TYPE_WINDOW) static void set_invisible_cursor (GdkWindow *window, gboolean invisible) { GdkCursor *cursor = NULL; if (invisible) { cursor = gdk_cursor_new (GDK_BLANK_CURSOR); } gdk_window_set_cursor (window, cursor); if (cursor) { g_object_unref (cursor); } } /* derived from tomboy */ static void gs_window_override_user_time (GSWindow *window) { guint32 ev_time = gtk_get_current_event_time (); if (ev_time == 0) { gint ev_mask = gtk_widget_get_events (GTK_WIDGET (window)); if (!(ev_mask & GDK_PROPERTY_CHANGE_MASK)) { gtk_widget_add_events (GTK_WIDGET (window), GDK_PROPERTY_CHANGE_MASK); } /* * NOTE: Last resort for D-BUS or other non-interactive * openings. Causes roundtrip to server. Lame. */ ev_time = gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (window))); } gdk_x11_window_set_user_time (gtk_widget_get_window (GTK_WIDGET (window)), ev_time); } static void gs_window_reset_background_surface (GSWindow *window) { cairo_pattern_t *pattern; pattern = cairo_pattern_create_for_surface (window->priv->background_surface); gdk_window_set_background_pattern (gtk_widget_get_window (GTK_WIDGET (window)), pattern); cairo_pattern_destroy (pattern); gtk_widget_queue_draw (GTK_WIDGET (window)); } void gs_window_set_background_surface (GSWindow *window, cairo_surface_t *surface) { g_return_if_fail (GS_IS_WINDOW (window)); if (window->priv->background_surface != NULL) { cairo_surface_destroy (window->priv->background_surface); } if (surface != NULL) { window->priv->background_surface = cairo_surface_reference (surface); gs_window_reset_background_surface (window); } } static void gs_window_clear_to_background_surface (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); if (!gtk_widget_get_visible (GTK_WIDGET (window))) { return; } if (window->priv->background_surface == NULL) { return; } gs_debug ("Clearing window to background pixmap"); gs_window_reset_background_surface (window); } static void clear_widget (GtkWidget *widget) { GdkRGBA rgba = { 0.0, 0.0, 0.0, 1.0 }; if (!gtk_widget_get_realized (widget)) return; gtk_widget_override_background_color (widget, GTK_STATE_FLAG_NORMAL, &rgba); gtk_widget_queue_draw (GTK_WIDGET (widget)); } static cairo_region_t * get_outside_region (GSWindow *window) { int i; cairo_region_t *region; region = cairo_region_create (); for (i = 0; i < window->priv->monitor; i++) { GdkRectangle geometry; cairo_rectangle_int_t rectangle; gdk_screen_get_monitor_geometry (gtk_window_get_screen (GTK_WINDOW (window)), i, &geometry); rectangle.x = geometry.x; rectangle.y = geometry.y; rectangle.width = geometry.width; rectangle.height = geometry.height; cairo_region_union_rectangle (region, &rectangle); } return region; } static void update_geometry (GSWindow *window) { GdkRectangle geometry; cairo_region_t *outside_region; cairo_region_t *monitor_region; outside_region = get_outside_region (window); gdk_screen_get_monitor_geometry (gtk_window_get_screen (GTK_WINDOW (window)), window->priv->monitor, &geometry); gs_debug ("got geometry for monitor %d: x=%d y=%d w=%d h=%d", window->priv->monitor, geometry.x, geometry.y, geometry.width, geometry.height); monitor_region = cairo_region_create_rectangle ((const cairo_rectangle_int_t *)&geometry); cairo_region_subtract (monitor_region, outside_region); cairo_region_destroy (outside_region); cairo_region_get_extents (monitor_region, (cairo_rectangle_int_t *)&geometry); cairo_region_destroy (monitor_region); gs_debug ("using geometry for monitor %d: x=%d y=%d w=%d h=%d", window->priv->monitor, geometry.x, geometry.y, geometry.width, geometry.height); window->priv->geometry.x = geometry.x; window->priv->geometry.y = geometry.y; window->priv->geometry.width = geometry.width; window->priv->geometry.height = geometry.height; } static void screen_size_changed (GdkScreen *screen, GSWindow *window) { gs_debug ("Got screen size changed signal"); gtk_widget_queue_resize (GTK_WIDGET (window)); } /* copied from panel-toplevel.c */ static void gs_window_move_resize_window (GSWindow *window, gboolean move, gboolean resize) { GtkWidget *widget; widget = GTK_WIDGET (window); g_assert (gtk_widget_get_realized (widget)); gs_debug ("Move and/or resize window on monitor %d: x=%d y=%d w=%d h=%d", window->priv->monitor, window->priv->geometry.x, window->priv->geometry.y, window->priv->geometry.width, window->priv->geometry.height); if (move && resize) { gdk_window_move_resize (gtk_widget_get_window (widget), window->priv->geometry.x, window->priv->geometry.y, window->priv->geometry.width, window->priv->geometry.height); } else if (move) { gdk_window_move (gtk_widget_get_window (widget), window->priv->geometry.x, window->priv->geometry.y); } else if (resize) { gdk_window_resize (gtk_widget_get_window (widget), window->priv->geometry.width, window->priv->geometry.height); } } static void gs_window_real_unrealize (GtkWidget *widget) { g_signal_handlers_disconnect_by_func (gtk_window_get_screen (GTK_WINDOW (widget)), screen_size_changed, widget); if (GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize) { GTK_WIDGET_CLASS (gs_window_parent_class)->unrealize (widget); } } /* copied from gdk */ extern char **environ; static gchar ** spawn_make_environment_for_screen (GdkScreen *screen, gchar **envp) { gchar **retval = NULL; gchar *display_name; gint display_index = -1; gint i, env_len; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); if (envp == NULL) envp = environ; for (env_len = 0; envp[env_len]; env_len++) if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0) display_index = env_len; retval = g_new (char *, env_len + 1); retval[env_len] = NULL; display_name = gdk_screen_make_display_name (screen); for (i = 0; i < env_len; i++) if (i == display_index) retval[i] = g_strconcat ("DISPLAY=", display_name, NULL); else retval[i] = g_strdup (envp[i]); g_assert (i == env_len); g_free (display_name); return retval; } static void gs_window_real_realize (GtkWidget *widget) { if (GTK_WIDGET_CLASS (gs_window_parent_class)->realize) { GTK_WIDGET_CLASS (gs_window_parent_class)->realize (widget); } gs_window_override_user_time (GS_WINDOW (widget)); gs_window_move_resize_window (GS_WINDOW (widget), TRUE, TRUE); g_signal_connect (gtk_window_get_screen (GTK_WINDOW (widget)), "size_changed", G_CALLBACK (screen_size_changed), widget); } /* every so often we should raise the window in case another window has somehow gotten on top */ static gboolean watchdog_timer (GSWindow *window) { GtkWidget *widget = GTK_WIDGET (window); gdk_window_focus (gtk_widget_get_window (widget), GDK_CURRENT_TIME); return TRUE; } static void remove_watchdog_timer (GSWindow *window) { if (window->priv->watchdog_timer_id != 0) { g_source_remove (window->priv->watchdog_timer_id); window->priv->watchdog_timer_id = 0; } } static void add_watchdog_timer (GSWindow *window, glong timeout) { window->priv->watchdog_timer_id = g_timeout_add_seconds (timeout, (GSourceFunc)watchdog_timer, window); } static void remove_popup_dialog_idle (GSWindow *window) { if (window->priv->popup_dialog_idle_id != 0) { g_source_remove (window->priv->popup_dialog_idle_id); window->priv->popup_dialog_idle_id = 0; } } static void add_popup_dialog_idle (GSWindow *window) { window->priv->popup_dialog_idle_id = g_idle_add ((GSourceFunc)popup_dialog_idle, window); } static gboolean emit_deactivated_idle (GSWindow *window) { g_signal_emit (window, signals [DEACTIVATED], 0); return FALSE; } static void add_emit_deactivated_idle (GSWindow *window) { g_idle_add ((GSourceFunc)emit_deactivated_idle, window); } static void gs_window_raise (GSWindow *window) { GdkWindow *win; g_return_if_fail (GS_IS_WINDOW (window)); gs_debug ("Raising screensaver window"); win = gtk_widget_get_window (GTK_WIDGET (window)); gdk_window_raise (win); } static gboolean x11_window_is_ours (Window window) { GdkWindow *gwindow; gboolean ret; ret = FALSE; gwindow = gdk_x11_window_lookup_for_display (gdk_display_get_default (), window); if (gwindow && (window != GDK_ROOT_WINDOW ())) { ret = TRUE; } return ret; } #ifdef HAVE_SHAPE_EXT static void unshape_window (GSWindow *window) { gdk_window_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), NULL, 0, 0); } #endif static void gs_window_xevent (GSWindow *window, GdkXEvent *xevent) { XEvent *ev; ev = xevent; /* MapNotify is used to tell us when new windows are mapped. ConfigureNofify is used to tell us when windows are raised. */ switch (ev->xany.type) { case MapNotify: { XMapEvent *xme = &ev->xmap; if (! x11_window_is_ours (xme->window)) { gs_window_raise (window); } else { gs_debug ("not raising our windows"); } break; } case ConfigureNotify: { XConfigureEvent *xce = &ev->xconfigure; if (! x11_window_is_ours (xce->window)) { gs_window_raise (window); } else { gs_debug ("not raising our windows"); } break; } default: /* extension events */ #ifdef HAVE_SHAPE_EXT if (ev->xany.type == (window->priv->shape_event_base + ShapeNotify)) { /*XShapeEvent *xse = (XShapeEvent *) ev;*/ unshape_window (window); gs_debug ("Window was reshaped!"); } #endif break; } } static GdkFilterReturn xevent_filter (GdkXEvent *xevent, GdkEvent *event, GSWindow *window) { gs_window_xevent (window, xevent); return GDK_FILTER_CONTINUE; } static void select_popup_events (void) { XWindowAttributes attr; unsigned long events; gdk_error_trap_push (); memset (&attr, 0, sizeof (attr)); XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_ROOT_WINDOW (), &attr); events = SubstructureNotifyMask | attr.your_event_mask; XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_ROOT_WINDOW (), events); gdk_error_trap_pop_ignored (); } static void window_select_shape_events (GSWindow *window) { #ifdef HAVE_SHAPE_EXT unsigned long events; int shape_error_base; gdk_error_trap_push (); if (XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &window->priv->shape_event_base, &shape_error_base)) { events = ShapeNotifyMask; XShapeSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (window))), events); } gdk_error_trap_pop_ignored (); #endif } static gboolean on_screensaver_plug_removed (GtkSocket *socket, GSWindow *window) { gtk_widget_hide (GTK_WIDGET (socket)); window->priv->screensaver = NULL; return FALSE; } static void create_screensaver_socket (GSWindow *window, guint32 id) { window->priv->screensaver = gtk_socket_new (); gtk_stack_add_named (GTK_STACK (window->priv->stack), window->priv->screensaver, "screensaver"); gtk_widget_show (window->priv->screensaver); g_signal_connect (window->priv->screensaver, "plug-removed", G_CALLBACK (on_screensaver_plug_removed), window); gtk_socket_add_id (GTK_SOCKET (window->priv->screensaver), id); gs_window_show_screensaver (window); } /* adapted from gspawn.c */ static int wait_on_child (int pid) { int status; wait_again: if (waitpid (pid, &status, 0) < 0) { if (errno == EINTR) { goto wait_again; } else if (errno == ECHILD) { ; /* do nothing, child already reaped */ } else { gs_debug ("waitpid () should not fail in 'GSWindow'"); } } return status; } static gboolean screensaver_command_watch (GIOChannel *source, GIOCondition condition, GSWindow *window) { gboolean finished = FALSE; g_return_val_if_fail (GS_IS_WINDOW (window), FALSE); if (condition & G_IO_IN) { GIOStatus status; GError *error = NULL; char *line; line = NULL; status = g_io_channel_read_line (source, &line, NULL, NULL, &error); gs_debug ("command output: %s", line); switch (status) { case G_IO_STATUS_NORMAL: if (strstr (line, "WINDOW ID=") != NULL) { guint32 id; char c; if (1 == sscanf (line, " WINDOW ID= %" G_GUINT32_FORMAT " %c", &id, &c)) { create_screensaver_socket (window, id); } } break; case G_IO_STATUS_EOF: finished = TRUE; break; case G_IO_STATUS_ERROR: finished = TRUE; gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); return FALSE; default: break; } g_free (line); } else if (condition & G_IO_HUP) { finished = TRUE; } if (finished) { window->priv->screensaver_watch_id = 0; screensaver_command_finish (window); return FALSE; } return TRUE; } static void gs_window_real_show (GtkWidget *widget) { GSWindow *window; if (GTK_WIDGET_CLASS (gs_window_parent_class)->show) { GTK_WIDGET_CLASS (gs_window_parent_class)->show (widget); } set_invisible_cursor (gtk_widget_get_window (widget), TRUE); window = GS_WINDOW (widget); if (window->priv->timer) { g_timer_destroy (window->priv->timer); } window->priv->timer = g_timer_new (); remove_watchdog_timer (window); add_watchdog_timer (window, 30); select_popup_events (); window_select_shape_events (window); gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, window); const char *screensaver_name = g_settings_get_string (window->priv->settings, SCREENSAVER_NAME_KEY); if (strlen(screensaver_name) != 0 && !window->priv->screensaver_pid) { char *screensaver_path = g_build_filename(GTKBUILDERDIR, "screensavers", screensaver_name, "main", NULL); gboolean result = spawn_on_window (window, screensaver_path, &window->priv->screensaver_pid, (GIOFunc)screensaver_command_watch, window, &window->priv->screensaver_watch_id); if (!result) { screensaver_path = g_build_filename(g_get_home_dir(), ".local/share/cinnamon-screensaver/screensavers", screensaver_name, "main", NULL); spawn_on_window (window, screensaver_path, &window->priv->screensaver_pid, (GIOFunc)screensaver_command_watch, window, &window->priv->screensaver_watch_id); } g_free (screensaver_path); } } static void set_info_text_and_icon (GSWindow *window, const char *icon_stock_id, const char *primary_text, const char *secondary_text) { GtkWidget *content_area; GtkWidget *hbox_content; GtkWidget *image; GtkWidget *vbox; gchar *primary_markup; gchar *secondary_markup; GtkWidget *primary_label; GtkWidget *secondary_label; hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); gtk_widget_show (hbox_content); image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG); gtk_widget_show (image); gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (hbox_content), vbox, FALSE, FALSE, 0); primary_markup = g_strdup_printf ("%s", primary_text); primary_label = gtk_label_new (primary_markup); g_free (primary_markup); gtk_widget_show (primary_label); gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0); gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE); gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE); gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5); if (secondary_text != NULL) { secondary_markup = g_strdup_printf ("%s", secondary_text); secondary_label = gtk_label_new (secondary_markup); g_free (secondary_markup); gtk_widget_show (secondary_label); gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0); gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE); gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE); gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5); } /* remove old content */ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (window->priv->info_bar)); if (window->priv->info_content != NULL) { gtk_container_remove (GTK_CONTAINER (content_area), window->priv->info_content); } gtk_box_pack_start (GTK_BOX (content_area), hbox_content, TRUE, FALSE, 0); window->priv->info_content = hbox_content; } static gboolean info_bar_timeout (GSWindow *window) { window->priv->info_bar_timer_id = 0; gtk_widget_hide (window->priv->info_bar); return FALSE; } void gs_window_show_message (GSWindow *window, const char *summary, const char *body, const char *icon) { g_return_if_fail (GS_IS_WINDOW (window)); set_info_text_and_icon (window, icon, summary, body); gtk_widget_show (window->priv->info_bar); if (window->priv->info_bar_timer_id > 0) { g_source_remove (window->priv->info_bar_timer_id); window->priv->info_bar_timer_id = 0; } window->priv->info_bar_timer_id = g_timeout_add_seconds (INFO_BAR_SECONDS, (GSourceFunc)info_bar_timeout, window); } void gs_window_show (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); gtk_widget_show (GTK_WIDGET (window)); } static void gs_window_real_hide (GtkWidget *widget) { GSWindow *window; window = GS_WINDOW (widget); gdk_window_remove_filter (NULL, (GdkFilterFunc)xevent_filter, window); remove_watchdog_timer (window); if (GTK_WIDGET_CLASS (gs_window_parent_class)->hide) { GTK_WIDGET_CLASS (gs_window_parent_class)->hide (widget); } } void gs_window_destroy (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); gs_window_cancel_unlock_request (window); screensaver_command_finish (window); gtk_widget_destroy (GTK_WIDGET (window)); } GdkWindow * gs_window_get_gdk_window (GSWindow *window) { g_return_val_if_fail (GS_IS_WINDOW (window), NULL); return gtk_widget_get_window (GTK_WIDGET (window)); } /* just for debugging */ static gboolean error_watch (GIOChannel *source, GIOCondition condition, gpointer data) { gboolean finished = FALSE; if (condition & G_IO_IN) { GIOStatus status; GError *error = NULL; char *line; line = NULL; status = g_io_channel_read_line (source, &line, NULL, NULL, &error); switch (status) { case G_IO_STATUS_NORMAL: gs_debug ("command error output: %s", line); break; case G_IO_STATUS_EOF: finished = TRUE; break; case G_IO_STATUS_ERROR: finished = TRUE; gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); return FALSE; case G_IO_STATUS_AGAIN: default: break; } g_free (line); } else if (condition & G_IO_HUP) { finished = TRUE; } if (finished) { return FALSE; } return TRUE; } static gboolean spawn_on_window (GSWindow *window, char *command, int *pid, GIOFunc watch_func, gpointer user_data, gint *watch_id) { int argc; char **argv; char **envp; GError *error; gboolean result; GIOChannel *channel; int standard_output; int standard_error; int child_pid; int id; error = NULL; if (! g_shell_parse_argv (command, &argc, &argv, &error)) { gs_debug ("Could not parse command: %s", error->message); g_error_free (error); return FALSE; } envp = spawn_make_environment_for_screen (gtk_window_get_screen (GTK_WINDOW (window)), NULL); error = NULL; result = g_spawn_async_with_pipes (NULL, argv, envp, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, NULL, &standard_output, &standard_error, &error); if (! result) { gs_debug ("Could not start command '%s': %s", command, error->message); g_error_free (error); g_strfreev (argv); return FALSE; } if (pid != NULL) { *pid = child_pid; } else { g_spawn_close_pid (child_pid); } /* output channel */ channel = g_io_channel_unix_new (standard_output); g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, NULL); id = g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, watch_func, user_data); if (watch_id != NULL) { *watch_id = id; } g_io_channel_unref (channel); /* error channel */ channel = g_io_channel_unix_new (standard_error); g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, NULL); id = g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, error_watch, NULL); g_io_channel_unref (channel); g_strfreev (argv); g_strfreev (envp); return result; } static void lock_plug_added (GtkWidget *widget, GSWindow *window) { gtk_widget_show (widget); } static gboolean lock_plug_removed (GtkWidget *widget, GSWindow *window) { gtk_widget_hide (widget); gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box)); window->priv->lock_box = NULL; return TRUE; } static void keyboard_plug_added (GtkWidget *widget, GSWindow *window) { gtk_widget_show (widget); } static gboolean keyboard_plug_removed (GtkWidget *widget, GSWindow *window) { gtk_widget_hide (widget); gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->keyboard_socket)); return TRUE; } static void keyboard_socket_destroyed (GtkWidget *widget, GSWindow *window) { g_signal_handlers_disconnect_by_func (widget, keyboard_socket_destroyed, window); g_signal_handlers_disconnect_by_func (widget, keyboard_plug_added, window); g_signal_handlers_disconnect_by_func (widget, keyboard_plug_removed, window); window->priv->keyboard_socket = NULL; } static void forward_key_events (GSWindow *window) { window->priv->key_events = g_list_reverse (window->priv->key_events); while (window->priv->key_events != NULL) { GdkEventKey *event = window->priv->key_events->data; gtk_window_propagate_key_event (GTK_WINDOW (window), event); gdk_event_free ((GdkEvent *)event); window->priv->key_events = g_list_delete_link (window->priv->key_events, window->priv->key_events); } } static void remove_key_events (GSWindow *window) { window->priv->key_events = g_list_reverse (window->priv->key_events); while (window->priv->key_events) { GdkEventKey *event = window->priv->key_events->data; gdk_event_free ((GdkEvent *)event); window->priv->key_events = g_list_delete_link (window->priv->key_events, window->priv->key_events); } } static void lock_socket_show (GtkWidget *widget, GSWindow *window) { gtk_widget_child_focus (window->priv->lock_socket, GTK_DIR_TAB_FORWARD); /* send queued events to the dialog */ forward_key_events (window); } static void lock_socket_destroyed (GtkWidget *widget, GSWindow *window) { g_signal_handlers_disconnect_by_func (widget, lock_socket_show, window); g_signal_handlers_disconnect_by_func (widget, lock_socket_destroyed, window); g_signal_handlers_disconnect_by_func (widget, lock_plug_added, window); g_signal_handlers_disconnect_by_func (widget, lock_plug_removed, window); window->priv->lock_socket = NULL; } static void create_keyboard_socket (GSWindow *window, guint32 id) { int height; height = (gdk_screen_get_height (gtk_widget_get_screen (GTK_WIDGET (window)))) / 4; window->priv->keyboard_socket = gtk_socket_new (); gtk_widget_set_size_request (window->priv->keyboard_socket, -1, height); g_signal_connect (window->priv->keyboard_socket, "destroy", G_CALLBACK (keyboard_socket_destroyed), window); g_signal_connect (window->priv->keyboard_socket, "plug_added", G_CALLBACK (keyboard_plug_added), window); g_signal_connect (window->priv->keyboard_socket, "plug_removed", G_CALLBACK (keyboard_plug_removed), window); gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->keyboard_socket, FALSE, FALSE, 0); gtk_socket_add_id (GTK_SOCKET (window->priv->keyboard_socket), id); } static void kill_keyboard_command (GSWindow *window) { if (window->priv->keyboard_pid > 0) { signal_pid (window->priv->keyboard_pid, SIGTERM); } } static void kill_dialog_command (GSWindow *window) { /* If a dialog is up we need to signal it and wait on it */ if (window->priv->lock_pid > 0) { signal_pid (window->priv->lock_pid, SIGTERM); } } static void gs_window_show_screensaver (GSWindow *window) { if (window->priv->screensaver) { gtk_stack_set_visible_child_name (GTK_STACK (window->priv->stack), "screensaver"); } } static void gs_window_hide_screensaver (GSWindow *window) { gtk_stack_set_visible_child_name (GTK_STACK (window->priv->stack), "lock_screen"); } static void kill_screensaver_command (GSWindow *window) { if (window->priv->screensaver_pid > 0) { signal_pid (window->priv->screensaver_pid, SIGTERM); } } static void screensaver_command_finish (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); gs_debug ("Screensaver finished"); gs_window_hide_screensaver (window); if (window->priv->screensaver) { gtk_widget_destroy (window->priv->screensaver); window->priv->screensaver = NULL; } kill_screensaver_command (window); if (window->priv->screensaver_pid > 0) { window->priv->screensaver_watch_id = 0; wait_on_child (window->priv->screensaver_pid); g_spawn_close_pid (window->priv->screensaver_pid); window->priv->screensaver_pid = 0; } } static void keyboard_command_finish (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); /* send a signal just in case */ kill_keyboard_command (window); gs_debug ("Keyboard finished"); if (window->priv->keyboard_pid > 0) { wait_on_child (window->priv->keyboard_pid); g_spawn_close_pid (window->priv->keyboard_pid); window->priv->keyboard_pid = 0; } } static gboolean keyboard_command_watch (GIOChannel *source, GIOCondition condition, GSWindow *window) { gboolean finished = FALSE; g_return_val_if_fail (GS_IS_WINDOW (window), FALSE); if (condition & G_IO_IN) { GIOStatus status; GError *error = NULL; char *line; line = NULL; status = g_io_channel_read_line (source, &line, NULL, NULL, &error); switch (status) { case G_IO_STATUS_NORMAL: { guint32 id; char c; gs_debug ("keyboard command output: %s", line); if (1 == sscanf (line, " %" G_GUINT32_FORMAT " %c", &id, &c)) { create_keyboard_socket (window, id); } } break; case G_IO_STATUS_EOF: finished = TRUE; break; case G_IO_STATUS_ERROR: finished = TRUE; gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); return FALSE; case G_IO_STATUS_AGAIN: default: break; } g_free (line); } else if (condition & G_IO_HUP) { finished = TRUE; } if (finished) { window->priv->keyboard_watch_id = 0; keyboard_command_finish (window); return FALSE; } return TRUE; } static void embed_keyboard (GSWindow *window) { gboolean res; if (! window->priv->keyboard_enabled || window->priv->keyboard_command == NULL) return; gs_debug ("Adding embedded keyboard widget"); /* FIXME: verify command is safe */ gs_debug ("Running command: %s", window->priv->keyboard_command); res = spawn_on_window (window, window->priv->keyboard_command, &window->priv->keyboard_pid, (GIOFunc)keyboard_command_watch, window, &window->priv->keyboard_watch_id); if (! res) { gs_debug ("Could not start command: %s", window->priv->keyboard_command); } } static void create_lock_socket (GSWindow *window, guint32 id) { window->priv->lock_socket = gtk_socket_new (); window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_widget_show (window->priv->lock_box); gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->lock_box, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (window->priv->lock_box), window->priv->lock_socket); g_signal_connect (window->priv->lock_socket, "show", G_CALLBACK (lock_socket_show), window); g_signal_connect (window->priv->lock_socket, "destroy", G_CALLBACK (lock_socket_destroyed), window); g_signal_connect (window->priv->lock_socket, "plug_added", G_CALLBACK (lock_plug_added), window); g_signal_connect (window->priv->lock_socket, "plug_removed", G_CALLBACK (lock_plug_removed), window); gtk_socket_add_id (GTK_SOCKET (window->priv->lock_socket), id); if (window->priv->keyboard_enabled) { embed_keyboard (window); } } static void gs_window_dialog_finish (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); gs_debug ("Dialog finished"); /* make sure we finish the keyboard and screensaver thing too */ keyboard_command_finish (window); /* send a signal just in case */ kill_dialog_command (window); if (window->priv->lock_pid > 0) { wait_on_child (window->priv->lock_pid); g_spawn_close_pid (window->priv->lock_pid); window->priv->lock_pid = 0; } /* remove events for the case were we failed to show socket */ remove_key_events (window); } static void maybe_kill_dialog (GSWindow *window) { if (!window->priv->dialog_shake_in_progress && window->priv->dialog_quit_requested && window->priv->lock_pid > 0) { kill (window->priv->lock_pid, SIGTERM); } } /* very rudimentary animation for indicating an auth failure */ static void shake_dialog (GSWindow *window) { int i; guint left; guint right; window->priv->dialog_shake_in_progress = TRUE; for (i = 0; i < 9; i++) { if (i % 2 == 0) { left = 30; right = 0; } else { left = 0; right = 30; } if (! window->priv->lock_box) { break; } gtk_alignment_set_padding (GTK_ALIGNMENT (window->priv->lock_box), 0, 0, left, right); while (gtk_events_pending ()) { gtk_main_iteration (); } g_usleep (10000); } window->priv->dialog_shake_in_progress = FALSE; maybe_kill_dialog (window); } static void window_set_dialog_up (GSWindow *window, gboolean dialog_up) { if (window->priv->dialog_up == dialog_up) { return; } window->priv->dialog_up = dialog_up; g_object_notify (G_OBJECT (window), "dialog-up"); } static void popdown_dialog (GSWindow *window) { gs_window_dialog_finish (window); set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), TRUE); window_set_dialog_up (window, FALSE); /* reset the pointer positions */ window->priv->last_x = -1; window->priv->last_y = -1; if (window->priv->lock_box != NULL) { gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box)); window->priv->lock_box = NULL; } remove_popup_dialog_idle (window); remove_command_watches (window); gs_window_show_screensaver (window); } static gboolean lock_command_watch (GIOChannel *source, GIOCondition condition, GSWindow *window) { gboolean finished = FALSE; g_return_val_if_fail (GS_IS_WINDOW (window), FALSE); if (condition & G_IO_IN) { GIOStatus status; GError *error = NULL; char *line; line = NULL; status = g_io_channel_read_line (source, &line, NULL, NULL, &error); switch (status) { case G_IO_STATUS_NORMAL: gs_debug ("command output: %s", line); if (strstr (line, "WINDOW ID=") != NULL) { gs_debug ("WINDOW ID command"); guint32 id; char c; if (1 == sscanf (line, " WINDOW ID= %" G_GUINT32_FORMAT " %c", &id, &c)) { gs_debug ("create socket call"); create_lock_socket (window, id); } } else if (strstr (line, "NOTICE=") != NULL) { if (strstr (line, "NOTICE=AUTH FAILED") != NULL) { shake_dialog (window); } } else if (strstr (line, "RESPONSE=") != NULL) { if (strstr (line, "RESPONSE=OK") != NULL) { gs_debug ("Got OK response"); window->priv->dialog_response = DIALOG_RESPONSE_OK; } else { gs_debug ("Got CANCEL response"); window->priv->dialog_response = DIALOG_RESPONSE_CANCEL; } finished = TRUE; } else if (strstr (line, "REQUEST QUIT") != NULL) { gs_debug ("Got request for quit"); window->priv->dialog_quit_requested = TRUE; maybe_kill_dialog (window); } break; case G_IO_STATUS_EOF: finished = TRUE; break; case G_IO_STATUS_ERROR: finished = TRUE; gs_debug ("Error reading from child: %s\n", error->message); g_error_free (error); return FALSE; case G_IO_STATUS_AGAIN: default: break; } g_free (line); } else if (condition & G_IO_HUP) { finished = TRUE; } if (finished) { popdown_dialog (window); if (window->priv->dialog_response == DIALOG_RESPONSE_OK) { kill_screensaver_command (window); add_emit_deactivated_idle (window); } window->priv->lock_watch_id = 0; return FALSE; } return TRUE; } static gboolean is_logout_enabled (GSWindow *window) { double elapsed; if (! window->priv->logout_enabled) { return FALSE; } if (! window->priv->logout_command) { return FALSE; } elapsed = g_timer_elapsed (window->priv->timer, NULL); if (window->priv->logout_timeout < (elapsed * 1000)) { return TRUE; } return FALSE; } static gboolean is_user_switch_enabled (GSWindow *window) { return window->priv->user_switch_enabled; } static void popup_dialog (GSWindow *window) { gboolean result; char *tmp; GString *command; gs_debug ("Popping up dialog"); tmp = g_build_filename (LIBEXECDIR, "cinnamon-screensaver-dialog", NULL); command = g_string_new (tmp); g_free (tmp); if (is_logout_enabled (window)) { command = g_string_append (command, " --enable-logout"); g_string_append_printf (command, " --logout-command='%s'", window->priv->logout_command); } if (is_user_switch_enabled (window)) { command = g_string_append (command, " --enable-switch"); } if (gs_debug_enabled ()) { command = g_string_append (command, " --verbose"); } set_invisible_cursor (gtk_widget_get_window (GTK_WIDGET (window)), FALSE); window->priv->dialog_quit_requested = FALSE; window->priv->dialog_shake_in_progress = FALSE; result = spawn_on_window (window, command->str, &window->priv->lock_pid, (GIOFunc)lock_command_watch, window, &window->priv->lock_watch_id); if (! result) { gs_debug ("Could not start command: %s", command->str); } g_string_free (command, TRUE); } static gboolean popup_dialog_idle (GSWindow *window) { popup_dialog (window); window->priv->popup_dialog_idle_id = 0; return FALSE; } void gs_window_request_unlock (GSWindow *window) { g_return_if_fail (GS_IS_WINDOW (window)); gs_debug ("Requesting unlock"); if (! gtk_widget_get_visible (GTK_WIDGET (window))) { gs_debug ("Request unlock but window is not visible!"); return; } if (window->priv->lock_watch_id > 0) { return; } if (! window->priv->lock_enabled) { add_emit_deactivated_idle (window); return; } if (window->priv->popup_dialog_idle_id == 0) { add_popup_dialog_idle (window); } window_set_dialog_up (window, TRUE); gs_window_hide_screensaver (window); } void gs_window_cancel_unlock_request (GSWindow *window) { /* FIXME: This is a bit of a hammer approach... * Maybe we should send a delete-event to * the plug? */ g_return_if_fail (GS_IS_WINDOW (window)); popdown_dialog (window); } void gs_window_set_lock_enabled (GSWindow *window, gboolean lock_enabled) { g_return_if_fail (GS_IS_WINDOW (window)); if (window->priv->lock_enabled == lock_enabled) { return; } window->priv->lock_enabled = lock_enabled; g_object_notify (G_OBJECT (window), "lock-enabled"); } void gs_window_set_screen (GSWindow *window, GdkScreen *screen) { g_return_if_fail (GS_IS_WINDOW (window)); g_return_if_fail (GDK_IS_SCREEN (screen)); gtk_window_set_screen (GTK_WINDOW (window), screen); } GdkScreen * gs_window_get_screen (GSWindow *window) { g_return_val_if_fail (GS_IS_WINDOW (window), NULL); return gtk_window_get_screen (GTK_WINDOW (window)); } void gs_window_set_keyboard_enabled (GSWindow *window, gboolean enabled) { g_return_if_fail (GS_IS_WINDOW (window)); window->priv->keyboard_enabled = enabled; } void gs_window_set_keyboard_command (GSWindow *window, const char *command) { g_return_if_fail (GS_IS_WINDOW (window)); g_free (window->priv->keyboard_command); if (command != NULL) { window->priv->keyboard_command = g_strdup (command); } else { window->priv->keyboard_command = NULL; } } void gs_window_set_logout_enabled (GSWindow *window, gboolean logout_enabled) { g_return_if_fail (GS_IS_WINDOW (window)); window->priv->logout_enabled = logout_enabled; } void gs_window_set_user_switch_enabled (GSWindow *window, gboolean user_switch_enabled) { g_return_if_fail (GS_IS_WINDOW (window)); window->priv->user_switch_enabled = user_switch_enabled; } void gs_window_set_logout_timeout (GSWindow *window, glong logout_timeout) { g_return_if_fail (GS_IS_WINDOW (window)); if (logout_timeout < 0) { window->priv->logout_timeout = 0; } else { window->priv->logout_timeout = logout_timeout; } } void gs_window_set_logout_command (GSWindow *window, const char *command) { g_return_if_fail (GS_IS_WINDOW (window)); g_free (window->priv->logout_command); if (command) { window->priv->logout_command = g_strdup (command); } else { window->priv->logout_command = NULL; } } void gs_window_set_monitor (GSWindow *window, int monitor) { g_return_if_fail (GS_IS_WINDOW (window)); if (window->priv->monitor == monitor) { return; } window->priv->monitor = monitor; gtk_widget_queue_resize (GTK_WIDGET (window)); g_object_notify (G_OBJECT (window), "monitor"); } int gs_window_get_monitor (GSWindow *window) { g_return_val_if_fail (GS_IS_WINDOW (window), -1); return window->priv->monitor; } static void gs_window_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GSWindow *self; self = GS_WINDOW (object); switch (prop_id) { case PROP_LOCK_ENABLED: gs_window_set_lock_enabled (self, g_value_get_boolean (value)); break; case PROP_KEYBOARD_ENABLED: gs_window_set_keyboard_enabled (self, g_value_get_boolean (value)); break; case PROP_KEYBOARD_COMMAND: gs_window_set_keyboard_command (self, g_value_get_string (value)); break; case PROP_LOGOUT_ENABLED: gs_window_set_logout_enabled (self, g_value_get_boolean (value)); break; case PROP_LOGOUT_COMMAND: gs_window_set_logout_command (self, g_value_get_string (value)); break; case PROP_LOGOUT_TIMEOUT: gs_window_set_logout_timeout (self, g_value_get_long (value)); break; case PROP_MONITOR: gs_window_set_monitor (self, g_value_get_int (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_window_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GSWindow *self; self = GS_WINDOW (object); switch (prop_id) { case PROP_LOCK_ENABLED: g_value_set_boolean (value, self->priv->lock_enabled); break; case PROP_KEYBOARD_ENABLED: g_value_set_boolean (value, self->priv->keyboard_enabled); break; case PROP_KEYBOARD_COMMAND: g_value_set_string (value, self->priv->keyboard_command); break; case PROP_LOGOUT_ENABLED: g_value_set_boolean (value, self->priv->logout_enabled); break; case PROP_LOGOUT_COMMAND: g_value_set_string (value, self->priv->logout_command); break; case PROP_LOGOUT_TIMEOUT: g_value_set_long (value, self->priv->logout_timeout); break; case PROP_MONITOR: g_value_set_int (value, self->priv->monitor); break; case PROP_OBSCURED: g_value_set_boolean (value, self->priv->obscured); break; case PROP_DIALOG_UP: g_value_set_boolean (value, self->priv->dialog_up); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void queue_key_event (GSWindow *window, GdkEventKey *event) { /* Eat the first return, enter, escape, or space */ if (window->priv->key_events == NULL && (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter || event->keyval == GDK_KEY_Escape || event->keyval == GDK_KEY_space)) { return; } /* Only cache MAX_QUEUED_EVENTS key events. If there are any more than this then something is wrong */ /* Don't queue keys that may cause focus navigation in the dialog */ if (g_list_length (window->priv->key_events) < MAX_QUEUED_EVENTS && event->keyval != GDK_KEY_Tab && event->keyval != GDK_KEY_Up && event->keyval != GDK_KEY_Down) { window->priv->key_events = g_list_prepend (window->priv->key_events, gdk_event_copy ((GdkEvent *)event)); } } static gboolean maybe_handle_activity (GSWindow *window) { gboolean handled; handled = FALSE; /* if we already have a socket then don't bother */ if (! window->priv->lock_socket && gtk_widget_get_sensitive (GTK_WIDGET (window))) { g_signal_emit (window, signals [ACTIVITY], 0, &handled); } return handled; } static void change_screen_brightness (GSWindow *window, const char *method) { GDBusMessage *message; if (window->priv->session_bus == NULL) { return; } gs_debug ("change_screen_brightness: %s", method); message = g_dbus_message_new_method_call ("org.cinnamon.SettingsDaemon", "/org/cinnamon/SettingsDaemon/Power", "org.cinnamon.SettingsDaemon.Power.Screen", method); g_dbus_connection_send_message (window->priv->session_bus, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); } static void change_keyboard_brightness (GSWindow *window, const char *method) { GDBusMessage *message; if (window->priv->session_bus == NULL) { return; } gs_debug ("change_keyboard_brightness: %s", method); message = g_dbus_message_new_method_call ("org.cinnamon.SettingsDaemon", "/org/cinnamon/SettingsDaemon/Power", "org.cinnamon.SettingsDaemon.Power.Keyboard", method); g_dbus_connection_send_message (window->priv->session_bus, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); } static gboolean gs_window_real_key_press_event (GtkWidget *widget, GdkEventKey *event) { GSWindow *window = GS_WINDOW (widget); g_debug ("KEY PRESS state: %u keyval %u; hw keycode: %u", event->state, event->keyval, event->hardware_keycode); /* Ignore brightness keys for the purpose of invoking the password * prompt (return TRUE), but do actually forward the brightness * events to the settings daemon. */ switch (event->keyval) { case GDK_KEY_MonBrightnessUp: change_screen_brightness (window, "StepUp"); return TRUE; case GDK_KEY_MonBrightnessDown: change_screen_brightness (window, "StepDown"); return TRUE; case GDK_KEY_KbdBrightnessUp: change_keyboard_brightness (window, "StepUp"); return TRUE; case GDK_KEY_KbdBrightnessDown: change_keyboard_brightness (window, "StepDown"); return TRUE; } maybe_handle_activity (window); queue_key_event (window, event); if (GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event) { GTK_WIDGET_CLASS (gs_window_parent_class)->key_press_event (widget, event); } return TRUE; } static gboolean gs_window_real_motion_notify_event (GtkWidget *widget, GdkEventMotion *event) { GSWindow *window; gdouble distance; gdouble min_distance; gdouble min_percentage = 0.1; GdkScreen *screen; window = GS_WINDOW (widget); screen = gs_window_get_screen (window); min_distance = gdk_screen_get_width (screen) * min_percentage; /* if the last position was not set then don't detect motion */ if (window->priv->last_x < 0 || window->priv->last_y < 0) { window->priv->last_x = event->x; window->priv->last_y = event->y; return FALSE; } /* just an approximate distance */ distance = MAX (ABS (window->priv->last_x - event->x), ABS (window->priv->last_y - event->y)); if (distance > min_distance) { maybe_handle_activity (window); window->priv->last_x = -1; window->priv->last_y = -1; } return FALSE; } static gboolean gs_window_real_button_press_event (GtkWidget *widget, GdkEventButton *event) { GSWindow *window; window = GS_WINDOW (widget); maybe_handle_activity (window); return FALSE; } static gboolean gs_window_real_scroll_event (GtkWidget *widget, GdkEventScroll *event) { GSWindow *window; window = GS_WINDOW (widget); maybe_handle_activity (window); return FALSE; } static void gs_window_real_size_request (GtkWidget *widget, GtkRequisition *requisition) { GSWindow *window; GtkBin *bin; GdkRectangle old_geometry; int position_changed = FALSE; int size_changed = FALSE; window = GS_WINDOW (widget); bin = GTK_BIN (widget); if (gtk_bin_get_child (bin) && gtk_widget_get_visible (gtk_bin_get_child (bin))) { gtk_widget_size_request (gtk_bin_get_child (bin), requisition); } old_geometry = window->priv->geometry; update_geometry (window); requisition->width = window->priv->geometry.width; requisition->height = window->priv->geometry.height; if (!gtk_widget_get_realized (widget)) { return; } if (old_geometry.width != window->priv->geometry.width || old_geometry.height != window->priv->geometry.height) { size_changed = TRUE; } if (old_geometry.x != window->priv->geometry.x || old_geometry.y != window->priv->geometry.y) { position_changed = TRUE; } gs_window_move_resize_window (window, position_changed, size_changed); } static gboolean gs_window_real_grab_broken (GtkWidget *widget, GdkEventGrabBroken *event) { if (event->grab_window != NULL) { gs_debug ("Grab broken on window %X %s, new grab on window %X", (guint32) GDK_WINDOW_XID (event->window), event->keyboard ? "keyboard" : "pointer", (guint32) GDK_WINDOW_XID (event->grab_window)); } else { gs_debug ("Grab broken on window %X %s, new grab is outside application", (guint32) GDK_WINDOW_XID (event->window), event->keyboard ? "keyboard" : "pointer"); } return FALSE; } gboolean gs_window_is_obscured (GSWindow *window) { g_return_val_if_fail (GS_IS_WINDOW (window), FALSE); return window->priv->obscured; } gboolean gs_window_is_dialog_up (GSWindow *window) { g_return_val_if_fail (GS_IS_WINDOW (window), FALSE); return window->priv->dialog_up; } static void window_set_obscured (GSWindow *window, gboolean obscured) { if (window->priv->obscured == obscured) { return; } window->priv->obscured = obscured; g_object_notify (G_OBJECT (window), "obscured"); } static gboolean gs_window_real_visibility_notify_event (GtkWidget *widget, GdkEventVisibility *event) { switch (event->state) { case GDK_VISIBILITY_FULLY_OBSCURED: window_set_obscured (GS_WINDOW (widget), TRUE); break; case GDK_VISIBILITY_PARTIAL: break; case GDK_VISIBILITY_UNOBSCURED: window_set_obscured (GS_WINDOW (widget), FALSE); break; default: break; } return FALSE; } static void gs_window_real_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width) { GtkRequisition requisition; gs_window_real_size_request (widget, &requisition); *minimal_width = *natural_width = requisition.width; } static void gs_window_real_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height) { GtkRequisition requisition; gs_window_real_size_request (widget, &requisition); *minimal_height = *natural_height = requisition.height; } static void gs_window_class_init (GSWindowClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->finalize = gs_window_finalize; object_class->get_property = gs_window_get_property; object_class->set_property = gs_window_set_property; widget_class->show = gs_window_real_show; widget_class->hide = gs_window_real_hide; widget_class->realize = gs_window_real_realize; widget_class->unrealize = gs_window_real_unrealize; widget_class->key_press_event = gs_window_real_key_press_event; widget_class->motion_notify_event = gs_window_real_motion_notify_event; widget_class->button_press_event = gs_window_real_button_press_event; widget_class->scroll_event = gs_window_real_scroll_event; widget_class->get_preferred_width = gs_window_real_get_preferred_width; widget_class->get_preferred_height = gs_window_real_get_preferred_height; widget_class->grab_broken_event = gs_window_real_grab_broken; widget_class->visibility_notify_event = gs_window_real_visibility_notify_event; g_type_class_add_private (klass, sizeof (GSWindowPrivate)); signals [ACTIVITY] = g_signal_new ("activity", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSWindowClass, activity), NULL, NULL, gs_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0); signals [DEACTIVATED] = g_signal_new ("deactivated", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSWindowClass, deactivated), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_object_class_install_property (object_class, PROP_OBSCURED, g_param_spec_boolean ("obscured", NULL, NULL, FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_DIALOG_UP, g_param_spec_boolean ("dialog-up", NULL, NULL, FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_LOCK_ENABLED, g_param_spec_boolean ("lock-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_ENABLED, g_param_spec_boolean ("logout-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_TIMEOUT, g_param_spec_long ("logout-timeout", NULL, NULL, -1, G_MAXLONG, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_COMMAND, g_param_spec_string ("logout-command", NULL, NULL, NULL, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_KEYBOARD_ENABLED, g_param_spec_boolean ("keyboard-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_KEYBOARD_COMMAND, g_param_spec_string ("keyboard-command", NULL, NULL, NULL, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_MONITOR, g_param_spec_int ("monitor", "Xinerama monitor", "The monitor (in terms of Xinerama) which the window is on", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); } static void create_info_bar (GSWindow *window) { window->priv->info_bar = gtk_info_bar_new (); gtk_widget_set_no_show_all (window->priv->info_bar, TRUE); gtk_box_pack_end (GTK_BOX (window->priv->vbox), window->priv->info_bar, FALSE, FALSE, 0); } static char * get_user_display_name (void) { const char *name; char *utf8_name; name = g_get_real_name (); if (name == NULL || strcmp (name, "Unknown") == 0) { name = g_get_user_name (); } utf8_name = NULL; if (name != NULL) { utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); } return utf8_name; } static void update_clock (GSWindow *window) { char *markup; if (window->priv->away_message != NULL && g_strcmp0(window->priv->away_message, "") != 0) { gchar *user_name = get_user_display_name (); markup = g_strdup_printf ("%s\n\n%s" "\n ~ %s", gnome_wall_clock_get_clock (window->priv->clock_tracker), window->priv->away_message, user_name); g_free (user_name); } else { markup = g_strdup_printf ("%s\n\n%s", gnome_wall_clock_get_clock (window->priv->clock_tracker), window->priv->font_message, window->priv->default_message); } gtk_label_set_markup (GTK_LABEL (window->priv->clock), markup); gtk_label_set_line_wrap (GTK_LABEL (window->priv->clock), TRUE); gtk_misc_set_alignment (GTK_MISC (window->priv->clock), 0.5, 0.5); g_free (markup); } static void on_clock_changed (GnomeWallClock *clock, GParamSpec *pspec, gpointer user_data) { update_clock (GS_WINDOW (user_data)); } static gboolean shade_background (GtkWidget *widget, cairo_t *cr, GSWindow *window) { cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.7); cairo_paint (cr); return FALSE; } static void on_realized (GtkWidget *widget, GSWindow *window) { gs_window_clear_to_background_surface (window); gtk_widget_queue_draw (widget); } void gs_window_set_away_message (GSWindow *window, const char *message) { g_return_if_fail (GS_IS_WINDOW (window)); g_free (window->priv->away_message); if (message) { window->priv->away_message = g_markup_escape_text (message, -1); } else { window->priv->away_message = NULL; } update_clock (window); } static void settings_changed_cb (GSettings *settings, const gchar *key, gpointer user_data) { GSWindow *window = user_data; g_clear_pointer (&window->priv->font_message, g_free); window->priv->font_message = g_settings_get_string (window->priv->settings, "font-message"); } static void gs_window_init (GSWindow *window) { window->priv = GS_WINDOW_GET_PRIVATE (window); window->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); window->priv->geometry.x = -1; window->priv->geometry.y = -1; window->priv->geometry.width = -1; window->priv->geometry.height = -1; window->priv->last_x = -1; window->priv->last_y = -1; window->priv->settings = g_settings_new ("org.cinnamon.desktop.screensaver"); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE); gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE); gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_set_events (GTK_WIDGET (window), gtk_widget_get_events (GTK_WIDGET (window)) | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); window->priv->stack = gtk_stack_new(); window->priv->lock_screen = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_stack_add_named (GTK_STACK (window->priv->stack), window->priv->lock_screen, "lock_screen"); gtk_widget_show (window->priv->stack); gtk_widget_show (window->priv->lock_screen); gtk_container_add (GTK_CONTAINER (window), window->priv->stack); GtkWidget *grid = gtk_grid_new(); GdkRGBA transparent_color = { 0.0, 0.0, 0.0, 0.0 }; gtk_widget_override_background_color(grid, GTK_STATE_NORMAL, &transparent_color); gtk_widget_show (grid); window->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show (window->priv->vbox); gtk_box_pack_start (GTK_BOX (window->priv->lock_screen), grid, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (grid), 6); gtk_widget_set_valign (window->priv->vbox, GTK_ALIGN_CENTER); gtk_widget_set_halign (window->priv->vbox, GTK_ALIGN_CENTER); gtk_widget_set_size_request(window->priv->vbox,450, -1); // Default message gchar *unesc = g_settings_get_string(window->priv->settings, "default-message"); window->priv->default_message = g_markup_escape_text (unesc, -1); g_free (unesc); // Clock -- need to find a way to make it appear on the bottom-left side of the background without shifting the position of the main dialog box window->priv->clock = gtk_label_new (NULL); gtk_widget_show (window->priv->clock); window->priv->clock_tracker = g_object_new (GNOME_TYPE_WALL_CLOCK, NULL); g_signal_connect (window->priv->clock_tracker, "notify::clock", G_CALLBACK (on_clock_changed), window); update_clock (window); gtk_misc_set_padding (GTK_MISC (window->priv->clock), 4, 4); gtk_grid_attach(GTK_GRID(grid), window->priv->clock, 0, 1, 1, 1); gtk_grid_attach(GTK_GRID(grid), window->priv->vbox, 1, 1, 1, 1); GtkWidget * right_label = gtk_label_new(NULL); gtk_widget_show (right_label); gtk_grid_attach(GTK_GRID(grid), right_label, 2, 1, 1, 1); gtk_grid_set_column_homogeneous (GTK_GRID(grid), TRUE); gtk_grid_set_column_spacing (GTK_GRID(grid), 6); gtk_widget_set_valign (grid, GTK_ALIGN_CENTER); gtk_widget_set_halign (grid, GTK_ALIGN_CENTER); gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_vexpand (grid, TRUE); window->priv->font_message = g_settings_get_string (window->priv->settings, "font-message"); g_signal_connect (window->priv->settings, "changed", G_CALLBACK (settings_changed_cb), window); g_signal_connect (window->priv->lock_screen, "draw", G_CALLBACK (shade_background), window); create_info_bar (window); } static void remove_command_watches (GSWindow *window) { if (window->priv->lock_watch_id != 0) { g_source_remove (window->priv->lock_watch_id); window->priv->lock_watch_id = 0; } if (window->priv->keyboard_watch_id != 0) { g_source_remove (window->priv->keyboard_watch_id); window->priv->keyboard_watch_id = 0; } if (window->priv->screensaver_watch_id != 0) { g_source_remove (window->priv->screensaver_watch_id); window->priv->screensaver_watch_id = 0; } } static void gs_window_finalize (GObject *object) { GSWindow *window; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_WINDOW (object)); window = GS_WINDOW (object); g_return_if_fail (window->priv != NULL); g_free (window->priv->away_message); g_free (window->priv->logout_command); g_free (window->priv->keyboard_command); g_free (window->priv->font_message); if (window->priv->clock_tracker) { g_object_unref (window->priv->clock_tracker); } if (window->priv->info_bar_timer_id > 0) { g_source_remove (window->priv->info_bar_timer_id); window->priv->info_bar_timer_id = 0; } remove_watchdog_timer (window); remove_popup_dialog_idle (window); if (window->priv->timer) { g_timer_destroy (window->priv->timer); } remove_key_events (window); remove_command_watches (window); gs_window_dialog_finish (window); if (window->priv->background_surface) { cairo_surface_destroy (window->priv->background_surface); } g_clear_object (&window->priv->settings); G_OBJECT_CLASS (gs_window_parent_class)->finalize (object); } GSWindow * gs_window_new (GdkScreen *screen, int monitor, gboolean lock_enabled) { GObject *result; result = g_object_new (GS_TYPE_WINDOW, "type", GTK_WINDOW_POPUP, "screen", screen, "monitor", monitor, "lock-enabled", lock_enabled, "app-paintable", TRUE, NULL); return GS_WINDOW (result); } cinnamon-screensaver-2.8.0/src/gs-lock-plug.c0000664000175000017500000016164212610211212020022 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2008 William Jon McCann * Copyright (C) 2008-2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WITH_KBD_LAYOUT_INDICATOR #include #endif #include "gs-lock-plug.h" #include "gs-debug.h" #define MDM_FLEXISERVER_COMMAND "mdmflexiserver" #define MDM_FLEXISERVER_ARGS "--startnew Standard" #define GDM_FLEXISERVER_COMMAND "gdmflexiserver" #define GDM_FLEXISERVER_ARGS "--startnew Standard" enum { AUTH_PAGE = 0, }; enum { LOCK_NONE = 0, LOCK_CAPS = 1 << 0, }; #define FACE_ICON_SIZE 48 #define DIALOG_TIMEOUT_MSEC 60000 static void gs_lock_plug_finalize (GObject *object); #define GS_LOCK_PLUG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_LOCK_PLUG, GSLockPlugPrivate)) struct GSLockPlugPrivate { GtkWidget *frame; GtkWidget *vbox; GtkWidget *auth_action_area; GtkWidget *auth_face_image; GtkWidget *auth_realname_label; GtkWidget *auth_username_label; GtkWidget *auth_prompt_label; GtkWidget *auth_prompt_entry; GtkWidget *auth_prompt_box; GtkWidget *auth_capslock_label; GtkWidget *auth_message_label; GtkWidget *auth_unlock_button; GtkWidget *auth_switch_button; GtkWidget *auth_logout_button; GtkWidget *auth_prompt_kbd_layout_indicator; int kbd_lock_mode; gboolean switch_enabled; gboolean logout_enabled; char *logout_command; guint timeout; guint cancel_timeout_id; guint auth_check_idle_id; guint response_idle_id; GList *key_events; }; typedef struct _ResponseData ResponseData; struct _ResponseData { gint response_id; }; enum { RESPONSE, CLOSE, LAST_SIGNAL }; enum { PROP_0, PROP_LOGOUT_ENABLED, PROP_LOGOUT_COMMAND, PROP_SWITCH_ENABLED }; static guint lock_plug_signals [LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (GSLockPlug, gs_lock_plug, GTK_TYPE_PLUG) static void gs_lock_plug_style_set (GtkWidget *widget, GtkStyle *previous_style) { GSLockPlug *plug; if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->style_set) { GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->style_set (widget, previous_style); } plug = GS_LOCK_PLUG (widget); gtk_container_set_border_width (GTK_CONTAINER (plug->priv->vbox), 20); gtk_box_set_spacing (GTK_BOX (plug->priv->vbox), 6); gtk_container_set_border_width (GTK_CONTAINER (plug->priv->auth_action_area), 0); gtk_box_set_spacing (GTK_BOX (plug->priv->auth_action_area), 6); gtk_box_set_homogeneous (GTK_BOX (plug->priv->auth_action_area), FALSE); gtk_button_box_set_child_non_homogeneous (GTK_BUTTON_BOX (plug->priv->auth_action_area), plug->priv->auth_switch_button, TRUE); } static gboolean process_is_running (const char * name) { int num_processes; gchar *command = g_strdup_printf ("pidof %s | wc -l", name); FILE *fp = popen(command, "r"); fscanf(fp, "%d", &num_processes); pclose(fp); g_free (command); if (num_processes > 0) { return TRUE; } else { return FALSE; } } static void do_user_switch (GSLockPlug *plug) { GError *error = NULL; GAppInfo *app; GAppLaunchContext *context; char *command; if (process_is_running ("mdm")) { command = g_strdup_printf ("%s %s", MDM_FLEXISERVER_COMMAND, MDM_FLEXISERVER_ARGS); error = NULL; context = (GAppLaunchContext*)gdk_app_launch_context_new (); app = g_app_info_create_from_commandline (command, MDM_FLEXISERVER_COMMAND, 0, &error); if (app) g_app_info_launch (app, NULL, context, &error); g_free (command); g_object_unref (context); g_object_unref (app); if (error != NULL) { gs_debug ("Unable to start MDM greeter: %s", error->message); g_error_free (error); } } else if (process_is_running ("gdm") || process_is_running("gdm3")) { command = g_strdup_printf ("%s %s", GDM_FLEXISERVER_COMMAND, GDM_FLEXISERVER_ARGS); error = NULL; context = (GAppLaunchContext*)gdk_app_launch_context_new (); app = g_app_info_create_from_commandline (command, GDM_FLEXISERVER_COMMAND, 0, &error); if (app) g_app_info_launch (app, NULL, context, &error); g_free (command); g_object_unref (context); g_object_unref (app); if (error != NULL) { gs_debug ("Unable to start GDM greeter: %s", error->message); g_error_free (error); } } else if (g_getenv("XDG_SEAT_PATH")) { GDBusConnection *bus; GVariant *result = NULL; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (error) g_warning ("Failed to get system bus: %s", error->message); g_clear_error (&error); if (bus) result = g_dbus_connection_call_sync (bus, "org.freedesktop.DisplayManager", g_getenv ("XDG_SEAT_PATH"), "org.freedesktop.DisplayManager.Seat", "SwitchToGreeter", g_variant_new ("()"), G_VARIANT_TYPE ("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) g_warning ("Failed to switch to greeter: %s", error->message); g_clear_error (&error); if (result) g_variant_unref (result); } } static void set_status_text (GSLockPlug *plug, const char *text) { if (plug->priv->auth_message_label != NULL) { gtk_label_set_text (GTK_LABEL (plug->priv->auth_message_label), text); } } void gs_lock_plug_set_sensitive (GSLockPlug *plug, gboolean sensitive) { g_return_if_fail (GS_IS_LOCK_PLUG (plug)); gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, sensitive); gtk_widget_set_sensitive (plug->priv->auth_action_area, sensitive); } static void remove_cancel_timeout (GSLockPlug *plug) { if (plug->priv->cancel_timeout_id > 0) { g_source_remove (plug->priv->cancel_timeout_id); plug->priv->cancel_timeout_id = 0; } } static void remove_response_idle (GSLockPlug *plug) { if (plug->priv->response_idle_id > 0) { g_source_remove (plug->priv->response_idle_id); plug->priv->response_idle_id = 0; } } static void gs_lock_plug_response (GSLockPlug *plug, gint response_id) { int new_response; new_response = response_id; g_return_if_fail (GS_IS_LOCK_PLUG (plug)); /* Act only on response IDs we recognize */ if (!(response_id == GS_LOCK_PLUG_RESPONSE_OK || response_id == GS_LOCK_PLUG_RESPONSE_CANCEL)) { return; } remove_cancel_timeout (plug); remove_response_idle (plug); if (response_id == GS_LOCK_PLUG_RESPONSE_CANCEL) { gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), ""); } g_signal_emit (plug, lock_plug_signals [RESPONSE], 0, new_response); } static gboolean response_cancel_idle_cb (GSLockPlug *plug) { plug->priv->response_idle_id = 0; gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL); return FALSE; } static gboolean dialog_timed_out (GSLockPlug *plug) { gs_lock_plug_set_sensitive (plug, FALSE); set_status_text (plug, _("Time has expired.")); if (plug->priv->response_idle_id != 0) { g_warning ("Response idle ID already set but shouldn't be"); } remove_response_idle (plug); plug->priv->response_idle_id = g_timeout_add_seconds (2, (GSourceFunc)response_cancel_idle_cb, plug); return FALSE; } static void kbd_lock_mode_update (GSLockPlug *plug, int mode) { if (plug->priv->kbd_lock_mode == mode) { return; } plug->priv->kbd_lock_mode = mode; if (plug->priv->auth_capslock_label == NULL) { return; } if ((mode & LOCK_CAPS) != 0) { gtk_label_set_text (GTK_LABEL (plug->priv->auth_capslock_label), _("You have the Caps Lock key on.")); } else { gtk_label_set_text (GTK_LABEL (plug->priv->auth_capslock_label), ""); } } static int get_kbd_lock_mode (void) { GdkKeymap *keymap; int mode; mode = LOCK_NONE; keymap = gdk_keymap_get_default (); if (keymap != NULL) { gboolean res; res = gdk_keymap_get_caps_lock_state (keymap); if (res) { mode |= LOCK_CAPS; } } return mode; } static void restart_cancel_timeout (GSLockPlug *plug) { remove_cancel_timeout (plug); plug->priv->cancel_timeout_id = g_timeout_add (plug->priv->timeout, (GSourceFunc)dialog_timed_out, plug); } void gs_lock_plug_get_text (GSLockPlug *plug, char **text) { const char *typed_text; char *null_text; char *local_text; typed_text = gtk_entry_get_text (GTK_ENTRY (plug->priv->auth_prompt_entry)); local_text = g_locale_from_utf8 (typed_text, strlen (typed_text), NULL, NULL, NULL); null_text = g_strnfill (strlen (typed_text) + 1, '\b'); gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), null_text); gtk_entry_set_text (GTK_ENTRY (plug->priv->auth_prompt_entry), ""); g_free (null_text); if (text != NULL) { *text = local_text; } else { g_free (local_text); } } typedef struct { GSLockPlug *plug; gint response_id; GMainLoop *loop; gboolean destroyed; } RunInfo; static void shutdown_loop (RunInfo *ri) { if (g_main_loop_is_running (ri->loop)) g_main_loop_quit (ri->loop); } static void run_unmap_handler (GSLockPlug *plug, gpointer data) { RunInfo *ri = data; shutdown_loop (ri); } static void run_response_handler (GSLockPlug *plug, gint response_id, gpointer data) { RunInfo *ri; ri = data; ri->response_id = response_id; shutdown_loop (ri); } static gint run_delete_handler (GSLockPlug *plug, GdkEventAny *event, gpointer data) { RunInfo *ri = data; shutdown_loop (ri); return TRUE; /* Do not destroy */ } static void run_destroy_handler (GSLockPlug *plug, gpointer data) { RunInfo *ri = data; /* shutdown_loop will be called by run_unmap_handler */ ri->destroyed = TRUE; } static void run_keymap_handler (GdkKeymap *keymap, GSLockPlug *plug) { kbd_lock_mode_update (plug, get_kbd_lock_mode ()); } /* adapted from GTK+ gtkdialog.c */ int gs_lock_plug_run (GSLockPlug *plug) { RunInfo ri = { NULL, GTK_RESPONSE_NONE, NULL, FALSE }; gboolean was_modal; gulong response_handler; gulong unmap_handler; gulong destroy_handler; gulong delete_handler; gulong keymap_handler; GdkKeymap *keymap; g_return_val_if_fail (GS_IS_LOCK_PLUG (plug), -1); g_object_ref (plug); was_modal = gtk_window_get_modal (GTK_WINDOW (plug)); if (!was_modal) { gtk_window_set_modal (GTK_WINDOW (plug), TRUE); } if (!gtk_widget_get_visible (GTK_WIDGET (plug))) { gtk_widget_show (GTK_WIDGET (plug)); } keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (plug))); keymap_handler = g_signal_connect (keymap, "state-changed", G_CALLBACK (run_keymap_handler), plug); response_handler = g_signal_connect (plug, "response", G_CALLBACK (run_response_handler), &ri); unmap_handler = g_signal_connect (plug, "unmap", G_CALLBACK (run_unmap_handler), &ri); delete_handler = g_signal_connect (plug, "delete_event", G_CALLBACK (run_delete_handler), &ri); destroy_handler = g_signal_connect (plug, "destroy", G_CALLBACK (run_destroy_handler), &ri); ri.loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (ri.loop); g_main_loop_unref (ri.loop); ri.loop = NULL; if (!ri.destroyed) { if (! was_modal) { gtk_window_set_modal (GTK_WINDOW (plug), FALSE); } g_signal_handler_disconnect (plug, response_handler); g_signal_handler_disconnect (plug, unmap_handler); g_signal_handler_disconnect (plug, delete_handler); g_signal_handler_disconnect (plug, destroy_handler); g_signal_handler_disconnect (keymap, keymap_handler); } g_object_unref (plug); return ri.response_id; } static cairo_surface_t * surface_from_pixbuf (GdkPixbuf *pixbuf) { cairo_surface_t *surface; cairo_t *cr; surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); cr = cairo_create (surface); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); cairo_destroy (cr); return surface; } static void rounded_rectangle (cairo_t *cr, gdouble aspect, gdouble x, gdouble y, gdouble corner_radius, gdouble width, gdouble height) { gdouble radius; gdouble degrees; radius = corner_radius / aspect; degrees = G_PI / 180.0; cairo_new_sub_path (cr); cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees); cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees); cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees); cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees); cairo_close_path (cr); } /* copied from mdm-user.c */ /** * go_cairo_convert_data_to_pixbuf: * @src: a pointer to pixel data in cairo format * @dst: a pointer to pixel data in pixbuf format * @width: image width * @height: image height * @rowstride: data rowstride * * Converts the pixel data stored in @src in CAIRO_FORMAT_ARGB32 cairo format * to GDK_COLORSPACE_RGB pixbuf format and move them * to @dst. If @src == @dst, pixel are converted in place. **/ static void go_cairo_convert_data_to_pixbuf (unsigned char *dst, unsigned char const *src, int width, int height, int rowstride) { int i,j; unsigned int t; unsigned char a, b, c; g_return_if_fail (dst != NULL); #define MULT(d,c,a,t) G_STMT_START { t = (a)? c * 255 / a: 0; d = t;} G_STMT_END if (src == dst || src == NULL) { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN MULT(a, dst[2], dst[3], t); MULT(b, dst[1], dst[3], t); MULT(c, dst[0], dst[3], t); dst[0] = a; dst[1] = b; dst[2] = c; #else MULT(a, dst[1], dst[0], t); MULT(b, dst[2], dst[0], t); MULT(c, dst[3], dst[0], t); dst[3] = dst[0]; dst[0] = a; dst[1] = b; dst[2] = c; #endif dst += 4; } dst += rowstride - width * 4; } } else { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN MULT(dst[0], src[2], src[3], t); MULT(dst[1], src[1], src[3], t); MULT(dst[2], src[0], src[3], t); dst[3] = src[3]; #else MULT(dst[0], src[1], src[0], t); MULT(dst[1], src[2], src[0], t); MULT(dst[2], src[3], src[0], t); dst[3] = src[0]; #endif src += 4; dst += 4; } src += rowstride - width * 4; dst += rowstride - width * 4; } } #undef MULT } static void cairo_to_pixbuf (guint8 *src_data, GdkPixbuf *dst_pixbuf) { unsigned char *src; unsigned char *dst; guint w; guint h; guint rowstride; w = gdk_pixbuf_get_width (dst_pixbuf); h = gdk_pixbuf_get_height (dst_pixbuf); rowstride = gdk_pixbuf_get_rowstride (dst_pixbuf); dst = gdk_pixbuf_get_pixels (dst_pixbuf); src = src_data; go_cairo_convert_data_to_pixbuf (dst, src, w, h, rowstride); } static GdkPixbuf * frame_pixbuf (GdkPixbuf *source) { GdkPixbuf *dest; cairo_t *cr; cairo_surface_t *surface; guint w; guint h; guint rowstride; int frame_width; double radius; guint8 *data; frame_width = 5; w = gdk_pixbuf_get_width (source) + frame_width * 2; h = gdk_pixbuf_get_height (source) + frame_width * 2; radius = w / 10; dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w, h); rowstride = gdk_pixbuf_get_rowstride (dest); data = g_new0 (guint8, h * rowstride); surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, w, h, rowstride); cr = cairo_create (surface); cairo_surface_destroy (surface); /* set up image */ cairo_rectangle (cr, 0, 0, w, h); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_fill (cr); rounded_rectangle (cr, 1.0, frame_width + 0.5, frame_width + 0.5, radius, w - frame_width * 2 - 1, h - frame_width * 2 - 1); cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3); cairo_fill_preserve (cr); surface = surface_from_pixbuf (source); cairo_set_source_surface (cr, surface, frame_width, frame_width); cairo_fill (cr); cairo_surface_destroy (surface); cairo_to_pixbuf (data, dest); cairo_destroy (cr); g_free (data); return dest; } /* end copied from mdm-user.c */ static void image_set_from_pixbuf (GtkImage *image, GdkPixbuf *source) { GdkPixbuf *pixbuf; pixbuf = frame_pixbuf (source); gtk_image_set_from_pixbuf (image, pixbuf); g_object_unref (pixbuf); } static GdkPixbuf * get_pixbuf_of_user_icon (GSLockPlug *plug) { GError *error; GDBusConnection *system_bus; GVariant *find_user_by_name_reply; const char *user; GVariant *get_icon_file_reply; GVariant *icon_file_variant; const char *icon_file; GdkPixbuf *pixbuf; error = NULL; system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (error != NULL) { g_warning ("Unable to get system bus: %s", error->message); g_error_free (error); return NULL; } find_user_by_name_reply = g_dbus_connection_call_sync (system_bus, "org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", "FindUserByName", g_variant_new ("(s)", g_get_user_name ()), G_VARIANT_TYPE ("(o)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_warning ("Couldn't find user in accounts service: %s", error->message); g_error_free (error); return NULL; } user = g_variant_get_string (g_variant_get_child_value (find_user_by_name_reply, 0), NULL); get_icon_file_reply = g_dbus_connection_call_sync (system_bus, "org.freedesktop.Accounts", user, "org.freedesktop.DBus.Properties", "Get", g_variant_new ("(ss)", "org.freedesktop.Accounts.User", "IconFile"), G_VARIANT_TYPE ("(v)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_variant_unref (find_user_by_name_reply); if (error != NULL) { g_warning ("Couldn't find user icon in accounts service: %s", error->message); g_error_free (error); return NULL; } g_variant_get_child (get_icon_file_reply, 0, "v", &icon_file_variant); icon_file = g_variant_get_string (icon_file_variant, NULL); if (icon_file == NULL) { char *string; string = g_variant_print (get_icon_file_reply, TRUE); g_warning ("reply for user icon path returned invalid response '%s'", string); g_free (string); pixbuf = NULL; } else { pixbuf = gdk_pixbuf_new_from_file_at_size (icon_file, 64, 64, &error); } g_variant_unref (icon_file_variant); g_variant_unref (get_icon_file_reply); if (error != NULL) { g_warning ("Couldn't load user icon: %s", error->message); g_error_free (error); return NULL; } return pixbuf; } static gboolean check_user_file (const gchar *filename, uid_t user, gssize max_file_size, gboolean relax_group, gboolean relax_other) { struct stat fileinfo; if (max_file_size < 0) { max_file_size = G_MAXSIZE; } /* Exists/Readable? */ if (g_stat (filename, &fileinfo) < 0) { return FALSE; } /* Is a regular file */ if (G_UNLIKELY (!S_ISREG (fileinfo.st_mode))) { return FALSE; } /* Owned by user? */ if (G_UNLIKELY (fileinfo.st_uid != user)) { return FALSE; } /* Group not writable or relax_group? */ if (G_UNLIKELY ((fileinfo.st_mode & S_IWGRP) == S_IWGRP && !relax_group)) { return FALSE; } /* Other not writable or relax_other? */ if (G_UNLIKELY ((fileinfo.st_mode & S_IWOTH) == S_IWOTH && !relax_other)) { return FALSE; } /* Size is ok? */ if (G_UNLIKELY (fileinfo.st_size > max_file_size)) { return FALSE; } return TRUE; } static gboolean set_face_image (GSLockPlug *plug) { GdkPixbuf *pixbuf; const char *homedir; char *path; int icon_size = 64; gsize user_max_file = 65536; uid_t uid; homedir = g_get_home_dir (); uid = getuid (); path = g_build_filename (homedir, ".face", NULL); pixbuf = NULL; if (check_user_file (path, uid, user_max_file, 0, 0)) { pixbuf = gdk_pixbuf_new_from_file_at_size (path, icon_size, icon_size, NULL); } g_free (path); if (pixbuf == NULL) { return FALSE; } image_set_from_pixbuf (GTK_IMAGE (plug->priv->auth_face_image), pixbuf); g_object_unref (pixbuf); return TRUE; } static void gs_lock_plug_show (GtkWidget *widget) { GSLockPlug *plug = GS_LOCK_PLUG (widget); gs_profile_start (NULL); gs_profile_start ("parent"); if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->show) { GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->show (widget); } gs_profile_end ("parent"); gtk_window_set_opacity (GTK_WINDOW (plug), 0.1); if (plug->priv->auth_face_image) { set_face_image (plug); } kbd_lock_mode_update (plug, get_kbd_lock_mode ()); restart_cancel_timeout (plug); gs_profile_end (NULL); } static void gs_lock_plug_hide (GtkWidget *widget) { if (GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->hide) { GTK_WIDGET_CLASS (gs_lock_plug_parent_class)->hide (widget); } } static void queue_key_event (GSLockPlug *plug, GdkEventKey *event) { GdkEvent *saved_event; saved_event = gdk_event_copy ((GdkEvent *)event); plug->priv->key_events = g_list_prepend (plug->priv->key_events, saved_event); } static void forward_key_events (GSLockPlug *plug) { plug->priv->key_events = g_list_reverse (plug->priv->key_events); while (plug->priv->key_events != NULL) { GdkEventKey *event = plug->priv->key_events->data; gtk_window_propagate_key_event (GTK_WINDOW (plug), event); gdk_event_free ((GdkEvent *)event); plug->priv->key_events = g_list_delete_link (plug->priv->key_events, plug->priv->key_events); } } static void gs_lock_plug_set_logout_enabled (GSLockPlug *plug, gboolean logout_enabled) { g_return_if_fail (GS_LOCK_PLUG (plug)); if (plug->priv->logout_enabled == logout_enabled) { return; } plug->priv->logout_enabled = logout_enabled; g_object_notify (G_OBJECT (plug), "logout-enabled"); if (plug->priv->auth_logout_button == NULL) { return; } if (logout_enabled) { gtk_widget_show (plug->priv->auth_logout_button); } else { gtk_widget_hide (plug->priv->auth_logout_button); } } static void gs_lock_plug_set_logout_command (GSLockPlug *plug, const char *command) { g_return_if_fail (GS_LOCK_PLUG (plug)); g_free (plug->priv->logout_command); if (command) { plug->priv->logout_command = g_strdup (command); } else { plug->priv->logout_command = NULL; } } static void gs_lock_plug_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GSLockPlug *self; self = GS_LOCK_PLUG (object); switch (prop_id) { case PROP_LOGOUT_ENABLED: g_value_set_boolean (value, self->priv->logout_enabled); break; case PROP_LOGOUT_COMMAND: g_value_set_string (value, self->priv->logout_command); break; case PROP_SWITCH_ENABLED: g_value_set_boolean (value, self->priv->switch_enabled); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_lock_plug_set_switch_enabled (GSLockPlug *plug, gboolean switch_enabled) { g_return_if_fail (GS_LOCK_PLUG (plug)); if (plug->priv->switch_enabled == switch_enabled) { return; } plug->priv->switch_enabled = switch_enabled; g_object_notify (G_OBJECT (plug), "switch-enabled"); if (plug->priv->auth_switch_button == NULL) { return; } if (switch_enabled) { if (process_is_running ("mdm") || process_is_running ("gdm") || process_is_running ("gdm3") || g_getenv("XDG_SEAT_PATH")) { gtk_widget_show (plug->priv->auth_switch_button); } else { gs_debug ("Warning: no compatible display manager found"); gtk_widget_hide (plug->priv->auth_switch_button); } } else { gtk_widget_hide (plug->priv->auth_switch_button); } } static void gs_lock_plug_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GSLockPlug *self; self = GS_LOCK_PLUG (object); switch (prop_id) { case PROP_LOGOUT_ENABLED: gs_lock_plug_set_logout_enabled (self, g_value_get_boolean (value)); break; case PROP_LOGOUT_COMMAND: gs_lock_plug_set_logout_command (self, g_value_get_string (value)); break; case PROP_SWITCH_ENABLED: gs_lock_plug_set_switch_enabled (self, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_lock_plug_close (GSLockPlug *plug) { /* Synthesize delete_event to close dialog. */ GtkWidget *widget = GTK_WIDGET (plug); GdkEvent *event; event = gdk_event_new (GDK_DELETE); event->any.window = g_object_ref (gtk_widget_get_window (widget)); event->any.send_event = TRUE; gtk_main_do_event (event); gdk_event_free (event); } static void gs_lock_plug_class_init (GSLockPlugClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkBindingSet *binding_set; object_class->finalize = gs_lock_plug_finalize; object_class->get_property = gs_lock_plug_get_property; object_class->set_property = gs_lock_plug_set_property; widget_class->style_set = gs_lock_plug_style_set; widget_class->show = gs_lock_plug_show; widget_class->hide = gs_lock_plug_hide; klass->close = gs_lock_plug_close; g_type_class_add_private (klass, sizeof (GSLockPlugPrivate)); lock_plug_signals [RESPONSE] = g_signal_new ("response", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSLockPlugClass, response), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); lock_plug_signals [CLOSE] = g_signal_new ("close", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GSLockPlugClass, close), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_object_class_install_property (object_class, PROP_LOGOUT_ENABLED, g_param_spec_boolean ("logout-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_COMMAND, g_param_spec_string ("logout-command", NULL, NULL, NULL, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SWITCH_ENABLED, g_param_spec_boolean ("switch-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); binding_set = gtk_binding_set_by_class (klass); gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0); } static void clear_clipboards (GSLockPlug *plug) { GtkClipboard *clipboard; clipboard = gtk_widget_get_clipboard (GTK_WIDGET (plug), GDK_SELECTION_PRIMARY); gtk_clipboard_clear (clipboard); gtk_clipboard_set_text (clipboard, "", -1); clipboard = gtk_widget_get_clipboard (GTK_WIDGET (plug), GDK_SELECTION_CLIPBOARD); gtk_clipboard_clear (clipboard); gtk_clipboard_set_text (clipboard, "", -1); } static void logout_button_clicked (GtkButton *button, GSLockPlug *plug) { char **argv = NULL; GError *error = NULL; gboolean res; if (! plug->priv->logout_command) { return; } res = g_shell_parse_argv (plug->priv->logout_command, NULL, &argv, &error); if (! res) { g_warning ("Could not parse logout command: %s", error->message); g_error_free (error); return; } g_spawn_async (g_get_home_dir (), argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); g_strfreev (argv); if (error) { g_warning ("Could not run logout command: %s", error->message); g_error_free (error); } } void gs_lock_plug_set_busy (GSLockPlug *plug) { GdkCursor *cursor; GtkWidget *top_level; top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug)); cursor = gdk_cursor_new (GDK_WATCH); gdk_window_set_cursor (gtk_widget_get_window (top_level), cursor); g_object_unref (cursor); } void gs_lock_plug_set_ready (GSLockPlug *plug) { GdkCursor *cursor; GtkWidget *top_level; top_level = gtk_widget_get_toplevel (GTK_WIDGET (plug)); cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor (gtk_widget_get_window (top_level), cursor); g_object_unref (cursor); } void gs_lock_plug_enable_prompt (GSLockPlug *plug, const char *message, gboolean visible) { char *markup; g_return_if_fail (GS_IS_LOCK_PLUG (plug)); gs_debug ("Setting prompt to: %s", message); gtk_widget_set_sensitive (plug->priv->auth_unlock_button, TRUE); gtk_widget_show (plug->priv->auth_unlock_button); gtk_widget_grab_default (plug->priv->auth_unlock_button); markup = g_strdup_printf ("%s", message); gtk_label_set_markup (GTK_LABEL (plug->priv->auth_prompt_label), markup); g_free (markup); gtk_widget_show (plug->priv->auth_prompt_label); gtk_entry_set_visibility (GTK_ENTRY (plug->priv->auth_prompt_entry), visible); gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, TRUE); gtk_widget_show (plug->priv->auth_prompt_entry); if (!gtk_widget_has_focus (plug->priv->auth_prompt_entry)) { gtk_widget_grab_focus (plug->priv->auth_prompt_entry); } /* were there any key events sent to the plug while the * entry wasnt ready? If so, forward them along */ forward_key_events (plug); restart_cancel_timeout (plug); } void gs_lock_plug_disable_prompt (GSLockPlug *plug) { g_return_if_fail (GS_IS_LOCK_PLUG (plug)); /* gtk_widget_hide (plug->priv->auth_prompt_entry); */ /* gtk_widget_hide (plug->priv->auth_prompt_label); */ gtk_widget_set_sensitive (plug->priv->auth_unlock_button, FALSE); gtk_widget_set_sensitive (plug->priv->auth_prompt_entry, FALSE); /* gtk_widget_hide (plug->priv->auth_unlock_button); */ } void gs_lock_plug_show_message (GSLockPlug *plug, const char *message) { g_return_if_fail (GS_IS_LOCK_PLUG (plug)); set_status_text (plug, message ? message : ""); } /* button press handler used to inhibit popup menu */ static gint entry_button_press (GtkWidget *widget, GdkEventButton *event) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { return TRUE; } return FALSE; } static gint entry_key_press (GtkWidget *widget, GdkEventKey *event, GSLockPlug *plug) { restart_cancel_timeout (plug); /* if the input widget is visible and ready for input * then just carry on as usual */ if (gtk_widget_get_visible (plug->priv->auth_prompt_entry) && gtk_widget_get_sensitive (plug->priv->auth_prompt_entry)) { return FALSE; } if (strcmp (event->string, "") == 0) { return FALSE; } queue_key_event (plug, event); return TRUE; } /* adapted from gtk_dialog_add_button */ static GtkWidget * gs_lock_plug_add_button (GSLockPlug *plug, GtkWidget *action_area, const gchar *button_text) { GtkWidget *button; g_return_val_if_fail (GS_IS_LOCK_PLUG (plug), NULL); g_return_val_if_fail (button_text != NULL, NULL); button = gtk_button_new_from_stock (button_text); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_box_pack_end (GTK_BOX (action_area), button, FALSE, TRUE, 0); return button; } static void create_page_one_buttons (GSLockPlug *plug) { gs_profile_start ("page one buttons"); plug->priv->auth_switch_button = gs_lock_plug_add_button (GS_LOCK_PLUG (plug), plug->priv->auth_action_area, _("S_witch User…")); gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (plug->priv->auth_action_area), plug->priv->auth_switch_button, TRUE); gtk_button_set_focus_on_click (GTK_BUTTON (plug->priv->auth_switch_button), FALSE); gtk_widget_set_no_show_all (plug->priv->auth_switch_button, TRUE); plug->priv->auth_logout_button = gs_lock_plug_add_button (GS_LOCK_PLUG (plug), plug->priv->auth_action_area, _("Log _Out")); gtk_button_set_focus_on_click (GTK_BUTTON (plug->priv->auth_logout_button), FALSE); gtk_widget_set_no_show_all (plug->priv->auth_logout_button, TRUE); plug->priv->auth_unlock_button = gs_lock_plug_add_button (GS_LOCK_PLUG (plug), plug->priv->auth_action_area, _("_Unlock")); gtk_button_set_focus_on_click (GTK_BUTTON (plug->priv->auth_unlock_button), FALSE); gtk_window_set_default (GTK_WINDOW (plug), plug->priv->auth_unlock_button); gs_profile_end ("page one buttons"); } static char * get_user_display_name (void) { const char *name; char *utf8_name; name = g_get_real_name (); if (name == NULL || strcmp (name, "Unknown") == 0) { name = g_get_user_name (); } utf8_name = NULL; if (name != NULL) { utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); } return utf8_name; } static char * get_user_name (void) { const char *name; char *utf8_name; name = g_get_user_name (); utf8_name = NULL; if (name != NULL) { utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); } return utf8_name; } static char * get_host_name (void) { const char *name; char *utf8_name; name = g_get_host_name (); utf8_name = NULL; if (name != NULL) { utf8_name = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); } return utf8_name; } static void update_realname_label (GSLockPlug *plug) { char *name; char *markup; name = get_user_display_name (); markup = g_strdup_printf ("%s", name); gtk_label_set_markup (GTK_LABEL (plug->priv->auth_realname_label), markup); g_free (markup); g_free (name); } static void update_username_label (GSLockPlug *plug) { char *name; char *hostname; char *markup; name = get_user_name (); hostname = get_host_name (); markup = g_strdup_printf ("%s @ %s", name, hostname); gtk_label_set_markup (GTK_LABEL (plug->priv->auth_username_label), markup); g_free (markup); g_free (name); g_free (hostname); } static void create_page_one (GSLockPlug *plug) { GtkWidget *hbox_user; GtkWidget *vbox_user; GtkWidget *hbox_pass; GtkWidget *vbox_status; gs_profile_start ("page one"); hbox_user = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (plug->priv->vbox), hbox_user, FALSE, FALSE, 0); plug->priv->auth_face_image = gtk_image_new (); gtk_box_pack_start (GTK_BOX (hbox_user), plug->priv->auth_face_image, TRUE, TRUE, 0); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_face_image), 1, 0.5); vbox_user = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (hbox_user), vbox_user, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox_user), 6); plug->priv->auth_realname_label = gtk_label_new (NULL); update_realname_label (plug); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_realname_label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox_user), plug->priv->auth_realname_label, TRUE, TRUE, 0); plug->priv->auth_username_label = gtk_label_new (NULL); update_username_label (plug); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_username_label), 0, 0); gtk_box_pack_start (GTK_BOX (vbox_user), plug->priv->auth_username_label, TRUE, TRUE, 0); hbox_pass = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start (GTK_BOX (plug->priv->vbox), hbox_pass, FALSE, FALSE, 0); plug->priv->auth_prompt_label = gtk_label_new_with_mnemonic (_("_Password:")); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_prompt_label), 0.5, 0.5); gtk_box_pack_start (GTK_BOX (hbox_pass), plug->priv->auth_prompt_label, FALSE, FALSE, 0); plug->priv->auth_prompt_entry = gtk_entry_new (); gtk_box_pack_start (GTK_BOX (hbox_pass), plug->priv->auth_prompt_entry, TRUE, TRUE, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (plug->priv->auth_prompt_label), plug->priv->auth_prompt_entry); #ifdef WITH_KBD_LAYOUT_INDICATOR gtk_box_pack_start (GTK_BOX (hbox_pass), plug->priv->auth_prompt_kbd_layout_indicator, FALSE, FALSE, 0); #endif vbox_status = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start (GTK_BOX (plug->priv->vbox), vbox_status, TRUE, TRUE, 0); plug->priv->auth_capslock_label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_capslock_label), 0.5, 0.5); gtk_box_pack_start (GTK_BOX (vbox_status), plug->priv->auth_capslock_label, FALSE, FALSE, 0); /* Status text */ plug->priv->auth_message_label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (plug->priv->auth_message_label), 0.5, 0.5); gtk_box_pack_start (GTK_BOX (vbox_status), plug->priv->auth_message_label, FALSE, FALSE, 0); /* Buttons */ plug->priv->auth_action_area = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_button_box_set_layout (GTK_BUTTON_BOX (plug->priv->auth_action_area), GTK_BUTTONBOX_END); gtk_box_pack_end (GTK_BOX (plug->priv->vbox), plug->priv->auth_action_area, FALSE, TRUE, 0); gtk_widget_show (plug->priv->auth_action_area); create_page_one_buttons (plug); gs_profile_end ("page one"); } static void unlock_button_clicked (GtkButton *button, GSLockPlug *plug) { gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_OK); } static void switch_user_button_clicked (GtkButton *button, GSLockPlug *plug) { remove_response_idle (plug); gs_lock_plug_set_sensitive (plug, FALSE); plug->priv->response_idle_id = g_timeout_add_seconds (2, (GSourceFunc)response_cancel_idle_cb, plug); gs_lock_plug_set_busy (plug); do_user_switch (plug); } static int delete_handler (GSLockPlug *plug, GdkEventAny *event, gpointer data) { gs_lock_plug_response (plug, GS_LOCK_PLUG_RESPONSE_CANCEL); return TRUE; /* Do not destroy */ } static void gs_lock_plug_init (GSLockPlug *plug) { gs_profile_start (NULL); plug->priv = GS_LOCK_PLUG_GET_PRIVATE (plug); clear_clipboards (plug); plug->priv->frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (plug->priv->frame), GTK_SHADOW_OUT); gtk_container_add (GTK_CONTAINER (plug), plug->priv->frame); plug->priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add (GTK_CONTAINER (plug->priv->frame), plug->priv->vbox); plug->priv->auth_prompt_kbd_layout_indicator = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); /* Page 1 */ create_page_one (plug); gtk_widget_show_all (plug->priv->frame); /* Layout indicator */ #ifdef WITH_KBD_LAYOUT_INDICATOR if (plug->priv->auth_prompt_kbd_layout_indicator != NULL) { XklEngine *engine; engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); if (xkl_engine_get_num_groups (engine) > 1) { GtkWidget *layout_indicator; layout_indicator = gkbd_indicator_new (); gkbd_indicator_set_parent_tooltips (GKBD_INDICATOR (layout_indicator), TRUE); gtk_box_pack_start (GTK_BOX (plug->priv->auth_prompt_kbd_layout_indicator), layout_indicator, FALSE, FALSE, 0); gtk_widget_show_all (layout_indicator); gtk_widget_show (plug->priv->auth_prompt_kbd_layout_indicator); } else { gtk_widget_hide (plug->priv->auth_prompt_kbd_layout_indicator); } g_object_unref (engine); } #endif if (plug->priv->auth_switch_button != NULL) { if (plug->priv->switch_enabled) { gtk_widget_show_all (plug->priv->auth_switch_button); } else { gtk_widget_hide (plug->priv->auth_switch_button); } } gtk_widget_grab_default (plug->priv->auth_unlock_button); if (! plug->priv->logout_enabled || ! plug->priv->logout_command) { if (plug->priv->auth_logout_button != NULL) { gtk_widget_hide (plug->priv->auth_logout_button); } } plug->priv->timeout = DIALOG_TIMEOUT_MSEC; g_signal_connect (plug, "key_press_event", G_CALLBACK (entry_key_press), plug); /* button press handler used to inhibit popup menu */ g_signal_connect (plug->priv->auth_prompt_entry, "button_press_event", G_CALLBACK (entry_button_press), NULL); gtk_entry_set_activates_default (GTK_ENTRY (plug->priv->auth_prompt_entry), TRUE); gtk_entry_set_visibility (GTK_ENTRY (plug->priv->auth_prompt_entry), FALSE); g_signal_connect (plug->priv->auth_unlock_button, "clicked", G_CALLBACK (unlock_button_clicked), plug); if (plug->priv->auth_switch_button != NULL) { g_signal_connect (plug->priv->auth_switch_button, "clicked", G_CALLBACK (switch_user_button_clicked), plug); } if (plug->priv->auth_logout_button != NULL) { g_signal_connect (plug->priv->auth_logout_button, "clicked", G_CALLBACK (logout_button_clicked), plug); } g_signal_connect (plug, "delete_event", G_CALLBACK (delete_handler), NULL); gtk_widget_set_size_request (GTK_WIDGET (plug), 450, -1); gs_profile_end (NULL); } static void gs_lock_plug_finalize (GObject *object) { GSLockPlug *plug; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_LOCK_PLUG (object)); plug = GS_LOCK_PLUG (object); g_return_if_fail (plug->priv != NULL); g_free (plug->priv->logout_command); remove_response_idle (plug); remove_cancel_timeout (plug); G_OBJECT_CLASS (gs_lock_plug_parent_class)->finalize (object); } GtkWidget * gs_lock_plug_new (void) { GtkWidget *result; result = g_object_new (GS_TYPE_LOCK_PLUG, NULL); gtk_window_set_focus_on_map (GTK_WINDOW (result), TRUE); return result; } cinnamon-screensaver-2.8.0/src/cinnamon-screensaver-dialog.c0000664000175000017500000004303212610211212023063 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "gs-lock-plug.h" #include "gs-auth.h" #include "setuid.h" #include "gs-debug.h" #define MAX_FAILURES 5 static gboolean verbose = FALSE; static gboolean show_version = FALSE; static gboolean enable_logout = FALSE; static gboolean enable_switch = FALSE; static char *logout_command = NULL; static GOptionEntry entries [] = { { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, N_("Show debugging output"), NULL }, { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, { "enable-logout", 0, 0, G_OPTION_ARG_NONE, &enable_logout, N_("Show the logout button"), NULL }, { "logout-command", 0, 0, G_OPTION_ARG_STRING, &logout_command, N_("Command to invoke from the logout button"), NULL }, { "enable-switch", 0, 0, G_OPTION_ARG_NONE, &enable_switch, N_("Show the switch user button"), NULL }, { NULL } }; static char * get_id_string (GtkWidget *widget) { char *id = NULL; g_return_val_if_fail (widget != NULL, NULL); g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); id = g_strdup_printf ("%" G_GUINT32_FORMAT, (guint32) GDK_WINDOW_XID (gtk_widget_get_window (widget))); return id; } static gboolean print_id (GtkWidget *widget) { char *id; gs_profile_start (NULL); id = get_id_string (widget); printf ("WINDOW ID=%s\n", id); fflush (stdout); gs_profile_end (NULL); g_free (id); return FALSE; } static void response_cancel (void) { printf ("RESPONSE=CANCEL\n"); fflush (stdout); } static void response_ok (void) { printf ("RESPONSE=OK\n"); fflush (stdout); } static gboolean quit_response_ok (void) { response_ok (); gtk_main_quit (); return FALSE; } static gboolean quit_response_cancel (void) { response_cancel (); gtk_main_quit (); return FALSE; } static void response_lock_init_failed (void) { /* if we fail to lock then we should drop the dialog */ response_ok (); } static char * request_response (GSLockPlug *plug, const char *prompt, gboolean visible) { int response; char *text; gs_lock_plug_set_sensitive (plug, TRUE); gs_lock_plug_enable_prompt (plug, prompt, visible); response = gs_lock_plug_run (plug); gs_debug ("got response: %d", response); text = NULL; if (response == GS_LOCK_PLUG_RESPONSE_OK) { gs_lock_plug_get_text (plug, &text); } gs_lock_plug_disable_prompt (plug); return text; } /* Adapted from MDM daemon/verify-pam.c on 2006-06-13 */ static const char * maybe_translate_message (const char *msg) { char *s; const char *ret; static GHashTable *hash = NULL; if (hash == NULL) { /* Here we come with some fairly standard messages so that we have as much as possible translated. Should really be translated in pam I suppose. This way we can "change" some of these messages to be more sane. */ hash = g_hash_table_new (g_str_hash, g_str_equal); /* login: is whacked always translate to Username: */ g_hash_table_insert (hash, "login:", _("Username:")); g_hash_table_insert (hash, "Username:", _("Username:")); g_hash_table_insert (hash, "username:", _("Username:")); g_hash_table_insert (hash, "Password:", _("Password:")); g_hash_table_insert (hash, "password:", _("Password:")); g_hash_table_insert (hash, "You are required to change your password immediately (password aged)", _("You are required to change your password immediately (password aged)")); g_hash_table_insert (hash, "You are required to change your password immediately (root enforced)", _("You are required to change your password immediately (root enforced)")); g_hash_table_insert (hash, "Your account has expired; please contact your system administrator", _("Your account has expired; please contact your system administrator")); g_hash_table_insert (hash, "No password supplied", _("No password supplied")); g_hash_table_insert (hash, "Password unchanged", _("Password unchanged")); g_hash_table_insert (hash, "Can not get username", _("Cannot get username")); g_hash_table_insert (hash, "Retype new UNIX password:", _("Retype new Unix password:")); g_hash_table_insert (hash, "Enter new UNIX password:", _("Enter new Unix password:")); g_hash_table_insert (hash, "(current) UNIX password:", _("(current) Unix password:")); g_hash_table_insert (hash, "Error while changing NIS password.", _("Error while changing NIS password.")); g_hash_table_insert (hash, "You must choose a longer password", _("You must choose a longer password")); g_hash_table_insert (hash, "Password has been already used. Choose another.", _("Password has been already used. Choose another.")); g_hash_table_insert (hash, "You must wait longer to change your password", _("You must wait longer to change your password")); g_hash_table_insert (hash, "Sorry, passwords do not match", _("Sorry, passwords do not match")); /* FIXME: what about messages which have some variables in them, perhaps try to do those as well */ } s = g_strstrip (g_strdup (msg)); ret = g_hash_table_lookup (hash, s); g_free (s); if (ret != NULL) { return ret; } else { return msg; } } static gboolean auth_message_handler (GSAuthMessageStyle style, const char *msg, char **response, gpointer data) { gboolean ret; GSLockPlug *plug; const char *message; plug = GS_LOCK_PLUG (data); gs_profile_start (NULL); gs_debug ("Got message style %d: '%s'", style, msg); gtk_widget_show (GTK_WIDGET (plug)); gs_lock_plug_set_ready (plug); ret = TRUE; *response = NULL; message = maybe_translate_message (msg); switch (style) { case GS_AUTH_MESSAGE_PROMPT_ECHO_ON: if (msg != NULL) { char *resp; resp = request_response (plug, message, TRUE); *response = resp; } break; case GS_AUTH_MESSAGE_PROMPT_ECHO_OFF: if (msg != NULL) { char *resp; resp = request_response (plug, message, FALSE); *response = resp; } break; case GS_AUTH_MESSAGE_ERROR_MSG: gs_lock_plug_show_message (plug, message); break; case GS_AUTH_MESSAGE_TEXT_INFO: gs_lock_plug_show_message (plug, message); break; default: g_assert_not_reached (); } if (*response == NULL) { gs_debug ("Got no response"); ret = FALSE; } else { gs_lock_plug_show_message (plug, _("Checking…")); gs_lock_plug_set_sensitive (plug, FALSE); } /* we may have pending events that should be processed before continuing back into PAM */ while (gtk_events_pending ()) { gtk_main_iteration (); } gs_lock_plug_set_busy (plug); gs_profile_end (NULL); return ret; } static gboolean reset_idle_cb (GSLockPlug *plug) { gs_lock_plug_set_sensitive (plug, TRUE); gs_lock_plug_show_message (plug, NULL); return FALSE; } static gboolean do_auth_check (GSLockPlug *plug) { GError *error; gboolean res; error = NULL; gs_lock_plug_disable_prompt (plug); gs_lock_plug_set_busy (plug); res = gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), auth_message_handler, plug, &error); gs_debug ("Verify user returned: %s", res ? "TRUE" : "FALSE"); if (! res) { if (error != NULL) { gs_debug ("Verify user returned error: %s", error->message); gs_lock_plug_show_message (plug, error->message); } else { gs_lock_plug_show_message (plug, _("Authentication failed.")); } printf ("NOTICE=AUTH FAILED\n"); fflush (stdout); if (error != NULL) { g_error_free (error); } } return res; } static void response_cb (GSLockPlug *plug, gint response_id) { if ((response_id == GS_LOCK_PLUG_RESPONSE_CANCEL) || (response_id == GTK_RESPONSE_DELETE_EVENT)) { quit_response_cancel (); } } static gboolean response_request_quit (void) { printf ("REQUEST QUIT\n"); fflush (stdout); return FALSE; } static gboolean quit_timeout_cb (gpointer data) { gtk_main_quit (); return FALSE; } static gboolean auth_check_idle (GSLockPlug *plug) { gboolean res; gboolean again; static guint loop_counter = 0; again = TRUE; res = do_auth_check (plug); if (res) { again = FALSE; g_idle_add ((GSourceFunc)quit_response_ok, NULL); } else { loop_counter++; if (loop_counter < MAX_FAILURES) { gs_debug ("Authentication failed, retrying (%u)", loop_counter); g_timeout_add_seconds (3, (GSourceFunc)reset_idle_cb, plug); } else { gs_debug ("Authentication failed, quitting (max failures)"); again = FALSE; /* Don't quit immediately, but rather request that cinnamon-screensaver * terminates us after it has finished the dialog shake. Time out * after 5 seconds and quit anyway if this doesn't happen though */ g_idle_add ((GSourceFunc)response_request_quit, NULL); g_timeout_add_seconds (5, (GSourceFunc)quit_timeout_cb, NULL); } } return again; } static void show_cb (GtkWidget *widget, gpointer data) { print_id (widget); } static gboolean popup_dialog_idle (void) { GtkWidget *widget; gs_profile_start (NULL); widget = gs_lock_plug_new (); if (enable_logout) { g_object_set (widget, "logout-enabled", TRUE, NULL); } if (logout_command) { g_object_set (widget, "logout-command", logout_command, NULL); } if (enable_switch) { g_object_set (widget, "switch-enabled", TRUE, NULL); } g_signal_connect (GS_LOCK_PLUG (widget), "response", G_CALLBACK (response_cb), NULL); g_signal_connect (widget, "show", G_CALLBACK (show_cb), NULL); gtk_widget_realize (widget); g_idle_add ((GSourceFunc)auth_check_idle, widget); gs_profile_end (NULL); return FALSE; } /* * Copyright (c) 1991-2004 Jamie Zawinski * Copyright (c) 2005 William Jon McCann * * Initializations that potentially take place as a priveleged user: If the executable is setuid root, then these initializations are run as root, before discarding privileges. */ static gboolean privileged_initialization (int *argc, char **argv, gboolean verbose) { gboolean ret; char *nolock_reason; char *orig_uid; char *uid_message; gs_profile_start (NULL); #ifndef NO_LOCKING /* before hack_uid () for proper permissions */ gs_auth_priv_init (); #endif /* NO_LOCKING */ ret = hack_uid (&nolock_reason, &orig_uid, &uid_message); if (nolock_reason) { g_debug ("Locking disabled: %s", nolock_reason); } if (uid_message && verbose) { g_print ("Modified UID: %s", uid_message); } g_free (nolock_reason); g_free (orig_uid); g_free (uid_message); gs_profile_end (NULL); return ret; } /* * Copyright (c) 1991-2004 Jamie Zawinski * Copyright (c) 2005 William Jon McCann * * Figure out what locking mechanisms are supported. */ static gboolean lock_initialization (int *argc, char **argv, char **nolock_reason, gboolean verbose) { if (nolock_reason != NULL) { *nolock_reason = NULL; } #ifdef NO_LOCKING if (nolock_reason != NULL) { *nolock_reason = g_strdup ("not compiled with locking support"); } return FALSE; #else /* !NO_LOCKING */ /* Finish initializing locking, now that we're out of privileged code. */ if (! gs_auth_init ()) { if (nolock_reason != NULL) { *nolock_reason = g_strdup ("error getting password"); } return FALSE; } /* If locking is currently enabled, but the environment indicates that we have been launched as MDM's "Background" program, then disable locking just in case. */ if (getenv ("RUNNING_UNDER_MDM")) { if (nolock_reason != NULL) { *nolock_reason = g_strdup ("running under MDM"); } return FALSE; } /* If the server is XDarwin (MacOS X) then disable locking. (X grabs only affect X programs, so you can use Command-Tab to bring any other Mac program to the front, e.g., Terminal.) */ { gboolean macos = FALSE; #ifdef __APPLE__ /* Disable locking if *running* on Apple hardware, since we have no reliable way to determine whether the server is running on MacOS. Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware" but I'm not really sure about that. */ macos = TRUE; #endif if (macos) { if (nolock_reason != NULL) { *nolock_reason = g_strdup ("Cannot lock securely on MacOS X"); } return FALSE; } } #endif /* NO_LOCKING */ return TRUE; } int main (int argc, char **argv) { GError *error = NULL; char *nolock_reason = NULL; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif gs_profile_start (NULL); if (! privileged_initialization (&argc, argv, verbose)) { response_lock_init_failed (); exit (1); } error = NULL; if (! gtk_init_with_args (&argc, &argv, NULL, entries, NULL, &error)) { if (error != NULL) { fprintf (stderr, "%s", error->message); g_error_free (error); } exit (1); } if (show_version) { g_print ("%s %s\n", argv [0], VERSION); exit (1); } if (! lock_initialization (&argc, argv, &nolock_reason, verbose)) { if (nolock_reason != NULL) { g_debug ("Screen locking disabled: %s", nolock_reason); g_free (nolock_reason); } response_lock_init_failed (); exit (1); } gs_debug_init (verbose, FALSE); g_idle_add ((GSourceFunc)popup_dialog_idle, NULL); gtk_main (); gs_profile_end (NULL); gs_debug_shutdown (); return 0; } cinnamon-screensaver-2.8.0/src/setuid.h0000664000175000017500000000151012610211212017003 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * xscreensaver, Copyright (c) 1993-2004 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #ifndef __GS_SETUID_H #define __GS_SETUID_H G_BEGIN_DECLS gboolean hack_uid (char **nolock_reason, char **orig_uid, char **uid_message); G_END_DECLS #endif /* __GS_SETUID_H */ cinnamon-screensaver-2.8.0/src/test-window.c0000664000175000017500000001104512610211212017771 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include "gs-window.h" #include "gs-grab.h" #include "gs-debug.h" static GSGrab *grab = NULL; static void window_deactivated_cb (GSWindow *window, gpointer data) { gs_window_destroy (window); } static void window_dialog_up_changed_cb (GSWindow *window, gpointer data) { } static void window_show_cb (GSWindow *window, gpointer data) { /* Grab keyboard so dialog can be used */ gs_grab_move_to_window (grab, gs_window_get_gdk_window (window), gs_window_get_screen (window), FALSE); } static gboolean window_activity_cb (GSWindow *window, gpointer data) { gs_window_request_unlock (window); return TRUE; } static void disconnect_window_signals (GSWindow *window) { gpointer data; data = NULL; g_signal_handlers_disconnect_by_func (window, window_activity_cb, data); g_signal_handlers_disconnect_by_func (window, window_deactivated_cb, data); g_signal_handlers_disconnect_by_func (window, window_dialog_up_changed_cb, data); g_signal_handlers_disconnect_by_func (window, window_show_cb, data); } static void window_destroyed_cb (GtkWindow *window, gpointer data) { disconnect_window_signals (GS_WINDOW (window)); gs_grab_release (grab); gtk_main_quit (); } static void connect_window_signals (GSWindow *window) { gpointer data; data = NULL; g_signal_connect_object (window, "activity", G_CALLBACK (window_activity_cb), data, 0); g_signal_connect_object (window, "destroy", G_CALLBACK (window_destroyed_cb), data, 0); g_signal_connect_object (window, "deactivated", G_CALLBACK (window_deactivated_cb), data, 0); g_signal_connect_object (window, "notify::dialog-up", G_CALLBACK (window_dialog_up_changed_cb), data, 0); g_signal_connect_object (window, "show", G_CALLBACK (window_show_cb), data, 0); } static void test_window (void) { GSWindow *window; gboolean lock_active; gboolean user_switch_enabled; GdkScreen *screen; int monitor; lock_active = TRUE; user_switch_enabled = TRUE; screen = gdk_screen_get_default (); monitor = 0; window = gs_window_new (screen, monitor, lock_active); gs_window_set_user_switch_enabled (window, user_switch_enabled); connect_window_signals (window); gs_window_show (window); } int main (int argc, char **argv) { GError *error = NULL; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { fprintf (stderr, "%s", error->message); g_error_free (error); exit (1); } gs_debug_init (TRUE, FALSE); grab = gs_grab_new (); test_window (); /* safety valve in case we can't authenticate */ g_timeout_add_seconds (30, (GSourceFunc)gtk_main_quit, NULL); gtk_main (); g_object_unref (grab); gs_debug_shutdown (); return 0; } cinnamon-screensaver-2.8.0/src/test-passwd.c0000664000175000017500000001636212610211212017772 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include "gs-auth.h" #include "setuid.h" /* Initializations that potentially take place as a priveleged user: If the executable is setuid root, then these initializations are run as root, before discarding privileges. */ static gboolean privileged_initialization (void) { gboolean ret; char *nolock_reason; char *orig_uid; char *uid_message; #ifndef NO_LOCKING /* before hack_uid () for proper permissions */ gs_auth_priv_init (); #endif /* NO_LOCKING */ ret = hack_uid (&nolock_reason, &orig_uid, &uid_message); if (nolock_reason) { g_warning ("Locking disabled: %s", nolock_reason); } if (uid_message && gs_auth_get_verbose ()) { g_print ("Modified UID: %s", uid_message); } g_free (nolock_reason); g_free (orig_uid); g_free (uid_message); return ret; } /* Figure out what locking mechanisms are supported. */ static gboolean lock_initialization (char **nolock_reason) { if (nolock_reason) { *nolock_reason = NULL; } #ifdef NO_LOCKING if (nolock_reason) { *nolock_reason = g_strdup ("not compiled with locking support"); } return FALSE; #else /* !NO_LOCKING */ /* Finish initializing locking, now that we're out of privileged code. */ if (! gs_auth_init ()) { if (nolock_reason) { *nolock_reason = g_strdup ("error getting password"); } return FALSE; } /* If locking is currently enabled, but the environment indicates that we have been launched as MDM's "Background" program, then disable locking just in case. */ if (getenv ("RUNNING_UNDER_MDM")) { if (nolock_reason) { *nolock_reason = g_strdup ("running under MDM"); } return FALSE; } /* If the server is XDarwin (MacOS X) then disable locking. (X grabs only affect X programs, so you can use Command-Tab to bring any other Mac program to the front, e.g., Terminal.) */ { gboolean macos = FALSE; #ifdef __APPLE__ /* Disable locking if *running* on Apple hardware, since we have no reliable way to determine whether the server is running on MacOS. Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware" but I'm not really sure about that. */ macos = TRUE; #endif if (macos) { if (nolock_reason) { *nolock_reason = g_strdup ("Cannot lock securely on MacOS X"); } return FALSE; } } #endif /* NO_LOCKING */ return TRUE; } static char * request_password (const char *prompt) { char buf [255]; char *pass; char *password; struct termios ts0; struct termios ts1; tcgetattr (fileno (stdin), &ts0); ts1 = ts0; ts1.c_lflag &= ~ECHO; printf ("%s", prompt); if (tcsetattr (fileno (stdin), TCSAFLUSH, &ts1) != 0) { fprintf (stderr, "Could not set terminal attributes\n"); exit (1); } pass = fgets (buf, sizeof (buf) - 1, stdin); tcsetattr (fileno (stdin), TCSANOW, &ts0); if (!pass || !*pass) { exit (0); } if (pass [strlen (pass) - 1] == '\n') { pass [strlen (pass) - 1] = 0; } password = g_strdup (pass); memset (pass, '\b', strlen (pass)); return password; } static gboolean auth_message_handler (GSAuthMessageStyle style, const char *msg, char **response, gpointer data) { gboolean ret; g_message ("Got message style %d: '%s'", style, msg); ret = TRUE; switch (style) { case GS_AUTH_MESSAGE_PROMPT_ECHO_ON: break; case GS_AUTH_MESSAGE_PROMPT_ECHO_OFF: { char *password; password = request_password (msg); *response = password; } break; case GS_AUTH_MESSAGE_ERROR_MSG: break; case GS_AUTH_MESSAGE_TEXT_INFO: break; default: g_assert_not_reached (); } return ret; } int main (int argc, char **argv) { GError *error = NULL; gboolean verbose = TRUE; char *nolock_reason = NULL; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif gs_auth_set_verbose (verbose); if (! privileged_initialization ()) { exit (1); } if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { fprintf (stderr, "%s", error->message); g_error_free (error); exit (1); } if (! lock_initialization (&nolock_reason)) { if (nolock_reason) { g_warning ("Screen locking disabled: %s", nolock_reason); g_free (nolock_reason); } exit (1); } again: error = NULL; if (gs_auth_verify_user (g_get_user_name (), g_getenv ("DISPLAY"), auth_message_handler, NULL, &error)) { printf ("Correct!\n"); } else { if (error != NULL) { fprintf (stderr, "ERROR: %s\n", error->message); g_error_free (error); } printf ("Incorrect\n"); goto again; } return 0; } cinnamon-screensaver-2.8.0/src/gs-marshal.h0000664000175000017500000000410512610211212017547 0ustar fabiofabio #ifndef __gs_marshal_MARSHAL_H__ #define __gs_marshal_MARSHAL_H__ #include G_BEGIN_DECLS /* BOOLEAN:VOID (gs-marshal.list:1) */ extern void gs_marshal_BOOLEAN__VOID (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* BOOLEAN:INT (gs-marshal.list:2) */ extern void gs_marshal_BOOLEAN__INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* BOOLEAN:BOOLEAN (gs-marshal.list:3) */ extern void gs_marshal_BOOLEAN__BOOLEAN (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:STRING,STRING,STRING (gs-marshal.list:4) */ extern void gs_marshal_VOID__STRING_STRING_STRING (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:STRING (gs-marshal.list:5) */ #define gs_marshal_VOID__STRING g_cclosure_marshal_VOID__STRING G_END_DECLS #endif /* __gs_marshal_MARSHAL_H__ */ cinnamon-screensaver-2.8.0/src/gs-prefs.h0000664000175000017500000000556512610211212017252 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_PREFS_H #define __GS_PREFS_H G_BEGIN_DECLS #define GS_TYPE_PREFS (gs_prefs_get_type ()) #define GS_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_PREFS, GSPrefs)) #define GS_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_PREFS, GSPrefsClass)) #define GS_IS_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_PREFS)) #define GS_IS_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_PREFS)) #define GS_PREFS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_PREFS, GSPrefsClass)) typedef struct GSPrefsPrivate GSPrefsPrivate; typedef struct { GObject parent; GSPrefsPrivate *priv; guint idle_activation_enabled : 1; /* whether to activate when idle */ guint lock_enabled : 1; /* whether to lock when active */ guint logout_enabled : 1; /* Whether to offer the logout option */ guint lock_disabled : 1; /* Whether locking the system is disabled */ guint user_switch_disabled : 1; /* Whether user switching is disabled */ guint user_switch_enabled : 1; /* Whether to offer the user switch option */ guint keyboard_enabled : 1; /* Whether to try to embed a keyboard */ guint lock_timeout; /* how long after activation locking starts */ guint logout_timeout; /* how long until the logout option appears */ char *logout_command; /* command to use to logout */ char *keyboard_command; /* command to use to embed a keyboard */ } GSPrefs; typedef struct { GObjectClass parent_class; void (* changed) (GSPrefs *prefs); } GSPrefsClass; GType gs_prefs_get_type (void); GSPrefs * gs_prefs_new (void); void gs_prefs_load (GSPrefs *prefs); G_END_DECLS #endif /* __GS_PREFS_H */ cinnamon-screensaver-2.8.0/src/gnome-datetime-source.c0000664000175000017500000002042112610211212021700 0ustar fabiofabio/* -*- mode: C; c-file-style: "linux"; indent-tabs-mode: t -*- * gdatetime-source.c - copy&paste from https://bugzilla.gnome.org/show_bug.cgi?id=655129 * * Copyright (C) 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Author: Colin Walters */ #include "config.h" #include "gnome-datetime-source.h" #ifdef HAVE_TIMERFD #include #include #include #endif typedef struct _GDateTimeSource GDateTimeSource; struct _GDateTimeSource { GSource source; gint64 real_expiration; gint64 wakeup_expiration; gboolean cancel_on_set : 1; gboolean initially_expired : 1; GPollFD pollfd; }; static inline void g_datetime_source_reschedule (GDateTimeSource *datetime_source, gint64 from_monotonic) { datetime_source->wakeup_expiration = from_monotonic + G_TIME_SPAN_SECOND; } static gboolean g_datetime_source_is_expired (GDateTimeSource *datetime_source) { gint64 real_now; gint64 monotonic_now; real_now = g_get_real_time (); monotonic_now = g_source_get_time ((GSource*)datetime_source); if (datetime_source->initially_expired) return TRUE; if (datetime_source->real_expiration <= real_now) return TRUE; /* We can't really detect without system support when things * change; so just trigger every second (i.e. our wakeup * expiration) */ if (datetime_source->cancel_on_set && monotonic_now >= datetime_source->wakeup_expiration) return TRUE; return FALSE; } /* In prepare, we're just checking the monotonic time against * our projected wakeup. */ static gboolean g_datetime_source_prepare (GSource *source, gint *timeout) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; gint64 monotonic_now; #ifdef HAVE_TIMERFD if (datetime_source->pollfd.fd != -1) { *timeout = -1; return datetime_source->initially_expired; /* Should be TRUE at most one time, FALSE forever after */ } #endif monotonic_now = g_source_get_time (source); if (monotonic_now < datetime_source->wakeup_expiration) { /* Round up to ensure that we don't try again too early */ *timeout = (datetime_source->wakeup_expiration - monotonic_now + 999) / 1000; return FALSE; } *timeout = 0; return g_datetime_source_is_expired (datetime_source); } /* In check, we're looking at the wall clock. */ static gboolean g_datetime_source_check (GSource *source) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; #ifdef HAVE_TIMERFD if (datetime_source->pollfd.fd != -1) return datetime_source->pollfd.revents != 0; #endif if (g_datetime_source_is_expired (datetime_source)) return TRUE; g_datetime_source_reschedule (datetime_source, g_source_get_time (source)); return FALSE; } static gboolean g_datetime_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { GDateTimeSource *datetime_source = (GDateTimeSource*)source; datetime_source->initially_expired = FALSE; if (!callback) { g_warning ("Timeout source dispatched without callback\n" "You must call g_source_set_callback()."); return FALSE; } (callback) (user_data); /* Always false as this source is documented to run once */ return FALSE; } static void g_datetime_source_finalize (GSource *source) { #ifdef HAVE_TIMERFD GDateTimeSource *datetime_source = (GDateTimeSource*)source; if (datetime_source->pollfd.fd != -1) close (datetime_source->pollfd.fd); #endif } static GSourceFuncs g_datetime_source_funcs = { g_datetime_source_prepare, g_datetime_source_check, g_datetime_source_dispatch, g_datetime_source_finalize }; #ifdef HAVE_TIMERFD static gboolean g_datetime_source_init_timerfd (GDateTimeSource *datetime_source, gint64 expected_now_seconds, gint64 unix_seconds) { struct itimerspec its; int settime_flags; datetime_source->pollfd.fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC); if (datetime_source->pollfd.fd == -1) return FALSE; memset (&its, 0, sizeof (its)); its.it_value.tv_sec = (time_t) unix_seconds; /* http://article.gmane.org/gmane.linux.kernel/1132138 */ #ifndef TFD_TIMER_CANCEL_ON_SET #define TFD_TIMER_CANCEL_ON_SET (1 << 1) #endif settime_flags = TFD_TIMER_ABSTIME; if (datetime_source->cancel_on_set) settime_flags |= TFD_TIMER_CANCEL_ON_SET; if (timerfd_settime (datetime_source->pollfd.fd, settime_flags, &its, NULL) < 0) { close (datetime_source->pollfd.fd); datetime_source->pollfd.fd = -1; return FALSE; } /* Now we need to check that the clock didn't go backwards before we * had the timerfd set up. See * https://bugzilla.gnome.org/show_bug.cgi?id=655129 */ clock_gettime (CLOCK_REALTIME, &its.it_value); if (its.it_value.tv_sec < expected_now_seconds) datetime_source->initially_expired = TRUE; datetime_source->pollfd.events = G_IO_IN; g_source_add_poll ((GSource*) datetime_source, &datetime_source->pollfd); return TRUE; } #endif /** * _gnome_date_time_source_new: * @now: The expected current time * @expiry: Time to await * @cancel_on_set: Also invoke callback if the system clock changes discontiguously * * This function is designed for programs that want to schedule an * event based on real (wall clock) time, as returned by * g_get_real_time(). For example, HOUR:MINUTE wall-clock displays * and calendaring software. The callback will be invoked when the * specified wall clock time @expiry is reached. This includes * events such as the system clock being set past the given time. * * Compare versus g_timeout_source_new() which is defined to use * monotonic time as returned by g_get_monotonic_time(). * * The parameter @now is necessary to avoid a race condition in * between getting the current time and calling this function. * * If @cancel_on_set is given, the callback will also be invoked at * most a second after the system clock is changed. This includes * being set backwards or forwards, and system * resume from suspend. Not all operating systems allow detecting all * relevant events efficiently - this function may cause the process * to wake up once a second in those cases. * * A wall clock display should use @cancel_on_set; a calendaring * program shouldn't need to. * * Note that the return value from the associated callback will be * ignored; this is a one time watch. * * This function currently does not detect time zone * changes. On Linux, your program should also monitor the * /etc/timezone file using * #GFileMonitor. * * Clock exampleFIXME: MISSING XINCLUDE CONTENT * * Return value: A newly-constructed #GSource * * Since: 2.30 **/ GSource * _gnome_datetime_source_new (GDateTime *now, GDateTime *expiry, gboolean cancel_on_set) { GDateTimeSource *datetime_source; gint64 unix_seconds; unix_seconds = g_date_time_to_unix (expiry); datetime_source = (GDateTimeSource*) g_source_new (&g_datetime_source_funcs, sizeof (GDateTimeSource)); datetime_source->cancel_on_set = cancel_on_set; #ifdef HAVE_TIMERFD { gint64 expected_now_seconds = g_date_time_to_unix (now); if (g_datetime_source_init_timerfd (datetime_source, expected_now_seconds, unix_seconds)) return (GSource*)datetime_source; /* Fall through to non-timerfd code */ } #endif datetime_source->real_expiration = unix_seconds * 1000000; g_datetime_source_reschedule (datetime_source, g_get_monotonic_time ()); return (GSource*)datetime_source; } cinnamon-screensaver-2.8.0/src/gs-auth.h0000664000175000017500000000411212610211212017057 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * */ #ifndef __GS_AUTH_H #define __GS_AUTH_H #include G_BEGIN_DECLS typedef enum { GS_AUTH_MESSAGE_PROMPT_ECHO_ON, GS_AUTH_MESSAGE_PROMPT_ECHO_OFF, GS_AUTH_MESSAGE_ERROR_MSG, GS_AUTH_MESSAGE_TEXT_INFO } GSAuthMessageStyle; typedef enum { GS_AUTH_ERROR_GENERAL, GS_AUTH_ERROR_AUTH_ERROR, GS_AUTH_ERROR_USER_UNKNOWN, GS_AUTH_ERROR_AUTH_DENIED } GSAuthError; typedef gboolean (* GSAuthMessageFunc) (GSAuthMessageStyle style, const char *msg, char **response, gpointer data); #define GS_AUTH_ERROR gs_auth_error_quark () GQuark gs_auth_error_quark (void); void gs_auth_set_verbose (gboolean verbose); gboolean gs_auth_get_verbose (void); gboolean gs_auth_priv_init (void); gboolean gs_auth_init (void); gboolean gs_auth_verify_user (const char *username, const char *display, GSAuthMessageFunc func, gpointer data, GError **error); G_END_DECLS #endif /* __GS_AUTH_H */ cinnamon-screensaver-2.8.0/src/gs-window.h0000664000175000017500000001107312610211212017431 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_WINDOW_H #define __GS_WINDOW_H #include #include G_BEGIN_DECLS #define GS_TYPE_WINDOW (gs_window_get_type ()) #define GS_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_WINDOW, GSWindow)) #define GS_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_WINDOW, GSWindowClass)) #define GS_IS_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_WINDOW)) #define GS_IS_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_WINDOW)) #define GS_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_WINDOW, GSWindowClass)) typedef struct GSWindowPrivate GSWindowPrivate; typedef struct { GtkWindow window; GSWindowPrivate *priv; } GSWindow; typedef struct { GtkWindowClass parent_class; gboolean (* activity) (GSWindow *window); void (* deactivated) (GSWindow *window); void (* dialog_up) (GSWindow *window); void (* dialog_down) (GSWindow *window); } GSWindowClass; GType gs_window_get_type (void); gboolean gs_window_is_obscured (GSWindow *window); gboolean gs_window_is_dialog_up (GSWindow *window); void gs_window_set_screen (GSWindow *window, GdkScreen *screen); GdkScreen * gs_window_get_screen (GSWindow *window); void gs_window_set_monitor (GSWindow *window, int monitor); int gs_window_get_monitor (GSWindow *window); void gs_window_set_background_surface (GSWindow *window, cairo_surface_t *surface); void gs_window_set_lock_enabled (GSWindow *window, gboolean lock_enabled); void gs_window_set_logout_enabled (GSWindow *window, gboolean logout_enabled); void gs_window_set_keyboard_enabled (GSWindow *window, gboolean enabled); void gs_window_set_keyboard_command (GSWindow *window, const char *command); void gs_window_set_user_switch_enabled (GSWindow *window, gboolean user_switch_enabled); void gs_window_set_logout_timeout (GSWindow *window, glong timeout); void gs_window_set_logout_command (GSWindow *window, const char *command); void gs_window_show_message (GSWindow *window, const char *summary, const char *body, const char *icon); void gs_window_set_away_message (GSWindow *window, const char *message); void gs_window_request_unlock (GSWindow *window); void gs_window_cancel_unlock_request (GSWindow *window); GSWindow * gs_window_new (GdkScreen *screen, int monitor, gboolean lock_enabled); void gs_window_show (GSWindow *window); void gs_window_destroy (GSWindow *window); GdkWindow * gs_window_get_gdk_window (GSWindow *window); GtkWidget * gs_window_get_drawing_area (GSWindow *window); void gs_window_clear (GSWindow *window); G_END_DECLS #endif /* __GS_WINDOW_H */ cinnamon-screensaver-2.8.0/src/test-watcher.c0000664000175000017500000000536012610211212020122 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include "gs-watcher.h" #include "gs-debug.h" static gboolean watcher_idle_cb (GSWatcher *watcher, gboolean is_idle, gpointer data) { g_message ("Idle status changed: %s", is_idle ? "idle" : "not idle"); /* return FALSE so that the idle watcher continues */ return FALSE; } static gboolean watcher_idle_notice_cb (GSWatcher *watcher, gboolean is_idle, gpointer data) { g_message ("Idle notice status changed: %s", is_idle ? "idle" : "not idle"); return TRUE; } static void connect_watcher_signals (GSWatcher *watcher) { g_signal_connect (watcher, "idle-changed", G_CALLBACK (watcher_idle_cb), NULL); g_signal_connect (watcher, "idle-notice-changed", G_CALLBACK (watcher_idle_notice_cb), NULL); } static void test_watcher (void) { GSWatcher *watcher; watcher = gs_watcher_new (); gs_watcher_set_enabled (watcher, TRUE); gs_watcher_set_active (watcher, TRUE); connect_watcher_signals (watcher); } int main (int argc, char **argv) { GError *error = NULL; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { fprintf (stderr, "%s", error->message); g_error_free (error); exit (1); } gs_debug_init (TRUE, FALSE); test_watcher (); gtk_main (); gs_debug_shutdown (); return 0; } cinnamon-screensaver-2.8.0/src/gs-marshal.list0000664000175000017500000000011712610211212020272 0ustar fabiofabioBOOLEAN:VOID BOOLEAN:INT BOOLEAN:BOOLEAN VOID:STRING,STRING,STRING VOID:STRING cinnamon-screensaver-2.8.0/src/gs-prefs.c0000664000175000017500000003130412610211212017233 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include "gs-prefs.h" #include "gs-debug.h" static void gs_prefs_class_init (GSPrefsClass *klass); static void gs_prefs_init (GSPrefs *prefs); static void gs_prefs_finalize (GObject *object); #define LOCKDOWN_SETTINGS_SCHEMA "org.cinnamon.desktop.lockdown" #define KEY_LOCK_DISABLE "disable-lock-screen" #define KEY_USER_SWITCH_DISABLE "disable-user-switching" #define GS_SETTINGS_SCHEMA "org.cinnamon.desktop.screensaver" #define KEY_IDLE_ACTIVATION_ENABLED "idle-activation-enabled" #define KEY_LOCK_ENABLED "lock-enabled" #define KEY_LOCK_DELAY "lock-delay" #define KEY_USER_SWITCH_ENABLED "user-switch-enabled" #define KEY_LOGOUT_ENABLED "logout-enabled" #define KEY_LOGOUT_DELAY "logout-delay" #define KEY_LOGOUT_COMMAND "logout-command" #define KEY_KEYBOARD_ENABLED "embedded-keyboard-enabled" #define KEY_KEYBOARD_COMMAND "embedded-keyboard-command" #define GS_PREFS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_PREFS, GSPrefsPrivate)) struct GSPrefsPrivate { GSettings *settings; GSettings *lockdown; }; enum { CHANGED, LAST_SIGNAL }; enum { PROP_0 }; static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSPrefs, gs_prefs, G_TYPE_OBJECT) static void gs_prefs_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_prefs_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_prefs_class_init (GSPrefsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_prefs_finalize; object_class->get_property = gs_prefs_get_property; object_class->set_property = gs_prefs_set_property; signals [CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSPrefsClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_type_class_add_private (klass, sizeof (GSPrefsPrivate)); } static void _gs_prefs_set_lock_timeout (GSPrefs *prefs, guint value) { /* prevent overflow when converting to milliseconds */ if (value > G_MAXUINT / 1000) { value = G_MAXUINT / 1000; } prefs->lock_timeout = value * 1000; } static void _gs_prefs_set_idle_activation_enabled (GSPrefs *prefs, gboolean value) { prefs->idle_activation_enabled = value; } static void _gs_prefs_set_lock_enabled (GSPrefs *prefs, gboolean value) { prefs->lock_enabled = value; } static void _gs_prefs_set_lock_disabled (GSPrefs *prefs, gboolean value) { prefs->lock_disabled = value; } static void _gs_prefs_set_user_switch_disabled (GSPrefs *prefs, gboolean value) { prefs->user_switch_disabled = value; } static void _gs_prefs_set_keyboard_enabled (GSPrefs *prefs, gboolean value) { prefs->keyboard_enabled = value; } static void _gs_prefs_set_keyboard_command (GSPrefs *prefs, const char *value) { g_free (prefs->keyboard_command); prefs->keyboard_command = NULL; if (value) { /* FIXME: check command */ prefs->keyboard_command = g_strdup (value); } } static void _gs_prefs_set_logout_enabled (GSPrefs *prefs, gboolean value) { prefs->logout_enabled = value; } static void _gs_prefs_set_logout_command (GSPrefs *prefs, const char *value) { g_free (prefs->logout_command); prefs->logout_command = NULL; if (value) { /* FIXME: check command */ prefs->logout_command = g_strdup (value); } } static void _gs_prefs_set_logout_timeout (GSPrefs *prefs, guint value) { /* prevent overflow when converting to milliseconds */ if (value > G_MAXUINT / 1000) { value = G_MAXUINT / 1000; } prefs->logout_timeout = value * 1000; } static void _gs_prefs_set_user_switch_enabled (GSPrefs *prefs, gboolean value) { prefs->user_switch_enabled = value; } static guint _gs_settings_get_uint (GSettings *settings, const char *key) { guint value; g_settings_get (settings, key, "u", &value); return value; } static void gs_prefs_load_from_settings (GSPrefs *prefs) { guint uvalue; gboolean bvalue; char *string; bvalue = g_settings_get_boolean (prefs->priv->settings, KEY_IDLE_ACTIVATION_ENABLED); _gs_prefs_set_idle_activation_enabled (prefs, bvalue); bvalue = g_settings_get_boolean (prefs->priv->settings, KEY_LOCK_ENABLED); _gs_prefs_set_lock_enabled (prefs, bvalue); uvalue = _gs_settings_get_uint (prefs->priv->settings, KEY_LOCK_DELAY); _gs_prefs_set_lock_timeout (prefs, uvalue); /* Embedded keyboard options */ bvalue = g_settings_get_boolean (prefs->priv->settings, KEY_KEYBOARD_ENABLED); _gs_prefs_set_keyboard_enabled (prefs, bvalue); string = g_settings_get_string (prefs->priv->settings, KEY_KEYBOARD_COMMAND); _gs_prefs_set_keyboard_command (prefs, string); g_free (string); /* Logout options */ bvalue = g_settings_get_boolean (prefs->priv->settings, KEY_LOGOUT_ENABLED); _gs_prefs_set_logout_enabled (prefs, bvalue); string = g_settings_get_string (prefs->priv->settings, KEY_LOGOUT_COMMAND); _gs_prefs_set_logout_command (prefs, string); g_free (string); uvalue = _gs_settings_get_uint (prefs->priv->settings, KEY_LOGOUT_DELAY); _gs_prefs_set_logout_timeout (prefs, uvalue); /* User switching options */ bvalue = g_settings_get_boolean (prefs->priv->settings, KEY_USER_SWITCH_ENABLED); _gs_prefs_set_user_switch_enabled (prefs, bvalue); /* Lockdown keys */ bvalue = g_settings_get_boolean (prefs->priv->lockdown, KEY_LOCK_DISABLE); _gs_prefs_set_lock_disabled (prefs, bvalue); bvalue = g_settings_get_boolean (prefs->priv->lockdown, KEY_USER_SWITCH_DISABLE); _gs_prefs_set_user_switch_disabled (prefs, bvalue); } static void key_changed_cb (GSettings *settings, const gchar *key, GSPrefs *prefs) { if (strcmp (key, KEY_LOCK_DELAY) == 0) { guint delay; delay = _gs_settings_get_uint (settings, key); _gs_prefs_set_lock_timeout (prefs, delay); } else if (strcmp (key, KEY_IDLE_ACTIVATION_ENABLED) == 0) { gboolean enabled; enabled = g_settings_get_boolean (settings, key); _gs_prefs_set_idle_activation_enabled (prefs, enabled); } else if (strcmp (key, KEY_LOCK_ENABLED) == 0) { gboolean enabled; enabled = g_settings_get_boolean (settings, key); _gs_prefs_set_lock_enabled (prefs, enabled); gs_debug ("lock-enabled=%d",enabled); } else if (strcmp (key, KEY_LOCK_DISABLE) == 0) { gboolean disabled; disabled = g_settings_get_boolean (settings, key); _gs_prefs_set_lock_disabled (prefs, disabled); } else if (strcmp (key, KEY_USER_SWITCH_DISABLE) == 0) { gboolean disabled; disabled = g_settings_get_boolean (settings, key); _gs_prefs_set_user_switch_disabled (prefs, disabled); } else if (strcmp (key, KEY_KEYBOARD_ENABLED) == 0) { gboolean enabled; enabled = g_settings_get_boolean (settings, key); _gs_prefs_set_keyboard_enabled (prefs, enabled); } else if (strcmp (key, KEY_KEYBOARD_COMMAND) == 0) { const char *command; command = g_settings_get_string (settings, key); _gs_prefs_set_keyboard_command (prefs, command); } else if (strcmp (key, KEY_LOGOUT_ENABLED) == 0) { gboolean enabled; enabled = g_settings_get_boolean (settings, key); _gs_prefs_set_logout_enabled (prefs, enabled); } else if (strcmp (key, KEY_LOGOUT_DELAY) == 0) { guint delay; delay = _gs_settings_get_uint (settings, key); _gs_prefs_set_logout_timeout (prefs, delay); } else if (strcmp (key, KEY_LOGOUT_COMMAND) == 0) { const char *command; command = g_settings_get_string (settings, key); _gs_prefs_set_logout_command (prefs, command); } else if (strcmp (key, KEY_USER_SWITCH_ENABLED) == 0) { gboolean enabled; enabled = g_settings_get_boolean (settings, key); _gs_prefs_set_user_switch_enabled (prefs, enabled); } else { return; } g_signal_emit (prefs, signals [CHANGED], 0); } static void gs_prefs_init (GSPrefs *prefs) { prefs->priv = GS_PREFS_GET_PRIVATE (prefs); prefs->priv->settings = g_settings_new (GS_SETTINGS_SCHEMA); g_signal_connect (prefs->priv->settings, "changed", G_CALLBACK (key_changed_cb), prefs); prefs->priv->lockdown = g_settings_new (LOCKDOWN_SETTINGS_SCHEMA); g_signal_connect (prefs->priv->lockdown, "changed", G_CALLBACK (key_changed_cb), prefs); prefs->idle_activation_enabled = TRUE; prefs->lock_enabled = TRUE; prefs->lock_disabled = FALSE; prefs->logout_enabled = FALSE; prefs->user_switch_enabled = FALSE; prefs->lock_timeout = 0; prefs->logout_timeout = 14400000; gs_prefs_load_from_settings (prefs); } static void gs_prefs_finalize (GObject *object) { GSPrefs *prefs; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_PREFS (object)); prefs = GS_PREFS (object); g_return_if_fail (prefs->priv != NULL); if (prefs->priv->settings) { g_object_unref (prefs->priv->settings); prefs->priv->settings = NULL; } if (prefs->priv->lockdown) { g_object_unref (prefs->priv->lockdown); prefs->priv->lockdown = NULL; } g_free (prefs->logout_command); g_free (prefs->keyboard_command); G_OBJECT_CLASS (gs_prefs_parent_class)->finalize (object); } GSPrefs * gs_prefs_new (void) { GObject *prefs; prefs = g_object_new (GS_TYPE_PREFS, NULL); return GS_PREFS (prefs); } cinnamon-screensaver-2.8.0/src/setuid.c0000664000175000017500000002117112610211212017003 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * setuid.c --- management of runtime privileges. * * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ #include "config.h" #ifndef EPERM #include #endif #include #include #include #include #include /* for getpwnam() and struct passwd */ #include /* for getgrgid() and struct group */ #include #include "setuid.h" static char * uid_gid_string (uid_t uid, gid_t gid) { static char *buf; struct passwd *p = NULL; struct group *g = NULL; p = getpwuid (uid); g = getgrgid (gid); buf = g_strdup_printf ("%s/%s (%ld/%ld)", (p && p->pw_name ? p->pw_name : "???"), (g && g->gr_name ? g->gr_name : "???"), (long) uid, (long) gid); return buf; } static gboolean set_ids_by_number (uid_t uid, gid_t gid, char **message_ret) { int uid_errno = 0; int gid_errno = 0; int sgs_errno = 0; struct passwd *p = getpwuid (uid); struct group *g = getgrgid (gid); if (message_ret) *message_ret = NULL; /* Rumor has it that some implementations of of setuid() do nothing when called with -1; therefore, if the "nobody" user has a uid of -1, then that would be Really Bad. Rumor further has it that such systems really ought to be using -2 for "nobody", since that works. So, if we get a uid (or gid, for good measure) of -1, switch to -2 instead. Note that this must be done after we've looked up the user/group names with getpwuid(-1) and/or getgrgid(-1). */ if (gid == (gid_t) -1) gid = (gid_t) -2; if (uid == (uid_t) -1) uid = (uid_t) -2; errno = 0; if (setgroups (1, &gid) < 0) sgs_errno = errno ? errno : -1; errno = 0; if (setgid (gid) != 0) gid_errno = errno ? errno : -1; errno = 0; if (setuid (uid) != 0) uid_errno = errno ? errno : -1; if (uid_errno == 0 && gid_errno == 0 && sgs_errno == 0) { static char *reason; reason = g_strdup_printf ("changed uid/gid to %s/%s (%ld/%ld).", (p && p->pw_name ? p->pw_name : "???"), (g && g->gr_name ? g->gr_name : "???"), (long) uid, (long) gid); if (message_ret) *message_ret = g_strdup (reason); g_free (reason); return TRUE; } else { char *reason = NULL; if (sgs_errno) { reason = g_strdup_printf ("couldn't setgroups to %s (%ld)", (g && g->gr_name ? g->gr_name : "???"), (long) gid); if (sgs_errno == -1) fprintf (stderr, "%s: unknown error\n", reason); else { errno = sgs_errno; perror (reason); } g_free (reason); reason = NULL; } if (gid_errno) { reason = g_strdup_printf ("couldn't set gid to %s (%ld)", (g && g->gr_name ? g->gr_name : "???"), (long) gid); if (gid_errno == -1) fprintf (stderr, "%s: unknown error\n", reason); else { errno = gid_errno; perror (reason); } g_free (reason); reason = NULL; } if (uid_errno) { reason = g_strdup_printf ("couldn't set uid to %s (%ld)", (p && p->pw_name ? p->pw_name : "???"), (long) uid); if (uid_errno == -1) fprintf (stderr, "%s: unknown error\n", reason); else { errno = uid_errno; perror (reason); } g_free (reason); reason = NULL; } return FALSE; } return FALSE; } /* If we've been run as setuid or setgid to someone else (most likely root) turn off the extra permissions so that random user-specified programs don't get special privileges. (On some systems it is necessary to install this program as setuid root in order to read the passwd file to implement lock-mode.) *** WARNING: DO NOT DISABLE ANY OF THE FOLLOWING CODE! If you do so, you will open a security hole. See the sections of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", and "USING XDM". */ /* Returns TRUE if OK to lock, FALSE otherwise */ gboolean hack_uid (char **nolock_reason, char **orig_uid, char **uid_message) { char *reason; gboolean ret; ret = TRUE; reason = NULL; if (nolock_reason != NULL) { *nolock_reason = NULL; } if (orig_uid != NULL) { *orig_uid = NULL; } if (uid_message != NULL) { *uid_message = NULL; } /* Discard privileges, and set the effective user/group ids to the real user/group ids. That is, give up our "chmod +s" rights. */ { uid_t euid = geteuid (); gid_t egid = getegid (); uid_t uid = getuid (); gid_t gid = getgid (); if (orig_uid != NULL) { *orig_uid = uid_gid_string (euid, egid); } #ifdef HAVE_BSDAUTH /* we need to setgid auth to run the bsd_auth(3) login_* helpers */ { struct group *authg = getgrnam("auth"); if (!authg || !authg->gr_name || !*authg->gr_name) { reason = g_strdup ("no such group as \"auth\" for bsdauth."); ret = FALSE; goto out; } if (! set_ids_by_number (uid, authg->gr_gid, uid_message)) { reason = g_strdup ("cannot setgid \"auth\" for bsdauth."); ret = FALSE; goto out; } } #else /* !HAVE_BSDAUTH */ if (uid != euid || gid != egid) { if (! set_ids_by_number (uid, gid, uid_message)) { reason = g_strdup ("unable to discard privileges."); ret = FALSE; goto out; } } #endif } /* Locking can't work when running as root, because we have no way of knowing what the user id of the logged in user is (so we don't know whose password to prompt for.) *** WARNING: DO NOT DISABLE THIS CODE! If you do so, you will open a security hole. See the sections of the xscreensaver manual titled "LOCKING AND ROOT LOGINS", and "USING XDM". */ if (getuid () == (uid_t) 0) { reason = g_strdup ("running as root"); ret = FALSE; goto out; } out: if (nolock_reason != NULL) { *nolock_reason = g_strdup (reason); } g_free (reason); return ret; } cinnamon-screensaver-2.8.0/src/gs-marshal.c0000664000175000017500000002023012610211212017537 0ustar fabiofabio#include "gs-marshal.h" #include #ifdef G_ENABLE_DEBUG #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) #define g_marshal_value_peek_char(v) g_value_get_schar (v) #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) #define g_marshal_value_peek_int(v) g_value_get_int (v) #define g_marshal_value_peek_uint(v) g_value_get_uint (v) #define g_marshal_value_peek_long(v) g_value_get_long (v) #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) #define g_marshal_value_peek_enum(v) g_value_get_enum (v) #define g_marshal_value_peek_flags(v) g_value_get_flags (v) #define g_marshal_value_peek_float(v) g_value_get_float (v) #define g_marshal_value_peek_double(v) g_value_get_double (v) #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) #define g_marshal_value_peek_param(v) g_value_get_param (v) #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) #define g_marshal_value_peek_variant(v) g_value_get_variant (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the * g_value_get_*() functions */ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int #define g_marshal_value_peek_char(v) (v)->data[0].v_int #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint #define g_marshal_value_peek_int(v) (v)->data[0].v_int #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint #define g_marshal_value_peek_long(v) (v)->data[0].v_long #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 #define g_marshal_value_peek_enum(v) (v)->data[0].v_long #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong #define g_marshal_value_peek_float(v) (v)->data[0].v_float #define g_marshal_value_peek_double(v) (v)->data[0].v_double #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ /* BOOLEAN:VOID (gs-marshal.list:1) */ void gs_marshal_BOOLEAN__VOID (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, gpointer data2); register GMarshalFunc_BOOLEAN__VOID callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 1); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, data2); g_value_set_boolean (return_value, v_return); } /* BOOLEAN:INT (gs-marshal.list:2) */ void gs_marshal_BOOLEAN__INT (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__INT) (gpointer data1, gint arg_1, gpointer data2); register GMarshalFunc_BOOLEAN__INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 2); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__INT) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_int (param_values + 1), data2); g_value_set_boolean (return_value, v_return); } /* BOOLEAN:BOOLEAN (gs-marshal.list:3) */ void gs_marshal_BOOLEAN__BOOLEAN (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN) (gpointer data1, gboolean arg_1, gpointer data2); register GMarshalFunc_BOOLEAN__BOOLEAN callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gboolean v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 2); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_BOOLEAN__BOOLEAN) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_boolean (param_values + 1), data2); g_value_set_boolean (return_value, v_return); } /* VOID:STRING,STRING,STRING (gs-marshal.list:4) */ void gs_marshal_VOID__STRING_STRING_STRING (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1, gpointer arg_1, gpointer arg_2, gpointer arg_3, gpointer data2); register GMarshalFunc_VOID__STRING_STRING_STRING callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 4); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_string (param_values + 1), g_marshal_value_peek_string (param_values + 2), g_marshal_value_peek_string (param_values + 3), data2); } /* VOID:STRING (gs-marshal.list:5) */ cinnamon-screensaver-2.8.0/src/gs-watcher.h0000664000175000017500000000472412610211212017564 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_WATCHER_H #define __GS_WATCHER_H G_BEGIN_DECLS #define GS_TYPE_WATCHER (gs_watcher_get_type ()) #define GS_WATCHER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_WATCHER, GSWatcher)) #define GS_WATCHER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_WATCHER, GSWatcherClass)) #define GS_IS_WATCHER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_WATCHER)) #define GS_IS_WATCHER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_WATCHER)) #define GS_WATCHER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_WATCHER, GSWatcherClass)) typedef struct GSWatcherPrivate GSWatcherPrivate; typedef struct { GObject parent; GSWatcherPrivate *priv; } GSWatcher; typedef struct { GObjectClass parent_class; gboolean (* idle_changed) (GSWatcher *watcher, gboolean is_idle); gboolean (* idle_notice_changed) (GSWatcher *watcher, gboolean in_effect); } GSWatcherClass; GType gs_watcher_get_type (void); GSWatcher * gs_watcher_new (void); gboolean gs_watcher_set_enabled (GSWatcher *watcher, gboolean enabled); gboolean gs_watcher_get_enabled (GSWatcher *watcher); gboolean gs_watcher_set_active (GSWatcher *watcher, gboolean active); gboolean gs_watcher_get_active (GSWatcher *watcher); G_END_DECLS #endif /* __GS_WATCHER_H */ cinnamon-screensaver-2.8.0/src/gs-listener-dbus.h0000664000175000017500000000710412610211212020702 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_LISTENER_H #define __GS_LISTENER_H G_BEGIN_DECLS #define GS_TYPE_LISTENER (gs_listener_get_type ()) #define GS_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_LISTENER, GSListener)) #define GS_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_LISTENER, GSListenerClass)) #define GS_IS_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_LISTENER)) #define GS_IS_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_LISTENER)) #define GS_LISTENER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_LISTENER, GSListenerClass)) typedef struct GSListenerPrivate GSListenerPrivate; typedef struct { GObject parent; GSListenerPrivate *priv; } GSListener; typedef struct { GObjectClass parent_class; void (* lock) (GSListener *listener); void (* quit) (GSListener *listener); void (* simulate_user_activity) (GSListener *listener); gboolean (* active_changed) (GSListener *listener, gboolean active); void (* throttle_changed) (GSListener *listener, gboolean throttled); void (* show_message) (GSListener *listener, const char *summary, const char *body, const char *icon); } GSListenerClass; typedef enum { GS_LISTENER_ERROR_SERVICE_UNAVAILABLE, GS_LISTENER_ERROR_ACQUISITION_FAILURE, GS_LISTENER_ERROR_ACTIVATION_FAILURE } GSListenerError; #define GS_LISTENER_ERROR gs_listener_error_quark () GQuark gs_listener_error_quark (void); GType gs_listener_get_type (void); GSListener *gs_listener_new (void); gboolean gs_listener_acquire (GSListener *listener, GError **error); gboolean gs_listener_set_active (GSListener *listener, gboolean active); gboolean gs_listener_set_session_idle (GSListener *listener, gboolean idle); void gs_listener_set_activation_enabled (GSListener *listener, gboolean enabled); gboolean gs_listener_get_activation_enabled (GSListener *listener); G_END_DECLS #endif /* __GS_LISTENER_H */ cinnamon-screensaver-2.8.0/src/gs-manager.c0000664000175000017500000012553312610211212017536 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2008 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #define GNOME_DESKTOP_USE_UNSTABLE_API #include #include "gs-prefs.h" /* for GSSaverMode */ #include "gs-manager.h" #include "gs-window.h" #include "gs-grab.h" #include "gs-fade.h" #include "gs-debug.h" static void gs_manager_class_init (GSManagerClass *klass); static void gs_manager_init (GSManager *manager); static void gs_manager_finalize (GObject *object); #define GS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_MANAGER, GSManagerPrivate)) struct GSManagerPrivate { GSList *windows; GSettings *settings; GnomeBG *bg; /* Policy */ glong lock_timeout; glong logout_timeout; guint lock_enabled : 1; guint logout_enabled : 1; guint keyboard_enabled : 1; guint user_switch_enabled : 1; char *logout_command; char *keyboard_command; /* State */ guint active : 1; guint lock_active : 1; guint fading : 1; guint dialog_up : 1; time_t activate_time; guint lock_timeout_id; GSGrab *grab; GSFade *fade; guint unfade_idle_id; char *away_message; }; enum { ACTIVATED, DEACTIVATED, AUTH_REQUEST_BEGIN, AUTH_REQUEST_END, LAST_SIGNAL }; enum { PROP_0, PROP_LOCK_ENABLED, PROP_LOGOUT_ENABLED, PROP_USER_SWITCH_ENABLED, PROP_KEYBOARD_ENABLED, PROP_LOCK_TIMEOUT, PROP_LOGOUT_TIMEOUT, PROP_LOGOUT_COMMAND, PROP_KEYBOARD_COMMAND, PROP_ACTIVE, }; #define FADE_TIMEOUT 250 static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSManager, gs_manager, G_TYPE_OBJECT) void gs_manager_get_lock_active (GSManager *manager, gboolean *lock_active) { if (lock_active != NULL) { *lock_active = FALSE; } g_return_if_fail (GS_IS_MANAGER (manager)); if (lock_active != NULL) { *lock_active = manager->priv->lock_active; } } void gs_manager_set_lock_active (GSManager *manager, gboolean lock_active) { g_return_if_fail (GS_IS_MANAGER (manager)); gs_debug ("Setting lock active: %d", lock_active); if (manager->priv->lock_active != lock_active) { GSList *l; manager->priv->lock_active = lock_active; for (l = manager->priv->windows; l; l = l->next) { gs_window_set_lock_enabled (l->data, lock_active); } } } void gs_manager_get_lock_enabled (GSManager *manager, gboolean *lock_enabled) { if (lock_enabled != NULL) { *lock_enabled = FALSE; } g_return_if_fail (GS_IS_MANAGER (manager)); if (lock_enabled != NULL) { *lock_enabled = manager->priv->lock_enabled; } } void gs_manager_set_lock_enabled (GSManager *manager, gboolean lock_enabled) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->lock_enabled != lock_enabled) { manager->priv->lock_enabled = lock_enabled; gs_debug ("GSManager: lock-enabled=%d", lock_enabled); } } void gs_manager_set_logout_enabled (GSManager *manager, gboolean logout_enabled) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->logout_enabled != logout_enabled) { GSList *l; manager->priv->logout_enabled = logout_enabled; for (l = manager->priv->windows; l; l = l->next) { gs_window_set_logout_enabled (l->data, logout_enabled); } } } void gs_manager_set_keyboard_enabled (GSManager *manager, gboolean enabled) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->keyboard_enabled != enabled) { GSList *l; manager->priv->keyboard_enabled = enabled; for (l = manager->priv->windows; l; l = l->next) { gs_window_set_keyboard_enabled (l->data, enabled); } } } void gs_manager_set_user_switch_enabled (GSManager *manager, gboolean user_switch_enabled) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->user_switch_enabled != user_switch_enabled) { GSList *l; manager->priv->user_switch_enabled = user_switch_enabled; for (l = manager->priv->windows; l; l = l->next) { gs_window_set_user_switch_enabled (l->data, user_switch_enabled); } } } static gboolean activate_lock_timeout (GSManager *manager) { if (manager->priv->lock_enabled) { gs_manager_set_lock_active (manager, TRUE); } manager->priv->lock_timeout_id = 0; return FALSE; } static void remove_lock_timer (GSManager *manager) { if (manager->priv->lock_timeout_id != 0) { g_source_remove (manager->priv->lock_timeout_id); manager->priv->lock_timeout_id = 0; } } static void add_lock_timer (GSManager *manager, glong timeout) { manager->priv->lock_timeout_id = g_timeout_add (timeout, (GSourceFunc)activate_lock_timeout, manager); } void gs_manager_set_lock_timeout (GSManager *manager, glong lock_timeout) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->lock_timeout != lock_timeout) { manager->priv->lock_timeout = lock_timeout; if (manager->priv->active && ! manager->priv->lock_active && (lock_timeout >= 0)) { glong elapsed = (time (NULL) - manager->priv->activate_time) * 1000; remove_lock_timer (manager); if (elapsed >= lock_timeout) { activate_lock_timeout (manager); } else { add_lock_timer (manager, lock_timeout - elapsed); } } } } void gs_manager_set_logout_timeout (GSManager *manager, glong logout_timeout) { g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->logout_timeout != logout_timeout) { GSList *l; manager->priv->logout_timeout = logout_timeout; for (l = manager->priv->windows; l; l = l->next) { gs_window_set_logout_timeout (l->data, logout_timeout); } } } void gs_manager_set_logout_command (GSManager *manager, const char *command) { GSList *l; g_return_if_fail (GS_IS_MANAGER (manager)); g_free (manager->priv->logout_command); if (command) { manager->priv->logout_command = g_strdup (command); } else { manager->priv->logout_command = NULL; } for (l = manager->priv->windows; l; l = l->next) { gs_window_set_logout_command (l->data, manager->priv->logout_command); } } void gs_manager_set_keyboard_command (GSManager *manager, const char *command) { GSList *l; g_return_if_fail (GS_IS_MANAGER (manager)); g_free (manager->priv->keyboard_command); if (command) { manager->priv->keyboard_command = g_strdup (command); } else { manager->priv->keyboard_command = NULL; } for (l = manager->priv->windows; l; l = l->next) { gs_window_set_keyboard_command (l->data, manager->priv->keyboard_command); } } static void gs_manager_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GSManager *self; self = GS_MANAGER (object); switch (prop_id) { case PROP_LOCK_ENABLED: gs_manager_set_lock_enabled (self, g_value_get_boolean (value)); break; case PROP_LOCK_TIMEOUT: gs_manager_set_lock_timeout (self, g_value_get_long (value)); break; case PROP_LOGOUT_ENABLED: gs_manager_set_logout_enabled (self, g_value_get_boolean (value)); break; case PROP_KEYBOARD_ENABLED: gs_manager_set_keyboard_enabled (self, g_value_get_boolean (value)); break; case PROP_USER_SWITCH_ENABLED: gs_manager_set_user_switch_enabled (self, g_value_get_boolean (value)); break; case PROP_LOGOUT_TIMEOUT: gs_manager_set_logout_timeout (self, g_value_get_long (value)); break; case PROP_LOGOUT_COMMAND: gs_manager_set_logout_command (self, g_value_get_string (value)); break; case PROP_KEYBOARD_COMMAND: gs_manager_set_keyboard_command (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_manager_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GSManager *self; self = GS_MANAGER (object); switch (prop_id) { case PROP_LOCK_ENABLED: g_value_set_boolean (value, self->priv->lock_enabled); break; case PROP_LOCK_TIMEOUT: g_value_set_long (value, self->priv->lock_timeout); break; case PROP_LOGOUT_ENABLED: g_value_set_boolean (value, self->priv->logout_enabled); break; case PROP_KEYBOARD_ENABLED: g_value_set_boolean (value, self->priv->keyboard_enabled); break; case PROP_USER_SWITCH_ENABLED: g_value_set_boolean (value, self->priv->user_switch_enabled); break; case PROP_LOGOUT_TIMEOUT: g_value_set_long (value, self->priv->logout_timeout); break; case PROP_LOGOUT_COMMAND: g_value_set_string (value, self->priv->logout_command); break; case PROP_KEYBOARD_COMMAND: g_value_set_string (value, self->priv->keyboard_command); break; case PROP_ACTIVE: g_value_set_boolean (value, self->priv->active); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_manager_class_init (GSManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_manager_finalize; object_class->get_property = gs_manager_get_property; object_class->set_property = gs_manager_set_property; signals [ACTIVATED] = g_signal_new ("activated", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSManagerClass, activated), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals [DEACTIVATED] = g_signal_new ("deactivated", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSManagerClass, deactivated), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals [AUTH_REQUEST_BEGIN] = g_signal_new ("auth-request-begin", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSManagerClass, auth_request_begin), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals [AUTH_REQUEST_END] = g_signal_new ("auth-request-end", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSManagerClass, auth_request_end), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_object_class_install_property (object_class, PROP_ACTIVE, g_param_spec_boolean ("active", NULL, NULL, FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_LOCK_ENABLED, g_param_spec_boolean ("lock-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOCK_TIMEOUT, g_param_spec_long ("lock-timeout", NULL, NULL, -1, G_MAXLONG, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_ENABLED, g_param_spec_boolean ("logout-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_USER_SWITCH_ENABLED, g_param_spec_boolean ("user-switch-enabled", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_TIMEOUT, g_param_spec_long ("logout-timeout", NULL, NULL, -1, G_MAXLONG, 0, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_LOGOUT_COMMAND, g_param_spec_string ("logout-command", NULL, NULL, NULL, G_PARAM_READWRITE)); g_type_class_add_private (klass, sizeof (GSManagerPrivate)); } static void on_bg_changed (GnomeBG *bg, GSManager *manager) { gs_debug ("background changed"); } static gboolean background_settings_change_event_cb (GSettings *settings, gpointer keys, gint n_keys, GSManager *manager) { gnome_bg_load_from_preferences (manager->priv->bg, manager->priv->settings); return FALSE; } static GSettings * get_system_settings (void) { GSettings *settings; settings = g_settings_new ("org.cinnamon.desktop.background"); return settings; } static void gs_manager_init (GSManager *manager) { manager->priv = GS_MANAGER_GET_PRIVATE (manager); manager->priv->fade = gs_fade_new (); manager->priv->grab = gs_grab_new (); manager->priv->settings = get_system_settings (); manager->priv->bg = gnome_bg_new (); g_signal_connect (manager->priv->bg, "changed", G_CALLBACK (on_bg_changed), manager); g_signal_connect (manager->priv->settings, "change-event", G_CALLBACK (background_settings_change_event_cb), manager); gnome_bg_load_from_preferences (manager->priv->bg, manager->priv->settings); } static void remove_timers (GSManager *manager) { remove_lock_timer (manager); } static void remove_unfade_idle (GSManager *manager) { if (manager->priv->unfade_idle_id > 0) { g_source_remove (manager->priv->unfade_idle_id); manager->priv->unfade_idle_id = 0; } } static gboolean window_deactivated_idle (GSManager *manager) { g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); /* don't deactivate directly but only emit a signal so that we let the parent deactivate */ g_signal_emit (manager, signals [DEACTIVATED], 0); return FALSE; } static void window_deactivated_cb (GSWindow *window, GSManager *manager) { g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); g_idle_add ((GSourceFunc)window_deactivated_idle, manager); } static GSWindow * find_window_at_pointer (GSManager *manager) { GdkDisplay *display; GdkScreen *screen; int monitor; int x, y; GSWindow *window; int screen_num; GSList *l; display = gdk_display_get_default (); gdk_display_get_pointer (display, &screen, &x, &y, NULL); monitor = gdk_screen_get_monitor_at_point (screen, x, y); screen_num = gdk_screen_get_number (screen); /* Find the gs-window that is on that screen */ window = NULL; for (l = manager->priv->windows; l; l = l->next) { GSWindow *win = GS_WINDOW (l->data); if (gs_window_get_screen (win) == screen && gs_window_get_monitor (win) == monitor) { window = win; } } if (window == NULL) { gs_debug ("WARNING: Could not find the GSWindow for screen %d", screen_num); /* take the first one */ window = manager->priv->windows->data; } else { gs_debug ("Requesting unlock for screen %d", screen_num); } return window; } void gs_manager_show_message (GSManager *manager, const char *summary, const char *body, const char *icon) { GSWindow *window; g_return_if_fail (GS_IS_MANAGER (manager)); /* Find the GSWindow that contains the pointer */ window = find_window_at_pointer (manager); gs_window_show_message (window, summary, body, icon); gs_manager_request_unlock (manager); } static gboolean manager_maybe_grab_window (GSManager *manager, GSWindow *window) { GdkDisplay *display; GdkScreen *screen; int monitor; int x, y; gboolean grabbed; display = gdk_display_get_default (); gdk_display_get_pointer (display, &screen, &x, &y, NULL); monitor = gdk_screen_get_monitor_at_point (screen, x, y); gdk_flush (); grabbed = FALSE; if (gs_window_get_screen (window) == screen && gs_window_get_monitor (window) == monitor) { gs_debug ("Moving grab to %p", window); gs_grab_move_to_window (manager->priv->grab, gs_window_get_gdk_window (window), gs_window_get_screen (window), FALSE); grabbed = TRUE; } return grabbed; } static void window_grab_broken_cb (GSWindow *window, GdkEventGrabBroken *event, GSManager *manager) { gs_debug ("GRAB BROKEN!"); if (event->keyboard) { gs_grab_keyboard_reset (manager->priv->grab); } else { gs_grab_mouse_reset (manager->priv->grab); } } static gboolean unfade_idle (GSManager *manager) { gs_debug ("resetting fade"); gs_fade_reset (manager->priv->fade); manager->priv->unfade_idle_id = 0; return FALSE; } static void add_unfade_idle (GSManager *manager) { remove_unfade_idle (manager); manager->priv->unfade_idle_id = g_timeout_add (500, (GSourceFunc)unfade_idle, manager); } static gboolean window_map_event_cb (GSWindow *window, GdkEvent *event, GSManager *manager) { gs_debug ("Handling window map_event event"); manager_maybe_grab_window (manager, window); return FALSE; } static void window_map_cb (GSWindow *window, GSManager *manager) { gs_debug ("Handling window map event"); } static void window_unmap_cb (GSWindow *window, GSManager *manager) { gs_debug ("window unmapped!"); } static void apply_background_to_window (GSManager *manager, GSWindow *window) { cairo_surface_t *surface; GdkScreen *screen; GdkWindow *gdk_window; gint monitor; GdkRectangle monitor_geometry; int width; int height; if (manager->priv->bg == NULL) { gs_debug ("No background available"); gs_window_set_background_surface (window, NULL); } screen = gs_window_get_screen (window); gdk_window = gs_window_get_gdk_window (window); monitor = gdk_screen_get_monitor_at_window (screen, gdk_window); gdk_screen_get_monitor_geometry (screen, monitor, &monitor_geometry); width = monitor_geometry.width; height = monitor_geometry.height; gs_debug ("Creating background w:%d h:%d", width, height); surface = gnome_bg_create_surface (manager->priv->bg, gdk_window, width, height, FALSE); gs_window_set_background_surface (window, surface); cairo_surface_destroy (surface); } static void manager_show_window (GSManager *manager, GSWindow *window) { apply_background_to_window (manager, window); manager->priv->activate_time = time (NULL); if (manager->priv->lock_timeout >= 0) { remove_lock_timer (manager); add_lock_timer (manager, manager->priv->lock_timeout); } add_unfade_idle (manager); /* FIXME: only emit signal once */ g_signal_emit (manager, signals [ACTIVATED], 0); } static void window_show_cb (GSWindow *window, GSManager *manager) { g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); g_return_if_fail (window != NULL); g_return_if_fail (GS_IS_WINDOW (window)); gs_debug ("Handling window show"); manager_show_window (manager, window); } static void handle_window_dialog_up (GSManager *manager, GSWindow *window) { g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); gs_debug ("Handling dialog up"); g_signal_emit (manager, signals [AUTH_REQUEST_BEGIN], 0); manager->priv->dialog_up = TRUE; /* Move keyboard and mouse grabs so dialog can be used */ gs_grab_move_to_window (manager->priv->grab, gs_window_get_gdk_window (window), gs_window_get_screen (window), FALSE); /* Release the pointer grab while dialog is up so that the dialog can be used. We'll regrab it when the dialog goes down. */ gs_grab_release_mouse (manager->priv->grab); } static void handle_window_dialog_down (GSManager *manager, GSWindow *window) { GSList *l; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); gs_debug ("Handling dialog down"); /* Regrab the mouse */ gs_grab_move_to_window (manager->priv->grab, gs_window_get_gdk_window (window), gs_window_get_screen (window), FALSE); /* Make all windows sensitive so we get events */ for (l = manager->priv->windows; l; l = l->next) { gtk_widget_set_sensitive (GTK_WIDGET (l->data), TRUE); } manager->priv->dialog_up = FALSE; g_signal_emit (manager, signals [AUTH_REQUEST_END], 0); } static void window_dialog_up_changed_cb (GSWindow *window, GParamSpec *pspec, GSManager *manager) { gboolean up; up = gs_window_is_dialog_up (window); gs_debug ("Handling window dialog up changed: %s", up ? "up" : "down"); if (up) { handle_window_dialog_up (manager, window); } else { handle_window_dialog_down (manager, window); } } static gboolean window_activity_cb (GSWindow *window, GSManager *manager) { gboolean handled; handled = gs_manager_request_unlock (manager); return handled; } static void disconnect_window_signals (GSManager *manager, GSWindow *window) { g_signal_handlers_disconnect_by_func (window, window_deactivated_cb, manager); g_signal_handlers_disconnect_by_func (window, window_activity_cb, manager); g_signal_handlers_disconnect_by_func (window, window_show_cb, manager); g_signal_handlers_disconnect_by_func (window, window_map_cb, manager); g_signal_handlers_disconnect_by_func (window, window_map_event_cb, manager); g_signal_handlers_disconnect_by_func (window, window_dialog_up_changed_cb, manager); g_signal_handlers_disconnect_by_func (window, window_unmap_cb, manager); g_signal_handlers_disconnect_by_func (window, window_grab_broken_cb, manager); } static void window_destroyed_cb (GtkWindow *window, GSManager *manager) { disconnect_window_signals (manager, GS_WINDOW (window)); } static void connect_window_signals (GSManager *manager, GSWindow *window) { g_signal_connect_object (window, "destroy", G_CALLBACK (window_destroyed_cb), manager, 0); g_signal_connect_object (window, "activity", G_CALLBACK (window_activity_cb), manager, 0); g_signal_connect_object (window, "deactivated", G_CALLBACK (window_deactivated_cb), manager, 0); g_signal_connect_object (window, "show", G_CALLBACK (window_show_cb), manager, G_CONNECT_AFTER); g_signal_connect_object (window, "map", G_CALLBACK (window_map_cb), manager, G_CONNECT_AFTER); g_signal_connect_object (window, "map_event", G_CALLBACK (window_map_event_cb), manager, G_CONNECT_AFTER); g_signal_connect_object (window, "notify::dialog-up", G_CALLBACK (window_dialog_up_changed_cb), manager, 0); g_signal_connect_object (window, "unmap", G_CALLBACK (window_unmap_cb), manager, G_CONNECT_AFTER); g_signal_connect_object (window, "grab_broken_event", G_CALLBACK (window_grab_broken_cb), manager, G_CONNECT_AFTER); } static void gs_manager_create_window_for_monitor (GSManager *manager, GdkScreen *screen, int monitor) { GSWindow *window; GdkRectangle rect; gdk_screen_get_monitor_geometry (screen, monitor, &rect); gs_debug ("Creating window for monitor %d [%d,%d] (%dx%d)", monitor, rect.x, rect.y, rect.width, rect.height); window = gs_window_new (screen, monitor, manager->priv->lock_active); gs_window_set_user_switch_enabled (window, manager->priv->user_switch_enabled); gs_window_set_away_message (window, manager->priv->away_message); gs_window_set_logout_enabled (window, manager->priv->logout_enabled); gs_window_set_logout_timeout (window, manager->priv->logout_timeout); gs_window_set_logout_command (window, manager->priv->logout_command); gs_window_set_keyboard_enabled (window, manager->priv->keyboard_enabled); gs_window_set_keyboard_command (window, manager->priv->keyboard_command); connect_window_signals (manager, window); manager->priv->windows = g_slist_append (manager->priv->windows, window); if (manager->priv->active && !manager->priv->fading) { gtk_widget_show (GTK_WIDGET (window)); } } static void on_screen_monitors_changed (GdkScreen *screen, GSManager *manager) { GSList *l; int n_monitors; int n_windows; int i; n_monitors = gdk_screen_get_n_monitors (screen); n_windows = g_slist_length (manager->priv->windows); gs_debug ("Monitors changed for screen %d: num=%d", gdk_screen_get_number (screen), n_monitors); if (n_monitors > n_windows) { /* Tear down unlock dialog in case we want to move it * to a new monitor */ l = manager->priv->windows; while (l != NULL) { gs_window_cancel_unlock_request (GS_WINDOW (l->data)); l = l->next; } /* add more windows */ for (i = n_windows; i < n_monitors; i++) { gs_manager_create_window_for_monitor (manager, screen, i); } /* And put unlock dialog up where ever it's supposed to be */ gs_manager_request_unlock (manager); } else { gdk_x11_grab_server (); /* remove the extra windows */ l = manager->priv->windows; while (l != NULL) { GdkScreen *this_screen; int this_monitor; GSList *next = l->next; this_screen = gs_window_get_screen (GS_WINDOW (l->data)); this_monitor = gs_window_get_monitor (GS_WINDOW (l->data)); if (this_screen == screen && this_monitor >= n_monitors) { gs_window_destroy (GS_WINDOW (l->data)); manager->priv->windows = g_slist_delete_link (manager->priv->windows, l); } l = next; } /* make sure there is a lock dialog on a connected monitor, * and that the keyboard is still properly grabbed after all * the windows above got destroyed*/ if (n_windows > n_monitors) { gs_manager_request_unlock (manager); } gdk_flush (); gdk_x11_ungrab_server (); } } static void gs_manager_destroy_windows (GSManager *manager) { GdkDisplay *display; GSList *l; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); if (manager->priv->windows == NULL) { return; } display = gdk_display_get_default (); g_signal_handlers_disconnect_by_func (gdk_display_get_default_screen (display), on_screen_monitors_changed, manager); for (l = manager->priv->windows; l; l = l->next) { gs_window_destroy (l->data); } g_slist_free (manager->priv->windows); manager->priv->windows = NULL; } static void gs_manager_finalize (GObject *object) { GSManager *manager; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_MANAGER (object)); manager = GS_MANAGER (object); g_return_if_fail (manager->priv != NULL); if (manager->priv->bg != NULL) { g_object_unref (manager->priv->bg); } if (manager->priv->settings != NULL) { g_settings_revert (manager->priv->settings); g_object_unref (manager->priv->settings); } g_free (manager->priv->away_message); g_free (manager->priv->logout_command); g_free (manager->priv->keyboard_command); remove_unfade_idle (manager); remove_timers (manager); gs_grab_release (manager->priv->grab); gs_manager_destroy_windows (manager); manager->priv->active = FALSE; manager->priv->activate_time = 0; manager->priv->lock_enabled = FALSE; g_object_unref (manager->priv->fade); g_object_unref (manager->priv->grab); G_OBJECT_CLASS (gs_manager_parent_class)->finalize (object); } static void gs_manager_create_windows_for_screen (GSManager *manager, GdkScreen *screen) { int n_monitors; int i; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); g_return_if_fail (GDK_IS_SCREEN (screen)); g_object_ref (manager); g_object_ref (screen); n_monitors = gdk_screen_get_n_monitors (screen); gs_debug ("Creating %d windows for screen %d", n_monitors, gdk_screen_get_number (screen)); for (i = 0; i < n_monitors; i++) { gs_manager_create_window_for_monitor (manager, screen, i); } g_object_unref (screen); g_object_unref (manager); } static void gs_manager_create_windows (GSManager *manager) { GdkDisplay *display; g_return_if_fail (manager != NULL); g_return_if_fail (GS_IS_MANAGER (manager)); g_assert (manager->priv->windows == NULL); display = gdk_display_get_default (); g_signal_connect (gdk_display_get_default_screen (display), "monitors-changed", G_CALLBACK (on_screen_monitors_changed), manager); gs_manager_create_windows_for_screen (manager, gdk_display_get_default_screen (display)); } GSManager * gs_manager_new (void) { GObject *manager; manager = g_object_new (GS_TYPE_MANAGER, NULL); return GS_MANAGER (manager); } static void show_windows (GSList *windows) { GSList *l; for (l = windows; l; l = l->next) { gtk_widget_show (GTK_WIDGET (l->data)); } } static void fade_done_cb (GSFade *fade, GSManager *manager) { gs_debug ("fade completed, showing windows"); show_windows (manager->priv->windows); manager->priv->fading = FALSE; } static gboolean gs_manager_activate (GSManager *manager) { gboolean do_fade; gboolean res; g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); if (manager->priv->active) { gs_debug ("Trying to activate manager when already active"); return FALSE; } res = gs_grab_grab_root (manager->priv->grab, FALSE); if (! res) { return FALSE; } if (manager->priv->windows == NULL) { gs_manager_create_windows (GS_MANAGER (manager)); } manager->priv->active = TRUE; /* fade to black and show windows */ do_fade = FALSE; if (do_fade) { manager->priv->fading = TRUE; gs_debug ("fading out"); gs_fade_async (manager->priv->fade, FADE_TIMEOUT, (GSFadeDoneFunc)fade_done_cb, manager); while (manager->priv->fading) { gtk_main_iteration (); } } else { show_windows (manager->priv->windows); } return TRUE; } static gboolean gs_manager_deactivate (GSManager *manager) { g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); if (! manager->priv->active) { gs_debug ("Trying to deactivate a screensaver that is not active"); return FALSE; } remove_unfade_idle (manager); gs_fade_reset (manager->priv->fade); remove_timers (manager); gs_grab_release (manager->priv->grab); gs_manager_destroy_windows (manager); gs_manager_set_away_message (manager, NULL); /* reset state */ manager->priv->active = FALSE; manager->priv->activate_time = 0; manager->priv->lock_active = FALSE; manager->priv->dialog_up = FALSE; manager->priv->fading = FALSE; return TRUE; } void gs_manager_set_away_message (GSManager *manager, const char *message) { GSList *l; g_return_if_fail (GS_IS_MANAGER (manager)); g_free (manager->priv->away_message); if (message) { manager->priv->away_message = g_strdup (message); } else { manager->priv->away_message = NULL; } for (l = manager->priv->windows; l; l = l->next) { gs_window_set_away_message (l->data, manager->priv->away_message); } } gboolean gs_manager_set_active (GSManager *manager, gboolean active) { gboolean res; if (active) { res = gs_manager_activate (manager); } else { res = gs_manager_deactivate (manager); } return res; } gboolean gs_manager_get_active (GSManager *manager) { g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); return manager->priv->active; } gboolean gs_manager_request_unlock (GSManager *manager) { GSWindow *window; g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); if (! manager->priv->active) { gs_debug ("Request unlock but manager is not active"); return FALSE; } if (manager->priv->dialog_up) { gs_debug ("Request unlock but dialog is already up"); return FALSE; } if (manager->priv->fading) { gs_debug ("Request unlock so finishing fade"); gs_fade_finish (manager->priv->fade); } if (manager->priv->windows == NULL) { gs_debug ("We don't have any windows!"); return FALSE; } /* Find the GSWindow that contains the pointer */ window = find_window_at_pointer (manager); gs_window_request_unlock (window); return TRUE; } void gs_manager_cancel_unlock_request (GSManager *manager) { GSList *l; for (l = manager->priv->windows; l; l = l->next) { gs_window_cancel_unlock_request (l->data); } } cinnamon-screensaver-2.8.0/src/bus.h0000664000175000017500000000465012610211212016307 0ustar fabiofabio/* vim: set noet ts=8 sts=8 sw=8 : * * Copyright © 2010 Saleem Abdulrasool * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * */ #ifndef bus_h #define bus_h /* logind */ #define LOGIND_SERVICE "org.freedesktop.login1" #define LOGIND_PATH "/org/freedesktop/login1" #define LOGIND_INTERFACE "org.freedesktop.login1.Manager" #define LOGIND_SESSION_INTERFACE "org.freedesktop.login1.Session" #define LOGIND_SESSION_PATH "/org/freedesktop/login1/session" /* ConsoleKit */ #define CK_SERVICE "org.freedesktop.ConsoleKit" #define CK_PATH "/org/freedesktop/ConsoleKit" #define CK_INTERFACE "org.freedesktop.ConsoleKit" #define CK_MANAGER_PATH CK_PATH "/Manager" #define CK_MANAGER_INTERFACE CK_INTERFACE ".Manager" #define CK_SESSION_PATH CK_PATH "/Session" #define CK_SESSION_INTERFACE CK_INTERFACE ".Session" /* DBus */ #define DBUS_SERVICE "org.freedesktop.DBus" #define DBUS_PATH "/org/freedesktop/DBus" #define DBUS_INTERFACE "org.freedesktop.DBus" /* Cinnamon Screensaver */ #define GS_SERVICE "org.cinnamon.ScreenSaver" #define GS_PATH "/org/cinnamon/ScreenSaver" #define GS_INTERFACE "org.cinnamon.ScreenSaver" /* Gnome Session Manager */ #define GSM_SERVICE "org.gnome.SessionManager" #define GSM_PATH "/org/gnome/SessionManager" #define GSM_INTERFACE "org.gnome.SessionManager" #define GSM_PRESENCE_PATH GSM_PATH "/Presence" #define GSM_PRESENCE_INTERFACE GSM_INTERFACE ".Presence" #endif cinnamon-screensaver-2.8.0/src/gs-auth-pam.c0000664000175000017500000005610712610211212017640 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2006 William Jon McCann * Copyright (C) 2006 Ray Strode * Copyright (C) 2003 Bill Nottingham * Copyright (c) 1993-2003 Jamie Zawinski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * */ #include "config.h" #include #ifdef HAVE_UNISTD_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gs-auth.h" #include "subprocs.h" /* Some time between Red Hat 4.2 and 7.0, the words were transposed in the various PAM_x_CRED macro names. Yay! */ #ifndef PAM_REFRESH_CRED # define PAM_REFRESH_CRED PAM_CRED_REFRESH #endif #ifdef HAVE_PAM_FAIL_DELAY /* We handle delays ourself.*/ /* Don't set this to 0 (Linux bug workaround.) */ # define PAM_NO_DELAY(pamh) pam_fail_delay ((pamh), 1) #else /* !HAVE_PAM_FAIL_DELAY */ # define PAM_NO_DELAY(pamh) /* */ #endif /* !HAVE_PAM_FAIL_DELAY */ /* On SunOS 5.6, and on Linux with PAM 0.64, pam_strerror() takes two args. On some other Linux systems with some other version of PAM (e.g., whichever Debian release comes with a 2.2.5 kernel) it takes one arg. I can't tell which is more "recent" or "correct" behavior, so configure figures out which is in use for us. Shoot me! */ #ifdef PAM_STRERROR_TWO_ARGS # define PAM_STRERROR(pamh, status) pam_strerror((pamh), (status)) #else /* !PAM_STRERROR_TWO_ARGS */ # define PAM_STRERROR(pamh, status) pam_strerror((status)) #endif /* !PAM_STRERROR_TWO_ARGS */ static gboolean verbose_enabled = FALSE; static pam_handle_t *pam_handle = NULL; static gboolean did_we_ask_for_password = FALSE; struct pam_closure { const char *username; GSAuthMessageFunc cb_func; gpointer cb_data; int signal_fd; int result; }; typedef struct { struct pam_closure *closure; GSAuthMessageStyle style; const char *msg; char **resp; gboolean should_interrupt_stack; } GsAuthMessageHandlerData; static GCond *message_handled_condition; static GMutex *message_handler_mutex; GQuark gs_auth_error_quark (void) { static GQuark quark = 0; if (! quark) { quark = g_quark_from_static_string ("gs_auth_error"); } return quark; } void gs_auth_set_verbose (gboolean enabled) { verbose_enabled = enabled; } gboolean gs_auth_get_verbose (void) { return verbose_enabled; } static GSAuthMessageStyle pam_style_to_gs_style (int pam_style) { GSAuthMessageStyle style; switch (pam_style) { case PAM_PROMPT_ECHO_ON: style = GS_AUTH_MESSAGE_PROMPT_ECHO_ON; break; case PAM_PROMPT_ECHO_OFF: style = GS_AUTH_MESSAGE_PROMPT_ECHO_OFF; break; case PAM_ERROR_MSG: style = GS_AUTH_MESSAGE_ERROR_MSG; break; case PAM_TEXT_INFO: style = GS_AUTH_MESSAGE_TEXT_INFO; break; default: g_assert_not_reached (); break; } return style; } static gboolean auth_message_handler (GSAuthMessageStyle style, const char *msg, char **response, gpointer data) { gboolean ret; ret = TRUE; *response = NULL; switch (style) { case GS_AUTH_MESSAGE_PROMPT_ECHO_ON: break; case GS_AUTH_MESSAGE_PROMPT_ECHO_OFF: if (msg != NULL && g_str_has_prefix (msg, _("Password:"))) { did_we_ask_for_password = TRUE; } break; case GS_AUTH_MESSAGE_ERROR_MSG: break; case GS_AUTH_MESSAGE_TEXT_INFO: break; default: g_assert_not_reached (); } return ret; } static gboolean gs_auth_queued_message_handler (GsAuthMessageHandlerData *data) { gboolean res; if (gs_auth_get_verbose ()) { g_message ("Waiting for lock"); } g_mutex_lock (message_handler_mutex); if (gs_auth_get_verbose ()) { g_message ("Waiting for response"); } res = data->closure->cb_func (data->style, data->msg, data->resp, data->closure->cb_data); data->should_interrupt_stack = res == FALSE; g_cond_signal (message_handled_condition); g_mutex_unlock (message_handler_mutex); if (gs_auth_get_verbose ()) { g_message ("Got response"); } return FALSE; } static gboolean gs_auth_run_message_handler (struct pam_closure *c, GSAuthMessageStyle style, const char *msg, char **resp) { GsAuthMessageHandlerData data; data.closure = c; data.style = style; data.msg = msg; data.resp = resp; data.should_interrupt_stack = TRUE; g_mutex_lock (message_handler_mutex); /* Queue the callback in the gui (the main) thread */ g_idle_add ((GSourceFunc) gs_auth_queued_message_handler, &data); if (gs_auth_get_verbose ()) { g_message ("Waiting for respose to message style %d: '%s'", style, msg); } /* Wait for the response */ g_cond_wait (message_handled_condition, message_handler_mutex); g_mutex_unlock (message_handler_mutex); if (gs_auth_get_verbose ()) { g_message ("Got respose to message style %d: interrupt:%d", style, data.should_interrupt_stack); } return data.should_interrupt_stack == FALSE; } static int pam_conversation (int nmsgs, const struct pam_message **msg, struct pam_response **resp, void *closure) { int replies = 0; struct pam_response *reply = NULL; struct pam_closure *c = (struct pam_closure *) closure; gboolean res; int ret; reply = (struct pam_response *) calloc (nmsgs, sizeof (*reply)); if (reply == NULL) { return PAM_CONV_ERR; } res = TRUE; ret = PAM_SUCCESS; for (replies = 0; replies < nmsgs && ret == PAM_SUCCESS; replies++) { GSAuthMessageStyle style; char *utf8_msg; style = pam_style_to_gs_style (msg [replies]->msg_style); utf8_msg = g_locale_to_utf8 (msg [replies]->msg, -1, NULL, NULL, NULL); /* if we couldn't convert text from locale then * assume utf-8 and hope for the best */ if (utf8_msg == NULL) { char *p; char *q; utf8_msg = g_strdup (msg [replies]->msg); p = utf8_msg; while (*p != '\0' && !g_utf8_validate ((const char *)p, -1, (const char **)&q)) { *q = '?'; p = q + 1; } } /* handle message locally first */ auth_message_handler (style, utf8_msg, &reply [replies].resp, NULL); if (c->cb_func != NULL) { if (gs_auth_get_verbose ()) { g_message ("Handling message style %d: '%s'", style, utf8_msg); } /* blocks until the gui responds */ res = gs_auth_run_message_handler (c, style, utf8_msg, &reply [replies].resp); if (gs_auth_get_verbose ()) { g_message ("Msg handler returned %d", res); } /* If the handler returns FALSE - interrupt the PAM stack */ if (res) { reply [replies].resp_retcode = PAM_SUCCESS; } else { int i; for (i = 0; i <= replies; i++) { free (reply [i].resp); } free (reply); reply = NULL; ret = PAM_CONV_ERR; } } g_free (utf8_msg); } *resp = reply; return ret; } static gboolean close_pam_handle (int status) { if (pam_handle != NULL) { int status2; status2 = pam_end (pam_handle, status); pam_handle = NULL; if (gs_auth_get_verbose ()) { g_message (" pam_end (...) ==> %d (%s)", status2, (status2 == PAM_SUCCESS ? "Success" : "Failure")); } } if (message_handled_condition != NULL) { g_cond_free (message_handled_condition); message_handled_condition = NULL; } if (message_handler_mutex != NULL) { g_mutex_free (message_handler_mutex); message_handler_mutex = NULL; } return TRUE; } static gboolean create_pam_handle (const char *username, const char *display, struct pam_conv *conv, int *status_code) { int status; const char *service = PAM_SERVICE_NAME; char *disp; gboolean ret; if (pam_handle != NULL) { g_warning ("create_pam_handle: Stale pam handle around, cleaning up"); close_pam_handle (PAM_SUCCESS); } /* init things */ pam_handle = NULL; status = -1; disp = NULL; ret = TRUE; /* Initialize a PAM session for the user */ if ((status = pam_start (service, username, conv, &pam_handle)) != PAM_SUCCESS) { pam_handle = NULL; g_warning (_("Unable to establish service %s: %s\n"), service, PAM_STRERROR (NULL, status)); if (status_code != NULL) { *status_code = status; } ret = FALSE; goto out; } if (gs_auth_get_verbose ()) { g_message ("pam_start (\"%s\", \"%s\", ...) ==> %d (%s)", service, username, status, PAM_STRERROR (pam_handle, status)); } disp = g_strdup (display); if (disp == NULL) { disp = g_strdup (":0.0"); } if ((status = pam_set_item (pam_handle, PAM_TTY, disp)) != PAM_SUCCESS) { g_warning (_("Can't set PAM_TTY=%s"), display); if (status_code != NULL) { *status_code = status; } ret = FALSE; goto out; } ret = TRUE; message_handled_condition = g_cond_new (); message_handler_mutex = g_mutex_new (); out: if (status_code != NULL) { *status_code = status; } g_free (disp); return ret; } static void set_pam_error (GError **error, int status) { if (status == PAM_AUTH_ERR || status == PAM_USER_UNKNOWN) { char *msg; if (did_we_ask_for_password) { msg = g_strdup (_("Incorrect password.")); } else { msg = g_strdup (_("Authentication failed.")); } g_set_error (error, GS_AUTH_ERROR, GS_AUTH_ERROR_AUTH_ERROR, "%s", msg); g_free (msg); } else if (status == PAM_PERM_DENIED) { g_set_error (error, GS_AUTH_ERROR, GS_AUTH_ERROR_AUTH_DENIED, "%s", _("Not permitted to gain access at this time.")); } else if (status == PAM_ACCT_EXPIRED) { g_set_error (error, GS_AUTH_ERROR, GS_AUTH_ERROR_AUTH_DENIED, "%s", _("No longer permitted to access the system.")); } } static int gs_auth_thread_func (int auth_operation_fd) { static const int flags = 0; int status; int status2; struct timespec timeout; sigset_t set; const void *p; timeout.tv_sec = 0; timeout.tv_nsec = 1; set = block_sigchld (); status = pam_authenticate (pam_handle, flags); sigtimedwait (&set, NULL, &timeout); unblock_sigchld (); if (gs_auth_get_verbose ()) { g_message (" pam_authenticate (...) ==> %d (%s)", status, PAM_STRERROR (pam_handle, status)); } if (status != PAM_SUCCESS) { goto done; } if ((status = pam_get_item (pam_handle, PAM_USER, &p)) != PAM_SUCCESS) { /* is not really an auth problem, but it will pretty much look as such, it shouldn't really happen */ goto done; } /* We don't actually care if the account modules fail or succeed, * but we need to run them anyway because certain pam modules * depend on side effects of the account modules getting run. */ status2 = pam_acct_mgmt (pam_handle, 0); if (gs_auth_get_verbose ()) { g_message ("pam_acct_mgmt (...) ==> %d (%s)\n", status2, PAM_STRERROR (pam_handle, status2)); } /* FIXME: should we handle these? */ switch (status2) { case PAM_SUCCESS: break; case PAM_NEW_AUTHTOK_REQD: break; case PAM_AUTHINFO_UNAVAIL: break; case PAM_ACCT_EXPIRED: break; case PAM_PERM_DENIED: break; default : break; } /* Each time we successfully authenticate, refresh credentials, for Kerberos/AFS/DCE/etc. If this fails, just ignore that failure and blunder along; it shouldn't matter. Note: this used to be PAM_REFRESH_CRED instead of PAM_REINITIALIZE_CRED, but Jason Heiss says that the Linux PAM library ignores that one, and only refreshes credentials when using PAM_REINITIALIZE_CRED. */ status2 = pam_setcred (pam_handle, PAM_REINITIALIZE_CRED); if (gs_auth_get_verbose ()) { g_message (" pam_setcred (...) ==> %d (%s)", status2, PAM_STRERROR (pam_handle, status2)); } done: /* we're done, close the fd and wake up the main * loop */ close (auth_operation_fd); return status; } static gboolean gs_auth_loop_quit (GIOChannel *source, GIOCondition condition, gboolean *thread_done) { *thread_done = TRUE; gtk_main_quit (); return FALSE; } static gboolean gs_auth_pam_verify_user (pam_handle_t *handle, int *status) { GThread *auth_thread; GIOChannel *channel; guint watch_id; int auth_operation_fds[2]; int auth_status; gboolean thread_done; channel = NULL; watch_id = 0; auth_status = PAM_AUTH_ERR; /* This pipe gives us a set of fds we can hook into * the event loop to be notified when our helper thread * is ready to be reaped. */ if (pipe (auth_operation_fds) < 0) { goto out; } if (fcntl (auth_operation_fds[0], F_SETFD, FD_CLOEXEC) < 0) { close (auth_operation_fds[0]); close (auth_operation_fds[1]); goto out; } if (fcntl (auth_operation_fds[1], F_SETFD, FD_CLOEXEC) < 0) { close (auth_operation_fds[0]); close (auth_operation_fds[1]); goto out; } channel = g_io_channel_unix_new (auth_operation_fds[0]); /* we use a recursive main loop to process ui events * while we wait on a thread to handle the blocking parts * of pam authentication. */ thread_done = FALSE; watch_id = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP, (GIOFunc) gs_auth_loop_quit, &thread_done); auth_thread = g_thread_create ((GThreadFunc) gs_auth_thread_func, GINT_TO_POINTER (auth_operation_fds[1]), TRUE, NULL); if (auth_thread == NULL) { goto out; } gtk_main (); /* if the event loop was quit before the thread is done then we can't * reap the thread without blocking on it finishing. The * thread may not ever finish though if the pam module is blocking. * * The only time the event loop is going to stop when the thread isn't * done, however, is if the dialog quits early (from, e.g., "cancel"), * so we can just exit. An alternative option would be to switch to * using pthreads directly and calling pthread_cancel. */ if (!thread_done) { raise (SIGTERM); } auth_status = GPOINTER_TO_INT (g_thread_join (auth_thread)); out: if (watch_id != 0) { g_source_remove (watch_id); watch_id = 0; } if (channel != NULL) { g_io_channel_unref (channel); } if (status) { *status = auth_status; } return auth_status == PAM_SUCCESS; } gboolean gs_auth_verify_user (const char *username, const char *display, GSAuthMessageFunc func, gpointer data, GError **error) { int status = -1; struct pam_conv conv; struct pam_closure c; struct passwd *pwent; pwent = getpwnam (username); if (pwent == NULL) { return FALSE; } c.username = username; c.cb_func = func; c.cb_data = data; conv.conv = &pam_conversation; conv.appdata_ptr = (void *) &c; /* Initialize PAM. */ create_pam_handle (username, display, &conv, &status); if (status != PAM_SUCCESS) { goto done; } pam_set_item (pam_handle, PAM_USER_PROMPT, _("Username:")); PAM_NO_DELAY(pam_handle); did_we_ask_for_password = FALSE; if (! gs_auth_pam_verify_user (pam_handle, &status)) { goto done; } done: if (status != PAM_SUCCESS) { set_pam_error (error, status); } close_pam_handle (status); return (status == PAM_SUCCESS ? TRUE : FALSE); } gboolean gs_auth_init (void) { return TRUE; } gboolean gs_auth_priv_init (void) { /* We have nothing to do at init-time. However, we might as well do some error checking. If "/etc/pam.d" exists and is a directory, but "/etc/pam.d/xlock" does not exist, warn that PAM probably isn't going to work. This is a priv-init instead of a non-priv init in case the directory is unreadable or something (don't know if that actually happens.) */ const char dir [] = "/etc/pam.d"; const char file [] = "/etc/pam.d/" PAM_SERVICE_NAME; const char file2 [] = "/etc/pam.conf"; struct stat st; if (g_stat (dir, &st) == 0 && st.st_mode & S_IFDIR) { if (g_stat (file, &st) != 0) { g_warning ("%s does not exist.\n" "Authentication via PAM is unlikely to work.", file); } } else if (g_stat (file2, &st) == 0) { FILE *f = g_fopen (file2, "r"); if (f) { gboolean ok = FALSE; char buf[255]; while (fgets (buf, sizeof(buf), f)) { if (strstr (buf, PAM_SERVICE_NAME)) { ok = TRUE; break; } } fclose (f); if (!ok) { g_warning ("%s does not list the `%s' service.\n" "Authentication via PAM is unlikely to work.", file2, PAM_SERVICE_NAME); } } /* else warn about file2 existing but being unreadable? */ } else { g_warning ("Neither %s nor %s exist.\n" "Authentication via PAM is unlikely to work.", file2, file); } /* Return true anyway, just in case. */ return TRUE; } cinnamon-screensaver-2.8.0/src/gs-monitor.h0000664000175000017500000000406012610211212017607 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_MONITOR_H #define __GS_MONITOR_H G_BEGIN_DECLS #define GS_TYPE_MONITOR (gs_monitor_get_type ()) #define GS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_MONITOR, GSMonitor)) #define GS_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_MONITOR, GSMonitorClass)) #define GS_IS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_MONITOR)) #define GS_IS_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_MONITOR)) #define GS_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_MONITOR, GSMonitorClass)) typedef struct GSMonitorPrivate GSMonitorPrivate; typedef struct { GObject parent; GSMonitorPrivate *priv; } GSMonitor; typedef struct { GObjectClass parent_class; } GSMonitorClass; GType gs_monitor_get_type (void); GSMonitor * gs_monitor_new (void); gboolean gs_monitor_start (GSMonitor *monitor, GError **error); void gs_monitor_set_lock_enabled (GSMonitor *monitor, gboolean lock_enabled); G_END_DECLS #endif /* __GS_MONITOR_H */ cinnamon-screensaver-2.8.0/src/gs-watcher-x11.c0000664000175000017500000004030612610211212020162 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * Copyright (C) 2008 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include "gs-watcher.h" #include "gs-marshal.h" #include "gs-debug.h" #include "bus.h" static void gs_watcher_class_init (GSWatcherClass *klass); static void gs_watcher_init (GSWatcher *watcher); static void gs_watcher_finalize (GObject *object); static gboolean watchdog_timer (GSWatcher *watcher); #define GS_WATCHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_WATCHER, GSWatcherPrivate)) struct GSWatcherPrivate { /* settings */ guint enabled : 1; guint delta_notice_timeout; /* state */ guint active : 1; guint idle : 1; guint idle_notice : 1; guint idle_id; DBusGProxy *presence_proxy; guint watchdog_timer_id; }; enum { PROP_0 }; enum { IDLE_CHANGED, IDLE_NOTICE_CHANGED, LAST_SIGNAL }; static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSWatcher, gs_watcher, G_TYPE_OBJECT) static void remove_watchdog_timer (GSWatcher *watcher) { if (watcher->priv->watchdog_timer_id != 0) { g_source_remove (watcher->priv->watchdog_timer_id); watcher->priv->watchdog_timer_id = 0; } } static void add_watchdog_timer (GSWatcher *watcher, glong timeout) { watcher->priv->watchdog_timer_id = g_timeout_add_seconds (timeout, (GSourceFunc)watchdog_timer, watcher); } static void gs_watcher_class_init (GSWatcherClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_watcher_finalize; signals [IDLE_CHANGED] = g_signal_new ("idle-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSWatcherClass, idle_changed), NULL, NULL, gs_marshal_BOOLEAN__BOOLEAN, G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN); signals [IDLE_NOTICE_CHANGED] = g_signal_new ("idle-notice-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSWatcherClass, idle_notice_changed), NULL, NULL, gs_marshal_BOOLEAN__BOOLEAN, G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN); g_type_class_add_private (klass, sizeof (GSWatcherPrivate)); } static gboolean _gs_watcher_set_session_idle_notice (GSWatcher *watcher, gboolean in_effect) { gboolean res; res = FALSE; if (in_effect != watcher->priv->idle_notice) { g_signal_emit (watcher, signals [IDLE_NOTICE_CHANGED], 0, in_effect, &res); if (res) { gs_debug ("Changing idle notice state: %d", in_effect); watcher->priv->idle_notice = in_effect; } else { gs_debug ("Idle notice signal not handled: %d", in_effect); } } return res; } static gboolean _gs_watcher_set_session_idle (GSWatcher *watcher, gboolean is_idle) { gboolean res; res = FALSE; if (is_idle != watcher->priv->idle) { g_signal_emit (watcher, signals [IDLE_CHANGED], 0, is_idle, &res); if (res) { gs_debug ("Changing idle state: %d", is_idle); watcher->priv->idle = is_idle; } else { gs_debug ("Idle changed signal not handled: %d", is_idle); } } return res; } gboolean gs_watcher_get_active (GSWatcher *watcher) { gboolean active; g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE); active = watcher->priv->active; return active; } static void _gs_watcher_reset_state (GSWatcher *watcher) { watcher->priv->idle = FALSE; watcher->priv->idle_notice = FALSE; } static gboolean _gs_watcher_set_active_internal (GSWatcher *watcher, gboolean active) { if (active != watcher->priv->active) { /* reset state */ _gs_watcher_reset_state (watcher); watcher->priv->active = active; } return TRUE; } gboolean gs_watcher_set_active (GSWatcher *watcher, gboolean active) { g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE); gs_debug ("turning watcher: %s", active ? "ON" : "OFF"); if (watcher->priv->active == active) { gs_debug ("Idle detection is already %s", active ? "active" : "inactive"); return FALSE; } if (! watcher->priv->enabled) { gs_debug ("Idle detection is disabled, cannot activate"); return FALSE; } return _gs_watcher_set_active_internal (watcher, active); } gboolean gs_watcher_set_enabled (GSWatcher *watcher, gboolean enabled) { g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE); if (watcher->priv->enabled != enabled) { gboolean is_active = gs_watcher_get_active (watcher); watcher->priv->enabled = enabled; /* if we are disabling the watcher and we are active shut it down */ if (! enabled && is_active) { _gs_watcher_set_active_internal (watcher, FALSE); } } return TRUE; } gboolean gs_watcher_get_enabled (GSWatcher *watcher) { gboolean enabled; g_return_val_if_fail (GS_IS_WATCHER (watcher), FALSE); enabled = watcher->priv->enabled; return enabled; } static gboolean on_idle_timeout (GSWatcher *watcher) { gboolean res; res = _gs_watcher_set_session_idle (watcher, TRUE); _gs_watcher_set_session_idle_notice (watcher, FALSE); /* try again if we failed i guess */ return !res; } static void set_status (GSWatcher *watcher, guint status) { gboolean is_idle; if (! watcher->priv->active) { gs_debug ("GSWatcher: not active, ignoring status changes"); return; } is_idle = (status == 3); if (!is_idle && !watcher->priv->idle_notice) { /* no change in idleness */ return; } if (is_idle) { _gs_watcher_set_session_idle_notice (watcher, is_idle); /* queue an activation */ if (watcher->priv->idle_id > 0) { g_source_remove (watcher->priv->idle_id); watcher->priv->idle_id = 0; } watcher->priv->idle_id = g_timeout_add_seconds (watcher->priv->delta_notice_timeout, (GSourceFunc)on_idle_timeout, watcher); } else { /* cancel notice too */ if (watcher->priv->idle_id > 0) { g_source_remove (watcher->priv->idle_id); watcher->priv->idle_id = 0; } _gs_watcher_set_session_idle (watcher, FALSE); _gs_watcher_set_session_idle_notice (watcher, FALSE); } } static void on_presence_status_changed (DBusGProxy *presence_proxy, guint status, GSWatcher *watcher) { set_status (watcher, status); } static void connect_presence_watcher (GSWatcher *watcher) { DBusGConnection *bus; GError *error; DBusGProxy *proxy; guint status; GValue value = { 0, }; error = NULL; bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (bus == NULL) { g_warning ("Unable to get session bus: %s", error->message); g_error_free (error); return; } watcher->priv->presence_proxy = dbus_g_proxy_new_for_name (bus, GSM_SERVICE, GSM_PRESENCE_PATH, GSM_PRESENCE_INTERFACE); dbus_g_proxy_add_signal (watcher->priv->presence_proxy, "StatusChanged", G_TYPE_UINT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (watcher->priv->presence_proxy, "StatusChanged", G_CALLBACK (on_presence_status_changed), watcher, NULL); proxy = dbus_g_proxy_new_from_proxy (watcher->priv->presence_proxy, "org.freedesktop.DBus.Properties", GSM_PRESENCE_PATH); status = 0; error = NULL; dbus_g_proxy_call (proxy, "Get", &error, G_TYPE_STRING, GSM_PRESENCE_INTERFACE, G_TYPE_STRING, "status", G_TYPE_INVALID, G_TYPE_VALUE, &value, G_TYPE_INVALID); if (error != NULL) { g_warning ("Couldn't get presence status: %s", error->message); g_error_free (error); return; } else { status = g_value_get_uint (&value); } g_value_unset (&value); error = NULL; set_status (watcher, status); } static void gs_watcher_init (GSWatcher *watcher) { watcher->priv = GS_WATCHER_GET_PRIVATE (watcher); watcher->priv->enabled = TRUE; watcher->priv->active = FALSE; connect_presence_watcher (watcher); /* time before idle signal to send notice signal */ watcher->priv->delta_notice_timeout = 10; add_watchdog_timer (watcher, 600); } static void gs_watcher_finalize (GObject *object) { GSWatcher *watcher; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_WATCHER (object)); watcher = GS_WATCHER (object); g_return_if_fail (watcher->priv != NULL); remove_watchdog_timer (watcher); if (watcher->priv->idle_id > 0) { g_source_remove (watcher->priv->idle_id); watcher->priv->idle_id = 0; } watcher->priv->active = FALSE; if (watcher->priv->presence_proxy != NULL) { g_object_unref (watcher->priv->presence_proxy); } G_OBJECT_CLASS (gs_watcher_parent_class)->finalize (object); } /* Figuring out what the appropriate XSetScreenSaver() parameters are (one wouldn't expect this to be rocket science.) */ static void disable_builtin_screensaver (GSWatcher *watcher, gboolean unblank_screen) { int current_server_timeout, current_server_interval; int current_prefer_blank, current_allow_exp; int desired_server_timeout, desired_server_interval; int desired_prefer_blank, desired_allow_exp; XGetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), ¤t_server_timeout, ¤t_server_interval, ¤t_prefer_blank, ¤t_allow_exp); desired_server_timeout = current_server_timeout; desired_server_interval = current_server_interval; desired_prefer_blank = current_prefer_blank; desired_allow_exp = current_allow_exp; desired_server_interval = 0; /* I suspect (but am not sure) that DontAllowExposures might have something to do with powering off the monitor as well, at least on some systems that don't support XDPMS? Who know... */ desired_allow_exp = AllowExposures; /* When we're not using an extension, set the server-side timeout to 0, so that the server never gets involved with screen blanking, and we do it all ourselves. (However, when we *are* using an extension, we tell the server when to notify us, and rather than blanking the screen, the server will send us an X event telling us to blank.) */ desired_server_timeout = 0; if (desired_server_timeout != current_server_timeout || desired_server_interval != current_server_interval || desired_prefer_blank != current_prefer_blank || desired_allow_exp != current_allow_exp) { gs_debug ("disabling server builtin screensaver:" " (xset s %d %d; xset s %s; xset s %s)", desired_server_timeout, desired_server_interval, (desired_prefer_blank ? "blank" : "noblank"), (desired_allow_exp ? "expose" : "noexpose")); XSetScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), desired_server_timeout, desired_server_interval, desired_prefer_blank, desired_allow_exp); XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), FALSE); } if (unblank_screen) { /* Turn off the server builtin saver if it is now running. */ XForceScreenSaver (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), ScreenSaverReset); } } /* This timer goes off every few minutes, whether the user is idle or not, to try and clean up anything that has gone wrong. It calls disable_builtin_screensaver() so that if xset has been used, or some other program (like xlock) has messed with the XSetScreenSaver() settings, they will be set back to sensible values (if a server extension is in use, messing with xlock can cause the screensaver to never get a wakeup event, and could cause monitor power-saving to occur, and all manner of heinousness.) */ static gboolean watchdog_timer (GSWatcher *watcher) { disable_builtin_screensaver (watcher, FALSE); return TRUE; } GSWatcher * gs_watcher_new (void) { GSWatcher *watcher; watcher = g_object_new (GS_TYPE_WATCHER, NULL); return GS_WATCHER (watcher); } cinnamon-screensaver-2.8.0/src/test-fade.c0000664000175000017500000000655312610211212017371 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2005 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "gs-fade.h" #include "gs-debug.h" #ifdef HAVE_XF86VMODE_GAMMA # include #endif #define XF86_VIDMODE_NAME "XFree86-VidModeExtension" static void test_fade (void) { GSFade *fade; int reps = 2; int delay = 2; fade = gs_fade_new (); while (reps-- > 0) { g_print ("fading out..."); gs_fade_sync (fade, 1000); g_print ("done.\n"); g_print ("fading in..."); gs_fade_reset (fade); g_print ("done.\n"); if (delay) { sleep (delay); } } g_object_unref (fade); } int main (int argc, char **argv) { GError *error = NULL; int op, event, err; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif if (error) { fprintf (stderr, "%s\n", error->message); exit (1); } if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { fprintf (stderr, "%s", error->message); g_error_free (error); exit (1); } if (! XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XF86_VIDMODE_NAME, &op, &event, &err)) { g_message ("no " XF86_VIDMODE_NAME " extension"); } else { # ifdef HAVE_XF86VMODE_GAMMA int major; int minor; if (! XF86VidModeQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor)) { g_message ("unable to get " XF86_VIDMODE_NAME " version"); } else { g_message (XF86_VIDMODE_NAME " version %d.%d", major, minor); } # else /* !HAVE_XF86VMODE_GAMMA */ g_message ("no support for display's " XF86_VIDMODE_NAME " extension"); # endif /* !HAVE_XF86VMODE_GAMMA */ } gs_debug_init (TRUE, FALSE); test_fade (); gs_debug_shutdown (); return 0; } cinnamon-screensaver-2.8.0/src/debug-screensaver.sh0000775000175000017500000000267012610211212021310 0ustar fabiofabio#!/bin/sh # This is probably linux only at the moment if [ -z "${DBUS_SESSION_BUS_ADDRESS}" ]; then pid=`pgrep -u $USER "gnome-session|x-session-manager"` if [ "x$pid" != "x" ]; then env_address=`(cat /proc/$pid/environ; echo) | tr "\000" "\n" | grep '^DBUS_SESSION_BUS_ADDRESS='` env_display=`(cat /proc/$pid/environ; echo) | tr "\000" "\n" | grep '^DISPLAY='` env_xdg_cookie=`(cat /proc/$pid/environ; echo) | tr "\000" "\n" | grep '^XDG_SESSION_COOKIE='` env_path=`(cat /proc/$pid/environ; echo) | tr "\000" "\n" | grep '^PATH='` if [ "x$env_address" != "x" ]; then echo "Setting $env_address" echo "Setting $env_display" echo "Setting $env_path" echo "Setting $env_xdg_cookie" eval "export $env_address" eval "export $env_display" eval "export $env_path" eval "export $env_xdg_cookie" fi fi fi if [ -z "${DBUS_SESSION_BUS_ADDRESS}" ]; then echo "Could not determine DBUS_SESSION_BUS_ADDRESS" exit 1 fi export G_DEBUG=fatal_criticals # kill the existing daemon cinnamon-screensaver-command --exit # run the daemon in the debugger #gdb --args cinnamon-screensaver --no-daemon --debug --sync # or if that isn't helpful just get the debug output #cinnamon-screensaver --no-daemon --debug > /tmp/gs-debug-log.txt 2>&1 # or just run it with debugging on cinnamon-screensaver --no-daemon --debug cinnamon-screensaver-2.8.0/src/gs-listener-dbus.c0000664000175000017500000015353712610211212020711 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_LOGIND #include #endif #include "gs-listener-dbus.h" #include "gs-marshal.h" #include "gs-debug.h" #include "bus.h" /* this is for dbus < 0.3 */ #if ((DBUS_VERSION_MAJOR == 0) && (DBUS_VERSION_MINOR < 30)) #define dbus_bus_name_has_owner(connection, name, err) dbus_bus_service_exists(connection, name, err) #define dbus_bus_request_name(connection, name, flags, err) dbus_bus_acquire_service(connection, name, flags, err) #endif static void gs_listener_class_init (GSListenerClass *klass); static void gs_listener_init (GSListener *listener); static void gs_listener_finalize (GObject *object); static void gs_listener_unregister_handler (DBusConnection *connection, void *data); static DBusHandlerResult gs_listener_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data); #define TYPE_MISMATCH_ERROR GS_INTERFACE ".TypeMismatch" #define GS_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_LISTENER, GSListenerPrivate)) struct GSListenerPrivate { DBusConnection *connection; DBusConnection *system_connection; guint session_idle : 1; guint active : 1; guint activation_enabled : 1; time_t active_start; time_t session_idle_start; char *session_id; gboolean use_logind; }; enum { LOCK, QUIT, SIMULATE_USER_ACTIVITY, ACTIVE_CHANGED, SHOW_MESSAGE, LAST_SIGNAL }; enum { PROP_0, PROP_ACTIVE, PROP_SESSION_IDLE, PROP_ACTIVATION_ENABLED, }; static DBusObjectPathVTable gs_listener_vtable = { &gs_listener_unregister_handler, &gs_listener_message_handler, NULL, NULL, NULL, NULL }; static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSListener, gs_listener, G_TYPE_OBJECT) GQuark gs_listener_error_quark (void) { static GQuark quark = 0; if (!quark) { quark = g_quark_from_static_string ("gs_listener_error"); } return quark; } static void gs_listener_unregister_handler (DBusConnection *connection, void *data) { } static gboolean send_dbus_message (DBusConnection *connection, DBusMessage *message) { gboolean is_connected; gboolean sent; g_return_val_if_fail (message != NULL, FALSE); if (! connection) { gs_debug ("There is no valid connection to the message bus"); return FALSE; } is_connected = dbus_connection_get_is_connected (connection); if (! is_connected) { gs_debug ("Not connected to the message bus"); return FALSE; } sent = dbus_connection_send (connection, message, NULL); return sent; } static void send_dbus_boolean_signal (GSListener *listener, const char *name, gboolean value) { DBusMessage *message; DBusMessageIter iter; g_return_if_fail (listener != NULL); message = dbus_message_new_signal (GS_PATH, GS_SERVICE, name); dbus_message_iter_init_append (message, &iter); dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &value); if (! send_dbus_message (listener->priv->connection, message)) { gs_debug ("Could not send %s signal", name); } dbus_message_unref (message); } static void gs_listener_send_signal_active_changed (GSListener *listener) { g_return_if_fail (listener != NULL); gs_debug ("Sending the ActiveChanged(%s) signal on the session bus", listener->priv->active ? "TRUE" : "FALSE"); send_dbus_boolean_signal (listener, "ActiveChanged", listener->priv->active); } static gboolean listener_check_activation (GSListener *listener) { gboolean res; gs_debug ("Checking for activation"); if (! listener->priv->activation_enabled) { return TRUE; } if (! listener->priv->session_idle) { return TRUE; } gs_debug ("Trying to activate"); res = gs_listener_set_active (listener, TRUE); return res; } static gboolean listener_set_session_idle_internal (GSListener *listener, gboolean idle) { listener->priv->session_idle = idle; if (idle) { listener->priv->session_idle_start = time (NULL); } else { listener->priv->session_idle_start = 0; } return TRUE; } static gboolean listener_set_active_internal (GSListener *listener, gboolean active) { listener->priv->active = active; /* if idle not in sync with active, change it */ if (listener->priv->session_idle != active) { listener_set_session_idle_internal (listener, active); } if (active) { listener->priv->active_start = time (NULL); } else { listener->priv->active_start = 0; } gs_listener_send_signal_active_changed (listener); return TRUE; } gboolean gs_listener_set_active (GSListener *listener, gboolean active) { gboolean res; g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE); if (listener->priv->active == active) { gs_debug ("Trying to set active state when already: %s", active ? "active" : "inactive"); return FALSE; } res = FALSE; g_signal_emit (listener, signals [ACTIVE_CHANGED], 0, active, &res); if (! res) { /* if the signal is not handled then we haven't changed state */ gs_debug ("Active-changed signal not handled"); /* clear the idle state */ if (active) { listener_set_session_idle_internal (listener, FALSE); } return FALSE; } listener_set_active_internal (listener, active); return TRUE; } gboolean gs_listener_set_session_idle (GSListener *listener, gboolean idle) { gboolean res; g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE); gs_debug ("Setting session idle: %d", idle); if (listener->priv->session_idle == idle) { gs_debug ("Trying to set idle state when already %s", idle ? "idle" : "not idle"); return FALSE; } listener->priv->session_idle = idle; res = listener_check_activation (listener); /* if activation fails then don't set idle */ if (res) { listener_set_session_idle_internal (listener, idle); } else { gs_debug ("Idle activation failed"); listener->priv->session_idle = !idle; } return res; } gboolean gs_listener_get_activation_enabled (GSListener *listener) { g_return_val_if_fail (GS_IS_LISTENER (listener), FALSE); return listener->priv->activation_enabled; } void gs_listener_set_activation_enabled (GSListener *listener, gboolean enabled) { g_return_if_fail (GS_IS_LISTENER (listener)); if (listener->priv->activation_enabled != enabled) { listener->priv->activation_enabled = enabled; } } static dbus_bool_t listener_property_set_bool (GSListener *listener, guint prop_id, dbus_bool_t value) { dbus_bool_t ret; ret = FALSE; switch (prop_id) { case PROP_ACTIVE: gs_listener_set_active (listener, value); ret = TRUE; break; default: break; } return ret; } static void raise_error (DBusConnection *connection, DBusMessage *in_reply_to, const char *error_name, char *format, ...) { char buf[512]; DBusMessage *reply; va_list args; va_start (args, format); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-nonliteral" vsnprintf (buf, sizeof (buf), format, args); #pragma clang diagnostic pop va_end (args); gs_debug (buf); reply = dbus_message_new_error (in_reply_to, error_name, buf); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); } static void raise_syntax (DBusConnection *connection, DBusMessage *in_reply_to, const char *method_name) { raise_error (connection, in_reply_to, GS_SERVICE ".SyntaxError", "There is a syntax error in the invocation of the method %s", method_name); } static void raise_property_type_error (DBusConnection *connection, DBusMessage *in_reply_to, const char *device_id) { char buf [512]; DBusMessage *reply; snprintf (buf, 511, "Type mismatch setting property with id %s", device_id); gs_debug (buf); reply = dbus_message_new_error (in_reply_to, TYPE_MISMATCH_ERROR, buf); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); } static DBusHandlerResult listener_set_property (GSListener *listener, DBusConnection *connection, DBusMessage *message, guint prop_id) { const char *path; int type; gboolean rc; DBusMessageIter iter; DBusMessage *reply; path = dbus_message_get_path (message); dbus_message_iter_init (message, &iter); type = dbus_message_iter_get_arg_type (&iter); rc = FALSE; switch (type) { case DBUS_TYPE_BOOLEAN: { dbus_bool_t v; dbus_message_iter_get_basic (&iter, &v); rc = listener_property_set_bool (listener, prop_id, v); break; } default: gs_debug ("Unsupported property type %d", type); break; } if (! rc) { raise_property_type_error (connection, message, path); return DBUS_HANDLER_RESULT_HANDLED; } reply = dbus_message_new_method_return (message); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_get_property (GSListener *listener, DBusConnection *connection, DBusMessage *message, guint prop_id) { DBusMessageIter iter; DBusMessage *reply; reply = dbus_message_new_method_return (message); dbus_message_iter_init_append (reply, &iter); if (reply == NULL) g_error ("No memory"); switch (prop_id) { case PROP_ACTIVE: { dbus_bool_t b; b = listener->priv->active; dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b); } break; default: gs_debug ("Unsupported property id %u", prop_id); break; } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_get_active_time (GSListener *listener, DBusConnection *connection, DBusMessage *message) { DBusMessageIter iter; DBusMessage *reply; dbus_uint32_t secs; reply = dbus_message_new_method_return (message); dbus_message_iter_init_append (reply, &iter); if (reply == NULL) { g_error ("No memory"); } if (listener->priv->active) { time_t now = time (NULL); if (now < listener->priv->active_start) { /* shouldn't happen */ gs_debug ("Active start time is in the future"); secs = 0; } else if (listener->priv->active_start <= 0) { /* shouldn't happen */ gs_debug ("Active start time was not set"); secs = 0; } else { secs = now - listener->priv->active_start; } } else { secs = 0; } gs_debug ("Returning screensaver active for %u seconds", secs); dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &secs); if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_lock (GSListener *listener, DBusConnection *connection, DBusMessage *message) { DBusMessageIter iter; DBusMessage *reply; DBusError error; reply = dbus_message_new_method_return (message); dbus_message_iter_init_append (reply, &iter); if (reply == NULL) { g_error ("No memory"); } char *body; dbus_error_init (&error); if (! dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &body, DBUS_TYPE_INVALID)) { raise_syntax (connection, message, "Lock"); return DBUS_HANDLER_RESULT_HANDLED; } g_signal_emit (listener, signals [LOCK], 0, body); if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_show_message (GSListener *listener, DBusConnection *connection, DBusMessage *message) { DBusMessageIter iter; DBusMessage *reply; DBusError error; reply = dbus_message_new_method_return (message); dbus_message_iter_init_append (reply, &iter); if (reply == NULL) { g_error ("No memory"); } if (listener->priv->active) { char *summary; char *body; char *icon; /* if we're not active we ignore the request */ dbus_error_init (&error); if (! dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &summary, DBUS_TYPE_STRING, &body, DBUS_TYPE_STRING, &icon, DBUS_TYPE_INVALID)) { raise_syntax (connection, message, "ShowMessage"); return DBUS_HANDLER_RESULT_HANDLED; } g_signal_emit (listener, signals [SHOW_MESSAGE], 0, summary, body, icon); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult do_introspect (DBusConnection *connection, DBusMessage *message, dbus_bool_t local_interface) { DBusMessage *reply; GString *xml; char *xml_string; /* standard header */ xml = g_string_new ("\n" "\n" " \n" " \n" " \n" " \n" " \n"); /* ScreenSaver interface */ xml = g_string_append (xml, " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n"); reply = dbus_message_new_method_return (message); xml = g_string_append (xml, "\n"); xml_string = g_string_free (xml, FALSE); dbus_message_append_args (reply, DBUS_TYPE_STRING, &xml_string, DBUS_TYPE_INVALID); g_free (xml_string); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult send_success_reply (DBusConnection *connection, DBusMessage *message) { DBusMessage *reply; if (dbus_message_get_no_reply (message)) { return DBUS_HANDLER_RESULT_HANDLED; } reply = dbus_message_new_method_return (message); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_dbus_handle_session_message (DBusConnection *connection, DBusMessage *message, void *user_data, dbus_bool_t local_interface) { GSListener *listener = GS_LISTENER (user_data); #if 0 g_message ("obj_path=%s interface=%s method=%s destination=%s", dbus_message_get_path (message), dbus_message_get_interface (message), dbus_message_get_member (message), dbus_message_get_destination (message)); #endif g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); if (dbus_message_is_method_call (message, GS_SERVICE, "Lock")) { return listener_lock (listener, connection, message); } if (dbus_message_is_method_call (message, GS_SERVICE, "Quit")) { g_signal_emit (listener, signals [QUIT], 0); return send_success_reply (connection, message); } if (dbus_message_is_method_call (message, GS_SERVICE, "SetActive")) { return listener_set_property (listener, connection, message, PROP_ACTIVE); } if (dbus_message_is_method_call (message, GS_SERVICE, "GetActive")) { return listener_get_property (listener, connection, message, PROP_ACTIVE); } if (dbus_message_is_method_call (message, GS_SERVICE, "GetActiveTime")) { return listener_get_active_time (listener, connection, message); } if (dbus_message_is_method_call (message, GS_SERVICE, "ShowMessage")) { return listener_show_message (listener, connection, message); } if (dbus_message_is_method_call (message, GS_SERVICE, "SimulateUserActivity")) { g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0); return send_success_reply (connection, message); } if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) { return do_introspect (connection, message, local_interface); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static gboolean _listener_message_path_is_our_session (GSListener *listener, DBusMessage *message) { const char *ssid; ssid = dbus_message_get_path (message); if (ssid == NULL) return FALSE; if (listener->priv->session_id == NULL) return FALSE; if (strcmp (ssid, listener->priv->session_id) == 0) return TRUE; return FALSE; } static gboolean properties_changed_match (DBusMessage *message, const char *property) { DBusMessageIter iter, sub, sub2; /* Checks whether a certain property is listed in the * specified PropertiesChanged message */ if (!dbus_message_iter_init (message, &iter)) goto failure; /* Jump over interface name */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) goto failure; dbus_message_iter_next (&iter); /* First, iterate through the changed properties array */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DICT_ENTRY) goto failure; dbus_message_iter_recurse (&iter, &sub); while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) { const char *name; if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_DICT_ENTRY) goto failure; dbus_message_iter_recurse (&sub, &sub2); dbus_message_iter_get_basic (&sub2, &name); if (strcmp (name, property) == 0) return TRUE; dbus_message_iter_next (&sub); } dbus_message_iter_next (&iter); /* Second, iterate through the invalidated properties array */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING) goto failure; dbus_message_iter_recurse (&iter, &sub); while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) { const char *name; if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_STRING) goto failure; dbus_message_iter_get_basic (&sub, &name); if (strcmp (name, property) == 0) return TRUE; dbus_message_iter_next (&sub); } return FALSE; failure: gs_debug ("Failed to decode PropertiesChanged message."); return FALSE; } static DBusHandlerResult listener_dbus_handle_system_message (DBusConnection *connection, DBusMessage *message, void *user_data, dbus_bool_t local_interface) { GSListener *listener = GS_LISTENER (user_data); g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); #if 1 gs_debug ("obj_path=%s interface=%s method=%s destination=%s", dbus_message_get_path (message), dbus_message_get_interface (message), dbus_message_get_member (message), dbus_message_get_destination (message)); #endif if (listener->priv->use_logind) { // Use logind if (dbus_message_is_signal (message, LOGIND_SESSION_INTERFACE, "Unlock")) { if (_listener_message_path_is_our_session (listener, message)) { gs_debug ("logind requested session unlock"); gs_listener_set_active (listener, FALSE); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_signal (message, LOGIND_SESSION_INTERFACE, "Lock")) { if (_listener_message_path_is_our_session (listener, message)) { gs_debug ("logind requested session lock"); g_signal_emit (listener, signals [LOCK], 0, ""); } return DBUS_HANDLER_RESULT_HANDLED; } #ifdef HAVE_LOGIND // @TODO: Replace sd_session_is_active() with a DBUS query. This is the only call requiring a dependency on libsystem-logind else if (dbus_message_is_signal (message, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged")) { if (_listener_message_path_is_our_session (listener, message)) { if (properties_changed_match (message, "Active")) { gboolean new_active; /* Instead of going via the bus to read the new property state, let's * shortcut this and ask directly the low-level information */ new_active = sd_session_is_active (listener->priv->session_id) != 0; if (new_active) g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0); } } return DBUS_HANDLER_RESULT_HANDLED; } #endif } else { // Use consolekit if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "Unlock")) { if (_listener_message_path_is_our_session (listener, message)) { gs_debug ("Console kit requested session unlock"); gs_listener_set_active (listener, FALSE); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "Lock")) { if (_listener_message_path_is_our_session (listener, message)) { gs_debug ("ConsoleKit requested session lock"); g_signal_emit (listener, signals [LOCK], 0, ""); } return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_signal (message, CK_SESSION_INTERFACE, "ActiveChanged")) { /* NB that `ActiveChanged' refers to the active * session in ConsoleKit terminology - ie which * session is currently displayed on the screen. * cinnamon-screensaver uses `active' to mean `is the * screensaver active' (ie, is the screen locked) but * that's not what we're referring to here. */ if (_listener_message_path_is_our_session (listener, message)) { DBusError error; dbus_bool_t new_active; dbus_error_init (&error); if (dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &new_active, DBUS_TYPE_INVALID)) { gs_debug ("ConsoleKit notified ActiveChanged %d", new_active); /* when we become active poke the lock */ if (new_active) { g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0); } } if (dbus_error_is_set (&error)) { dbus_error_free (&error); } } return DBUS_HANDLER_RESULT_HANDLED; } } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static DBusHandlerResult gs_listener_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data) { g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); #if 0 g_message ("obj_path=%s interface=%s method=%s destination=%s", dbus_message_get_path (message), dbus_message_get_interface (message), dbus_message_get_member (message), dbus_message_get_destination (message)); #endif if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) { DBusMessage *reply; reply = dbus_message_new_method_return (message); if (reply == NULL) { g_error ("No memory"); } if (! dbus_connection_send (connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) { dbus_connection_unref (connection); return DBUS_HANDLER_RESULT_HANDLED; } else { return listener_dbus_handle_session_message (connection, message, user_data, TRUE); } } static gboolean gs_listener_dbus_init (GSListener *listener) { DBusError error; dbus_error_init (&error); if (listener->priv->connection == NULL) { listener->priv->connection = dbus_bus_get (DBUS_BUS_SESSION, &error); if (listener->priv->connection == NULL) { if (dbus_error_is_set (&error)) { gs_debug ("couldn't connect to session bus: %s", error.message); dbus_error_free (&error); } return FALSE; } dbus_connection_setup_with_g_main (listener->priv->connection, NULL); dbus_connection_set_exit_on_disconnect (listener->priv->connection, FALSE); } if (listener->priv->system_connection == NULL) { listener->priv->system_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); if (listener->priv->system_connection == NULL) { if (dbus_error_is_set (&error)) { gs_debug ("couldn't connect to system bus: %s", error.message); dbus_error_free (&error); } return FALSE; } dbus_connection_setup_with_g_main (listener->priv->system_connection, NULL); dbus_connection_set_exit_on_disconnect (listener->priv->system_connection, FALSE); } return TRUE; } static gboolean reinit_dbus (GSListener *listener) { gboolean initialized; gboolean try_again; initialized = gs_listener_dbus_init (listener); /* if we didn't initialize then try again */ /* FIXME: Should we keep trying forever? If we fail more than once or twice then the session bus may have died. The problem is that if it is restarted it will likely have a different bus address and we won't be able to find it */ try_again = !initialized; return try_again; } static DBusHandlerResult listener_dbus_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) { GSListener *listener = GS_LISTENER (user_data); const char *path; path = dbus_message_get_path (message); /* g_message ("obj_path=%s interface=%s method=%s", dbus_message_get_path (message), dbus_message_get_interface (message), dbus_message_get_member (message)); */ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && strcmp (path, DBUS_PATH_LOCAL) == 0) { g_message ("Got disconnected from the session message bus; " "retrying to reconnect every 10 seconds"); dbus_connection_unref (connection); listener->priv->connection = NULL; g_timeout_add (10000, (GSourceFunc)reinit_dbus, listener); } else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { } else { return listener_dbus_handle_session_message (connection, message, user_data, FALSE); } return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult listener_dbus_system_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) { GSListener *listener = GS_LISTENER (user_data); const char *path; path = dbus_message_get_path (message); if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && strcmp (path, DBUS_PATH_LOCAL) == 0) { g_message ("Got disconnected from the system message bus; " "retrying to reconnect every 10 seconds"); dbus_connection_unref (connection); listener->priv->system_connection = NULL; g_timeout_add (10000, (GSourceFunc)reinit_dbus, listener); } else { return listener_dbus_handle_system_message (connection, message, user_data, FALSE); } return DBUS_HANDLER_RESULT_HANDLED; } static void gs_listener_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GSListener *self; self = GS_LISTENER (object); switch (prop_id) { case PROP_ACTIVE: gs_listener_set_active (self, g_value_get_boolean (value)); break; case PROP_SESSION_IDLE: gs_listener_set_session_idle (self, g_value_get_boolean (value)); break; case PROP_ACTIVATION_ENABLED: gs_listener_set_activation_enabled (self, g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_listener_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GSListener *self; self = GS_LISTENER (object); switch (prop_id) { case PROP_ACTIVE: g_value_set_boolean (value, self->priv->active); break; case PROP_SESSION_IDLE: g_value_set_boolean (value, self->priv->session_idle); break; case PROP_ACTIVATION_ENABLED: g_value_set_boolean (value, self->priv->activation_enabled); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void gs_listener_class_init (GSListenerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_listener_finalize; object_class->get_property = gs_listener_get_property; object_class->set_property = gs_listener_set_property; signals [LOCK] = g_signal_new ("lock", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSListenerClass, lock), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); signals [QUIT] = g_signal_new ("quit", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSListenerClass, quit), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals [SIMULATE_USER_ACTIVITY] = g_signal_new ("simulate-user-activity", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSListenerClass, simulate_user_activity), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals [ACTIVE_CHANGED] = g_signal_new ("active-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSListenerClass, active_changed), NULL, NULL, gs_marshal_BOOLEAN__BOOLEAN, G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN); signals [SHOW_MESSAGE] = g_signal_new ("show-message", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSListenerClass, show_message), NULL, NULL, gs_marshal_VOID__STRING_STRING_STRING, G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); g_object_class_install_property (object_class, PROP_ACTIVE, g_param_spec_boolean ("active", NULL, NULL, FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_ACTIVATION_ENABLED, g_param_spec_boolean ("activation-enabled", NULL, NULL, TRUE, G_PARAM_READWRITE)); g_type_class_add_private (klass, sizeof (GSListenerPrivate)); } static gboolean screensaver_is_running (DBusConnection *connection) { DBusError error; gboolean exists; g_return_val_if_fail (connection != NULL, FALSE); dbus_error_init (&error); exists = dbus_bus_name_has_owner (connection, GS_SERVICE, &error); if (dbus_error_is_set (&error)) { dbus_error_free (&error); } return exists; } gboolean gs_listener_acquire (GSListener *listener, GError **error) { int res; DBusError buserror; gboolean is_connected; g_return_val_if_fail (listener != NULL, FALSE); if (! listener->priv->connection) { g_set_error (error, GS_LISTENER_ERROR, GS_LISTENER_ERROR_ACQUISITION_FAILURE, "%s", _("failed to register with the message bus")); return FALSE; } is_connected = dbus_connection_get_is_connected (listener->priv->connection); if (! is_connected) { g_set_error (error, GS_LISTENER_ERROR, GS_LISTENER_ERROR_ACQUISITION_FAILURE, "%s", _("not connected to the message bus")); return FALSE; } if (screensaver_is_running (listener->priv->connection)) { g_set_error (error, GS_LISTENER_ERROR, GS_LISTENER_ERROR_ACQUISITION_FAILURE, "%s", _("screensaver already running in this session")); return FALSE; } dbus_error_init (&buserror); if (dbus_connection_register_object_path (listener->priv->connection, GS_PATH, &gs_listener_vtable, listener) == FALSE) { g_critical ("out of memory registering object path"); return FALSE; } res = dbus_bus_request_name (listener->priv->connection, GS_SERVICE, DBUS_NAME_FLAG_DO_NOT_QUEUE, &buserror); if (dbus_error_is_set (&buserror)) { g_set_error (error, GS_LISTENER_ERROR, GS_LISTENER_ERROR_ACQUISITION_FAILURE, "%s", buserror.message); } if (res == DBUS_REQUEST_NAME_REPLY_EXISTS) { g_set_error (error, GS_LISTENER_ERROR, GS_LISTENER_ERROR_ACQUISITION_FAILURE, "%s", _("screensaver already running in this session")); return FALSE; } dbus_error_free (&buserror); dbus_connection_add_filter (listener->priv->connection, listener_dbus_filter_function, listener, NULL); dbus_bus_add_match (listener->priv->connection, "type='signal'" ",interface='"DBUS_INTERFACE_DBUS"'" ",sender='"DBUS_SERVICE_DBUS"'" ",member='NameOwnerChanged'", NULL); if (listener->priv->system_connection != NULL) { dbus_connection_add_filter (listener->priv->system_connection, listener_dbus_system_filter_function, listener, NULL); if (listener->priv->use_logind) { // Use logind dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",sender='"LOGIND_SERVICE"'" ",interface='"LOGIND_SESSION_INTERFACE"'" ",member='Unlock'", NULL); dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",sender='"LOGIND_SERVICE"'" ",interface='"LOGIND_SESSION_INTERFACE"'" ",member='Lock'", NULL); dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",sender='"LOGIND_SERVICE"'" ",interface='"DBUS_INTERFACE_PROPERTIES"'" ",member='PropertiesChanged'", NULL); return (res != -1); } else { // Use consolekit dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",interface='"CK_SESSION_INTERFACE"'" ",member='Unlock'", NULL); dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",interface='"CK_SESSION_INTERFACE"'" ",member='Lock'", NULL); dbus_bus_add_match (listener->priv->system_connection, "type='signal'" ",interface='"CK_SESSION_INTERFACE"'" ",member='ActiveChanged'", NULL); } } return (res != -1); } static char * query_session_id (GSListener *listener) { DBusMessage *message; DBusMessage *reply; DBusError error; DBusMessageIter reply_iter; char *ssid; if (listener->priv->system_connection == NULL) { gs_debug ("No connection to the system bus"); return NULL; } ssid = NULL; dbus_error_init (&error); if (listener->priv->use_logind) { // Use logind dbus_uint32_t pid = getpid(); message = dbus_message_new_method_call (LOGIND_SERVICE, LOGIND_PATH, LOGIND_INTERFACE, "GetSessionByPID"); if (message == NULL) { gs_debug ("Couldn't allocate the dbus message"); return NULL; } if (dbus_message_append_args (message, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID) == FALSE) { gs_debug ("Couldn't add args to the dbus message"); return NULL; } /* FIXME: use async? */ reply = dbus_connection_send_with_reply_and_block (listener->priv->system_connection, message, -1, &error); dbus_message_unref (message); if (dbus_error_is_set (&error)) { gs_debug ("%s raised:\n %s\n\n", error.name, error.message); dbus_error_free (&error); return NULL; } dbus_message_iter_init (reply, &reply_iter); dbus_message_iter_get_basic (&reply_iter, &ssid); dbus_message_unref (reply); return g_strdup (ssid); } else { // Use consolekit message = dbus_message_new_method_call (CK_SERVICE, CK_MANAGER_PATH, CK_MANAGER_INTERFACE, "GetCurrentSession"); if (message == NULL) { gs_debug ("Couldn't allocate the dbus message"); return NULL; } /* FIXME: use async? */ reply = dbus_connection_send_with_reply_and_block (listener->priv->system_connection, message, -1, &error); dbus_message_unref (message); if (dbus_error_is_set (&error)) { gs_debug ("%s raised:\n %s\n\n", error.name, error.message); dbus_error_free (&error); return NULL; } dbus_message_iter_init (reply, &reply_iter); dbus_message_iter_get_basic (&reply_iter, &ssid); dbus_message_unref (reply); return g_strdup (ssid); } } static void init_session_id (GSListener *listener) { g_free (listener->priv->session_id); listener->priv->session_id = query_session_id (listener); gs_debug ("Got session-id: %s", listener->priv->session_id); } static void gs_listener_init (GSListener *listener) { listener->priv = GS_LISTENER_GET_PRIVATE (listener); GSettings *session_settings = g_settings_new ("org.cinnamon.desktop.session"); listener->priv->use_logind = g_settings_get_boolean (session_settings, "screensaver-uses-logind"); g_object_unref (session_settings); gs_listener_dbus_init (listener); init_session_id (listener); } static void gs_listener_finalize (GObject *object) { GSListener *listener; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_LISTENER (object)); listener = GS_LISTENER (object); g_return_if_fail (listener->priv != NULL); g_free (listener->priv->session_id); G_OBJECT_CLASS (gs_listener_parent_class)->finalize (object); } GSListener * gs_listener_new (void) { GSListener *listener; listener = g_object_new (GS_TYPE_LISTENER, NULL); return GS_LISTENER (listener); } cinnamon-screensaver-2.8.0/src/gs-grab-x11.c0000664000175000017500000005165412610211212017450 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_XF86MISCSETGRABKEYSSTATE # include #endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ #include "gs-window.h" #include "gs-grab.h" #include "gs-debug.h" static void gs_grab_class_init (GSGrabClass *klass); static void gs_grab_init (GSGrab *grab); static void gs_grab_finalize (GObject *object); #define GS_GRAB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_GRAB, GSGrabPrivate)) G_DEFINE_TYPE (GSGrab, gs_grab, G_TYPE_OBJECT) static gpointer grab_object = NULL; struct GSGrabPrivate { GDBusConnection *session_bus; guint mouse_hide_cursor : 1; GdkWindow *mouse_grab_window; GdkWindow *keyboard_grab_window; GdkScreen *mouse_grab_screen; GdkScreen *keyboard_grab_screen; GtkWidget *invisible; }; static const char * grab_string (int status) { switch (status) { case GDK_GRAB_SUCCESS: return "GrabSuccess"; case GDK_GRAB_ALREADY_GRABBED: return "AlreadyGrabbed"; case GDK_GRAB_INVALID_TIME: return "GrabInvalidTime"; case GDK_GRAB_NOT_VIEWABLE: return "GrabNotViewable"; case GDK_GRAB_FROZEN: return "GrabFrozen"; default: { static char foo [255]; sprintf (foo, "unknown status: %d", status); return foo; } } } #ifdef HAVE_XF86MISCSETGRABKEYSSTATE /* This function enables and disables the Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys, which (in XFree86 4.2) break any grabs and/or kill the grabbing client. That would effectively unlock the screen, so we don't like that. The Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys only exist if AllowDeactivateGrabs and/or AllowClosedownGrabs are turned on in XF86Config. I believe they are disabled by default. This does not affect any other keys (specifically Ctrl-Alt-BS or Ctrl-Alt-F1) but I wish it did. Maybe it will someday. */ static void xorg_lock_smasher_set_active (GSGrab *grab, gboolean active) { int status, event, error; if (!XF86MiscQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &event, &error)) { gs_debug ("No XFree86-Misc extension present"); return; } if (active) { gs_debug ("Enabling the x.org grab smasher"); } else { gs_debug ("Disabling the x.org grab smasher"); } gdk_error_trap_push (); status = XF86MiscSetGrabKeysState (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), active); gdk_display_sync (gdk_display_get_default ()); error = gdk_error_trap_pop (); if (active && status == MiscExtGrabStateAlready) { /* shut up, consider this success */ status = MiscExtGrabStateSuccess; } if (error == Success) { gs_debug ("XF86MiscSetGrabKeysState(%s) returned %s\n", active ? "on" : "off", (status == MiscExtGrabStateSuccess ? "MiscExtGrabStateSuccess" : status == MiscExtGrabStateLocked ? "MiscExtGrabStateLocked" : status == MiscExtGrabStateAlready ? "MiscExtGrabStateAlready" : "unknown value")); } else { gs_debug ("XF86MiscSetGrabKeysState(%s) failed with error code %d\n", active ? "on" : "off", error); } } #else static void xorg_lock_smasher_set_active (GSGrab *grab, gboolean active) { } #endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ static int gs_grab_get_keyboard (GSGrab *grab, GdkWindow *window, GdkScreen *screen) { GdkGrabStatus status; g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (screen != NULL, FALSE); gs_debug ("Grabbing keyboard widget=%X", (guint32) GDK_WINDOW_XID (window)); status = gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) { if (grab->priv->keyboard_grab_window != NULL) { g_object_remove_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), (gpointer *) &grab->priv->keyboard_grab_window); } grab->priv->keyboard_grab_window = window; g_object_add_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), (gpointer *) &grab->priv->keyboard_grab_window); grab->priv->keyboard_grab_screen = screen; } else { gs_debug ("Couldn't grab keyboard! (%s)", grab_string (status)); } return status; } static int gs_grab_get_mouse (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { GdkGrabStatus status; GdkCursor *cursor; g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (screen != NULL, FALSE); cursor = gdk_cursor_new (GDK_BLANK_CURSOR); gs_debug ("Grabbing mouse widget=%X", (guint32) GDK_WINDOW_XID (window)); status = gdk_pointer_grab (window, TRUE, 0, NULL, (hide_cursor ? cursor : NULL), GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) { if (grab->priv->mouse_grab_window != NULL) { g_object_remove_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), (gpointer *) &grab->priv->mouse_grab_window); } grab->priv->mouse_grab_window = window; g_object_add_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), (gpointer *) &grab->priv->mouse_grab_window); grab->priv->mouse_grab_screen = screen; grab->priv->mouse_hide_cursor = hide_cursor; } g_object_unref (cursor); return status; } void gs_grab_keyboard_reset (GSGrab *grab) { if (grab->priv->keyboard_grab_window != NULL) { g_object_remove_weak_pointer (G_OBJECT (grab->priv->keyboard_grab_window), (gpointer *) &grab->priv->keyboard_grab_window); } grab->priv->keyboard_grab_window = NULL; grab->priv->keyboard_grab_screen = NULL; } static gboolean gs_grab_release_keyboard (GSGrab *grab) { gs_debug ("Ungrabbing keyboard"); gdk_keyboard_ungrab (GDK_CURRENT_TIME); gs_grab_keyboard_reset (grab); return TRUE; } void gs_grab_mouse_reset (GSGrab *grab) { if (grab->priv->mouse_grab_window != NULL) { g_object_remove_weak_pointer (G_OBJECT (grab->priv->mouse_grab_window), (gpointer *) &grab->priv->mouse_grab_window); } grab->priv->mouse_grab_window = NULL; grab->priv->mouse_grab_screen = NULL; } gboolean gs_grab_release_mouse (GSGrab *grab) { gs_debug ("Ungrabbing pointer"); gdk_pointer_ungrab (GDK_CURRENT_TIME); gs_grab_mouse_reset (grab); return TRUE; } static gboolean gs_grab_move_mouse (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { gboolean result; GdkWindow *old_window; GdkScreen *old_screen; gboolean old_hide_cursor; /* if the pointer is not grabbed and we have a mouse_grab_window defined then we lost the grab */ if (! gdk_pointer_is_grabbed ()) { gs_grab_mouse_reset (grab); } if (grab->priv->mouse_grab_window == window) { gs_debug ("Window %X is already grabbed, skipping", (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window)); return TRUE; } #if 0 gs_debug ("Intentionally skipping move pointer grabs"); /* FIXME: GTK doesn't like having the pointer grabbed */ return TRUE; #else if (grab->priv->mouse_grab_window) { gs_debug ("Moving pointer grab from %X to %X", (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window), (guint32) GDK_WINDOW_XID (window)); } else { gs_debug ("Getting pointer grab on %X", (guint32) GDK_WINDOW_XID (window)); } #endif gs_debug ("*** doing X server grab"); gdk_x11_grab_server (); old_window = grab->priv->mouse_grab_window; old_screen = grab->priv->mouse_grab_screen; old_hide_cursor = grab->priv->mouse_hide_cursor; if (old_window) { gs_grab_release_mouse (grab); } result = gs_grab_get_mouse (grab, window, screen, hide_cursor); if (result != GDK_GRAB_SUCCESS) { sleep (1); result = gs_grab_get_mouse (grab, window, screen, hide_cursor); } if ((result != GDK_GRAB_SUCCESS) && old_window) { gs_debug ("Could not grab mouse for new window. Resuming previous grab."); gs_grab_get_mouse (grab, old_window, old_screen, old_hide_cursor); } gs_debug ("*** releasing X server grab"); gdk_x11_ungrab_server (); gdk_flush (); return (result == GDK_GRAB_SUCCESS); } static gboolean gs_grab_move_keyboard (GSGrab *grab, GdkWindow *window, GdkScreen *screen) { gboolean result; GdkWindow *old_window; GdkScreen *old_screen; if (grab->priv->keyboard_grab_window == window) { gs_debug ("Window %X is already grabbed, skipping", (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window)); return TRUE; } if (grab->priv->keyboard_grab_window != NULL) { gs_debug ("Moving keyboard grab from %X to %X", (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window), (guint32) GDK_WINDOW_XID (window)); } else { gs_debug ("Getting keyboard grab on %X", (guint32) GDK_WINDOW_XID (window)); } gs_debug ("*** doing X server grab"); gdk_x11_grab_server (); old_window = grab->priv->keyboard_grab_window; old_screen = grab->priv->keyboard_grab_screen; if (old_window) { gs_grab_release_keyboard (grab); } result = gs_grab_get_keyboard (grab, window, screen); if (result != GDK_GRAB_SUCCESS) { sleep (1); result = gs_grab_get_keyboard (grab, window, screen); } if ((result != GDK_GRAB_SUCCESS) && old_window) { gs_debug ("Could not grab keyboard for new window. Resuming previous grab."); gs_grab_get_keyboard (grab, old_window, old_screen); } gs_debug ("*** releasing X server grab"); gdk_x11_ungrab_server (); gdk_flush (); return (result == GDK_GRAB_SUCCESS); } static void gs_grab_nuke_focus (void) { Window focus = 0; int rev = 0; gs_debug ("Nuking focus"); gdk_error_trap_push (); XGetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &focus, &rev); XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), None, RevertToNone, CurrentTime); gdk_error_trap_pop_ignored (); } void gs_grab_release (GSGrab *grab) { gs_debug ("Releasing all grabs"); gs_grab_release_mouse (grab); gs_grab_release_keyboard (grab); /* FIXME: is it right to enable this ? */ xorg_lock_smasher_set_active (grab, TRUE); gdk_display_sync (gdk_display_get_default ()); gdk_flush (); } /* The Cinnamon Shell holds an X grab when we're in the overview; * ask it to bounce out before we try locking the screen. */ static void request_shell_exit_overview (GSGrab *grab) { GDBusMessage *message; /* Shouldn't happen, but... */ if (!grab->priv->session_bus) return; message = g_dbus_message_new_method_call ("org.Cinnamon", "/org/Cinnamon", "org.freedesktop.DBus.Properties", "Set"); g_dbus_message_set_body (message, g_variant_new ("(ssv)", "org.Cinnamon", "OverviewActive", g_variant_new ("b", FALSE))); g_dbus_connection_send_message (grab->priv->session_bus, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); message = g_dbus_message_new_method_call ("org.Cinnamon", "/org/Cinnamon", "org.freedesktop.DBus.Properties", "Set"); g_dbus_message_set_body (message, g_variant_new ("(ssv)", "org.Cinnamon", "ExpoActive", g_variant_new ("b", FALSE))); g_dbus_connection_send_message (grab->priv->session_bus, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); } gboolean gs_grab_grab_window (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { gboolean mstatus = FALSE; gboolean kstatus = FALSE; int i; int retries = 4; gboolean focus_fuckus = FALSE; /* First, have stuff we control in GNOME un-grab */ request_shell_exit_overview (grab); AGAIN: for (i = 0; i < retries; i++) { kstatus = gs_grab_get_keyboard (grab, window, screen); if (kstatus == GDK_GRAB_SUCCESS) { break; } /* else, wait a second and try to grab again. */ sleep (1); } if (kstatus != GDK_GRAB_SUCCESS) { if (!focus_fuckus) { focus_fuckus = TRUE; gs_grab_nuke_focus (); goto AGAIN; } } for (i = 0; i < retries; i++) { mstatus = gs_grab_get_mouse (grab, window, screen, hide_cursor); if (mstatus == GDK_GRAB_SUCCESS) { break; } /* else, wait a second and try to grab again. */ sleep (1); } if (mstatus != GDK_GRAB_SUCCESS) { gs_debug ("Couldn't grab pointer! (%s)", grab_string (mstatus)); } #if 0 /* FIXME: release the pointer grab so GTK will work */ gs_grab_release_mouse (grab); #endif /* When should we allow blanking to proceed? The current theory is that both a keyboard grab and a mouse grab are mandatory - If we don't have a keyboard grab, then we won't be able to read a password to unlock, so the kbd grab is manditory. - If we don't have a mouse grab, then we might not see mouse clicks as a signal to unblank, on-screen widgets won't work ideally, and gs_grab_move_to_window() will spin forever when it gets called. */ if (kstatus != GDK_GRAB_SUCCESS || mstatus != GDK_GRAB_SUCCESS) { /* Do not blank without a keyboard and mouse grabs. */ /* Release keyboard or mouse which was grabbed. */ if (kstatus == GDK_GRAB_SUCCESS) { gs_grab_release_keyboard (grab); } if (mstatus == GDK_GRAB_SUCCESS) { gs_grab_release_mouse (grab); } return FALSE; } /* Grab is good, go ahead and blank. */ return TRUE; } /* this is used to grab the keyboard and mouse to the root */ gboolean gs_grab_grab_root (GSGrab *grab, gboolean hide_cursor) { GdkDisplay *display; GdkWindow *root; GdkScreen *screen; gboolean res; gs_debug ("Grabbing the root window"); display = gdk_display_get_default (); gdk_display_get_pointer (display, &screen, NULL, NULL, NULL); root = gdk_screen_get_root_window (screen); res = gs_grab_grab_window (grab, root, screen, hide_cursor); return res; } /* this is used to grab the keyboard and mouse to an offscreen window */ gboolean gs_grab_grab_offscreen (GSGrab *grab, gboolean hide_cursor) { GdkScreen *screen; gboolean res; gs_debug ("Grabbing an offscreen window"); screen = gtk_invisible_get_screen (GTK_INVISIBLE (grab->priv->invisible)); res = gs_grab_grab_window (grab, gtk_widget_get_window (grab->priv->invisible), screen, hide_cursor); return res; } /* This is similar to gs_grab_grab_window but doesn't fail */ void gs_grab_move_to_window (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { gboolean result = FALSE; g_return_if_fail (GS_IS_GRAB (grab)); xorg_lock_smasher_set_active (grab, FALSE); do { result = gs_grab_move_keyboard (grab, window, screen); gdk_flush (); } while (!result); do { result = gs_grab_move_mouse (grab, window, screen, hide_cursor); gdk_flush (); } while (!result); } static void gs_grab_class_init (GSGrabClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_grab_finalize; g_type_class_add_private (klass, sizeof (GSGrabPrivate)); } static void gs_grab_init (GSGrab *grab) { grab->priv = GS_GRAB_GET_PRIVATE (grab); grab->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); grab->priv->mouse_hide_cursor = FALSE; grab->priv->invisible = gtk_invisible_new (); gtk_widget_show (grab->priv->invisible); } static void gs_grab_finalize (GObject *object) { GSGrab *grab; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_GRAB (object)); grab = GS_GRAB (object); g_object_unref (grab->priv->session_bus); g_return_if_fail (grab->priv != NULL); gtk_widget_destroy (grab->priv->invisible); G_OBJECT_CLASS (gs_grab_parent_class)->finalize (object); } GSGrab * gs_grab_new (void) { if (grab_object) { g_object_ref (grab_object); } else { grab_object = g_object_new (GS_TYPE_GRAB, NULL); g_object_add_weak_pointer (grab_object, (gpointer *) &grab_object); } return GS_GRAB (grab_object); } cinnamon-screensaver-2.8.0/src/gs-grab.h0000664000175000017500000000522712610211212017041 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_GRAB_H #define __GS_GRAB_H #include #include G_BEGIN_DECLS #define GS_TYPE_GRAB (gs_grab_get_type ()) #define GS_GRAB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_GRAB, GSGrab)) #define GS_GRAB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_GRAB, GSGrabClass)) #define GS_IS_GRAB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_GRAB)) #define GS_IS_GRAB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_GRAB)) #define GS_GRAB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_GRAB, GSGrabClass)) typedef struct GSGrabPrivate GSGrabPrivate; typedef struct { GObject parent; GSGrabPrivate *priv; } GSGrab; typedef struct { GObjectClass parent_class; } GSGrabClass; GType gs_grab_get_type (void); GSGrab * gs_grab_new (void); void gs_grab_release (GSGrab *grab); gboolean gs_grab_release_mouse (GSGrab *grab); gboolean gs_grab_grab_window (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor); gboolean gs_grab_grab_root (GSGrab *grab, gboolean hide_cursor); gboolean gs_grab_grab_offscreen (GSGrab *grab, gboolean hide_cursor); void gs_grab_move_to_window (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor); void gs_grab_mouse_reset (GSGrab *grab); void gs_grab_keyboard_reset (GSGrab *grab); G_END_DECLS #endif /* __GS_GRAB_H */ cinnamon-screensaver-2.8.0/src/gs-fade.c0000664000175000017500000006310212610211212017014 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2009 William Jon McCann * Copyright (C) 2009 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ #include #include #include "gs-fade.h" #include "gs-debug.h" #define GNOME_DESKTOP_USE_UNSTABLE_API #include /* XFree86 4.x+ Gamma fading */ #ifdef HAVE_XF86VMODE_GAMMA #include #define XF86_MIN_GAMMA 0.1 #endif /* HAVE_XF86VMODE_GAMMA */ static void gs_fade_class_init (GSFadeClass *klass); static void gs_fade_init (GSFade *fade); static void gs_fade_finalize (GObject *object); #define GS_FADE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_FADE, GSFadePrivate)) struct GSGammaInfo { int size; unsigned short *r; unsigned short *g; unsigned short *b; }; struct GSFadeScreenPrivate { int fade_type; int num_ramps; /* one per crtc in randr mode */ struct GSGammaInfo *info; /* one per screen in theory */ GnomeRRScreen *rrscreen; #ifdef HAVE_XF86VMODE_GAMMA /* one per screen also */ XF86VidModeGamma vmg; #endif /* HAVE_XF86VMODE_GAMMA */ gboolean (*fade_setup) (GSFade *fade); gboolean (*fade_set_alpha_gamma) (GSFade *fade, gdouble alpha); void (*fade_finish) (GSFade *fade); }; struct GSFadePrivate { guint enabled : 1; guint active : 1; guint timeout; guint step; guint num_steps; guint timer_id; gdouble alpha_per_iter; gdouble current_alpha; struct GSFadeScreenPrivate *screen_priv; }; enum { FADED, LAST_SIGNAL }; enum { FADE_TYPE_NONE, FADE_TYPE_GAMMA_NUMBER, FADE_TYPE_GAMMA_RAMP, FADE_TYPE_XRANDR, }; static guint signals [LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (GSFade, gs_fade, G_TYPE_OBJECT) static gpointer fade_object = NULL; #ifdef HAVE_XF86VMODE_GAMMA /* This is needed because the VidMode extension doesn't work on remote displays -- but if the remote display has the extension at all, XF86VidModeQueryExtension returns true, and then XF86VidModeQueryVersion dies with an X error. */ static gboolean error_handler_hit = FALSE; static int ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error) { error_handler_hit = TRUE; return 0; } static Bool safe_XF86VidModeQueryVersion (Display *dpy, int *majP, int *minP) { Bool result; XErrorHandler old_handler; XSync (dpy, False); error_handler_hit = FALSE; old_handler = XSetErrorHandler (ignore_all_errors_ehandler); result = XF86VidModeQueryVersion (dpy, majP, minP); XSync (dpy, False); XSetErrorHandler (old_handler); XSync (dpy, False); return (error_handler_hit ? False : result); } static gboolean xf86_whack_gamma (struct GSFadeScreenPrivate *screen_priv, float ratio) { Bool status; struct GSGammaInfo *gamma_info; gamma_info = screen_priv->info; if (!gamma_info) return FALSE; if (ratio < 0) { ratio = 0; } if (ratio > 1) { ratio = 1; } if (gamma_info->size == 0) { /* we only have a gamma number, not a ramp. */ XF86VidModeGamma g2; g2.red = screen_priv->vmg.red * ratio; g2.green = screen_priv->vmg.green * ratio; g2.blue = screen_priv->vmg.blue * ratio; if (g2.red < XF86_MIN_GAMMA) { g2.red = XF86_MIN_GAMMA; } if (g2.green < XF86_MIN_GAMMA) { g2.green = XF86_MIN_GAMMA; } if (g2.blue < XF86_MIN_GAMMA) { g2.blue = XF86_MIN_GAMMA; } gdk_error_trap_push (); status = XF86VidModeSetGamma (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, &g2); gdk_flush (); if (gdk_error_trap_pop ()) { gs_debug ("Failed to set gamma. Bailing out and aborting fade"); return FALSE; } } else { # ifdef HAVE_XF86VMODE_GAMMA_RAMP unsigned short *r, *g, *b; int i; r = g_new0 (unsigned short, gamma_info->size); g = g_new0 (unsigned short, gamma_info->size); b = g_new0 (unsigned short, gamma_info->size); for (i = 0; i < gamma_info->size; i++) { r[i] = gamma_info->r[i] * ratio; g[i] = gamma_info->g[i] * ratio; b[i] = gamma_info->b[i] * ratio; } gdk_error_trap_push (); status = XF86VidModeSetGammaRamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, gamma_info->size, r, g, b); gdk_flush (); if (gdk_error_trap_pop ()) { gs_debug ("Failed to set gamma. Bailing out and aborting fade"); return FALSE; } g_free (r); g_free (g); g_free (b); # else /* !HAVE_XF86VMODE_GAMMA_RAMP */ abort (); # endif /* !HAVE_XF86VMODE_GAMMA_RAMP */ } return status; } #endif /* HAVE_XF86VMODE_GAMMA */ /* VidModeExtension version 2.0 or better is needed to do gamma. 2.0 added gamma values; 2.1 added gamma ramps. */ # define XF86_VIDMODE_GAMMA_MIN_MAJOR 2 # define XF86_VIDMODE_GAMMA_MIN_MINOR 0 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR 2 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR 1 gboolean gs_fade_get_enabled (GSFade *fade) { g_return_val_if_fail (GS_IS_FADE (fade), FALSE); return fade->priv->enabled; } void gs_fade_set_enabled (GSFade *fade, gboolean enabled) { g_return_if_fail (GS_IS_FADE (fade)); if (fade->priv->enabled != enabled) { fade->priv->enabled = enabled; } } #ifdef HAVE_XF86VMODE_GAMMA static gboolean gamma_fade_setup (GSFade *fade) { gboolean res; struct GSFadeScreenPrivate *screen_priv; screen_priv = fade->priv->screen_priv; if (screen_priv->info) return TRUE; # ifndef HAVE_XF86VMODE_GAMMA_RAMP if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type) { /* server is newer than client! */ screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER; } # endif # ifdef HAVE_XF86VMODE_GAMMA_RAMP screen_priv->info = g_new0(struct GSGammaInfo, 1); screen_priv->num_ramps = 1; if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type) { /* have ramps */ res = XF86VidModeGetGammaRampSize (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, &screen_priv->info->size); if (!res || screen_priv->info->size <= 0) { screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER; goto test_number; } screen_priv->info->r = g_new0 (unsigned short, screen_priv->info->size); screen_priv->info->g = g_new0 (unsigned short, screen_priv->info->size); screen_priv->info->b = g_new0 (unsigned short, screen_priv->info->size); if (! (screen_priv->info->r && screen_priv->info->g && screen_priv->info->b)) { screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER; goto test_number; } res = XF86VidModeGetGammaRamp (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, screen_priv->info->size, screen_priv->info->r, screen_priv->info->g, screen_priv->info->b); if (! res) { screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER; goto test_number; } gs_debug ("Initialized gamma ramp fade"); } # endif /* HAVE_XF86VMODE_GAMMA_RAMP */ test_number: if (FADE_TYPE_GAMMA_NUMBER == screen_priv->fade_type) { /* only have gamma parameter, not ramps. */ res = XF86VidModeGetGamma (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, &screen_priv->vmg); if (! res) { screen_priv->fade_type = FADE_TYPE_NONE; goto test_none; } gs_debug ("Initialized gamma fade for screen: %f %f %f", screen_priv->vmg.red, screen_priv->vmg.green, screen_priv->vmg.blue); } test_none: if (FADE_TYPE_NONE == screen_priv->fade_type) { goto FAIL; } return TRUE; FAIL: return FALSE; } #endif /* HAVE_XF86VMODE_GAMMA */ static void screen_fade_finish (GSFade *fade) { struct GSFadeScreenPrivate *screen_priv; screen_priv = fade->priv->screen_priv; if (!screen_priv->info) return; int i; for (i = 0; i < screen_priv->num_ramps; i++) { if (screen_priv->info[i].r) g_free (screen_priv->info[i].r); if (screen_priv->info[i].g) g_free (screen_priv->info[i].g); if (screen_priv->info[i].b) g_free (screen_priv->info[i].b); } g_free (screen_priv->info); screen_priv->info = NULL; screen_priv->num_ramps = 0; } #ifdef HAVE_XF86VMODE_GAMMA static gboolean gamma_fade_set_alpha_gamma (GSFade *fade, gdouble alpha) { struct GSFadeScreenPrivate *screen_priv; screen_priv = fade->priv->screen_priv; xf86_whack_gamma (screen_priv, alpha); return TRUE; } #endif /* HAVE_XF86VMODE_GAMMA */ static void check_gamma_extension (GSFade *fade) { struct GSFadeScreenPrivate *screen_priv; #ifdef HAVE_XF86VMODE_GAMMA int event; int error; int major; int minor; gboolean res; #endif /* HAVE_XF86VMODE_GAMMA */ screen_priv = fade->priv->screen_priv; #ifdef HAVE_XF86VMODE_GAMMA if (g_getenv("LTSP_CLIENT")) { /* We're on an LTSP Client, bad idea to fade at all */ goto fade_none; } res = XF86VidModeQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &event, &error); if (! res) goto fade_none; res = safe_XF86VidModeQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor); if (! res) goto fade_none; if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR || (major == XF86_VIDMODE_GAMMA_MIN_MAJOR && minor < XF86_VIDMODE_GAMMA_MIN_MINOR)) goto fade_none; screen_priv->fade_setup = gamma_fade_setup; screen_priv->fade_finish = screen_fade_finish; screen_priv->fade_set_alpha_gamma = gamma_fade_set_alpha_gamma; if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR || (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR && minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR)) { screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER; return; } /* Copacetic */ screen_priv->fade_type = FADE_TYPE_GAMMA_RAMP; return; fade_none: #endif screen_priv->fade_type = FADE_TYPE_NONE; } /* Xrandr support */ static gboolean xrandr_fade_setup (GSFade *fade) { struct GSFadeScreenPrivate *screen_priv; GnomeRRCrtc *crtc; GnomeRRCrtc **crtcs; int crtc_count = 0; struct GSGammaInfo *info; gboolean res; screen_priv = fade->priv->screen_priv; if (screen_priv->info) return TRUE; /* refresh the screen info */ gnome_rr_screen_refresh (screen_priv->rrscreen, NULL); crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen); while (*crtcs) { crtc_count++; crtcs++; }; screen_priv->info = g_new0 (struct GSGammaInfo, crtc_count); screen_priv->num_ramps = crtc_count; crtc_count = 0; crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen); while (*crtcs) { crtc = *crtcs; info = &screen_priv->info[crtc_count]; /* if no mode ignore crtc */ if (!gnome_rr_crtc_get_current_mode (crtc)) { info->size = 0; info->r = NULL; info->g = NULL; info->b = NULL; } else { res = gnome_rr_crtc_get_gamma (crtc, &info->size, &info->r, &info->g, &info->b); if (res == FALSE) goto fail; } crtcs++; crtc_count++; } return TRUE; fail: return FALSE; } static void xrandr_crtc_whack_gamma (GnomeRRCrtc *crtc, struct GSGammaInfo *gamma_info, float ratio) { unsigned short *r, *g, *b; int i; if (gamma_info->size == 0) return; if (ratio < 0) { ratio = 0; } if (ratio > 1) { ratio = 1; } r = g_new0 (unsigned short, gamma_info->size); g = g_new0 (unsigned short, gamma_info->size); b = g_new0 (unsigned short, gamma_info->size); for (i = 0; i < gamma_info->size; i++) { r[i] = gamma_info->r[i] * ratio; g[i] = gamma_info->g[i] * ratio; b[i] = gamma_info->b[i] * ratio; } gnome_rr_crtc_set_gamma (crtc, gamma_info->size, r, g, b); g_free (r); g_free (g); g_free (b); } static gboolean xrandr_fade_set_alpha_gamma (GSFade *fade, gdouble alpha) { struct GSFadeScreenPrivate *screen_priv; struct GSGammaInfo *info; GnomeRRCrtc **crtcs; int i; screen_priv = fade->priv->screen_priv; if (!screen_priv->info) return FALSE; crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen); i = 0; while (*crtcs) { info = &screen_priv->info[i]; xrandr_crtc_whack_gamma (*crtcs, info, alpha); i++; crtcs++; } return TRUE; } static void check_randr_extension (GSFade *fade) { GdkDisplay *display = gdk_display_get_default (); GdkScreen *screen = gdk_display_get_default_screen (display); struct GSFadeScreenPrivate *screen_priv; GnomeRRCrtc **crtcs; GnomeRRCrtc *crtc; gboolean res; int gamma_size; screen_priv = fade->priv->screen_priv; screen_priv->rrscreen = gnome_rr_screen_new (screen, NULL); if (!screen_priv->rrscreen) { screen_priv->fade_type = FADE_TYPE_NONE; return; } crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen); while (*crtcs) { crtc = *crtcs; res = gnome_rr_crtc_get_gamma (crtc, &gamma_size, NULL, NULL, NULL); if (res == FALSE || gamma_size == 0) { screen_priv->fade_type = FADE_TYPE_NONE; return; } crtcs++; } screen_priv->fade_type = FADE_TYPE_XRANDR; screen_priv->fade_setup = xrandr_fade_setup; screen_priv->fade_finish = screen_fade_finish; screen_priv->fade_set_alpha_gamma = xrandr_fade_set_alpha_gamma; } static gboolean gs_fade_set_alpha (GSFade *fade, gdouble alpha) { gboolean ret = FALSE; switch (fade->priv->screen_priv->fade_type) { case FADE_TYPE_GAMMA_RAMP: case FADE_TYPE_GAMMA_NUMBER: case FADE_TYPE_XRANDR: ret = fade->priv->screen_priv->fade_set_alpha_gamma (fade, alpha); break; case FADE_TYPE_NONE: ret = FALSE; break; default: g_warning ("Unknown fade type"); ret = FALSE; break; } return ret; } static gboolean gs_fade_out_iter (GSFade *fade) { gboolean ret; if (fade->priv->current_alpha < 0.01) { return FALSE; } fade->priv->current_alpha -= fade->priv->alpha_per_iter; ret = gs_fade_set_alpha (fade, fade->priv->current_alpha); return ret; } static gboolean gs_fade_stop (GSFade *fade) { if (fade->priv->timer_id > 0) { g_source_remove (fade->priv->timer_id); fade->priv->timer_id = 0; } fade->priv->step = 0; fade->priv->active = FALSE; return TRUE; } void gs_fade_finish (GSFade *fade) { g_return_if_fail (GS_IS_FADE (fade)); if (! fade->priv->active) { return; } gs_fade_stop (fade); g_signal_emit (fade, signals [FADED], 0); fade->priv->active = FALSE; } static gboolean fade_out_timer (GSFade *fade) { gboolean res; res = gs_fade_out_iter (fade); /* if failed then fade is complete */ if (! res) { gs_fade_finish (fade); return FALSE; } return TRUE; } gboolean gs_fade_get_active (GSFade *fade) { g_return_val_if_fail (GS_IS_FADE (fade), FALSE); return fade->priv->active; } static void gs_fade_set_timeout (GSFade *fade, guint timeout) { g_return_if_fail (GS_IS_FADE (fade)); fade->priv->timeout = timeout; } static void gs_fade_start (GSFade *fade, guint timeout) { guint steps_per_sec = 60; guint msecs_per_step; struct GSFadeScreenPrivate *screen_priv; gboolean active_fade, res; g_return_if_fail (GS_IS_FADE (fade)); screen_priv = fade->priv->screen_priv; if (screen_priv->fade_type != FADE_TYPE_NONE) { res = screen_priv->fade_setup (fade); if (res == FALSE) return; } if (fade->priv->timer_id > 0) { gs_fade_stop (fade); } fade->priv->active = TRUE; gs_fade_set_timeout (fade, timeout); active_fade = FALSE; if (screen_priv->fade_type != FADE_TYPE_NONE) active_fade = TRUE; if (active_fade) { guint num_steps; num_steps = (fade->priv->timeout / 1000.) * steps_per_sec; msecs_per_step = 1000 / steps_per_sec; fade->priv->alpha_per_iter = 1.0 / (gdouble)num_steps; fade->priv->timer_id = g_timeout_add (msecs_per_step, (GSourceFunc)fade_out_timer, fade); } else { gs_fade_finish (fade); } } typedef struct { GSFadeDoneFunc done_cb; gpointer data; } FadedCallbackData; static void gs_fade_async_callback (GSFade *fade, FadedCallbackData *cdata) { g_signal_handlers_disconnect_by_func (fade, gs_fade_async_callback, cdata); if (cdata->done_cb) { cdata->done_cb (fade, cdata->data); } g_free (cdata); } void gs_fade_async (GSFade *fade, guint timeout, GSFadeDoneFunc func, gpointer data) { g_return_if_fail (GS_IS_FADE (fade)); /* if fade is active then pause it */ if (fade->priv->active) { gs_fade_stop (fade); } if (func) { FadedCallbackData *cb_data; cb_data = g_new0 (FadedCallbackData, 1); cb_data->done_cb = func; cb_data->data = data; g_signal_connect (fade, "faded", G_CALLBACK (gs_fade_async_callback), cb_data); } gs_fade_start (fade, timeout); } static void gs_fade_sync_callback (GSFade *fade, int *flag) { *flag = TRUE; g_signal_handlers_disconnect_by_func (fade, gs_fade_sync_callback, flag); } void gs_fade_sync (GSFade *fade, guint timeout) { int flag = FALSE; g_return_if_fail (GS_IS_FADE (fade)); /* if fade is active then pause it */ if (fade->priv->active) { gs_fade_stop (fade); } g_signal_connect (fade, "faded", G_CALLBACK (gs_fade_sync_callback), &flag); gs_fade_start (fade, timeout); while (! flag) { gtk_main_iteration (); } } void gs_fade_reset (GSFade *fade) { struct GSFadeScreenPrivate *screen_priv; g_return_if_fail (GS_IS_FADE (fade)); gs_debug ("Resetting fade"); if (fade->priv->active) { gs_fade_stop (fade); } fade->priv->current_alpha = 1.0; gs_fade_set_alpha (fade, fade->priv->current_alpha); screen_priv = fade->priv->screen_priv; if (screen_priv->fade_type != FADE_TYPE_NONE) { screen_priv->fade_finish (fade); } } static void gs_fade_class_init (GSFadeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = gs_fade_finalize; signals [FADED] = g_signal_new ("faded", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GSFadeClass, faded), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); g_type_class_add_private (klass, sizeof (GSFadePrivate)); } static void gs_fade_init (GSFade *fade) { fade->priv = GS_FADE_GET_PRIVATE (fade); fade->priv->timeout = 1000; fade->priv->current_alpha = 1.0; fade->priv->screen_priv = g_new0(struct GSFadeScreenPrivate, 1); check_randr_extension (fade); if (!fade->priv->screen_priv->fade_type) check_gamma_extension (fade); gs_debug ("Fade type: %d", fade->priv->screen_priv->fade_type); } static void gs_fade_finalize (GObject *object) { GSFade *fade; g_return_if_fail (object != NULL); g_return_if_fail (GS_IS_FADE (object)); fade = GS_FADE (object); g_return_if_fail (fade->priv != NULL); fade->priv->screen_priv->fade_finish(fade); if (fade->priv->screen_priv) { if (fade->priv->screen_priv->rrscreen) { g_object_unref (fade->priv->screen_priv->rrscreen); g_free (fade->priv->screen_priv); fade->priv->screen_priv = NULL; } } G_OBJECT_CLASS (gs_fade_parent_class)->finalize (object); } GSFade * gs_fade_new (void) { if (fade_object) { g_object_ref (fade_object); } else { fade_object = g_object_new (GS_TYPE_FADE, NULL); g_object_add_weak_pointer (fade_object, (gpointer *) &fade_object); } return GS_FADE (fade_object); } cinnamon-screensaver-2.8.0/src/gs-fade.h0000664000175000017500000000513412610211212017022 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_FADE_H #define __GS_FADE_H G_BEGIN_DECLS #define GS_TYPE_FADE (gs_fade_get_type ()) #define GS_FADE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_FADE, GSFade)) #define GS_FADE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_FADE, GSFadeClass)) #define GS_IS_FADE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_FADE)) #define GS_IS_FADE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_FADE)) #define GS_FADE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_FADE, GSFadeClass)) typedef struct GSFadePrivate GSFadePrivate; typedef struct { GObject parent; GSFadePrivate *priv; } GSFade; typedef struct { GObjectClass parent_class; void (* faded) (GSFade *fade); } GSFadeClass; typedef void (* GSFadeDoneFunc) (GSFade *fade, gpointer data); GType gs_fade_get_type (void); GSFade * gs_fade_new (void); void gs_fade_async (GSFade *fade, guint timeout, GSFadeDoneFunc done_cb, gpointer data); void gs_fade_sync (GSFade *fade, guint timeout); void gs_fade_finish (GSFade *fade); void gs_fade_reset (GSFade *fade); gboolean gs_fade_get_active (GSFade *fade); gboolean gs_fade_get_enabled (GSFade *fade); void gs_fade_set_enabled (GSFade *fade, gboolean enabled); G_END_DECLS #endif /* __GS_FADE_H */ cinnamon-screensaver-2.8.0/src/Makefile.am0000664000175000017500000001167312610211212017404 0ustar fabiofabio## We require new-style dependency handling. AUTOMAKE_OPTIONS = 1.7 NULL = saverdir = $(libexecdir)/cinnamon-screensaver INCLUDES = \ -I. \ -I$(srcdir) \ $(CINNAMON_SCREENSAVER_CFLAGS) \ $(CINNAMON_SCREENSAVER_DIALOG_CFLAGS) \ $(CINNAMON_SCREENSAVER_CAPPLET_CFLAGS) \ $(DISABLE_DEPRECATED_CFLAGS) \ -DPREFIX=\""$(prefix)"\" \ -DBINDIR=\""$(bindir)"\" \ -DLIBDIR=\""$(libdir)"\" \ -DLIBEXECDIR=\""$(libexecdir)"\" \ -DDATADIR=\""$(datadir)"\" \ -DSYSCONFDIR=\""$(sysconfdir)"\" \ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ -DSAVERDIR=\""$(saverdir)"\" \ -DGTKBUILDERDIR=\"$(pkgdatadir)\" \ -DPAM_SERVICE_NAME=\""cinnamon-screensaver"\" \ $(WARN_CFLAGS) \ $(AUTH_CFLAGS) \ $(DEBUG_CFLAGS) \ $(DBUS_CFLAGS) \ $(LIBGNOMEKBDUI_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ $(LOGIND_CFLAGS) \ $(NULL) bin_PROGRAMS = \ cinnamon-screensaver \ cinnamon-screensaver-command \ $(NULL) libexec_PROGRAMS = \ cinnamon-screensaver-dialog \ $(NULL) noinst_PROGRAMS = \ test-fade \ test-passwd \ test-watcher \ test-window \ $(NULL) desktopdir = $(datadir)/applications desktop_in_files = cinnamon-screensaver.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) @INTLTOOL_DESKTOP_RULE@ cinnamon_screensaver_command_SOURCES = \ bus.h \ cinnamon-screensaver-command.c \ $(NULL) cinnamon_screensaver_command_LDADD = \ $(CINNAMON_SCREENSAVER_COMMAND_LIBS) \ $(NULL) AUTH_SOURCES = \ gs-auth-@AUTH_SCHEME@.c \ $(NULL) test_fade_SOURCES = \ test-fade.c \ gs-fade.c \ gs-fade.h \ gs-debug.c \ gs-debug.h \ $(NULL) test_fade_LDADD = \ $(CINNAMON_SCREENSAVER_LIBS) \ $(SAVER_LIBS) \ $(NULL) test_passwd_SOURCES = \ test-passwd.c \ gs-auth.h \ $(AUTH_SOURCES) \ setuid.c \ setuid.h \ subprocs.c \ subprocs.h \ $(NULL) test_passwd_LDADD = \ $(CINNAMON_SCREENSAVER_DIALOG_LIBS)\ $(AUTH_LIBS) \ $(NULL) test_watcher_SOURCES = \ bus.h \ test-watcher.c \ gs-watcher.h \ gs-watcher-x11.c \ gs-marshal.c \ gs-marshal.h \ gs-debug.c \ gs-debug.h \ $(NULL) test_watcher_LDADD = \ $(CINNAMON_SCREENSAVER_LIBS) \ $(SAVER_LIBS) \ $(NULL) test_window_SOURCES = \ test-window.c \ gs-window.h \ gs-window-x11.c \ gs-grab-x11.c \ gs-grab.h \ gs-marshal.c \ gs-marshal.h \ gs-debug.c \ gs-debug.h \ subprocs.c \ subprocs.h \ $(NULL) test_window_LDADD = \ $(CINNAMON_SCREENSAVER_LIBS) \ $(SAVER_LIBS) \ $(NULL) cinnamon_screensaver_dialog_SOURCES = \ cinnamon-screensaver-dialog.c \ gs-lock-plug.c \ gs-lock-plug.h \ gs-debug.c \ gs-debug.h \ setuid.c \ setuid.h \ subprocs.c \ subprocs.h \ gs-auth.h \ $(AUTH_SOURCES) \ $(NULL) cinnamon_screensaver_dialog_LDADD = \ $(CINNAMON_SCREENSAVER_DIALOG_LIBS)\ $(SAVER_LIBS) \ $(AUTH_LIBS) \ $(LIBGNOMEKBDUI_LIBS) \ $(LIBNOTIFY_LIBS) \ $(NULL) BUILT_SOURCES = \ gs-marshal.c \ gs-marshal.h \ $(NULL) gs-marshal.c: gs-marshal.list echo "#include \"gs-marshal.h\"" > $@ && \ @GLIB_GENMARSHAL@ $< --prefix=gs_marshal --body >> $@ gs-marshal.h: gs-marshal.list @GLIB_GENMARSHAL@ $< --prefix=gs_marshal --header > $@ cinnamon_screensaver_SOURCES = \ bus.h \ cinnamon-screensaver.c \ cinnamon-screensaver.h \ gs-monitor.c \ gs-monitor.h \ gs-watcher-x11.c \ gs-watcher.h \ gs-listener-dbus.c \ gs-listener-dbus.h \ gs-manager.c \ gs-manager.h \ gs-window-x11.c \ gs-window.h \ gs-prefs.c \ gs-prefs.h \ gs-debug.c \ gs-debug.h \ subprocs.c \ subprocs.h \ gs-grab-x11.c \ gs-grab.h \ gs-fade.c \ gs-fade.h \ gnome-datetime-source.c \ gnome-datetime-source.h \ gnome-wall-clock.c \ gnome-wall-clock.h \ $(BUILT_SOURCES) \ $(NULL) cinnamon_screensaver_LDADD = \ $(CINNAMON_SCREENSAVER_LIBS) \ $(SAVER_LIBS) \ $(LOGIND_LIBS) \ $(NULL) cinnamon_screensaver_LDFLAGS = -export-dynamic EXTRA_DIST = \ debug-screensaver.sh \ gs-marshal.list \ cinnamon-screensaver.desktop.in \ $(NULL) CLEANFILES = \ $(desktop_DATA) \ cinnamon-screensaver.desktop.in \ $(BUILT_SOURCES) MAINTAINERCLEANFILES = \ *~ \ Makefile.in install-exec-hook: @if [ "x@NEED_SETUID@" = "xyes" ]; then \ echo "***" ; \ echo "*** Warning: cinnamon-screensaver has been compiled with support for" ; \ echo "*** bsdauth(3) and must be installed as a setuid root" ; \ echo "*** program in order for locking to work. To do this, you" ; \ echo "*** must run:" ; \ echo "***" ; \ echo "*** chown root $(DESTDIR)$(libexecdir)/cinnamon-screensaver-dialog" ; \ echo "*** chmod +s $(DESTDIR)$(libexecdir)/cinnamon-screensaver-dialog" ; \ echo "***" ; \ echo "*** For now, it will be installed non-setuid, which" ; \ echo "*** means that locking might not work." ; \ echo "***" ; \ fi -include $(top_srcdir)/git.mk cinnamon-screensaver-2.8.0/src/cinnamon-screensaver.c0000664000175000017500000000650112610211212021626 0ustar fabiofabio/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "cinnamon-screensaver.h" #include "gs-monitor.h" #include "gs-debug.h" void cinnamon_screensaver_quit (void) { gtk_main_quit (); } int main (int argc, char **argv) { GSMonitor *monitor; GError *error = NULL; static gboolean show_version = FALSE; static gboolean no_daemon = TRUE; static gboolean debug = FALSE; static GOptionEntry entries [] = { { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &no_daemon, N_("Don't become a daemon"), NULL }, { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL }, { NULL } }; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif if (! gtk_init_with_args (&argc, &argv, NULL, entries, NULL, &error)) { if (error) { g_warning ("%s", error->message); g_error_free (error); } else { g_warning ("Unable to initialize GTK+"); } exit (1); } if (show_version) { g_print ("%s %s\n", argv [0], VERSION); exit (1); } gs_debug_init (debug, FALSE); gs_debug ("initializing cinnamon-screensaver %s", VERSION); monitor = gs_monitor_new (); if (monitor == NULL) { exit (1); } error = NULL; if (! gs_monitor_start (monitor, &error)) { if (error) { g_warning ("%s", error->message); g_error_free (error); } else { g_warning ("Unable to start screensaver"); } exit (1); } gtk_main (); g_object_unref (monitor); gs_debug ("cinnamon-screensaver finished"); gs_debug_shutdown (); return 0; } cinnamon-screensaver-2.8.0/src/gs-manager.h0000664000175000017500000001067612610211212017544 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __GS_MANAGER_H #define __GS_MANAGER_H #include "gs-prefs.h" G_BEGIN_DECLS #define GS_TYPE_MANAGER (gs_manager_get_type ()) #define GS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_MANAGER, GSManager)) #define GS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_MANAGER, GSManagerClass)) #define GS_IS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_MANAGER)) #define GS_IS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_MANAGER)) #define GS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_MANAGER, GSManagerClass)) typedef struct GSManagerPrivate GSManagerPrivate; typedef struct { GObject parent; GSManagerPrivate *priv; } GSManager; typedef struct { GObjectClass parent_class; void (* activated) (GSManager *manager); void (* deactivated) (GSManager *manager); void (* auth_request_begin) (GSManager *manager); void (* auth_request_end) (GSManager *manager); } GSManagerClass; GType gs_manager_get_type (void); GSManager * gs_manager_new (void); gboolean gs_manager_set_active (GSManager *manager, gboolean active); gboolean gs_manager_get_active (GSManager *manager); void gs_manager_set_away_message (GSManager *manager, const char *message); void gs_manager_get_lock_active (GSManager *manager, gboolean *lock_active); void gs_manager_set_lock_active (GSManager *manager, gboolean lock_active); void gs_manager_set_keyboard_enabled (GSManager *manager, gboolean enabled); void gs_manager_set_keyboard_command (GSManager *manager, const char *command); void gs_manager_get_lock_enabled (GSManager *manager, gboolean *lock_enabled); void gs_manager_set_lock_enabled (GSManager *manager, gboolean lock_enabled); void gs_manager_set_lock_timeout (GSManager *manager, glong lock_timeout); void gs_manager_set_logout_enabled (GSManager *manager, gboolean logout_enabled); void gs_manager_set_user_switch_enabled (GSManager *manager, gboolean user_switch_enabled); void gs_manager_set_logout_timeout (GSManager *manager, glong logout_timeout); void gs_manager_set_logout_command (GSManager *manager, const char *command); void gs_manager_set_themes (GSManager *manager, GSList *themes); void gs_manager_show_message (GSManager *manager, const char *summary, const char *body, const char *icon); gboolean gs_manager_request_unlock (GSManager *manager); void gs_manager_cancel_unlock_request (GSManager *manager); G_END_DECLS #endif /* __GS_MANAGER_H */ cinnamon-screensaver-2.8.0/src/cinnamon-screensaver-command.c0000664000175000017500000003426212610211212023247 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA * 02110-1335, USA. * * Authors: William Jon McCann * */ #include "config.h" #include #include #include #include #include #include "bus.h" static gboolean do_quit = FALSE; static gboolean do_lock = FALSE; static gboolean do_activate = FALSE; static gboolean do_deactivate = FALSE; static gboolean do_version = FALSE; static gboolean do_query = FALSE; static gboolean do_time = FALSE; static gchar *away_message = ""; static GOptionEntry entries [] = { { "exit", 0, 0, G_OPTION_ARG_NONE, &do_quit, N_("Causes the screensaver to exit gracefully"), NULL }, { "query", 'q', 0, G_OPTION_ARG_NONE, &do_query, N_("Query the state of the screensaver"), NULL }, { "time", 't', 0, G_OPTION_ARG_NONE, &do_time, N_("Query the length of time the screensaver has been active"), NULL }, { "lock", 'l', 0, G_OPTION_ARG_NONE, &do_lock, N_("Tells the running screensaver process to lock the screen immediately"), NULL }, { "activate", 'a', 0, G_OPTION_ARG_NONE, &do_activate, N_("Turn the screensaver on (blank the screen)"), NULL }, { "deactivate", 'd', 0, G_OPTION_ARG_NONE, &do_deactivate, N_("If the screensaver is active then deactivate it (un-blank the screen)"), NULL }, { "version", 'V', 0, G_OPTION_ARG_NONE, &do_version, N_("Version of this application"), NULL }, { "away-message", 'm', 0, G_OPTION_ARG_STRING, &away_message, N_("Message to be displayed in lock screen"), NULL}, { NULL } }; static GMainLoop *loop = NULL; static GDBusMessage * screensaver_send_message_bool (GDBusConnection *connection, const char *name, gboolean value) { GDBusMessage *message, *reply; GError *error; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); message = g_dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name); if (message == NULL) { g_warning ("Couldn't allocate the dbus message"); return NULL; } g_dbus_message_set_body (message, g_variant_new ("(b)", value)); error = NULL; reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if (error != NULL) { g_warning ("unable to send message: %s", error->message); g_clear_error (&error); } g_dbus_connection_flush_sync (connection, NULL, &error); if (error != NULL) { g_warning ("unable to flush message queue: %s", error->message); g_clear_error (&error); } g_object_unref (message); return reply; } static GDBusMessage * screensaver_send_message_string (GDBusConnection *connection, const char *name, gchar *value) { GDBusMessage *message, *reply; GError *error; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); message = g_dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name); if (message == NULL) { g_warning ("Couldn't allocate the dbus message"); return NULL; } g_dbus_message_set_body (message, g_variant_new ("(s)", value)); error = NULL; reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if (error != NULL) { g_warning ("unable to send message: %s", error->message); g_clear_error (&error); } g_dbus_connection_flush_sync (connection, NULL, &error); if (error != NULL) { g_warning ("unable to flush message queue: %s", error->message); g_clear_error (&error); } g_object_unref (message); return reply; } static GDBusMessage * screensaver_send_message_void (GDBusConnection *connection, const char *name, gboolean expect_reply) { GDBusMessage *message, *reply; GError *error; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); message = g_dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name); if (message == NULL) { g_warning ("Couldn't allocate the dbus message"); return NULL; } error = NULL; if (! expect_reply) { reply = NULL; g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error); } else { reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); } if (error != NULL) { g_warning ("unable to send message: %s", error->message); g_clear_error (&error); } g_dbus_connection_flush_sync (connection, NULL, &error); if (error != NULL) { g_warning ("unable to flush message queue: %s", error->message); g_clear_error (&error); } g_object_unref (message); return reply; } static gboolean screensaver_is_running (GDBusConnection *connection) { GVariant *reply; gboolean exists = FALSE; g_return_val_if_fail (connection != NULL, FALSE); reply = g_dbus_connection_call_sync (connection, DBUS_SERVICE, DBUS_PATH, DBUS_INTERFACE, "GetNameOwner", g_variant_new ("(s)", GS_SERVICE), NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, NULL); if (reply != NULL) { exists = TRUE; g_variant_unref (reply); } return exists; } static gboolean do_command (GDBusConnection *connection) { GDBusMessage *reply; if (do_quit) { reply = screensaver_send_message_void (connection, "Quit", FALSE); goto done; } if (do_query) { GVariant *body; gboolean v; if (! screensaver_is_running (connection)) { g_message ("Screensaver is not running!"); goto done; } reply = screensaver_send_message_void (connection, "GetActive", TRUE); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } body = g_dbus_message_get_body (reply); g_variant_get (body, "(b)", &v); g_object_unref (reply); if (v) { g_print (_("The screensaver is active\n")); } else { g_print (_("The screensaver is inactive\n")); } } if (do_time) { GVariant *body; gboolean v; gint32 t; reply = screensaver_send_message_void (connection, "GetActive", TRUE); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } body = g_dbus_message_get_body (reply); g_variant_get (body, "(b)", &v); g_object_unref (reply); if (v) { reply = screensaver_send_message_void (connection, "GetActiveTime", TRUE); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } body = g_dbus_message_get_body (reply); g_variant_get (body, "(u)", &t); g_object_unref (reply); g_print (ngettext ("The screensaver has been active for %d second.\n", "The screensaver has been active for %d seconds.\n", t), t); } else { g_print (_("The screensaver is not currently active.\n")); } } if (do_lock) { reply = screensaver_send_message_string (connection, "Lock", away_message); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } g_object_unref (reply); } if (do_activate) { reply = screensaver_send_message_bool (connection, "SetActive", TRUE); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } g_object_unref (reply); } if (do_deactivate) { reply = screensaver_send_message_bool (connection, "SetActive", FALSE); if (reply == NULL) { g_message ("Did not receive a reply from the screensaver."); goto done; } g_object_unref (reply); } done: g_main_loop_quit (loop); return FALSE; } int main (int argc, char **argv) { GDBusConnection *connection; GOptionContext *context; gboolean retval; GError *error; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, "/usr/share/locale"); # ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); # endif textdomain (GETTEXT_PACKAGE); #endif g_set_prgname (argv[0]); if (setlocale (LC_ALL, "") == NULL) { g_warning ("Locale not understood by C library, internationalization will not work\n"); } error = NULL; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); retval = g_option_context_parse (context, &argc, &argv, &error); g_option_context_free (context); if (! retval) { g_warning ("%s", error->message); g_error_free (error); return EXIT_FAILURE; } if (do_version) { g_print ("%s %s\n", argv [0], VERSION); return EXIT_SUCCESS; } connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (connection == NULL) { g_message ("Failed to get session bus: %s", error->message); g_error_free (error); return EXIT_FAILURE; } g_idle_add ((GSourceFunc) do_command, connection); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); g_object_unref (connection); return EXIT_SUCCESS; } cinnamon-screensaver-2.8.0/src/gnome-datetime-source.h0000664000175000017500000000223312610211212021706 0ustar fabiofabio/* gnome-rr.h * * Copyright 2011, Red Hat, Inc. * * This file is part of the Gnome Library. * * The Gnome Library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The Gnome Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, * Boston, MA 02110-1335, USA. * * Author: Colin Walters */ #ifndef GNOME_DATETIME_SOURCE_H #define GNOME_DATETIME_SOURCE_H #include GSource *_gnome_datetime_source_new (GDateTime *now, GDateTime *expiry, gboolean cancel_on_set); #endif /* GNOME_DATETIME_SOURCE_H */ cinnamon-screensaver-2.8.0/src/cinnamon-screensaver.h0000664000175000017500000000204612610211212021633 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2004-2005 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Authors: William Jon McCann * */ #ifndef __CINNAMON_SCREENSAVER_H #define __CINNAMON_SCREENSAVER_H G_BEGIN_DECLS void cinnamon_screensaver_quit (void); G_END_DECLS #endif cinnamon-screensaver-2.8.0/src/gnome-wall-clock.h0000664000175000017500000000424612610211212020652 0ustar fabiofabio/* gnome-tz-monitor.h - fade window background between two surfaces Copyright 2008, Red Hat, Inc. Copyright 2011, Red Hat, Inc. This file is part of the Gnome Library. The Gnome Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The Gnome Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the Gnome Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. Author: Colin Walters */ #ifndef __GNOME_WALL_CLOCK_H__ #define __GNOME_WALL_CLOCK_H__ #include G_BEGIN_DECLS #define GNOME_TYPE_WALL_CLOCK (gnome_wall_clock_get_type ()) #define GNOME_WALL_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_WALL_CLOCK, GnomeWallClock)) #define GNOME_WALL_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_WALL_CLOCK, GnomeWallClockClass)) #define GNOME_IS_WALL_CLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_WALL_CLOCK)) #define GNOME_IS_WALL_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_WALL_CLOCK)) #define GNOME_WALL_CLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_WALL_CLOCK, GnomeWallClockClass)) typedef struct _GnomeWallClockPrivate GnomeWallClockPrivate; typedef struct _GnomeWallClock GnomeWallClock; typedef struct _GnomeWallClockClass GnomeWallClockClass; struct _GnomeWallClock { GObject parent_object; GnomeWallClockPrivate *priv; }; struct _GnomeWallClockClass { GObjectClass parent_class; }; GType gnome_wall_clock_get_type (void); const char * gnome_wall_clock_get_clock (GnomeWallClock *clock); G_END_DECLS #endif cinnamon-screensaver-2.8.0/cinnamon-screensaver.pot0000664000175000017500000001001012610211212021405 0ustar fabiofabio# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-10-16 16:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: src/cinnamon-screensaver-command.c:274 msgid "The screensaver is active\n" msgstr "" #: src/cinnamon-screensaver-command.c:276 msgid "The screensaver is inactive\n" msgstr "" #: src/cinnamon-screensaver-command.c:306 #, c-format msgid "The screensaver has been active for %d second.\n" msgid_plural "The screensaver has been active for %d seconds.\n" msgstr[0] "" msgstr[1] "" #: src/cinnamon-screensaver-command.c:308 msgid "The screensaver is not currently active.\n" msgstr "" #: src/cinnamon-screensaver-dialog.c:173 src/cinnamon-screensaver-dialog.c:174 #: src/cinnamon-screensaver-dialog.c:175 src/gs-auth-pam.c:699 msgid "Username:" msgstr "" #: src/cinnamon-screensaver-dialog.c:176 src/cinnamon-screensaver-dialog.c:177 #: src/gs-auth-pam.c:166 msgid "Password:" msgstr "" #: src/cinnamon-screensaver-dialog.c:178 msgid "You are required to change your password immediately (password aged)" msgstr "" #: src/cinnamon-screensaver-dialog.c:179 msgid "You are required to change your password immediately (root enforced)" msgstr "" #: src/cinnamon-screensaver-dialog.c:180 msgid "Your account has expired; please contact your system administrator" msgstr "" #: src/cinnamon-screensaver-dialog.c:181 msgid "No password supplied" msgstr "" #: src/cinnamon-screensaver-dialog.c:182 msgid "Password unchanged" msgstr "" #: src/cinnamon-screensaver-dialog.c:183 msgid "Cannot get username" msgstr "" #: src/cinnamon-screensaver-dialog.c:184 msgid "Retype new Unix password:" msgstr "" #: src/cinnamon-screensaver-dialog.c:185 msgid "Enter new Unix password:" msgstr "" #: src/cinnamon-screensaver-dialog.c:186 msgid "(current) Unix password:" msgstr "" #: src/cinnamon-screensaver-dialog.c:187 msgid "Error while changing NIS password." msgstr "" #: src/cinnamon-screensaver-dialog.c:188 msgid "You must choose a longer password" msgstr "" #: src/cinnamon-screensaver-dialog.c:189 msgid "Password has been already used. Choose another." msgstr "" #: src/cinnamon-screensaver-dialog.c:190 msgid "You must wait longer to change your password" msgstr "" #: src/cinnamon-screensaver-dialog.c:191 msgid "Sorry, passwords do not match" msgstr "" #: src/cinnamon-screensaver-dialog.c:257 msgid "Checking…" msgstr "" #: src/cinnamon-screensaver-dialog.c:299 src/gs-auth-pam.c:457 msgid "Authentication failed." msgstr "" #: src/gnome-wall-clock.c:223 msgid "%A, %B %e" msgstr "" #: src/gs-auth-pam.c:397 #, c-format msgid "Unable to establish service %s: %s\n" msgstr "" #: src/gs-auth-pam.c:423 #, c-format msgid "Can't set PAM_TTY=%s" msgstr "" #: src/gs-auth-pam.c:455 msgid "Incorrect password." msgstr "" #: src/gs-auth-pam.c:471 msgid "Not permitted to gain access at this time." msgstr "" #: src/gs-auth-pam.c:477 msgid "No longer permitted to access the system." msgstr "" #: src/gs-listener-dbus.c:1302 msgid "failed to register with the message bus" msgstr "" #: src/gs-listener-dbus.c:1312 msgid "not connected to the message bus" msgstr "" #: src/gs-listener-dbus.c:1321 src/gs-listener-dbus.c:1351 msgid "screensaver already running in this session" msgstr "" #: src/gs-lock-plug.c:323 msgid "Time has expired." msgstr "" #: src/gs-lock-plug.c:354 msgid "You have the Caps Lock key on." msgstr "" #: src/gs-lock-plug.c:1445 msgid "S_witch User…" msgstr "" #: src/gs-lock-plug.c:1454 msgid "Log _Out" msgstr "" #: src/gs-lock-plug.c:1461 msgid "_Unlock" msgstr "" #: src/gs-lock-plug.c:1587 msgid "_Password:" msgstr "" cinnamon-screensaver-2.8.0/makepot0000775000175000017500000000015312610211212016136 0ustar fabiofabio#!/bin/bash xgettext --language=C --from-code=UTF-8 --keyword=_ --output=cinnamon-screensaver.pot src/*.c cinnamon-screensaver-2.8.0/ChangeLog0000664000175000017500000000000012610211212016311 0ustar fabiofabiocinnamon-screensaver-2.8.0/COPYING.LIB0000664000175000017500000006126212610211212016220 0ustar fabiofabio GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! cinnamon-screensaver-2.8.0/autogen.sh0000775000175000017500000000107312610211212016553 0ustar fabiofabio#!/bin/bash # Run this to generate all the initial makefiles, etc. srcdir=`dirname $0` test -z "$srcdir" && srcdir=. PKG_NAME="cinnamon-screensaver" (test -f $srcdir/configure.ac \ && test -d $srcdir/src) || { echo -n "**Error**: Directory"\`$srcdir\'" does not look like the" echo " top-level cinnamon-screensaver directory" exit 1 } which gnome-autogen.sh || { echo "You need to install gnome-common from GNOME Git (or from" echo "your OS vendor's package manager)." exit 1 } USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.shcinnamon-screensaver-2.8.0/HACKING0000664000175000017500000000062112610211212015537 0ustar fabiofabioHACKING ======= Cinnamon-Screensaver is normally build using dpkg. If using Linux Mint, Ubuntu, or any other member of the Debian family, install the `devscripts` package with `sudo apt-get install devscripts`. Once you have devscripts, run `debuild -us -uc` to build cinnamon-screensaver (or any other cinnamon package) and `sudo dpkg -i ../cinnamon-screensaver_{version}_{arch}.deb` to install. cinnamon-screensaver-2.8.0/data/0000775000175000017500000000000012610211212015462 5ustar fabiofabiocinnamon-screensaver-2.8.0/data/cinnamon-screensaver.xml.in0000664000175000017500000000132212610211212022727 0ustar fabiofabio Cinnamon Screensaver @VERSION@ Documentation Version @VERSION@ 6 June, 2006 William Jon McCann
mccann@jhu.edu
cinnamon-screensaver-2.8.0/data/screensavers/0000775000175000017500000000000012610211212020165 5ustar fabiofabiocinnamon-screensaver-2.8.0/data/screensavers/xscreensaver@cinnamon.org/0000775000175000017500000000000012610211212025306 5ustar fabiofabiocinnamon-screensaver-2.8.0/data/screensavers/xscreensaver@cinnamon.org/main0000775000175000017500000000417612610211212026170 0ustar fabiofabio#!/usr/bin/env python from gi.repository import Gtk, Gdk, GdkX11, Gio, GLib import sys import subprocess import shlex import argparse import syslog parser = argparse.ArgumentParser(description="XScreenSaver chainloader") parser.add_argument("--standalone", action="store_true", help="run as standalone window instead of embedded in screensaver", dest="standalone") parser.add_argument("--dir", action="store", help="directory to search for xscreensaver hacks") parser.add_argument("--hack", action="store", help="xscreensaver hack to load") args = parser.parse_args() hackCalled = False def loadHack (plug, data): global hackCalled if hackCalled: return xid = str(plug.get_window().get_xid()) directories = ["/usr/lib/xscreensaver/", "/usr/libexec/xscreensaver/", "/usr/local/lib/xscreensaver/", "/usr/local/libexec/xscreensaver/"] if args.dir: directories.append(args.dir) if (args.hack): hack = args.hack else: settings = Gio.Settings.new("org.cinnamon.desktop.screensaver") hack = settings.get_string("xscreensaver-hack") success = False for direc in directories: try: path = shlex.split(direc + hack) path.append("-window-id") path.append(xid) GLib.spawn_async(path) success = True hackCalled = True break; except: pass if not success: syslog.syslog("cinnamon-screensaver: Screensaver '%s' not found" % hack) color = Gdk.RGBA() color.red = 0 color.green = 0 color.blue = 0 color.alpha = 1 label = Gtk.Label() label.override_background_color(Gtk.StateFlags.NORMAL, color) label.show() plug.add(label) if __name__ == "__main__": if args.standalone: plug = Gtk.Window() else: plug = Gtk.Plug() plug.show_all() plug.connect("delete-event", Gtk.main_quit) xid = str(plug.get_window().get_xid()) print("WINDOW ID=" + xid) sys.stdout.flush() plug.connect("draw", loadHack) Gtk.main() cinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/0000775000175000017500000000000012610211212024063 5ustar fabiofabiocinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/webkit-stars@cinnamon.org/0000775000175000017500000000000012610211212031113 5ustar fabiofabio././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootcinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/webkit-stars@cinnamon.org/index.htmlcinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/webkit-stars@cinnamon.org/index.htm0000664000175000017500000000302112610211212032730 0ustar fabiofabio ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootcinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/webkit-stars@cinnamon.org/metadata.jsoncinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/webkit-stars@cinnamon.org/metadata.0000664000175000017500000000017212610211212032674 0ustar fabiofabio{ "uuid": "webkit-stars@cinnamon.org", "name": "Stars", "description": "Stars flying all over the screen!" } cinnamon-screensaver-2.8.0/data/screensavers/webkit@cinnamon.org/main0000775000175000017500000000250512610211212024737 0ustar fabiofabio#!/usr/bin/env python from gi.repository import Gtk, Gdk, GdkX11, WebKit2, Gio import sys import os import argparse parser = argparse.ArgumentParser(description="XScreenSaver chainloader") parser.add_argument("--standalone", action="store_true", help="run as standalone window instead of embedded in screensaver", dest="standalone") parser.add_argument("--plugin", action="store", help="plugin to load") args = parser.parse_args() hackCalled = False if __name__ == "__main__": if args.standalone: plug = Gtk.Window() else: plug = Gtk.Plug() plug.show_all() plug.connect("delete-event", Gtk.main_quit) xid = str(plug.get_window().get_xid()) print("WINDOW ID=" + xid) sys.stdout.flush() webkit = WebKit2.WebView() settings = Gio.Settings("org.cinnamon.desktop.screensaver") if (args.plugin): plugin = args.plugin else: plugin = settings.get_string("screensaver-webkit-theme") uri = os.path.join(os.path.dirname(os.path.realpath(__file__)), plugin, "index.html") if os.path.isfile(uri): webkit.load_uri("file://" + uri) else: uri2 = os.path.join(os.getenv("HOME"), ".local/share/cinnamon-screensaver/screensavers/webkit", plugin, "index.html") webkit.load_uri("file://" + uri2) webkit.show() plug.add (webkit) Gtk.main() cinnamon-screensaver-2.8.0/data/screensavers/Makefile.in0000664000175000017500000000052612610211212022235 0ustar fabiofabioprefix = @prefix@ datadir = @datadir@ pkgdatadir = $(datadir)/@PACKAGE@ all: clean: distclean: install: mkdir -p $(DESTDIR)$(pkgdatadir)/screensavers/; \ find -mindepth 1 -maxdepth 1 -type d -exec cp -R {} $(DESTDIR)$(pkgdatadir)/screensavers/ \; uninstall: find -mindepth 1 -type f -exec rm $(DESTDIR)$(pkgdatadir)/screensavers/{} \; cinnamon-screensaver-2.8.0/data/org.cinnamon.ScreenSaver.service.in0000664000175000017500000000014612610211212024261 0ustar fabiofabio[D-BUS Service] Name=org.cinnamon.ScreenSaver Exec=@EXPANDED_BINDIR@/cinnamon-screensaver --no-daemon cinnamon-screensaver-2.8.0/data/cinnamon-screensaver.xml0000664000175000017500000000131212610211212022321 0ustar fabiofabio Cinnamon Screensaver 1.8.0 Documentation Version 1.8.0 6 June, 2006 William Jon McCann
mccann@jhu.edu
cinnamon-screensaver-2.8.0/data/cinnamon-screensaver0000664000175000017500000000063512610211212021531 0ustar fabiofabio#%PAM-1.0 # Fedora Core auth include system-auth auth optional pam_gnome_keyring.so account include system-auth password include system-auth session include system-auth # SuSE/Novell #auth include common-auth #auth optional pam_gnome_keyring.so #account include common-account #password include common-password #session include common-session cinnamon-screensaver-2.8.0/data/cinnamon-screensaver.10000664000175000017500000000257312610211212021673 0ustar fabiofabio.\" Copyright (C) 2007 Sven Arvidsson .\" .\" This is free software; you may redistribute it and/or modify .\" it under the terms of the GNU General Public License as .\" published by the Free Software Foundation; either version 2, .\" or (at your option) any later version. .\" .\" This is distributed in the hope that it will be useful, but .\" WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\"You should have received a copy of the GNU General Public License along .\"with this program; if not, write to the Free Software Foundation, Inc., .\"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. .TH cinnamon-screensaver 1 "2007\-09\-27" "Cinnamon" .SH NAME cinnamon-screensaver \- screen saver and locker .SH SYNOPSIS .B cinnamon-screensaver .RI [ OPTIONS... ] .SH DESCRIPTION Cinnamon Screensaver is the default screen saver and locker in a GNOME desktop. It is designed with simplicity and security in mind. .SH OPTIONS .TP .B \-\-no\-daemon Don't become a daemon .TP .B \-\-debug Enable debugging code .P This program also accepts the standard GTK options. .SH AUTHORS .B cinnamon-screensaver is written by William Jon McCann . .P This manual page was written by Sven Arvidsson . .SH SEE ALSO .BR "gtk-options" (7) cinnamon-screensaver-2.8.0/data/cinnamon-screensaver-command.10000664000175000017500000000337212610211212023305 0ustar fabiofabio.\" Copyright (C) 2007 Sven Arvidsson .\" .\" This is free software; you may redistribute it and/or modify .\" it under the terms of the GNU General Public License as .\" published by the Free Software Foundation; either version 2, .\" or (at your option) any later version. .\" .\" This is distributed in the hope that it will be useful, but .\" WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\"You should have received a copy of the GNU General Public License along .\"with this program; if not, write to the Free Software Foundation, Inc., .\"51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. .TH cinnamon-screensaver-command 1 "2007\-09\-27" "CINNAMON" .SH NAME cinnamon-screensaver-command \- controls Cinnamon screensaver .SH SYNOPSIS .B cinnamon-screensaver-command .RI [ OPTION... ] .SH DESCRIPTION cinnamon-screensaver-command is a tool for controlling an already running instance of cinnamon-screensaver. .SH OPTIONS .TP .B \-\-exit Causes the screensaver to exit gracefully .TP .B \-q, \-\-query Query the state of the screensaver .TP .B \-t, \-\-time Query the length of time the screensaver has been active .TP .B \-l, \-\-lock Tells the running screensaver process to lock the screen immediately .TP .B \-a, \-\-activate Turn the screensaver on (blank the screen) .TP .B \-d, \-\-deactivate If the screensaver is active then deactivate it (un-blank the screen) .TP .B \-V, \-\-version Version of this application .SH AUTHORS .B cinnamon-screensaver-command is written by William Jon McCann . .P This manual page was written by Sven Arvidsson . .SH SEE ALSO .BR "cinnamon-screensaver" (1) cinnamon-screensaver-2.8.0/data/Makefile.am0000664000175000017500000000424512610211212017523 0ustar fabiofabioNULL = man_MANS = \ cinnamon-screensaver.1 \ cinnamon-screensaver-command.1 \ $(NULL) @INTLTOOL_XML_NOMERGE_RULE@ dbussessionservicedir = $(DBUS_SESSION_SERVICE_DIR) dbussessionservice_DATA = org.cinnamon.ScreenSaver.service SUBDIRS = screensavers EXTRA_DIST = \ $(man_MANS) \ cinnamon-screensaver \ org.cinnamon.ScreenSaver.service.in\ $(NULL) DISTCLEANFILES = \ $(desktop_DATA) \ $(NULL) MAINTAINERCLEANFILES = \ *~ \ Makefile.in install-data-hook: @system=`uname`; \ if test -f /usr/include/security/pam_appl.h; then \ if test '!' -d $(DESTDIR)$(PAM_PREFIX)/pam.d; then \ $(mkinstalldirs) $(DESTDIR)$(PAM_PREFIX)/pam.d; \ chmod 755 $(DESTDIR)$(PAM_PREFIX)/pam.d; \ fi; \ if test $$system = Linux; then \ if test '!' -f $(DESTDIR)$(PAM_PREFIX)/pam.d/cinnamon-screensaver; then \ $(INSTALL_DATA) cinnamon-screensaver $(DESTDIR)$(PAM_PREFIX)/pam.d/cinnamon-screensaver; \ fi; \ if test "x$(PAM_PREFIX)" != "x/etc/pam.d"; then \ echo "***" ; \ echo "*** Warning: cinnamon-screensaver has been compiled with support for" ; \ echo "*** Pluggable Authentication Modules (PAM). However, you may need to" ; \ echo "*** manually install $(PAM_PREFIX)/pam.d/cinnamon-screensaver" ; \ echo "*** to /etc/pam.d/cinnamon-screensaver. Otherwise, unlocking might" ; \ echo "*** not work." ; \ echo "***" ; \ echo "*** Note: If you are using SuSE/Novell you may have to modify this file." ; \ echo "***" ; \ fi; \ fi; \ if test $$system = SunOS; then \ echo "***" ; \ echo "*** Warning: cinnamon-screensaver has been compiled with support for" ; \ echo "*** Pluggable Authentication Modules (PAM). However, you" ; \ echo "*** need to manually add authentication for cinnamon-screensaver in" ; \ echo "*** $(PAM_PREFIX)/pam.conf or /etc/pam.conf." ; \ echo "*** Otherwise, unlocking might not work." ; \ echo "***" ; \ fi; \ fi -include $(top_srcdir)/git.mk cinnamon-screensaver-2.8.0/AUTHORS0000664000175000017500000000004412610211212015617 0ustar fabiofabioWilliam Jon McCann cinnamon-screensaver-2.8.0/README0000664000175000017500000000254212610211212015434 0ustar fabiofabiocinnamon-screensaver ================= cinnamon-screensaver is a screen saver and locker that aims to have simple, sane, secure defaults and be well integrated with the desktop. It is designed to support: * the ability to lock down configuration settings * translation into many languages * user switching Known Issues ============ Installation ============ See the file 'INSTALL' How to report bugs ================== Bugs should be reported to the GNOME bug tracking system: http://bugzilla.gnome.org/simple-bug-guide.cgi?product=cinnamon-screensaver You will need to create an account if you don't have one already. Please read the following page on how to prepare a useful bug report: http://bugzilla.gnome.org/bug-HOWTO.html In the bug report please include information about your system, if possible: - What operating system and version - What version of gnome-screenaver The output of the "cinnamon-screensaver-command --version" command. How to submit patches ===================== Patches should also be submitted to bugzilla.gnome.org. If the patch fixes an existing bug, add the patch as an attachment to that bug report. Otherwise, enter a new bug report that describes the patch, and attach the patch to that bug report. Patches should be in unified diff form. (The -u -p options to GNU diff.) cinnamon-screensaver-2.8.0/Makefile.am0000664000175000017500000000144012610211212016604 0ustar fabiofabio# This file will be processed with automake-1.7 to create Makefile.in AUTOMAKE_OPTIONS = 1.7 NULL = SUBDIRS = \ src \ po \ data \ files \ $(NULL) EXTRA_DIST = \ COPYING \ COPYING.LIB \ AUTHORS \ INSTALL \ README \ ChangeLog \ NEWS \ HACKING \ intltool-extract.in \ intltool-merge.in \ intltool-update.in \ $(NULL) DISTCLEANFILES = \ intltool-extract \ intltool-merge \ intltool-update \ ./po/.intltool-merge-cache \ $(NULL) MAINTAINERCLEANFILES = \ *~ \ intltool-*.in \ compile \ configure \ INSTALL \ install-sh \ missing \ mkinstalldirs \ config.guess \ ltmain.sh \ config.sub \ depcomp \ Makefile.in \ config.h.* \ aclocal.m4 \ acinclude.m4 \ $(NULL) -include $(top_srcdir)/git.mk cinnamon-screensaver-2.8.0/doc/0000775000175000017500000000000012610211212015316 5ustar fabiofabiocinnamon-screensaver-2.8.0/doc/dbus-interface.html0000664000175000017500000003724612610211212021113 0ustar fabiofabioCinnamon Screensaver 1.8.0 Documentation

Cinnamon Screensaver 1.8.0 Documentation

William Jon McCann

Version 1.8.0


Chapter1.DBUS Interface

This API is currently unstable and is likely to change in the future.

Introduction

Cinnamon Screensaver exposes a DBUS API for programs to obtain information about the screensaver state and to interact with the screensaver in limited ways.

The following constants are used to uniquely refer to the CinnamonScreensaver object when making DBUS method calls:

DBUS Service:org.cinnamon.ScreenSaver
DBUS Object Path:/org.cinnamon.ScreenSaver
DBUS Interface:org.cinnamon.ScreenSaver

Methods

These are the DBUS methods.

Lock

Request that the screen be locked.

DirectionTypeDescription
instringthe away message

Cycle

Request that the screen saver theme be restarted and, if applicable, switch to the next one in the list.

SimulateUserActivity

Simulate user activity. If the screensaver is activated this will attempt to deactivate and authentication will be requested if necessary. If the screensaver is not activated then the idle timers will be reset.

Throttle

Request that running themes while the screensaver is active be blocked until UnThrottle is called or the calling process exits.

DirectionTypeDescription
instringthe application name, e.g. "gnome-power-manager"
instringthe localized reason to inhibit, e.g. "on battery power"
outunsigned integerthe cookie

A cookie is a random, unique, non-zero UINT32 used to identify the throttle request.

UnThrottle

Cancel a previous call to Throttle() identified by the cookie.

DirectionTypeDescription
inunsigned integerthe cookie

SetActive

Request a change in the state of the screensaver. Set to TRUE to request that the screensaver activate. Active means that the screensaver has blanked the screen and may run a graphical theme. This does not necessary mean that the screen is locked.

DirectionTypeDescription
inbooleanTRUE to request activation, FALSE to request deactivation

GetActive

Returns the value of the current state of activity. See SetActive().

DirectionTypeDescription
outbooleanActivation state

GetActiveTime

Returns the number of seconds that the screensaver has been active. Returns zero if the screensaver is not active.

DirectionTypeDescription
outunsigned integerActive time in seconds

GetSessionIdle

Returns the value of the current state of session idleness.

DirectionTypeDescription
outbooleanIf the session is idle

GetSessionIdleTime

Returns the number of seconds that the session has been idle. Returns zero if the session is not idle.

DirectionTypeDescription
outunsigned integerIdle time in seconds

Signals

These are the DBUS signals.

ActiveChanged

See method GetActive().

DirectionTypeDescription
outbooleanReturns the value of the current state of activity.

SessionIdleChanged

See method GetActive().

DirectionTypeDescription
outbooleanReturns the value of the current state of activity.

AuthenticationRequestBegin

Emitted before an authentication request

AuthenticationRequestEnd

Emitted after an authentication request

Examples

You can get the number of seconds the screensaver has been active by running the following:

dbus-send --session \
          --dest=org.cinnamon.ScreenSaver \
          --type=method_call \
          --print-reply \
          --reply-timeout=20000 \
          /org/cinnamon/ScreenSaver \
          org.cinnamon.ScreenSaver.GetSessionIdleTime
    

You can activate the screensaver like so:

dbus-send --session \
          --dest=org.cinnamon.ScreenSaver \
          --type=method_call \
          --print-reply \
          --reply-timeout=20000 \
          /org/cinnamon/ScreenSaver \
          org.cinnamon.ScreenSaver.SetActive \
          boolean:true
    

You can monitor screensaver changes:

dbus-monitor --session \
          "type='signal',interface='org.cinnamon.ScreenSaver'"
    

Or watch for a specific screensaver signal:

dbus-monitor --session \
          "type='signal',interface='org.cinnamon.ScreenSaver',member='SessionIdleChanged'"
    
cinnamon-screensaver-2.8.0/po/0000775000175000017500000000000012610211212015167 5ustar fabiofabiocinnamon-screensaver-2.8.0/po/LINGUAS0000664000175000017500000000006112610211212016211 0ustar fabiofabio# please keep this list sorted alphabetically # cinnamon-screensaver-2.8.0/po/POTFILES.skip0000664000175000017500000000004412610211212017302 0ustar fabiofabiosrc/cinnamon-screensaver.desktop.in cinnamon-screensaver-2.8.0/po/ChangeLog0000664000175000017500000017600512610211212016752 0ustar fabiofabio2009-04-18 Funda Wang * zh_CN.po: Updated zh_CN translation. 2009-04-14 Reşat SABIQ * crh.po: Updated Crimean Tatar (Crimean Turkish) translation. 2009-04-06 Reşat SABIQ * LINGUAS: crh * crh.po: Added Crimean Tatar (Crimean Turkish) translation. 2009-04-05 Takeshi AIHANA * ja.po: Fixed #576532. 2009-03-24 Shankar Prasad * kn.po: Updated Kannada Translation. 2009-03-18 Djihed Afifi * ar.po: Updated Arabic translation by Djihed Afifi. 2009-03-16 Nickolay V. Shmyrev * ru.po: Updated Russian translation. 2009-03-16 Ignacio Casal Quinteiro * gl.po: Updated Galician translation by Suso Baleato. 2009-03-14 Praveen Arimbrathodiyil * ml.po: Updated Malayalam Translation by Abhshek Jacob. 2009-03-14 Rajesh Ranjan * hi.po: Updated Hindi Translation. 2009-03-14 Kenneth Nielsen * da.po: Updated Danish translation by Ask H. Larsen 2009-03-13 Kostas Papadimas * el.po: Updated Greek Translation by Jennie Petoumenou. 2009-03-13 Sandeep Shedmake * mr.po: Updated Marathi Translations. 2009-03-11 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2009-03-10 Jorge Gonzalez * es.po: Updated Spanish translation 2009-03-11 Manoj Kumar Giri * or.po: Updated Oriya Translation. 2009-03-10 I. Felix * ta.po: Tamil Translation updated 2009-03-08 Petr Kovar * cs.po: Updated Czech translation. 2009-03-04 Luca Ferretti * it.po: Updated Italian translation. 2009-03-03 Runa Bhattacharjee * bn_IN.po: Updated Bengali India Translation. 2009-03-02 Manoj Kumar Giri * or.po: Updated Oriya Translation. 2009-03-02 Sweta Kothari * gu.po: Committed Gujarati Translation. 2009-02-28 Yair Hershkovitz * he.po: Updated Hebrew translation. 2009-02-25 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2009-02-25 Takeshi AIHANA * ja.po: Updated Japanese translation. 2009-02-23 Philip Withnall * en_GB.po: Updated British English translation. 2009-02-23 Gabor Kelemen * hu.po: Translation updated. 2009-02-21 Claude Paroz * fr.po: Updated French translation. 2009-02-21 Baris Cicek * tr.po: Updated Turkish translation 2009-02-21 Christian Kirbach * de.po: Updated German translation by Wolfgang Stöggl. 2009-02-17 Gil Forcada * ca.po: Updated Catalan translation. 2009-02-17 Chao-Hsiung Liao * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). * zh_TW.po: Updated Traditional Chinese translation(Taiwan). 2009-02-15 Duarte Loreto * pt.po: Updated Portuguese translation. 2009-02-14 Jorge Gonzalez * es.po: Updated Spanish translation, fixes bug #569457 2009-02-14 Gabor Kelemen * hu.po: Translation updated. 2009-02-14 Wouter Bolsterlee * nl.po: Updated Dutch translation by Wouter Bolsterlee. 2009-02-11 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation. 2009-02-11 Gil Forcada * ast.po: Added Asturian translation on behalf of Mikel González. 2009-02-11 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2009-02-11 Theppitak Karoonboonyanan * th.po: Updated Thai translation. >>>>>>> .r1619 2009-02-06 Chao-Hsiung Liao * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). * zh_TW.po: Updated Traditional Chinese translation(Taiwan). 2009-02-06 Clytie Siddall * vi.po: Updated Vietnamese translation. 2009-02-05 Sweta Kothari * gu.po: Committed Gujarati Translation. 2009-02-03 Tomasz Dominikowski * pl.po: Updated Polish translation 2009-02-02 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2009-01-28 Changwoo Ryu * ko.po: Updated Korean translation. 2009-01-27 Ilkka Tuohela * fi.po: Updated Finnish translation. 2009-01-26 Jonh Wendell * pt_BR.po: Updated translation by André Gondim. 2009-01-25 Raivis Dejus * lv.po: Updated Latvian translation. 2009-01-22 Daniel Nylander * sv.po: Updated Swedish translation. 2009-01-20 Jorge Gonzalez * es.po: Updated Spanish translation. 2008-10-23 Andre Klapper * LINGUAS: Added ast. * ast.po: Added Asturian translation on behalf of Mikel González. 2008-10-19 Djihed Afifi * ar.po: Updated Arabic Translation by Djihed Afifi. 2008-10-11 Ihar Hrachyshka * be@latin.po: Updated Belarusian Latin translation by Ihar Hračyška. 2008-09-27 Leonardo Ferreira Fontenelle * pt_BR.po: Removed obsolete translations because of bug #549898. 2008-09-23 Pema Geyleg * dz.po: Updated Dzongkha Translation 2008-09-21 Kenneth Nielsen * da.po: Updated Danish translation by Kenneth Nielsen 2008-09-21 Wadim Dziedzic * pl.po: Updated Polish translation 2008-09-20 Mugurel Tudor * ro.po: Updated Romanian translation by Mişu Moldovan 2008-09-20 Goran Rakić * sr.po, sr@latin.po: Updated Serbian Translation. 2008-09-18 Runa Bhattacharjee * bn_IN.po: Updated Bengali India Translation 2008-09-18 Djihed Afifi * ar.po: Updated Arabic Translation by Djihed Afifi. 2008-09-17 I. Felix * ta.po: Tamil Translation updated 2008-09-16 Gil Forcada * ca.po: Updated Catalan translation. 2008-09-16 Shankar Prasad * kn.po: Updated Kannada Translation. 2008-09-15 Gabor Kelemen * hu.po: Translation updated. 2008-09-15 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-09-14 Priit Laes * et.po: Translation updated by Ivar Smolin 2008-09-13 Leonardo Ferreira Fontenelle * pt_BR.po: Terminology in Brazilian Portuguese translation. 2008-09-13 Praveen Arimbrathodiyil * ml.po: Malayalam translation updated. 2008-09-13 Baris Cicek * tr.po: Updated Turkish Translation. 2008-09-12 Sandeep Shedmake * mr.po: Updated Marathi translations. 2008-09-10 Shankar Prasad * kn.po: Added Kannada translation * LINGUAS: Added Kannada(kn) to the list of Languages 2008-09-10 Luca Ferretti * it.po: Updated Italian translation. 2008-09-09 Robert Sedak * hr.po: Added Croatian translation. * LINGUAS: Added hr 2008-09-08 Changwoo Ryu * ko.po: Updated Korean translation. 2008-09-07 Wouter Bolsterlee * nl.po: Updated Dutch translation by Wouter Bolsterlee. 2008-09-06 Philip Withnall * en_GB.po: Updated British English translation. 2008-09-05 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2008-09-01 Hendrik Richter * de.po: Updated German translation. 2008-08-30 Seán de Búrca * ga.po: Updated Irish translation. 2008-08-29 Claude Paroz * fr.po: Updated French translation. 2008-08-29 Arangel Angov * mk.po: Updated Macedonian translation. 2008-08-28 Petr Kovar * cs.po: Updated Czech translation. 2008-08-25 Goran Rakic * LINGUAS, sr@latin.po, sr@Latn.po: Conversion from sr@Latn to sr@latin. 2008-08-24 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2008-08-22 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation. 2008-08-20 Takeshi AIHANA * ja.po: Updated Japanese translation. 2008-08-12 Duarte Loreto * pt.po: Updated Portuguese translation. 2008-08-11 Ilkka Tuohela * fi.po: Updated Finnish translation. 2008-08-07 Og Maciel * pt_BR.po: Updated translation by Vladimir Melo. 2008-08-06 Yair Hershkovitz * he.po: Updated Hebrew translation. 2008-08-6 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-08-05 Daniel Nylander * sv.po: Updated Swedish translation. 2008-08-04: Sweta Kothari * gu.po: Updated Gujarati Translation. 2008-08-02 Leonardo Ferreira Fontenelle * pt_BR.po: Terminology fixes by Vladimir Melo. 2008-07-29 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-07-10 Matej Urbančič * sl.po: Updated Slovenian translation. 2008-07-02 Yannig Marchegay * oc.po: Updated Occitan translation. 2008-06-30 Yair Hershkovitz * he.po: Updated Hebrew translation. 2008-06-11 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-06-11 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2008-06-05 Priit Laes * et.po: Translation updated by Ivar Smolin 2008-06-01 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2008-05-25 Clytie Siddall * vi.po: Updated Vietnamese translation. 2008-05-23 Jorge Gonzalez * es.po: Updated Spanish translation 2008-05-22 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-05-19 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-05-14 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2008-05-07 Andre Klapper * LINGUAS: * is.po: Added Icelandic Translation on behalf of Anna Ármannsdóttir 2008-04-21 Alexander Shopov * bg.po: Updated Bulgarian translation by Yavor Doganov 2008-04-04 Eskild Hustvedt * nn.po: Updated Norwegian Nynorsk translation 2008-03-16 Kostas Papadimas * el.po: Updated Greek translation. 2008-03-12 Sunil Mohan Adapa * te.po: Updated Telugu traslation done by Krishna Babu K . 2008-03-11 Andre Klapper * LINGUAS: * ps.po: Added Pashto translation on behalf of Zabeeh Khan (bug #521378). 2008-03-10 Marcel Telka * sk.po: Updated Slovak translation. 2008-03-10 Alexander Nyakhaychyk * be.po: Added Belarusian Translation. * LINGUAS: Added Belarusian Translation. 2008-03-10 Baris Cicek * tr.po: Updated Turkish translation from Deniz Kocak 2008-03-09 Kenneth Nielsen * da.po: Updated Danish translation 2008-03-09 Runa Bhattacharjee * bn_IN.po: Updated Bengali India Translation by Sankarshan Mukhopadhyay 2008-03-09 Gabor Kelemen * hu.po: Translation updated 2008-03-07 Mugurel Tudor *ro.po: Updated Romanian translation by Mişu Moldovan 2008-03-07 Maxim Dziumanenko * uk.po: Update Ukrainian translation. 2008-03-05 Rahul Bhalerao * mr.po: Added Marathi Translations by Sandeep Shedmake. * LINGUAS: Added an entry for Marathi (mr). 2008-03-03 Jorge Gonzalez * es.po: Updated Spanish translation 2008-03-03 Philip Withnall * en_GB.po: Updated British English translation. 2008-03-02 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2008-02-28 Takeshi AIHANA * ja.po: Updated Japanese translation. 2008-02-26 Changwoo Ryu * ko.po: Updated Korean translation. 2008-02-24 Ilkka Tuohela * fi.po: Updated Finnish translation (bug #518255). 2008-02-23 Yair Hershkovitz * he.po: Updated Hebrew translation. 2008-02-22 Claude Paroz * fr.po: Updated French translation by Robert-André Mauchin. 2008-02-22 Arangel Angov * mk.po: Updated Macedonian translation. 2008-02-19 Priit Laes * et.po: Translation updated by Ivar Smolin 2008-02-17 Ihar Hrachyshka * be@latin.po: Updated Belarusian Latin translation. 2008-02-16 Gil Forcada * ca.po: Updated Catalan translation. 2008-02-14 Priit Laes * et.po: Translation updated by Ivar Smolin 2008-02-14 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2008-02-14 Pawan Chitrakar * ne.po: Updated Nepali Translation. 2008-02-13 Ilkka Tuohela * fi.po: Updated Finnish translation. 2008-02-11 Petr Kovar * cs.po: Updated Czech translation. 2008-02-09 Duarte Loreto * pt.po: Updated Portuguese translation. 2008-02-09 Andre Klapper * de.po: Updated German translation. 2008-02-08 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation. 2008-02-08 Chao-Hsiung Liao * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). * zh_TW.po: Updated Traditional Chinese translation(Taiwan). 2008-02-07 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2008-02-6 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2008-02-05 Amitakhya Phukan * LINGUAS: Added as. * as.po: Updated assamese translations. 2008-02-04 Wouter Bolsterlee * nl.po: Dutch translation updated by Wouter Bolsterlee. 2008-02-02 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2008-02-02 Yannig Marchegay * oc.po: Updated Occitan translation. 2008-02-02 Leonardo Ferreira Fontenelle * pt_BR.po: Brazilian Portuguese translation updated by Vladimir Melo. 2008-02-02 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2008-02-01 Daniel Nylander * sv.po: Updated Swedish translation. 2008-01-31 Djihed Afifi * ar.po: Updated Arabic Translation by Anas Husseini. 2008-01-30 William Jon McCann * POTFILES.in: Update files. 2008-01-29 Jorge Gonzalez * es.po: Updated Spanish translation 2008-01-29 Luca Ferretti * POTIFILES.in: added new file. * it.po: Updated Italian translation. 2008-01-21 Gil Forcada * ca.po: Small fix thanks to David Planella. 2008-01-16 Yair Hershkovitz * he.po: Updated Hebrew translation from Rosseta. 2008-01-09 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation. 2007-12-31 Yannig Marchegay * oc.po: Updated Occitan translation. 2007-12-20 Seán de Búrca * ga.po: Added Irish translation. * LINGUAS: Added Irish. 2007-12-13 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation from Eskild. 2007-12-13 Kjartan Maraas * nn.po: Added Norwegian nynorsk translation from Eskild Hustvedt 2007-12-08 Jakub Friedl * cs.po: Czech Translation updated by Petr Kovar. 2007-12-01 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2007-11-25 Nickolay V. Shmyrev * ru.po: Updated Russian translation by Vasiliy Faronov 2007-11-14 Matej Urbančič * sl.po: Updated Slovenian translation. 2007-10-31 Ilkka Tuohela * fi.po: Updated Finnish translation. 2007-10-23 Djihed Afifi * ar.po: Updated Arabic Translation by Anas Husseini. 2007-10-21 Djihed Afifi * ar.po: Updated Arabic Translation by Anas Husseini. 2007-10-21 Djihed Afifi * ar.po: Updated Arabic Translation by Anas Husseini. 2007-10-15 Matej Urbančič * sl.po: Updated Slovenian translation. 2007-10-15 Yair Hershkovitz * he.po: Updated Hebrew translation. 2007-09-30 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2007-09-24 Changwoo Ryu * ko.po: Updated Korean translation. 2007-09-18 Goran Rakić * sr.po, sr@Latn.po: Updated Serbian translation (by Miloš Popović) 2007-09-17 Baris Cicek * tr.po: Updated Turkish translation from Deniz Kocak 2007-09-17 Takeshi AIHANA * ja.po: Fixed wrong translation. 2007-09-17 Danishka Navin * si.po: Sinhala Translation updated by Danishka Navin 2007-09-16 Nickolay V. Shmyrev * ru.po: Updated Russian translation. 2007-09-16 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2007-09-15 Andre Klapper * sk.po: Updated Slovak translation on behalf of Peter Tuharsky . 2007-09-15 Mugurel Tudor * LINGUAS: added ro * ro.po: Added Romanian translation by Alexandru Szasz 2007-09-13 Djihed Afifi * ar.po: Updated Arabic Translation by Anas Husseini. 2007-09-12 Maxim Dziumanenko * uk.po: Update Ukrainian translation. 2007-09-09 Nikos Charonitakis * el.po: Updated Greek translation. 2007-09-09 Kenneth Nielsen * da.po: Updated Danish translation 2007-09-06 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2007-09-06 Stéphane Raimbault * fr.po: Updated French translation by Jonathan Ernst and Stéphane Raimbault. 2007-09-05 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2007-09-05 Ani Peter * ml.po: Updated Malayalam Translation 2007-09-04 Luca Ferretti * it.po: Updated Italian translation. 2007-09-04 Jovan Naumovski * mk.po: Updated Macedonian translation. 2007-09-04 Gabor Kelemen * hu.po: Translation updated. 2007-09-03 Clytie Siddall * vi.po: Updated Vietnamese translation. 2007-09-03 Priit Laes * et.po: Estonian translation updates by Ivar Smolin 2007-09-03 Duarte Loreto * pt.po: Updated Portuguese translation. 2007-09-01 Gil Forcada * ca.po: Updated catalan translation. 2007-08-31 Ani Peter * ml.po: Updated Malayalam Translation 2007-08-29 I. Felix * ta.po: Tamil Translation updated by Tirumurthi Vasudevan 2007-08-27 Changwoo Ryu * ko.po: Updated Korean translation by Young-Ho Cha. 2007-08-23 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2007-08-23 Sunil Mohan Adapa * te.po: Added Telugu translation done by Srinivas Chary . 2007-08-17 Ani Peter * ml.po: Updated Malayalam TRanslation 2007-08-16 Priit Laes * et.po: Estonian translation updates by Ivar Smolin 2007-08-16 Priit Laes * et.po: Estonian translation update by Ivar Smolin. 2007-08-15 Hendrik Richter * de.po: Updated German translation. 2007-08-13 Ilkka Tuohela * fi.po: Updated Finnish translation. 2007-08-12 Takeshi AIHANA * ja.po: Updated Japanese translation. 2007-08-11 Leonardo Ferreira Fontenelle * pt_BR.po: Brazilian Portuguese translation updated by Vladimir Melo . 2007-08-11 Daniel Nylander * sv.po: Updated Swedish translation. 2007-08-06 Ankit Patel * gu.po: Updated Gujarati Translation. 2007-08-04 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation 2007-08-03 Jorge Gonzalez * es.po: Updated Spanish translation 2007-08-03 Ihar Hrachyshka * be@latin.po: Updated Belarusian Latin translation. 2007-08-03 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2007-08-01 Daniel Nylander * sv.po: Updated Swedish translation. 2007-07-31 Jorge Gonzalez * es.po: Updated Spanish translation 2007-07-25 Andre Klapper * de.po: updated german translation. 2007-07-24 Priit Laes * et.po: Estonian translation update by Ivar Smolin. 2007-07-21 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2007-07-17 Daniel Nylander * sv.po: Updated Swedish translation. 2007-07-17 Takeshi AIHANA * ja.po: Updated Japanese translation. 2007-07-16 Ilkka Tuohela * fi.po: Updated Finnish translation. 2007-07-13 Priit Laes * et.po: Estonian translation update by Ivar Smolin. 2007-07-13 I. Felix * ta.po: Tamil Translation updated by Tirumurthi Vasudevan 2007-07-11 Gabor Kelemen * hu.po: Translation updated. 2007-07-10 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2007-07-06 Jorge Gonzalez * es.po: Updated Spanish translation 2007-07-01 Nguyễn Thái Ngọc Duy * vi.po: Updated Vietnamese translation. 2007-06-29 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2007-06-27 Clytie Siddall * vi.po: Updated Vietnamese translation. 2007-06-22 I. Felix * si.po: Sinhala Translation updated by Danishka Navin * LINGUAS: Added Sinhala (si) to The List of Languages. 2007-06-21 I Felix * ta.po: Updated Tamil Translation. 2007-06-13 Pema Geyleg * dz.po: Updated dzongkha translation. 2007-05-31 Priit Laes * et.po: Updated Estonian translation by Ivar Smolin . 2007-05-30 Priit Laes * et.po: Updated Estonian translation by Ivar Smolin . 2007-05-29 Ihar Hrachyshka * be@latin.po: Added Belarusian Latin translation. 2007-05-18 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2007-05-08 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2007-05-04 Jorge Gonzalez * es.po: Updated Spanish translation 2007-04-25 David Lodge * en_GB.po: Updated British English translation 2007-04-24 Daniel Nylander * sv.po: Updated Swedish translation. 2007-04-05 Raivis Dejus * lv.po: Updated Latvian Translation. 2007-04-02 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation. 2007-03-31 Inaki Larranaga Murgoitio * eu.po: Updated Basque translation. 2007-03-31 Funda Wang * zh_CN.po: Updated Simplified Chinese translation from Yang Zhang. 2007-03-27 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. * POTFILES.in: Updated. 2007-03-22 Peter Bach * da.po: Updated Danish translation. 2007-03-18 Matic Zgur * sl.po: Updated Slovenian translation. 2007-03-10 Nickolay V. Shmyrev * ru.po: Updated Russian translation. 2007-03-06 Pema Geyleg * dz.po: Updated Dzongkha Translation. 2007-03-06 Jovan Naumovski * mk.po: Updated Macedonian translation. 2007-03-05 Ankit Patel * gu.po: Updated Gujarati Translation. 2007-03-04 Luca Ferretti * it.po: Updated Italian translation. 2007-03-03 Yair Hershkovitz * he.po: Updated Hebrew translation. 2007-02-28 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2007-02-28 Djihed Afifi * ar.po: Updated Arabic Translation by Khaled Hosny. 2007-02-27 Abel Cheung * POTFILES.in: Some desktop files have been renamed. 2007-02-27 Abel Cheung * zh_HK.po, zh_TW.po: Updated traditional Chinese translation by Woodman Tuen . 2007-02-27 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2007-02-25 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2007-02-24 Gabor Kelemen * hu.po: Translation updated. 2007-02-25 Changwoo Ryu * ko.po: Updated Korean translation. 2007-02-22 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2007-02-21 Maxim Dziumanenko * uk.po: Update Ukrainian translation. 2007-02-20 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2007-02-19 Ilkka Tuohela * fi.po: Updated Finnish translation. 2007-02-18 Takeshi AIHANA * ja.po: Updated Japanese translation. 2007-02-17 Hendrik Brandt * de.op: Updated German translation. 2007-02-17 David Lodge * POTFILES.in: Changed a couple of the savers to use .in.in instead of .in so that the pot file would generate 2007-02-15 William Jon McCann * POTFILES.in: Remove FUSA. 2007-02-14 Duarte Loreto * pt.po: Updated Portuguese translation. 2007-02-10 Lasse Bang Mikkelsen * da.po: Updated Danish translation by Kenneth Nielsen 2007-02-06 Leonardo Ferreira Fontenelle * pt_BR.po: Updated Brazilian Portuguese translation by Og Maciel . 2007-02-02 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2007-01-31 Stéphane Raimbault * fr.po: Updated French translation by Robert-André Mauchin and Stéphane Raimbault. 2007-01-30 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2007-01-30 William Jon McCann * POTFILES.in: Removed deleted file 2007-01-26 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation. 2007-01-12 Kjartan Maraas * nb.po: Fix a typo. Thanks to Bjarte Lund for saving me from some embarrassment. Closes bug #395567. 2007-01-11 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation by Gil Forcada . 2007-01-07 Priit Laes * et.po: Estonian translation update by Ivar Smolin. 2007-01-06 Clytie Siddall * vi.po: Updated Vietnamese translation. 2007-01-01 David Lodge * en_GB.po: Updated English (British) translation 2006-12-27 Djihed Afifi * ar.po: Updated Arabic Translation. 2006-12-24 Djihed Afifi * ar.po: Updated Arabic Translation. 2006-12-20 Raivis Dejus * lv.po: Updated Latvian Translation. 2006-12-18 Djihed Afifi * ar.po: Added Arabic Translation. * LINGUAS: Added ar. 2006-12-14 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-12-11 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-12-11 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-12-07 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-11-19 Daniel Nylander * sv.po: Updated Swedish translation. 2006-11-08 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-11-01 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-26 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-10-21 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-20 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-10-20 Jovan Naumovski * mk.po: Updated Macedonian translation. 2006-10-19 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-10-19 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-10-17 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-10-13 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-13 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation. 2006-10-09 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-10-08 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-07 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-05 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-04 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-10-03 Jakub Friedl * cs.po: Czech translation update. 2006-10-02 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-09-27 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-09-25 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-09-14 Luca Ferretti * it.po: Updated Italian translation. 2006-09-14 Satoru SATOH * ja.po: Fixed up mismatch between nplurals and number of plural forms some messages have. 2006-09-10 David Lodge * en_GB.po: Updated English (British) translation. 2006-09-05 Lucas Rocha * pt_BR.po: Updated Brazilian Portuguese translation by Leonardo Ferreira Fontenelle and Henrique Grolli Bassotto 2006-09-04 Baris Cicek * tr.po: Added Turkish Translation from Deniz Kocak * LINGUAS: Added entry for "tr" (turkish); 2006-09-04 Roozbeh Pournader * fa.po: Added Persian translation by Elnaz Sarbar and Meelad Zakaria. * LINGUAS: Added entry for "fa" (Persian). 2006-09-04 Abel Cheung * zh_HK.po: Updated Chinese (Hong Kong) translation from Ching-Hung Lin . * zh_TW.po: Updated Chinese (Taiwan) translation from Ching-Hung Lin . 2006-09-03 Subhransu Behera * or.po: Updated Oriya Translation. 2006-09-02 Kostas Papadimas * el.po: Updated Greek Translation 2006-09-01 Jovan Naumovski * mk.po: Updated Macedonian translation. 2006-08-31 Rajesh Ranjan * hi.po: Updated Hindi Translation. 2006-08-31 Gabor Kelemen * hu.po: Translation updated. 2006-08-31 Duarte Loreto * pt.po: Updated Portuguese translation. 2006-08-30 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2006-08-29 Christophe Merlet * fr.po: Updated French translation from Robert-André Mauchin . 2006-08-29 Gintautas Miliauskas * lt.po: Updated Lithuanian translation. 2006-08-27 Theppitak Karoonboonyanan * th.po: Fixed plural forms. 2006-08-26 Jovan Naumovski * mk.po: Updated Macedonian translation. 2006-08-24 Raivis Dejus * lv.po: Updated Latvian translation. 2006-08-24 Inaki Larranaga * eu.po: Added Basque translation. * LINGUAS: Added "eu" (Basque) entry. 2006-08-22 Matic Žgur * sl.po: Updated Slovenian translation. 2006-08-21 Subhransu Behera * or.po: Added and Updated Oriya Translation. * LINGUAS: Added Oriya (or) to The List of Languages. 2006-08-19 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2006-08-19 Maxim Dziumanenko * uk.po: Update Ukrainian translation. 2006-08-16 Erdal Ronahi * ku.po: Updated Kurdish translations by Riza Seckin 2006-08-16 Hendrik Richter * de.po: Updated German translation. 2006-08-16 Daniel Nylander * sv.po: Updated Swedish translation. 2006-08-16 Gabor Kelemen * hu.po: Translation updated. 2006-08-15 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-08-15 Leonid Kanter * ru.po: Updated Russian translation 2006-08-14 Sanlig Badral * mn.po: Added Mongolian translation. * LINGUAS: Added mn entry. 2006-08-14 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-08-12 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2006-08-12 Changwoo Ryu * ko.po: Updated Korean translation. 2008-08-10 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation by Gil Forcada 2006-08-10 Guntupalli Karunakar * dz.po: Updated Dzongkha translation by Dzongkhalinux team, DIT 2006-08-09 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-08-09 Satoru SATOH * ja.po: Updated Japanese translation. 2006-08-08 Ani Peter * ml.po: Added and Updated Malayalam translation * LINGUAS: Added Malayalam (ml) to the list of Languages 2006-08-02 Jovan Naumovski * mk.po: Updated Macedonian translation. 2006-08-02 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-08-02 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-08-01 Jovan Naumovski * mk.po: Updated/fixed Macedonian translation. 2006-08-01 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-08-01 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-07-31 Christophe Merlet * fr.po: Updated French translation. 2006-07-30 Arangel Angov * sl.po: Added Slovenian translation. 2006-07-30 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2006-07-29 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-07-27 Ahmad Riza H Nst * id.po: Updated. 2006-07-27 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-07-26 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-07-25 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-07-23 Changwoo Ryu * ko.po: Updated Korean translation. 2006-07-21 Jakub Friedl * cs.po: Updated Czech translation 2006-07-21 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation by Gil Forcada. 2006-07-20 Hendrik Richter * de.po: Updated German translation. 2006-07-20 Kostas Papadimas * el.po: Updated Greek translation. 2006-07-20 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-07-19 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-07-19 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-07-18 Guntupalli Karunakar * dz.po: Updated Dzongkha translation by Dzongkhalinux team, DIT 2006-07-17 Thierry Randrianiriana * mg.po: Added Malagasy translation. * LINGUAS: Added Malagasy 'mg'. 2006-07-16 Daniel Nylander * sv.po: Updated Swedish translation. 2006-07-14 Priit Laes * et.po: Translation updated. 2006-07-14 Jakub Friedl * cs.po: Updated Czech translation 2006-07-05 Alexander Shopov * bg.po: Updated Bulgarian translation by Rostislav Raykov 2006-07-03 Runa Bhattacharjee * bn_IN.po: Added Bengali India Translation * LINGUAS: Added Bengali India (bn_IN) to the list of languages. 2006-07-03 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-07-02 Benoît Dejean * fr.po: Updated French translation. 2006-07-01 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-07-01 Pawan Chitrakar * ne.po: Added Nepali translation * LINGUAS: Added ne 2006-06-30 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-06-30 Rajesh Ranjan * hi.po: Updated Hindi Translation. 2006-06-30 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-06-30 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-06-29 Rajesh Ranjan * hi.po: Updated Hindi Translation. 2006-06-29 Yair Hershkovitz * he.po: Added Hebrew translation. 2006-06-28 Guntupalli Karunakar * dz.po: Updated Dzongkha translation by Dzongkhalinux, DIT 2006-06-27 Jovan Naumovski * mk.po: Updated Macedonian Translation. 2006-06-23 I. felix * ta.po: Added Tamil translation. * LINGUAS: Added Tamil (ta) entry. 2006-06-19 Raivis Dejus * lv.po: Added Latvian translation. * LINGUAS: Added Latvian (lv) entry. 2006-06-16 Jakub Friedl * cs.po: Updated Czech translation. 2006-06-15 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-06-15 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-06-15 Hendrik Richter * de.po: Updated German translation. 2006-06-15 Daniel Nylander * sv.po: Updated Swedish translation. 2006-06-15 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-06-14 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-06-13 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-06-13 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-06-12 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-06-12 Jakub Friedl * cs.po: Updated Czech translation. 2006-06-12 Kjartan Maraas * POTFILES.in: Add src/gs-auth-pam.c * nb.po: Updated Norwegian bokmål translation. 2006-06-12 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-06-11 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-06-09 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-06-09 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-06-09 Jakub Friedl * cs.po: Updated Czech translation. 2006-06-07 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-06-06 Jakub Friedl * cs.po: Updated Czech translation. 2006-05-30 Pema Geyleg * dz.po: Updated Dzongkha translation. 2006-05-29 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-05-29 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-05-29 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-05-29 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-05-28 Pema Geyleg * dz.po: updated Dzongkha translation. 2006-05-26 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-05-25 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-05-23 Jakub Friedl * cs.po: Updated Czech translation. 2006-05-19 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-05-19 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-05-16 Nickolay V. Shmyrev * LINGUAS: Added Russian translation. 2006-05-14 Chao-Hsiung Liao * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). * zh_TW.po: Updated Traditional Chinese translation(Taiwan). 2006-05-11 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-05-06 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-04-30 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. 2006-04-26 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-04-25 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-04-24 William Jon McCann * POTFILES.in: Add new file. 2006-04-19 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-04-18 William Jon McCann * LINGUAS: Don't split over multiple lines as it breaks the build. 2006-04-18 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-04-17 Kjartan Maraas * LINGUAS: Remove obsolete entry for no_NO * no.po: And the translation. 2006-04-17 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-04-13 Vladimer Sichinava * ka.po: Updated Georgian translation. 2006-04-10 Artur Flinta * pl.po: Updated Polish translation by GNOME PL Team. 2006-04-08 Benoît Dejean * fr.po: Updated French translation. 2007-04-05 Pema Geyleg * dz.po: Added Dzongkha translation. 2006-04-03 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-03-31 Lukas Novotny * cs.po: Updated Czech translation. 2006-03-20 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-17 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-17 Wouter Bolsterlee * nl.po: Translation updated by Wouter Bolsterlee. 2006-03-17 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-14 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-03-13 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-13 Erdal Ronahi * ku.po: Added initial Kurdish translation 2006-03-13 Runa Bhattacharjee * bn.po: Added Bengali Translation (partial) by Mahay Alam Khan. 2006-03-12 Miloslav Trmac * cs.po: Updated Czech translation by Petr Tomeš. 2006-03-11 Guilherme de S. Pastore * pt_BR.po: Updated Brazilian Portuguese translation. 2006-03-11 Jens Seidel * de.po: Proofreading. 2006-03-11 Frank Arnold * de.po: Replaced wrong spaces caused by copy/paste inside gtranslator. 2006-03-11 Duarte Loreto * pt.po: Added Portuguese translation. 2006-03-10 Luca Ferretti * it.po: Updated Italian translation 2006-03-08 Rajesh Ranjan * hi.po: Added Hindi tranlsation. 2006-03-08 Lasse Bang Mikkelsen * da.po: Added Danish translation by David Nielsen. 2006-03-08 Laurent Dhima * sq.po: Added Albanian translation. 2006-03-08 Rhys Jones * cy.po: Added Welsh translation. 2006-03-07 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-07 Daniel Nylander * sv.po: Updated Swedish translation. 2006-03-06 Maxim Dziumanenko * uk.po: Updated Ukrainian translation. 2006-03-05 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. * no.po: Same. 2006-03-05 Priit Laes * et.po: Translation updated by Ivar Smolin. 2006-03-04 Priit Laes * et.po: Translation added by Ivar Smolin. 2006-03-02 Hendrik Richter * de.po: Updated German translation. 2003-03-02 Kang Jeong-Hee * ko.po: Updated Korean translation. 2006-03-01 Alexander Shopov * bg.po: Updated Bulgarian translation by Rostislav Raykov 2006-03-01 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation. 2006-02-25 Luca Ferretti * it.po: Italian translation updated. 2006-02-25 Gabor Kelemen * hu.po: Hungarian translation updated. 2006-02-23 Leonid Kanter * ru.po: Initial Russian translation 2006-02-23 Kostas Papadimas *el.po Updated Greek Translation 2006-02-23 Kostas Papadimas *el.po Updated Greek Translation 2006-02-23 Clytie Siddall * ka.po: Added Georgian translation by Alexander Didebulidze and Vladimer SIchinava . 2006-02-23 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2006-02-21 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2006-02-21 Kang Jeong-Hee * ko.po: Added Korean translation 2006-02-21 Slobodan D. Sredojevic * sr.po, sr@Latn.po: Updated Serbian translation 2006-02-21 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-02-18 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-02-18 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. * no.po: Same. 2006-02-17 Satoru SATOH * ja.po: Updated Japanese translation. 2006-02-16 Nikos Charonitakis * el.po: Added Greek translation. 2006-02-16 Luca Ferretti * it.po: Updated Italian translation. 2006-02-16 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-02-16 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-02-15 Ilkka Tuohela * fi.po: Changed "%s on %s" to %s@%s for Finnish. 2006-02-15 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-02-15 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-02-15 Raphael Higino * pt_BR.po: Updated Brazilian Portuguese translation. 2006-02-11 Øivind Hoel * nb.po: Updated Norwegian Bokmål translation. 2006-02-10 Josep Puigdemont i Casamajó * ca.po: Updated Catalan translation, by Gil Forcada 2006-02-06 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2006-01-31 Lukas Novotny * cs.po: Updated Czech translation. 2006-01-30 Hendrik Brandt * de.po: Updated German translation. 2006-01-29 Hendrik Brandt * de.po: Updated German translation, plural bugfix. 2006-01-29 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2006-01-27 Chao-Hsiung Liao * zh_TW.po: Updated Traditional Chinese translation(Taiwan). * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). 2006-01-25 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2006-01-18 Slobodan D. Sredojevic * sr.po, sr@Latn.po: Updated Serbian translation 2006-01-18 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-01-18 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2006-01-17 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-01-16 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-01-16 Clytie Siddall * vi.po: Updated Vietnamese translation. 2006-01-15 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2006-01-15 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2006-01-08 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2006-01-08 Takeshi AIHANA * ja.po: Updated Japanese translation. 2006-01-07 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2006-01-07 Ilkka Tuohela * fi.po: Updated Finnish translation. 2006-01-07 Chao-Hsiung Liao * zh_TW.po: Updated Traditional Chinese Translation.(Taiwan) * zh_HK.po: Added Traditional Chinese Translation.(Hong Kong) 2006-01-06 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2006-01-03 Slobodan D. Sredojevic * sr.po, sr@Latn.po: Added Serbian translation 2006-01-02 Josep Puigdemont i Casamajó * ca.po: Added Catalan translation. 2006-01-01 Ankit Patel * gu.po: Updated Gujarati Translation. 2006-01-01 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-12-31 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-12-31 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2005-12-30 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-12-26 Ilkka Tuohela * fi.po: Updated Finnish translation. 2005-12-26 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2005-12-23 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-12-20 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-12-20 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-12-19 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-12-19 Ankit Patel * gu.po: Added Gujarati Translation. 2005-12-19 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2005-12-18 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-12-17 Theppitak Karoonboonyanan * th.po: Updated Thai translation. 2005-12-14 William Jon McCann * POTFILES.in: Updated. 2005-12-13 Gabor Kelemen * hu.po: Hungarian translation updated. 2005-12-13 Gabor Kelemen * hu.po: Hungarian translation updated. 2005-12-13 Gabor Kelemen * hu.po: Hungarian translation updated. 2005-12-11 Miloslav Trmac * cs.po: Updated Czech translation. 2005-12-08 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. * no.po: Same. 2005-12-04 Theppitak Karoonboonyanan * th.po: Fixed typos. 2005-11-28 Ignacio Casal Quinteiro * gl.po: Updated Galician Translation. 2005-11-27 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2005-11-27 Theppitak Karoonboonyanan * th.po: Added Thai translation. 2005-11-27 Marcel Telka * sk.po: Updated Slovak translation. 2005-11-22 Alexander Shopov * bg.po: Updated Bulgarian translation by Alexander Shopov 2005-11-20 Amanpreet Singh Alam * pa.po: Add Punjabi (pa) Translaiton 2005-11-20 Ilkka Tuohela * fi.po: Updated Finnish translation. 2005-11-17 Marcel Telka * sk.po: Added Slovak translation. 2005-11-14 Christophe Merlet * fr.po: Updated French translation from Davy Defaud . 2005-11-11 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-11-06 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-11-04 Žygimantas Beručka * lt.po: Updated Lithuanian translation. 2005-11-04 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-11-02 Miloslav Trmac * cs.po: Updated Czech translation. 2005-11-03 Christophe Merlet * fr.po: Updated French translation from Davy Defaud . 2005-11-01 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-10-31 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-29 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-10-28 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-10-26 Gabor Kelemen * hu.po: Hungarian translation added. 2005-10-19 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-16 Kjartan Maraas * nb.po: Updated Norwegian bokmål translation. * no.po: Same. 2005-10-14 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-11 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-10-11 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-10-09 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-10-08 Funda Wang * zh_CN.po: Updated Simplified Chinese translation. 2005-10-07 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-06 Alexander Shopov * bg.po: Updated Bulgarian translation by Rostislav Raykov 2005-10-05 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-04 Žygimantas Beručka * lt.po: Added Lithuanian translation. 2005-10-02 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-10-02 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-09-30 Kjartan Maraas * nb.po: Added Norwegian bokmål translation. * no.po: Same. 2005-09-29 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-09-29 Alexander Shopov * bg.po: Updated Bulgarian translation by Rostislav Raykov 2005-09-27 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-09-25 Miloslav Trmac * cs.po: Added Czech translation. 2005-09-24 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-09-23 William Jon McCann * POTFILES.in: Remove obsolete and add new files. 2005-09-22 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-09-21 Ilkka Tuohela * fi.po Updated Finnish translation 2005-09-18 Alessio Frusciante * it.po: Added Italian translation by Luca Ferretti . 2005-09-17 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-09-16 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-09-06 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-09-05 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-09-02 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-09-01 Vincent van Adrighem * nl.po: Translation updated by Tino Meinen. 2005-08-31 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-08-31 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-08-27 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-08-27 Clytie Siddall * vi.po: Updated Vietnamese translation. 2005-08-26 Christophe Merlet * fr.po: Added French translation from Eric Maeker . 2005-08-24 William Jon McCann * POTFILES.in: Add missing files. 2005-08-10 Alexander Shopov * bg.po: Added Bulgarian translation by Rostislav Raykov 2005-08-02 Maxim Dziumanenko * uk.po: Added Ukrainian translation. 2005-07-25 Tommi Vainikainen * fi.po: Added Finnish translation. 2005-07-19 Takeshi AIHANA * ja.po: Updated Japanese translation. 2005-07-18 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-07-18 Vincent van Adrighem * nl.po: Translation added by Tino Meinen. 2005-07-15 Abel Cheung * zh_TW.po: New traditional Chinese translation from GNOME HK Team 2005-07-06 Christian Rose * sv.po: Updated Swedish translation. 2005-07-04 Hendrik Richter * de.po: Fixed German translation by Jens Seidel . 2005-07-03 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-07-03 Takeshi AIHANA * ja.po: Added Japanese translation. 2005-06-26 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-06-23 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-06-17 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-06-13 William Jon McCann * POTFILES: Add new file. 2005-06-05 James Ogley * en_GB.po: Updated British English translation. 2005-06-04 Francisco Javier F. Serrador * es.po: Updated Spanish translation. 2005-05-24 Frank Arnold * de.po: Updated German translation. 2005-05-23 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-05-23 William Jon McCann * POTFILES.in: Add missing file. 2005-05-21 Frank Arnold * de.po: Added German translation. 2005-05-19 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-05-05 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-05-04 Adam Weinberger * en_CA.po: Updated Canadian English translation. 2005-05-01 Francisco Javier F. Serrador * es.po: Added Spanish translation. 2005-04-29 Christian Rose * POTFILES.in: Added missing files. * sv.po: Updated Swedish translation. 2005-04-24 Raphael Higino * pt_BR.po: Updated Brazilian Portuguese translation. 2005-04-19 Gareth Owen * en_GB.po: Added British English translation 2005-04-15 Adam Weinberger * en_CA.po: Added Canadian English translation. 2005-04-15 Raphael Higino * pt_BR.po: Added Brazilian Portuguese translation. 2005-04-15 Funda Wang * zh_CN.po: Added Simplified Chinese translation. 2005-04-14 Christian Rose * sv.po: Added Swedish translation. 2005-04-14 Christian Rose * POTFILES.in: Added this file. * .cvsignore: Updated this file. cinnamon-screensaver-2.8.0/po/POTFILES.in0000664000175000017500000000047612610211212016753 0ustar fabiofabio# List of source files containing translatable strings. # Please keep this file sorted alphabetically. src/cinnamon-screensaver-command.c src/cinnamon-screensaver-dialog.c src/cinnamon-screensaver.c src/cinnamon-screensaver.desktop.in.in src/gs-auth-pam.c src/gs-listener-dbus.c src/gs-lock-plug.c src/gs-window-x11.c cinnamon-screensaver-2.8.0/po/Makefile.in.in0000664000175000017500000001604612610211212017650 0ustar fabiofabio# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # Copyright (C) 2004-2008 Rodney Dawes # # This file may be copied and used freely without restrictions. It may # be used in projects which are not available under a GNU Public License, # but which still want to provide support for the GNU gettext functionality. # # - Modified by Owen Taylor to use GETTEXT_PACKAGE # instead of PACKAGE and to look for po2tbl in ./ not in intl/ # # - Modified by jacob berkman to install # Makefile.in.in and po2tbl.sed.in for use with glib-gettextize # # - Modified by Rodney Dawes for use with intltool # # We have the following line for use by intltoolize: # INTLTOOL_MAKEFILE GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = @SHELL@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = @datadir@ datarootdir = @datarootdir@ libdir = @libdir@ DATADIRNAME = @DATADIRNAME@ itlocaledir = $(prefix)/$(DATADIRNAME)/locale subdir = po install_sh = @install_sh@ # Automake >= 1.8 provides @mkdir_p@. # Until it can be supposed, use the safe fallback: mkdir_p = $(install_sh) -d INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ GMSGFMT = @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = @XGETTEXT@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot ALL_LINGUAS = @ALL_LINGUAS@ PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi) USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi) USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) DISTFILES = Makefile.in.in POTFILES.in $(POFILES) EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS POTFILES = \ # This comment gets stripped out CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) .SUFFIXES: .SUFFIXES: .po .pox .gmo .mo .msg .cat AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V)) INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY)) INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@; .po.pox: $(MAKE) $(GETTEXT_PACKAGE).pot $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox .po.mo: $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $< .po.gmo: $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && gencat $@ $*.msg all: all-@USE_NLS@ all-yes: $(CATALOGS) all-no: $(GETTEXT_PACKAGE).pot: $(POTFILES) $(GENPOT) install: install-data install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $$dir; \ if test -r $$lang.gmo; then \ $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ else \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ echo "installing $(srcdir)/$$lang.gmo as" \ "$$dir/$(GETTEXT_PACKAGE).mo"; \ fi; \ if test -r $$lang.gmo.m; then \ $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ if test -r $(srcdir)/$$lang.gmo.m ; then \ $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ $$dir/$(GETTEXT_PACKAGE).mo.m; \ echo "installing $(srcdir)/$$lang.gmo.m as" \ "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ else \ true; \ fi; \ fi; \ done # Empty stubs to satisfy archaic automake needs dvi info ctags tags CTAGS TAGS ID: # Define this as empty until I found a useful application. install-exec installcheck: uninstall: linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ done check: all $(GETTEXT_PACKAGE).pot rm -f missing notexist srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m if [ -r missing -o -r notexist ]; then \ exit 1; \ fi mostlyclean: rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp rm -f .intltool-merge-cache clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES stamp-it rm -f *.mo *.msg *.cat *.cat.m *.gmo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f Makefile.in.in distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(DISTFILES) dists="$(DISTFILES)"; \ extra_dists="$(EXTRA_DISTFILES)"; \ for file in $$extra_dists; do \ test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ done; \ for file in $$dists; do \ test -f $$file || file="$(srcdir)/$$file"; \ ln $$file $(distdir) 2> /dev/null \ || cp -p $$file $(distdir); \ done update-po: Makefile $(MAKE) $(GETTEXT_PACKAGE).pot tmpdir=`pwd`; \ linguas="$(USE_LINGUAS)"; \ for lang in $$linguas; do \ echo "$$lang:"; \ result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ if $$result; then \ if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.gmo failed!"; \ rm -f $$tmpdir/$$lang.new.po; \ fi; \ done Makefile POTFILES: stamp-it @if test ! -f $@; then \ rm -f stamp-it; \ $(MAKE) stamp-it; \ fi stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cinnamon-screensaver-2.8.0/NEWS0000664000175000017500000013141512610211212015255 0ustar fabiofabio============== Version 3.4.1 ============== - Drop num lock warning - Translation updates (Greek, Marathi, Hindi, Aragonese) ============== Version 3.4.0 ============== - Translations updates (crh) ============== Version 3.3.92 ============== - Fix fade when explicitly locking screen - Translations updates (ko) ============== Version 3.2.2 ============== - Fix --with-systemd=auto configure option - Stop using deprecated GTK+ API - Fix misleading debug messages referring to ConsoleKit - Fix a compile warning when compiled with systemd - Use correct signature for GetActiveTime D-Bus API - Translation updates (Xhosa) - Properly turn off caps lock warning ============== Version 3.2.1 ============== - Optionally use systemd instead of ConsoleKit - Always lock when asked - Fade out quickly on explicit locks - Allow arbitrary long idle times - Fix background scaling on multi-monitor setups - Implement OpenBSD authentication - Translation updates (Burmese, Czech, Norwegian bokmål) ============== Version 3.2.0 ============== - Translation updates (Gujarati, Telugu, Assamese, Lithuanian, Irish) =============== Version 3.1.92 =============== - Use maintainer mode by default - Fix the clock to actually update every minute - Translation updates (Japanese) =============== Version 3.1.91 =============== - Use GnomeWallClock to keep informed about time and timezone changes =============== Version 3.1.90 =============== - Properly set background to black when cancelling unlock - Drop the .pc file ============== Version 3.1.5 ============== - Add back keyboard layout indicator - Detect clock skew when resuming or ntp runs and compensate - Fix crash in user switcher - Drop libgnome-menu dependency - Translation updates (Finnish, Thai, Polish, Turkish, Czech, Esperanto, Belarusian, Catalan (Valencian), Persian) ============== Version 3.0.0 ============== - Remove inihibit APIs from the documentation - Translation updates (Russian, Bulgarian, Vietnamese, Punjabi, Uighur, Brazilian Portuguese, Latvian, Simplified Chinese, Traditional Chinese, Basque, Japanese, Danish, Tamil, Czech, Dutch, Catalan, Bengali) ================ Version 2.91.92 ================ - Store time values in seconds instead of minutes - Don't monitor session settings - Ensure the initial state of the clock is correct - Remove dbus activation - Remove daemonization - Request shell exit overview when locking - Translation updates ((Polish, Vietnamese, Brazilian Portuguese, Arabic, Dutch, Romanian, Africaans, Hungarian, Estonian, Slovenian, Portuguese, Hebrew, Norwegian bokmål, British English, German, Ukrainian, Swedish, Catalan, Serbian, Korean, French, Indonesian, Assamese) ================ Version 2.91.91 ================ - Follow the users clock format preference - Port to GDBus - Build cleanups - Remove --poke option from the commandline tool (didn't work anyway) - Remove unused delay and timeout preferences - Remove inhibit interface (inhibit the session instead) - Remove theme and job support - Update style to match gnome-shell - Use accountsservice to get face - Translation updates (Korean, Simplified Chinese, Norwegian bokmål, Latvian Oriya, Ukrainian, Russian) =============== Version 2.91.90 =============== - Use username in top panel if real name is empty - Various settings fixes - Translation updates =============== Version 2.91.4 =============== - Fix build against recent GTK+ - GNOME 3 style updates - Translation updates =============== Version 2.91.3 =============== - Fix build against recent GTK+ - Use GIO to launch gdmflexiserver - Translation updates =============== Version 2.91.2 =============== - Fix build against recent GTK+ - Port to GSettings =============== Version 2.91.1 =============== - Fix build against recent GTK+ and gnome-desktop - Port background handling to gsettings - Translation updates =============== Version 2.91.0 =============== - Switch to GTK+ 3.0 - Fix crash on systems that lack vidmode and randr extensions - Add session service activation file - Use better unicode symbols in strings - Drop "Leave a message" feature - Drop unlock dialog theme support - Drop support for non-PAM based authentication - Improve aesthetics of unlock dialog - Monitor hotplug fixes - Auto-activate screensaver when needed if not running - Translation updates =============== Version 2.30.0 =============== Translation updates =============== Version 2.29.92 =============== Fixed bugs: - Build fix for systems with x11 < 1.3 =============== Version 2.29.91 =============== Fixed bugs: - #609789 - CVE-2010-0422, handle monitor hotplugging more securely - Fix screen dirt in floaters screensaver =============== Version 2.29.90 =============== Fixed bugs: - #609337, CVE-2010-0414, handle monitor removal more securely =============== Version 2.29.1 =============== Fixed bugs: - #597874, Use xrandr 1.2 gamma fading - RH bug #546656, Fix crash in popsquares - #598476, Don't crash when lock dialog dies during shake - #593616, Fix multi-head issues - #600488, Remove session inhibitors if the originator falls of the bus =============== Version 2.28.0 =============== Fixed bugs: - #444927, get idle time from xorg - #463010, Port cinnamon-screensaver from libglade to gtkbuilder - #564061, Install .desktop file - #570402, screensaver crash if number of screens changes - #570941, String not marked for translation cinnamon-screensaver-command.c - #574896, [Leave message] Cancel button should clean clipboard buffe - #576463, can't unlock screen after upgrade until restarting gnome- screensaver - #581995, Fade out doesn't properly fall back to gamma number if X server only supports 0-size ramp - #586174, Encoding key in desktop files is deprecated - #589728, cinnamon-screensaver: implicit declaration g_printf - #590776, screensaver is never activated - #591193, Update/Create .gitignore - #591194, Add Comment and Icon in cinnamon-screensaver.desktop - #594082, cinnamon-screensaver ignores input when fading to black Translators: - Khaled Hosny (ar) - Amitakhya Phukan (as) - Alexander Shopov (bg) - Runa Bhattacharjee (bn_IN) - Jamil Ahmed (bn) - Denis ARNAUD (br) - Carles Ferrando (ca@valencia) - Petr Kovar (cz) - Ask H. Larsen (da) - Mario Blättermann, Christian Kirbach (de) - Philip Withnall (en_GB) - Jorge González (es) - Ivar Smolin, Mattias Põldaru (et) - Inaki Larranaga Murgoitio (eu) - Tommi Vainikainen (fi) - Claude Paroz (fr) - Seán de Búrca (ga) - Antón Méixome (gl) - Sweta Kothari (gu) - Yaron Shahrabani (he) - Rajesh Ranjan (hi) - Gabor Kelemen (hu) - Luca Ferretti (it) - Shankar Prasad (kn) - Changwoo Ryu (ko) - Gintautas Miliauskas (lt) - Rajesh Ranjan (mai) - Ani (ml) - Sandeep Shedmake (mr) - Kjartan Maraas (nb) - Niels-Christoph Fiedler (nds) - Manoj Kumar Giri (or) - A S Alam (pa) - Tomasz Dominikowski (pl) - Rodrigo L. M. Flores, Krix Apolinário (pt_BR) - Duarte Loreto (pt) - Lucian Adrian Grijincu (ro) - Matej Urbančič (sl) - Miloš Popović (sr@latin) - Miloš Popović (sr) - Daniel Nylander (sv) - ifelix (ta) - krishnababu k (te) - Theppitak Karoonboonyanan (th) - Maxim V. Dziumanenko (uk) - Chao-Hsiung Liao (zh_HK) - Chao-Hsiung Liao (zh_TW) =============== Version 2.27.0 =============== - Add an autostart file for cinnamon-screensaver (#585485) Updated Translations: Telugu, Catalan, zh_CN, Crimean Tatar =============== Version 2.26.1 =============== - Fixed #572955, audit GError usage (William Jon McCann) - Fixed #572956, use g_strerror (William Jon McCann) - Fixed #573495, logout_command setting may be overwritten with keyboard_command value (William Jon McCann) - Fixed #577739, cinnamon-screensaver-gl-helper calls gdk_x11_visual_get_xvisual with NULL visual (William Jon McCann) - Fixed #578669, Screenserver (William Jon McCann) Translations: - Updated crh: Reşat SABIQ - Updated ja: Takeshi AIHANA - Updated kn: Shankar Prasad =============== Version 2.26.0 =============== - Remove power notice signal - Rely on GNOME session idle detection - Proxy g-s inhibitors over to the session - Read status message from session - Accept a full path for theme (Matthias Clasen) =============== Version 2.25.2 =============== - Fix pixmap leak (Matthias Clasen) - Fix dialog border width =============== Version 2.25.1 =============== - Add bevel around dialog - Fixed #444927, get idle time from xorg - Fixed #492949, screensavers-personal-slideshow should not show hidden directories (Jörg) - Fixed #530561, "Random" preview is always the last saver (Maxim Ermilov) - Fixed #561855, Calls wrong slideshow binary if there is one installed in $PATH (Frederic Crozat) Translations: None =============== Version 2.24.1 =============== - Fixed #555701, libgnome-desktop:gnome_bg_create_pixmap() leaks pixmaps and X clients (Scott Remnant) - Fixed #451498, Preview of "Blank screen" is not consistent (Neil Patel) - Fixed #552119, Add GTK and GNOME to screensaver desktop (William Jon McCann) - Fixed #552523, Screensaver suddenly stopped working (William Jon McCann) - Fixed #555254, cinnamon-screensaver-dialog NULL pointer crash (William Jon McCann) - Fixed #555491, cinnamon-screensaver should release mouse/keyboard when failed to grab both of them (Joey Yu Zheng) - Fixed #560456, Cleaning up GTK Includes in cinnamon-screensaver (Maxim Ermilov) Translations: - Updated ar: Djihed Afifi - Updated ast: Andre Klapper, Astur - Updated be@latin: Ihar Hračyška, Ihar Hrachyshka - Updated pt_BR: Leonardo Ferreira Fontenelle, Vladimir Melo =============== Version 2.24.0 =============== - Updated LINGUAS, sr@latin.po, sr@Latn: Arangel Angov - Updated ar: Djihed Afifi, Khaled Hosny - Updated bg: Alexander Shopov - Updated bn_IN: Runa Bhattacharjee - Updated ca: Gil Forcada - Updated da: Kenneth Nielsen - Updated de: Hendrik Richter - Updated dz: Pema Geyleg, Dawa pemo - Updated en_GB: Philip Withnall, David Lodge - Updated et: Ivar Smolin - Updated fr: Claude Paroz - Updated ga: Seán de Búrca - Updated hr: Robert Sedak, Ante Karamatić - Updated hu: Gabor Kelemen - Updated it: Luca Ferretti - Updated kn: Shankar Prasad - Updated ko: Changwoo Ryu - Updated mk: Arangel Angov, Clytie Siddall - Updated ml: Praveen Arimbrathodiyil, പ്രവീണ്‍ അരിമ്പ്രത്തൊടിയില്‍ - Updated mr: Sandeep Shedmake - Updated nl: Wouter Bolsterlee - Updated pl: Wadim Dziedzic, wadim dziedzic - Updated pt_BR: Vladimir Melo - Updated ro: Mugurel Tudor, Mișu Moldovan - Updated sr.po, sr@latin: Goran Rakić - Updated ta: I. Felix - Updated tr: Baris Cicek =============== Version 2.23.90 =============== - use standard icon names (Matthias Clasen) - Paint widget background color as face background color. - Add/remove windows as necessary in response to RANDR 1.2 events - Honor the disable_user_switching lockdown key. - Fixed #547013, The dialog incorrectly tell that the numlock is on (William Jon McCann) Translations: - Updated LINGUAS, sr@latin.po, sr@Latn: Goran Rakic - Updated ar: Khaled Hosny - Updated cs: Petr Kovar - Updated eu: Inaki Larranaga Murgoitio, Iñaki Larrañaga Murgoitio - Updated fi: Ilkka Tuohela, Timo Jyrinki - Updated gu: Daniel Nylander, Sweta Kothari - Updated he: Yair Hershkovitz , Yaniv Abir - Updated ja: Takeshi AIHANA - Updated lt: Gintautas Miliauskas - Updated pt: Duarte Loreto - Updated pt_BR: Vladimir Melo - Updated sv: Daniel Nylander Help Manual Translations: None =============== Version 2.23.3 =============== * Fix build issue (Wouter Bolsterlee) * Add a simple frame around user icon * Add a new child widget to use for themes to draw on =============== Version 2.23.2 =============== * Fix gamma lost during fade * Show default desktop background behind lock dialog * Add reporting of inhibitors to --query command =============== Version 2.22.2 =============== * Add a 160 char limit to the message text box. =============== Version 2.22.1 =============== * Fix for bug 525785 – CVE-2008-0887 =============== Version 2.22.0 =============== Translators - Updated oc: Yannig Marchegay - Updated ca: Gil Forcada - Updated eu: Inaki Larranaga Murgoitio, Djihed Afifi - Updated as: Amitakhya Phukan - Updated ar: Artur Flinta, Djihed Afifi - Updated cs: Petr Kovar, Clytie Siddall - Updated et: Priit Laes - Updated bn_IN: Runa Bhattacharjee - Updated nl: Wouter Bolsterlee - Updated pt: Duarte Loreto - Updated nb: Kjartan Maraas - Updated tr: Baris Cicek - Updated ne: Pawan Chitrakar - Updated lt: Gintautas Miliauskas - Updated th: Theppitak Karoonboonyanan - Updated zh_TW: Taiwan - Updated en_GB: Philip Withnall - Updated be: Alexander Nyakhaychyk - Updated fr: Claude Paroz - Updated zh_HK: Hong Kong - Updated pt_BR: Leonardo Ferreira Fontenelle - Updated de: Andre Klapper - Updated hu: Gabor Kelemen - Updated fi: bug #518255, Ilkka Tuohela - Updated da: Kenneth Nielsen - Updated ja: Takeshi AIHANA - Updated he: Yair Hershkovitz - Updated be@latin: Ihar Hrachyshka - Updated ko: Changwoo Ryu - Updated sv: Daniel Nylander - Updated mk: Arangel Angov, Ignacio Casal Quinteiro , Clytie Siddall - Updated sk: Marcel Telka - Updated pl: Artur Flinta - Updated uk: Maxim Dziumanenko - Updated mr: Rahul Bhalerao, mr =============== Version 2.21.6 =============== * New theme transfer progress dialog. (John Millikin) * Migrate gnome-vfs to GIO (John Millikin) * Set default action after cancelling note. =============== Version 2.20.0 =============== cinnamon-screensaver * Fixed #442853, Unlock dialog shows Switch User button when /apps/cinnamon-screensaver/user_switch_enabled is false (William Jon McCann) Translators * Updated el: Nikos Charonitakis * Updated vi: Clytie Siddall * Updated ca: Gil Forcada * Updated it: Luca Ferretti * Updated ar: Djihed Afifi * Updated et: Priit Laes * Updated ru: Nickolay V. Shmyrev * Updated nl: Wouter Bolsterlee * Updated pt: Duarte Loreto * Updated nb: Kjartan Maraas * Updated tr: Baris Cicek * Updated lt: Gintautas Miliauskas * Updated ro: Mugurel Tudor * Updated ta: I. Felix * Updated fr: Stéphane Raimbault * Updated da: Kenneth Nielsen * Updated hu: Gabor Kelemen * Updated ja: Takeshi AIHANA * Updated ml: Ani Peter * Updated mk: Jovan Naumovski + * Updated sk: Andre Klapper * Updated si: Danishka Navin * Updated uk: Maxim Dziumanenko =============== Version 2.19.7 =============== cinnamon-screensaver * Fixed #437225, Solaris needs additional libs linked with to build (William Jon McCann) * Fixed #463754, remove last dep on libgnome (Jani Monoses) * Initialize XWindowAttributes (Rodrigo Moya) * Improvements to slideshow (Frederic Crozat) Translators * Updated gu: Ankit Patel * Updated be@latin: Ihar Hrachyshka * Updated pt_BR: Leonardo Ferreira Fontenelle * Updated ml: Ani Peter * Updated de: Hendrik Richter * Updated ko: Changwoo Ryu * Updated sv: Daniel Nylander * Updated es: Jorge Gonzalez * Updated th: Theppitak Karoonboonyanan * Updated fi: Ilkka Tuohela * Updated eu: Inaki Larranaga Murgoitio * Updated et: Priit Laes * Updated te: Sunil Mohan Adapa * Updated ja: Takeshi AIHANA * Updated pl: Artur Flinta =============== Version 2.19.6 =============== cinnamon-screensaver * Fixed #327602, cinnamon-screensaver never propagates the environment to its helper dialog (William Jon McCann) * Fixed #456705, useless message on stdout (Bill Nottingham) * Fixed #461028, console-kit ActiveChanged (VC switch) does not trigger unlock request (Ian Jackson) * Fixed #461722, Add support to disable slideshow randomization (Frederic Crozat) * Fixed #461814, Allow to specify background color for image slideshow (Frederic Crozat) * Fixed #461824, remove libexif dependency (Frederic Crozat) Translators * Updated mn: Djihed Afifi * Updated nl: Wouter Bolsterlee * Updated be@latin: Ihar Hrachyshka * Updated vi: Nguyễn Thái Ngọc Duy, Clytie Siddall * Updated nb: Kjartan Maraas * Updated de: Andre Klapper * Updated sv: Daniel Nylander * Updated mk: Daniel Nylander * Updated hu: Gabor Kelemen * Updated lv: Daniel Nylander, Djihed Afifi * Updated si: I. Felix, si * Updated en_GB: David Lodge * Updated dz: Pema Geyleg * Updated pl: Artur Flinta * Updated th: Theppitak Karoonboonyanan * Updated fi: Ilkka Tuohela * Updated et: Priit Laes * Updated ja: Takeshi AIHANA * Updated es: Jorge Gonzalez * Updated ta: I. Felix, I Felix =============== Version 2.19.5 =============== cinnamon-screensaver * Fixed #331515, No translation for themes in command line help (William Jon McCann) * Fixed #354663, lock dialog not visible when using nvidia clone (William Jon McCann) * Fixed #434712, cinnamon-screensaver crashes without dbus system bus (William Jon McCann) * Fixed #436818, replace gnome_help_display (William Jon McCann) * Fixed #445443, Screensaver deactivation is not correct (William Jon McCann) Translators * Updated be@latin: Ihar Hrachyshka * Updated vi: Nguyễn Thái Ngọc Duy, Clytie Siddall * Updated nb: Kjartan Maraas * Updated sv: Daniel Nylander * Updated lv: Daniel Nylander * Updated si: I. Felix, si * Updated en_GB: David Lodge * Updated dz: Pema Geyleg * Updated es: Jorge Gonzalez * Updated th: Theppitak Karoonboonyanan * Updated et: Priit Laes * Updated pl: Artur Flinta * Updated ta: I Felix =============== Version 2.19.1 =============== cinnamon-screensaver * Fixed #384509, cinnamon-screensaver could allow users to leave notes when screen is locked (William Jon McCann) * Fixed #411252, Use xdg-user-dirs to find pictures directory (William Jon McCann) * Fixed #428199, Make fast-user-switching work with gdm configurations involving multiple X servers (William Jon McCann) =============== Version 2.18.1 =============== cinnamon-screensaver * Fixed #424165, power management button should reflect g-p-m status (William Jon McCann) * Fixed #425550, cinnamon-screensaver should probably require mouse grab to lock (Ray Strode) Translators * Updated zh_CN: Funda Wang * Updated ca: Josep Puigdemont i Casamajó * Updated da: Peter Bach * Updated lv: Raivis Dejus * Updated sl: Matic Zgur * Updated eu: Inaki Larranaga Murgoitio * Updated gl: Ignacio Casal Quinteiro =============== Version 2.18.0 =============== cinnamon-screensaver * Fixed #412486, cinnamon-screensaver doesn't work with xnest (William Lachance) * Fixed #412492, cinnamon-screensaver won't build * Fixed #417323, build from trunk fails; undefined reference to pango symbols (Elijah Newren) * Fixed #417538, unapproved change broke theme management (William Jon McCann) Translators * Updated ru: Nickolay V. Shmyrev * Updated gu: Ankit Patel * Updated zh_HK.po, zh_TW: Abel Cheung * Updated it: Luca Ferretti * Updated mk: Jovan Naumovski + * Updated lt: Gintautas Miliauskas * Updated ar: Djihed Afifi * Updated dz: Pema Geyleg * Updated pl: Artur Flinta * Updated he: Yair Hershkovitz =============== Version 2.17.8 =============== cinnamon-screensaver * Fixed #400579, cinnamon-screensaver fails to compile against openpam (Ray Strode) * Fixed #407524, Freeze on unlock screen (William Jon McCann) * Fixed #407964, direct fast user switching (William Jon McCann) * Fixed #411393, 'switch user' button needs to turn inactive on selection (William Jon McCann) * Set ConsoleKit idle-hint state Translators * Updated bg: Alexander Shopov * Updated pt: Duarte Loreto * Updated ko: Changwoo Ryu * Updated hu: Gabor Kelemen * Updated lt: Gintautas Miliauskas * Updated uk: Maxim Dziumanenko * Updated fi: Ilkka Tuohela * Updated ja: Takeshi AIHANA * Updated pl: Artur Flinta =============== Version 2.17.7 =============== cinnamon-screensaver * #402183, use gdm socket command to start a login procedure when available (Matthias Clasen) * #403936, Specifically block shaping the window (William Jon McCann) * Sync FUSA code with upstream Translators * Updated fr: Stéphane Raimbault * Updated nl: Wouter Bolsterlee * Updated ca: Josep Puigdemont i Casamajó * Updated pt_BR: Leonardo Ferreira Fontenelle * Updated da: Lasse Bang Mikkelsen =============== Version 2.17.6 =============== cinnamon-screensaver * Categorize preferences for the control center (Denis Washington) Translators * Updated nb: Kjartan Maraas * Updated ca: Josep Puigdemont i Casamajó =============== Version 2.17.5 =============== cinnamon-screensaver * Fix some PAM threading issues * Fixed #387572, auth hangs when password is expired * Fixed #392780, Pass DBUS_SESSION_BUS_ADDRESS into hack environment Translators * Updated lv: Raivis Dejus * Updated et: Priit Laes * Updated ar: Djihed Afifi * Updated en_GB: British * Updated vi: Clytie Siddall =============== Version 2.17.4 =============== cinnamon-screensaver * Fix non-ramp gamma fading * Add script to help debugging * Be sure to initialize threading Themes * (slideshow) Check for empty file list Translators * Khaled Hosny (ar) * Francisco Javier F. Serrador (es) * Kjartan Maraas (nb) * Theppitak Karoonboonyanan (th) =============== Version 2.17.3 =============== cinnamon-screensaver * Convert PAM messages to UTF-8 (Ray Strode) * Make PAM authentication async (Ray Strode) Translators * Ivar Smolin (et) * Daniel Nylander (sv) =============== Version 2.17.2 =============== cinnamon-screensaver * Remove the pointer polling * Add a keyboard layout indicator (Sergey Udaltsov) * Only notice mouse motion of 10% of screen width (Thomas Andersen) * Add SessionPowerManagementIdleChanged D-Bus signal * Add GetInhibitors D-Bus method cinnamon-screensaver-preferences * Add a button to launch the power management preferences cinnamon-screensaver-command * Add option to how long screensaver was active (Patrick McLean) Translators * Francisco Javier F. Serrador (es) * Ivar Smolin (et) * Ilkka Tuohela (fi) * Ankit Patel (gu) * Jovan Naumovski (mk) * Kjartan Maraas (nb) =============== Version 2.17.1 =============== cinnamon-screensaver * Don't poll in dialog cinnamon-screensaver-preferences * Don't show expander column Translators * Gil Forcada (ca) * Jakub Friedl (cs) * Ivar Smolin (et) * Ignacio Casal Quinteiro (gl) =============== Version 2.16.1 =============== cinnamon-screensaver * Set the correct value of DISPLAY for the gl helper * Don't queue keys that may cause focus navigation (Bruno Boaventura) cinnamon-screensaver-preferences * Don't explicitly set icon sizes in preview bar (Dimitur Kirov) Translators * David Lodge (en_GB) * Ivar Smolin (et) * Rajesh Ranjan (hi) * Luca Ferretti (it) * Satoru SATOH (ja) * Leonardo Ferreira Fontenelle (pt_BR) =============== Version 2.16.0 =============== Translators * Kostas Papadimas (el) * Iñaki Larrañaga Murgoitio (eu) * Meelad Zakaria (fa) * Robert-André Mauchin (fr) * Rajesh Ranjan (hi) * Gabor Kelemen (hu) * Gintautas Miliauskas (lt) * Raivis Dejus (lv) * Jovan Naumovski (mk) * Subhransu Behera (or) * Duarte Loreto (pt) * Matic %GŽ%@gur (sl) * Theppitak Karoonboonyanan (th) * Deniz Koçak (tr) * Ching-Hung Lin (zh_HK) * Ching-Hung Lin (zh_TW) =============== Version 2.15.7 =============== Translators * Rostislav \"zbrox\" Raykov (bg) * Gil Forcada (ca) * Hendrik Richter (de) * Ivar Smolin (et) * Ilkka Tuohela (fi) * Ankit Patel (gu) * Gabor Kelemen (hu) * Satoru SATOH (ja) * Vladimer Sichinava (ka) * Changwoo Ryu (ko) * rizoye-xerzi (ku) * Ani Peter (ml) * Badral (mn) * Wouter Bolsterlee (nl) * Subhransu Behera (or) * Leonid Kanter (ru) * Daniel Nylander (sv) * Maxim V. Dziumanenko (uk) * Clytie Siddall (vi) =============== Version 2.15.6 =============== cinnamon-screensaver * Support drag-n-drop of themes to preferences dialog * Add support for embedding a keyboard in window * More memory usage reduction * Only allow a small number of queued key events Translators * Francisco Javier F. Serrador (es) * Ivar Smolin (et) * Ilkka Tuohela (fi) * Christophe Merlet (RedFox) (fr) * Ankit Patel (gu) * ahmad riza h nst (id) * %GŽ%@ygimantas Beru%Gč%@ka (lt) * Jovan Naumovski (mk) * Kjartan Maraas (nb) * Matic %GŽ%@gur (sl) * Theppitak Karoonboonyanan (th) =============== Version 2.15.5 =============== cinnamon-screensaver * Turn off themes when screen is not visible * Make the unlock dialog show on correct window under Xinerama * Prevent theme flickering from watchdog timer * Listen for HAL coffee key events * Ignore brightness key events cinnamon-screensaver-preferences * Populate themes list in an idle after startup Translators * Mahay Alam Khan (bn_IN) * Gil Forcada (ca) * Jakub Friedl (cs) * Hendrik Richter (de) * Kostas Papadimas (el) * Francisco Javier F. Serrador (es) * Priit Laes (et) * Ankit Patel (gu) * Rajesh Ranjan (hi) * Changwoo Ryu (ko) * Fano Rajaonarisoa (mg) * Daniel Nylander (sv) * Theppitak Karoonboonyanan (th) =============== Version 2.15.4 =============== cinnamon-screensaver * Override gtk+ theme background style * Use helper command to get best GL visual * Add a blocking inhibit option to the command-line tool * Add short options to the command-line tool * Misc memory reduction Translators * Rostislav \"zbrox\" Raykov (bg) * Mahay Alam Khan (bn_IN) * Jakub Friedl (cs) * Hendrik Richter (de) * Francisco Javier F. Serrador (es) * Ilkka Tuohela (fi) * Robert-André Mauchin (fr) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Yaniv Abir (he) * Rajesh Ranjan (hi) * Raivis Dejus (lv) * Jovan Naumovski (mk) * Kjartan Maraas (nb) * Shyam Krishna Bal (ne) * Daniel Nylander (sv) * Felix (ta) * Theppitak Karoonboonyanan (th) =============== Version 2.15.3 =============== cinnamon-screensaver * Fully support PAM driving the unlock dialog * Only support one auth backend configured at build time * Don't try to unlock using root's password * DBUS API changes based on XDG feedback * Add docbook documentation (Richard Hughes) * Use replacable tokens in the lock dialog theme glade file * Set lock flag before activating (Rodrigo Moya) * Fix support for RUNNING_UNDER_GDM environment variable * Increase minimum distance the mouse must move to detect motion * Add theme engine profiling support * Switch user when double clicking in treeview * Don't reset throttle when deactivating * Try to grab keyboard before doing idle notice fade-out * Make activation wait for fade to complete. cinnamon-screensaver-preferences * Print a warning that locking is disabled when running as root Themes * (slideshow) Performance improvements (L. David Baron) Translators * Jakub Friedl (cs) * Francisco Javier F. Serrador (es) * Ankit Patel (gu) * Kjartan Maraas (nb) * Theppitak Karoonboonyanan (th) * Clytie Siddall (vi) =============== Version 2.15.2 =============== cinnamon-screensaver * Sync with FUSA code (fixes GDM configuration) * Make cancel close the unlock dialog * Make button presses and scroll events request an unlock * Send DBUS signals before/after authentication is requested * Various fixes for async fade out * Fix potential crasher when poked while fading * Support short username in themed dialog (Matthias Clasen) Themes * (popsquares) Fix crash when window is NULL (Joe Marcus Clarke) Translators * Francisco Javier F. Serrador (es) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Kjartan Maraas (nb) * Chao-Hsiung Liao (zh_HK) * Chao-Hsiung Liao (zh_TW) =============== Version 2.15.1 =============== cinnamon-screensaver * Add support for theming the lock dialog * Use OpenGL to get the best visual and use it * Shorten mouse poll interval * New DBUS API for throttle and inhibit * Support themes in all XDG dirs (including $HOME) * Make caps-lock warning more accurate cinnamon-screensaver-preferences * Add fullscreen preview * Update wording Translators * Priit Laes (et) * Ilkka Tuohela (fi) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Clytie Siddall (vi) =============== Version 2.14.1 =============== cinnamon-screensaver * Detect button press activity (Ray Strode) * Make operation after system suspend (Ray Strode) * Cygwin build fix * Use GTimer for portability * Obtain new Kerberos credentials when unlocking screen Themes * (floaters) Use the entire screen at start Translators * Lukas Novotny (cs) * Ivar Smolin (et) * Benoît Dejean (fr) * Wouter Bolsterlee (nl) * Andrzej PolatyÅski (pl) * Theppitak Karoonboonyanan (th) * Clytie Siddall (vi) =============== Version 2.14.0 =============== cinnamon-screensaver * Removed unused GConf keys from schemas * Don't queue keypad enter keypresses * Use black circle as invisible character in password entry Translators * Rostislav \"zbrox\" Raykov (bg) * Mahay Alam Khan (bn) * Gil Forcada (ca) * Petr TomeÅ¡ (cs) * Rhys Jones (cy) * David Nielsen (da) * Frank Arnold (de) * Ivar Smolin (et) * Rajesh Ranjan (hi) * Luca Ferretti (it) * Young-Ho Cha (ko) * Kjartan Maraas (nb) * Kjartan Maraas (no) * Raphael Higino (pt_BR) * Duarte Loreto (pt) * Laurent Dhima (sq) * Daniel Nylander (sv) * Maxim V. Dziumanenko (uk) =============== Version 2.13.92 =============== cinnamon-screensaver * Fix problems when some other program has keyboard grabbed * Add a pkg-config file for out of tree themes * Use a black bullet character instead of * for password entry * Capitalize DBUS method names that weren't already cinnamon-screensaver-preferences * Track gconf key changes for themes Translators * Kostas Papadimas (el) * Francisco Javier F. Serrador (es) * Ilkka Tuohela (fi) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Gabor Kelemen (hu) * Luca Ferretti (it) * Satoru SATOH (ja) * Vladimer SIchinava (ka) * Hyun-Jin Moon (ko) * Žygimantas BeruÄka (lt) * Kjartan Maraas (nb) * Tino Meinen (nl) * Kjartan Maraas (no) * Raphael Higino (pt_BR) * Leonid Kanter (ru) * Theppitak Karoonboonyanan (th) * Clytie Siddall (vi) =============== Version 2.13.91 =============== cinnamon-screensaver * Maintain a pointer grab unless the unlock dialog is up * Convert the real and user names to UTF8 * Use G_GUINT32_FORMAT for communicating XID * Start themes after grabbing window * Handle broken grabs * Don't abort when fade isn't available * Display host name in unlock dialog cinnamon-screensaver-preferences * Add help * Don't make heading bold or indent under it Themes * (floaters) More performance work (Ray Strode) Translators * Gil Forcada (ca) * Lukas Novotny (cs) * Žygimantas BeruÄka (lt) * Ãivind Hoel (nb) =============== Version 2.13.90 =============== cinnamon-screensaver * Ignore our windows when watching for map and configure events * Clear window after showing to prevent flashing * Don't start child processes in home directory themes * (floaters) Cap update rate (Ray Strode) Translators * Rostislav \"zbrox\" Raykov (bg) * Hendrik Brandt (de) * Ilkka Tuohela (fi) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Tino Meinen (nl) * Theppitak Karoonboonyanan (th) * Chao-Hsiung Liao (zh_HK) * Chao-Hsiung Liao (zh_TW) ============== Version 2.13.5 ============== cinnamon-screensaver * Move DPMS functionality to gnome-power-manager * Rename the DBUS interface from screensaver to ScreenSaver * Disable the X.org grab smasher * Don't do the slow fade if we are inhibited * Fix screen flashing after idle activation cinnamon-screensaver-preferences * Rework dialog for setting session idle timeout * Remove unused help button Translators * Rostislav \"zbrox\" Raykov (bg) * Adam Weinberger (en_CA) * Francisco Javier F. Serrador (es) * Ilkka Tuohela (fi) * Ignacio Casal Quinteiro (gl) * Takeshi AIHANA (ja) * Tino Meinen (nl) * Clytie Siddall (vi) * Abel Cheung (zh_HK) * Abel Cheung (zh_TW) ============== Version 0.0.24 ============== cinnamon-screensaver * Add proper session idle reporting * Clear all children of toplevel windows Translators * Josep Puigdemont i Casamajó (ca) * Adam Weinberger (en_CA) * Francisco Javier F. Serrador (es) * Ilkka Tuohela (fi) * Ankit Patel (gu) * Žygimantas BeruÄka (lt) * Tino Meinen (nl) * Слободан Ð. СÑедоÑÐµÐ²Ð¸Ñ (sr) * Theppitak Karoonboonyanan (th) * Clytie Siddall (vi) ============== Version 0.0.23 ============== cinnamon-screensaver * Fix idle warning cancellation * Changes to D-Bus API * Add --debug command line option * Build fix when DPMS disabled themes * (floaters) New theme engine (Ray Strode et al) Translators * Francisco Javier F. Serrador (es) * Ignacio Casal Quinteiro (gl) * Ankit Patel (gu) * Takeshi AIHANA (ja) * Theppitak Karoonboonyanan (th) ============== Version 0.0.22 ============== cinnamon-screensaver * Don't mess up event mask for root window. Translators * Miloslav Trmac (cs) * Gabor Kelemen (hu) * Kjartan Maraas (nb) * Kjartan Maraas (no) ============== Version 0.0.21 ============== cinnamon-screensaver * Try to prevent popups over screensaver window * Use an interruptable slow fade before idle activation Translators * Rostislav \"zbrox\" Raykov (bg) * Ilkka Tuohela (fi) * Åygimantas BeruÄka (lt) * Amanpreet Singh Alam (pa) * Marcel Telka (sk) * Theppitak Karoonboonyanan (th) ============== Version 0.0.20 ============== cinnamon-screensaver * Fix blanking when running under Xnest ============== Version 0.0.19 ============== cinnamon-screensaver * Allow trying password after auth failure * Allow more space for user list * Make unlock dialog centered vertically * Use OverrideRedirect windows * Sync with latest FUSA version * Add test for window/dialog subsystem * Fix leaking of signal handlers * Misc correctness fixes Translators * Adam Weinberger (en_CA) * Francisco Javier F. Serrador (es) * Davy Defaud (fr) * Takeshi AIHANA (ja) * Åygimantas Beruka (lt) ============== Version 0.0.18 ============== cinnamon-screensaver * UI tweaks for unlock dialog * Fix Intel compiler warnings (Kjartan Maraas) * Do more error checking of GConf input * Check for command parsing errors * Fix leaks * Redesign the idle watcher and fix leaks * Solaris build fixes (Damien Carbery) cinnamon-screensaver-preferences * Make lock toggle work again Translators * Miloslav Trmac (cs) * Adam Weinberger (en_CA) * Francisco Javier F. Serrador (es) * Davy Defaud (fr) * Gabor Kelemen (hu) * Takeshi AIHANA (ja) * Tino Meinen (nl) ============== Version 0.0.17 ============== cinnamon-screensaver * Restart idle watch if can't grab keyboard * Make timeout in preferences work again * Daemonize process by default * Add option --no-daemon * Don't use any icon if face image is not found Translators * Adam Weinberger (en_CA) * Kjartan Maraas (nb) * Kjartan Maraas (no) ============== Version 0.0.16 ============== cinnamon-screensaver * Shake the dialog when authentication fails * Maintain nicer aspect ratio on unlock dialog * Only notice motion of 10 pixels or more * Periodically raise windows * Don't emit duplicate response signals from dialog * Make dialog buttons insensitive when input isn't allowed * Add a gconf setting for the logout command themes * (slideshow) Skip thumbnail images Translators * Rostislav \"zbrox\" Raykov (bg) * Adam Weinberger (en_CA) * Francisco Javier F. Serrador (es) * Takeshi AIHANA (ja) * Tino Meinen (nl) * Funda Wang (zh_CN) ============== Version 0.0.15 ============== cinnamon-screensaver * First version with working power management * Add Gamma fade out * Don't forward first enter or space to unlock dialog * Make poke command work when screen is blanked * Add getIdleTime dbus method * Translation fixes themes * (slideshow) Optionally use EXIF info to rotate images (torkel@acc.umu.se) Translators * Rostislav \"zbrox\" Raykov (bg) * Miloslav Trmac (cs) * Adam Weinberger (en_CA) * Žygimantas BeruÄka (lt) * Kjartan Maraas (nb) * Tino Meinen (nl) * Kjartan Maraas (no) ============== Version 0.0.14 ============== cinnamon-screensaver * Don't drop keypresses before unlock dialog appears * Use .desktop files and menu spec to find themes * Simplify unlock dialog * Make user switching a gconf option (Matthias Clasen) * Make user switching disabled by default * Fix a crash due to a missing error handler cinnamon-screensaver-preferences * Use new themes API that will theme list to be modified by distro/sysadmin/user. Translators * Ilkka Tuohela (fi) * Luca Ferretti (it) * Takeshi AIHANA (ja) * Tino Meinen (nl) * Clytie Siddall (vi) ============== Version 0.0.13 ============== cinnamon-screensaver * Fix problem when starting GNOME from KDM * Only look for theme files that end in .xml * Look for xscreensaver themes in a few more places ============== Version 0.0.12 ============== cinnamon-screensaver * Fix crasher caused by destroying NULL hash table * Don't activate after last inhibitor is removed Translators * Adam Weinberger (en_CA) ============== Version 0.0.11 ============== cinnamon-screensaver * Make unlock dialog show more quickly * Support the gconf cycle timeout key * Add system name to unlock dialog cinnamon-screensaver-preferences * Add random theme (Rodrigo) Translators * Francisco Javier F. Serrador (es) * Tino Meinen (nl) * Clytie Siddall (vi) ============== Version 0.0.10 ============== cinnamon-screensaver * Fix hang on system resume * Actually use the gconf lock key * Add configure option to look for xscreensaver hacks (Rodrigo) cinnamon-screensaver-preferences * Add checkbox to enable/disable locking (Rodrigo) * Make type ahead find work correctly * HIG fixes (Dennis Cranston) Translators * Adam Weinberger (en_CA) * Eric Maeker (fr) * Takeshi AIHANA (ja) * Clytie Siddall (vi) ============= Version 0.0.9 ============= cinnamon-screensaver * Added slideshow theme engine * Display username if real name is unknown (Rodrigo) themes * Added personal slideshow theme * Added cosmos slideshow theme Translators * Rostislav \"zbrox\" Raykov (bg) * Tommi Vainikainen (fi) * Maxim V. Dziumanenko (uk) ============= Version 0.0.8 ============= cinnamon-screensaver * Add Dbus API for inhibiting the idle activation * Integrate fast-user-switching directly into the unlock dialog. * Restart unlock dialog timer after every keystroke * Fix leaks * Fix xauth problems for some displays Translators * Adam Weinberger (en_CA) * Takeshi AIHANA (ja) * Tino Meinen (nl) * Abel Cheung (zh_TW) ============= Version 0.0.7 ============= cinnamon-screensaver * Fix authentication on SuSE/Novell * Automatically find the SuSE/Novell gdm.conf file * Don't require the gdm.conf file to exist at build time * Actually ship the translations * Fix crash in popsquares * Reset throttle value after deactivation Translators * Hendrik Richter (de) * Adam Weinberger (en_CA) * Takeshi AIHANA (ja) * Christian Rose (sv) ============= Version 0.0.6 ============= cinnamon-screensaver * Added Multi-head/Xinerama support * Added screensaver throttle capability * Depend on dbus >= 0.3 * Use property based dbus methods/signals * Fix Solaris build * Install own PAM configuration instead of relying on xscreensaver * Add ability to disable 'New Login' button cinnamon-screensaver-preferences * Support drag and drop of theme configuration files * Display a nicer form of the activation time value Translators * Frank Arnold (de) * Adam Weinberger (en_CA) * James Ogley (en_GB) * Francisco Javier F. Serrador (es) * Raphael Higino (pt_BR) * Christian Rose (sv) * Funda Wang (zh_CN) ============= Version 0.0.5 ============= cinnamon-screensaver * Support user themes in USER_DATA_DIR/cinnamon-screensaver/themes/ * Send activation/deactivation signals on session message bus * Added DPMS support * Added xscreensaver compatible XML configuration for themes * Add optional logout button after a specified amount of time * Fix leaking of file descriptors cinnamon-screensaver-preferences * Added configuration applet * Use screensaver icon themes * Added version of popsquares that follows GNOME theme cinnamon-screensaver-2.8.0/.gitignore0000664000175000017500000000133612610211212016544 0ustar fabiofabioINSTALL Makefile Makefile.in aclocal.m4 autom4te.cache/ compile config.guess config.h config.h.in config.log config.status config.sub configure data/Makefile data/Makefile.in data/org.cinnamon.ScreenSaver.service data/screensavers/Makefile depcomp files/Makefile install-sh intltool-extract.in intltool-merge.in intltool-update.in libtool ltmain.sh missing omf.make po/.intltool-merge-cache po/Makefile po/Makefile.in po/POTFILES po/stamp-it src/.deps/ src/Makefile src/Makefile.in src/*.o src/cinnamon-screensaver src/cinnamon-screensaver-command src/cinnamon-screensaver-dialog src/cinnamon-screensaver.desktop src/cinnamon-screensaver.desktop.in src/test-fade src/test-passwd src/test-watcher src/test-window stamp-h1 xmldocs.make