diff options
author | root <root@rshg054.dnsready.net> | 2013-09-10 01:37:49 -0700 |
---|---|---|
committer | root <root@rshg054.dnsready.net> | 2013-09-10 01:37:49 -0700 |
commit | f5039428394b8715a685c006ab4c7421f45d0aff (patch) | |
tree | f5330d39e85a451f7ebfdc2ebbaac0b011c77a7b /community/lxdm | |
parent | 25f164e4d715807385e621f21bf1715d64d925a8 (diff) |
Tue Sep 10 01:36:04 PDT 2013
Diffstat (limited to 'community/lxdm')
-rw-r--r-- | community/lxdm/PKGBUILD | 91 | ||||
-rw-r--r-- | community/lxdm/default-config.patch | 80 | ||||
-rw-r--r-- | community/lxdm/git-fixes.patch | 2038 | ||||
-rw-r--r-- | community/lxdm/lxdm.install | 23 |
4 files changed, 2163 insertions, 69 deletions
diff --git a/community/lxdm/PKGBUILD b/community/lxdm/PKGBUILD index 8316a95aa..1c8043ebc 100644 --- a/community/lxdm/PKGBUILD +++ b/community/lxdm/PKGBUILD @@ -1,82 +1,63 @@ -# $Id: PKGBUILD 95338 2013-08-09 22:46:10Z dwallace $ +# $Id: PKGBUILD 96932 2013-09-08 22:11:41Z bgyorgy $ # Maintainer: Bartłomiej Piotrowski <nospam@bpiotrowski.pl> # Contributor: AndyRTR <andyrtr@archlinux.org> # Contributor: kiefer <jorgelmadrid@gmail.com> pkgname=lxdm pkgver=0.4.1 -pkgrel=23 +pkgrel=25 pkgdesc='Lightweight X11 Display Manager' arch=('i686' 'x86_64') url="http://sourceforge.net/projects/lxdm/" license=('GPL') groups=('lxde') depends=('gtk2' 'xorg-server') -makedepends=('intltool') -optdepends=('librsvg: display the default background') -install=${pkgname}.install +makedepends=('git' 'intltool') +optdepends=('gtk-engines: default GTK+ theme' + 'librsvg: display the default background') +install=$pkgname.install backup=('etc/lxdm/lxdm.conf' 'etc/pam.d/lxdm' 'etc/lxdm/Xsession' 'etc/lxdm/PreLogin' 'etc/lxdm/LoginReady' 'etc/lxdm/PostLogin' 'etc/lxdm/PostLogout' 'etc/lxdm/PreReboot' 'etc/lxdm/PreShutdown') source=(http://downloads.sourceforge.net/lxde/$pkgname-$pkgver.tar.gz - lxdm.pam lxdm.service - lxdm-0.4.1-Xsession-source-profile.patch - lxdm-0.4.1-conf.patch - lxdm-0.4.1-event-check-bug.patch - lxdm-0.4.1-industrial-greeter-ui.patch - lxdm-0.4.1-modern-systems.patch - lxdm-0.4.1-nolang-show-sessions.patch - lxdm-0.4.1-pam-env-vars.patch - lxdm-0.4.1-kill_user_processes.patch - ) + git-fixes.patch + default-config.patch) md5sums=('8da1cfc2be6dc9217c85a7cf51e1e821' - '9cc734228696a3c6f06d91bba61b03c1' - 'b86317143ae44d7ed38c150fe4f25502' - 'd2e4a4a22ee2aa1a986be154c647b6c6' - 'c50dd01b715b0a236407d48066191601' - 'a1e3c46a8bef691bc544028f5b6cfe22' - '2c4afdbe3532be4f90d8f6240d352766' - 'baed9055e8825a5511712bc095197519' - '28475239d0c8b4fd778ec49f5ec72962' - '4c1d43e81e9a256e8d1ea7686c24b3d3' - '3ac63085f9df9296dfa645fa623af0e2') + 'b9e0d1fcf2a3e163446269a5614c2779' + '3c1aa66182acbbf85f2e0aad03bf133b') prepare(){ - cd $srcdir/$pkgname-$pkgver - patch -Np1 -i $srcdir/lxdm-0.4.1-event-check-bug.patch - patch -Np1 -i $srcdir/lxdm-0.4.1-nolang-show-sessions.patch - patch -Np1 -i $srcdir/lxdm-0.4.1-pam-env-vars.patch - patch -Np1 -i $srcdir/lxdm-0.4.1-kill_user_processes.patch -} + cd "$srcdir/$pkgname-$pkgver" -build() { - cd $srcdir/$pkgname-$pkgver + # Apply various fixes from git + patch -Np1 -i ../git-fixes.patch + # Adjust Arch-specific settings + patch -Np1 -i ../default-config.patch - ./configure --sysconfdir=/etc --prefix=/usr --libexecdir=/usr/lib/lxdm \ - --bindir=/usr/bin \ - --sbindir=/usr/bin - make - - patch -Np0 -i $srcdir/lxdm-0.4.1-modern-systems.patch - patch -Np0 -i $srcdir/lxdm-0.4.1-conf.patch - patch -Np0 -i $srcdir/lxdm-0.4.1-Xsession-source-profile.patch - patch -Np0 -i $srcdir/lxdm-0.4.1-industrial-greeter-ui.patch + # Fix version number + sed -i 's/3.6.0/3.8/' gnome-shell/LXDM_User_Switch@dgod/metadata.json } +build() { + cd "$srcdir/$pkgname-$pkgver" + autoreconf -fi + ./configure --prefix=/usr --sbindir=/usr/bin --libexecdir=/usr/lib/lxdm \ + --sysconfdir=/etc --localstatedir=/var + make +} package() { - cd $srcdir/$pkgname-$pkgver - make DESTDIR=$pkgdir sbindir=/usr/bin install - - install -m644 $srcdir/lxdm.pam $pkgdir/etc/pam.d/lxdm - install -Dm644 $srcdir/lxdm.service $pkgdir/usr/lib/systemd/system/lxdm.service - install -d $pkgdir/var/lib/lxdm - echo "GDK_CORE_DEVICE_EVENTS\t\t\tDEFAULT=1" > $pkgdir/var/lib/lxdm/.pam_environment - chmod 644 $pkgdir/var/lib/lxdm/.pam_environment - - # fix the greeter location - sed -i -e 's/local\/libexec/lib\/lxdm/' $pkgdir/etc/lxdm/lxdm.conf - sed -i 's:sbin:bin:' $pkgdir/usr/bin/lxdm - + cd "$srcdir/$pkgname-$pkgver" + make DESTDIR="$pkgdir" install + chmod 644 "$pkgdir/etc/lxdm/lxdm.conf" + + # Home directory + install -dm 755 "$pkgdir/var/lib/lxdm" + echo 'GDK_CORE_DEVICE_EVENTS=true' > "$pkgdir"/var/lib/lxdm/.pam_environment + chown -R 121:121 "$pkgdir/var/lib/lxdm" + + # GNOME Shell extension + mkdir -p "$pkgdir/usr/share/gnome-shell/extensions" + cp -r gnome-shell/LXDM_User_Switch@dgod "$pkgdir/usr/share/gnome-shell/extensions" } diff --git a/community/lxdm/default-config.patch b/community/lxdm/default-config.patch new file mode 100644 index 000000000..c0a579840 --- /dev/null +++ b/community/lxdm/default-config.patch @@ -0,0 +1,80 @@ +diff -Naur lxdm.orig/data/lxdm.conf.in lxdm/data/lxdm.conf.in +--- lxdm.orig/data/lxdm.conf.in 2013-08-30 17:56:16.097006000 +0200 ++++ lxdm/data/lxdm.conf.in 2013-09-04 01:54:12.942117085 +0200 +@@ -23,7 +23,7 @@ + + [server] + ## arg used to start xserver, not fully function +-# arg=/usr/bin/X -background vt1 ++arg=/usr/bin/X -background vt1 + # uncomment this if you really want xserver listen to tcp + # tcp_listen=1 + # uncoment this if you want reset the xserver after logou +@@ -34,7 +34,7 @@ + gtk_theme=Clearlooks + + ## background of the greeter +-bg=/usr/share/backgrounds/default.png ++# bg=/usr/share/backgrounds/default.png + + ## if show bottom pane + bottom_pane=1 +diff -Naur lxdm.orig/data/lxdm.in lxdm/data/lxdm.in +--- lxdm.orig/data/lxdm.in 2013-08-30 17:56:16.097006000 +0200 ++++ lxdm/data/lxdm.in 2013-09-04 01:57:56.950799946 +0200 +@@ -1,21 +1,13 @@ + #!/bin/sh + +-[ -f /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n +- +-if [ -z "$LANG" -a -e /etc/sysconfig/language ]; then +- . /etc/sysconfig/language +- if [ -n "$RC_LANG"]; then +- LANG=$RC_LANG +- fi ++if [ -r /etc/profile.d/locale.sh ]; then ++ . /etc/profile.d/locale.sh + fi + + if [ -n "$LANG" ]; then + export LANG + fi + +-[ -f /etc/sysconfig/desktop ] && . /etc/sysconfig/desktop +-[ -f /etc/sysconfig/windowmanager ] && . /etc/sysconfig/windowmanager +- + if [ -n "$DEFAULT_WM" ]; then + PREFERRED=$DEFAULT_WM + fi +diff -Naur lxdm.orig/data/Xsession lxdm/data/Xsession +--- lxdm.orig/data/Xsession 2013-08-30 17:56:16.097006000 +0200 ++++ lxdm/data/Xsession 2013-09-04 01:58:19.941348762 +0200 +@@ -9,6 +9,8 @@ + LXSESSION=/usr/bin/startlxde + fi + ++[ -f /etc/profile ] && . /etc/profile ++[ -f ~/.profile ] && . ~/.profile + [ -f /etc/xprofile ] && . /etc/xprofile + [ -f ~/.xprofile ] && . ~/.xprofile + +diff -Naur lxdm.orig/pam/lxdm lxdm/pam/lxdm +--- lxdm.orig/pam/lxdm 2013-08-30 17:56:16.100339000 +0200 ++++ lxdm/pam/lxdm 2013-08-30 17:58:35.543771605 +0200 +@@ -1,10 +1,7 @@ + #%PAM-1.0 +-auth substack system-auth +-auth optional pam_gnome_keyring.so +-account include system-auth +-session optional pam_keyinit.so force revoke +-session include system-auth +-session required pam_loginuid.so +-session optional pam_console.so +-session optional pam_gnome_keyring.so auto_start +-session optional pam_selinux.so ++auth include system-login ++-auth optional pam_gnome_keyring.so ++account include system-login ++password include system-login ++session include system-login ++-session optional pam_gnome_keyring.so auto_start diff --git a/community/lxdm/git-fixes.patch b/community/lxdm/git-fixes.patch new file mode 100644 index 000000000..0f724d0e2 --- /dev/null +++ b/community/lxdm/git-fixes.patch @@ -0,0 +1,2038 @@ +diff --git a/Makefile.am b/Makefile.am +index bfac56b..6f997b8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,4 +1,5 @@ + NULL = ++ + SUBDIRS= \ + src \ + po \ +@@ -6,6 +7,10 @@ SUBDIRS= \ + data \ + $(NULL) + ++if HAVE_SYSTEMD ++SUBDIRS += systemd ++endif ++ + rpm: dist @PACKAGE_NAME@.spec + rpmbuild -bb \ + --define "_sourcedir `pwd`" \ +diff --git a/configure.ac b/configure.ac +index e952473..c307de2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2,8 +2,8 @@ + # Process this file with autoconf to produce a configure script. + + AC_PREREQ([2.63]) +-AC_INIT([lxdm], [0.4.1], [http://lxde.org/]) +-AM_INIT_AUTOMAKE([-Wall -Werror foreign]) ++AC_INIT([lxdm], [0.4.2], [http://lxde.org/]) ++AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) + + AC_CONFIG_SRCDIR([src/lxdm.c]) + AC_CONFIG_HEADERS([config.h]) +@@ -16,10 +16,17 @@ AM_PROG_CC_C_O + # Checks for libraries. + AC_CHECK_LIB([crypt], [crypt]) + +-AC_ARG_WITH(pam,AC_HELP_STRING([--without-pam],[build without pam]), +-[],[AC_CHECK_LIB([pam], [pam_open_session])]) +- +-AC_CHECK_LIB([ck-connector],[ck_connector_open_session]) ++# Check for PAM support ++AC_ARG_WITH(pam, AC_HELP_STRING([--with-pam],[Use PAM for authentication]), ++ [USE_PAM=$withval], [USE_PAM=$use_pam_default]) ++if test "x$USE_PAM" != "xno" ; then ++ AC_SEARCH_LIBS(pam_open_session,[pam]) ++ AC_CHECK_FUNC(pam_open_session, ++ [AC_DEFINE(USE_PAM,1,[Use PAM for authentication])], ++ [if test "x$USE_PAM" != "xtry" ; then ++ AC_MSG_ERROR(["PAM support requested, but pam_open_session not found."]) ++ fi]) ++fi + + # Checks for header files. + AC_PATH_X +@@ -80,11 +87,22 @@ PKG_CHECK_MODULES(GTK, [$pkg_modules]) + AC_SUBST(GTK_CFLAGS) + AC_SUBST(GTK_LIBS) + +-PKG_CHECK_MODULES(CONSOLEKIT, "ck-connector",[ ++ ++AC_ARG_ENABLE(consolekit, ++ AC_HELP_STRING([--disable-consolekit],[disable ConsoleKit support]), ++ [enable_consolekit=$enableval], ++ [enable_consolekit=yes] ++) ++ ++if test "x$enable_consolekit" = "xyes" ; then ++ PKG_CHECK_MODULES(CONSOLEKIT, "ck-connector",[ + AC_SUBST(CONSOLEKIT_CFLAGS) + AC_SUBST(CONSOLEKIT_LIBS)],[ + echo "ConsoleKit devel package not found" + ]) ++ AC_CHECK_LIB([ck-connector],[ck_connector_open_session]) ++fi ++ + + AC_ARG_ENABLE(password, + AC_HELP_STRING([--enable-password],[enable to load autologin password store at config file]), +@@ -138,6 +156,14 @@ AC_ARG_WITH(xconn, + ] + ) + ++AC_ARG_WITH([systemdsystemunitdir], ++ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), ++ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) ++if test "x$with_systemdsystemunitdir" != xno; then ++ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) ++fi ++AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) ++ + GETTEXT_PACKAGE=lxdm + AC_SUBST(GETTEXT_PACKAGE) + AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.]) +@@ -148,6 +174,7 @@ AC_CONFIG_FILES([ + src/Makefile + po/Makefile.in + pam/Makefile ++ systemd/Makefile + data/Makefile + data/PostLogin + data/PostLogout +diff --git a/data/Makefile.am b/data/Makefile.am +index 6d3fad6..9500da9 100644 +--- a/data/Makefile.am ++++ b/data/Makefile.am +@@ -1,6 +1,6 @@ + FULL_LIBEXECDIR=$(libexecdir) + +-lxdm.conf : lxdm.conf.in ++lxdm.conf: lxdm.conf.in + cat lxdm.conf.in | sed 's,@FULL_LIBEXECDIR@,$(FULL_LIBEXECDIR),' > $@ + + NULL= +diff --git a/data/Xsession b/data/Xsession +index 287db71..fe76de0 100755 +--- a/data/Xsession ++++ b/data/Xsession +@@ -15,12 +15,7 @@ fi + if [ -f /etc/X11/xinit/xinitrc-common ]; then + # fedora + . /etc/X11/xinit/xinitrc-common +- if ! [ -z "$XDG_SESSION_COOKIE" ]; then +- CK_XINIT_SESSION= +- elif [ -x /usr/bin/ck-launch-session -a -z "$CK_XINIT_SESSION" ]; then +- CK_XINIT_SESSION="/usr/bin/ck-launch-session" +- fi +- exec -l $SHELL -c "$CK_XINIT_SESSION \"$LXSESSION\"" ++ exec -l bash -c "$LXSESSION" + elif [ -x /etc/X11/xinit/Xsession ]; then + # fedora + exec /etc/X11/xinit/Xsession "$LXSESSION" +@@ -30,17 +25,24 @@ elif [ -x /etc/X11/Xsession ]; then + elif [ -x /etc/X11/xinit/xinitrc ]; then + #suse + export WINDOWMANAGER=$LXSESSION +- exec -l $SHELL -c /etc/X11/xinit/xinitrc ++ exec -l bash -c /etc/X11/xinit/xinitrc + else + # unknown, user should custom /etc/lxdm/xinitrc self + if [ -x /etc/lxdm/xinitrc ]; then +- . /etc/lxdm/xinitrc ++ . /etc/lxdm/xinitrc "$LXSESSION" ++ fi ++ if [ -d /etc/X11/xinit/xinitrc.d ] ; then ++ for f in /etc/X11/xinit/xinitrc.d/* ; do ++ [ -x "$f" ] && . "$f" ++ done ++ unset f + fi +- if ! [ -z "$XDG_SESSION_COOKIE" ]; then +- CK_XINIT_SESSION= +- elif [ -x /usr/bin/ck-launch-session ]; then +- CK_XINIT_SESSION="/usr/bin/ck-launch-session" ++ ++ if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; ++ then ++ eval "$(dbus-launch --sh-syntax --exit-with-session)" + fi +- exec -l $SHELL -c "$CK_XINIT_SESSION \"$LXSESSION\"" ++ ++ exec -l bash -c "$LXSESSION" + fi + +diff --git a/data/config.ui b/data/config.ui +index 423fe56..b6d724d 100644 +--- a/data/config.ui ++++ b/data/config.ui +@@ -175,8 +175,99 @@ + </packing> + </child> + <child> ++ <object class="GtkHBox" id="hbox3"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <child> ++ <object class="GtkCheckButton" id="lxdm-enable-bottom-pane"> ++ <property name="label" translatable="yes">Enable bottom panel</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="xalign">0</property> ++ <property name="draw_indicator">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">3</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkAlignment" id="alignment3"> ++ <property name="visible">True</property> ++ <property name="xscale">0</property> ++ <property name="yscale">0</property> ++ <child> ++ <object class="GtkHBox" id="hbox4"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <child> ++ <object class="GtkLabel" id="label3"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="label" translatable="yes">Bottom Panel Options</property> ++ <attributes> ++ <attribute name="underline" value="True"/> ++ </attributes> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ </object> ++ </child> ++ </object> ++ </child> ++ <child> ++ <object class="GtkVBox" id="vbox2"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <child> ++ <object class="GtkCheckButton" id="lxdm-transparent-pane"> ++ <property name="label" translatable="yes">Transparent panel</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="xalign">0</property> ++ <property name="draw_indicator">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkCheckButton" id="lxdm-hide-sessions"> ++ <property name="label" translatable="yes">Hide sessions</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="xalign">0</property> ++ <property name="draw_indicator">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">1</property> ++ </packing> ++ </child> ++ <child> + <object class="GtkCheckButton" id="lxdm-show-lang"> +- <property name="label" translatable="yes">Show languanges menu</property> ++ <property name="label" translatable="yes">Show languages menu</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> +@@ -187,7 +278,7 @@ + <packing> + <property name="expand">False</property> + <property name="fill">True</property> +- <property name="position">3</property> ++ <property name="position">2</property> + </packing> + </child> + <child> +@@ -203,9 +294,60 @@ + <packing> + <property name="expand">False</property> + <property name="fill">True</property> ++ <property name="position">3</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkCheckButton" id="lxdm-hide-exit"> ++ <property name="label" translatable="yes">Hide quit button</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="xalign">0</property> ++ <property name="draw_indicator">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> + <property name="position">4</property> + </packing> + </child> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">5</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkAlignment" id="alignment4"> ++ <property name="visible">True</property> ++ <property name="xscale">0</property> ++ <property name="yscale">0</property> ++ <child> ++ <object class="GtkHBox" id="hbox5"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <child> ++ <object class="GtkLabel" id="label4"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="label" translatable="yes">Other Options</property> ++ <attributes> ++ <attribute name="underline" value="True"/> ++ </attributes> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ </object> ++ </child> ++ </object> ++ </child> + <child> + <object class="GtkCheckButton" id="lxdm-user-list"> + <property name="label" translatable="yes">Show user list</property> +@@ -219,7 +361,23 @@ + <packing> + <property name="expand">False</property> + <property name="fill">True</property> +- <property name="position">5</property> ++ <property name="position">7</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkCheckButton" id="lxdm-hide-time"> ++ <property name="label" translatable="yes">Hide time</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="xalign">0</property> ++ <property name="draw_indicator">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">True</property> ++ <property name="position">8</property> + </packing> + </child> + <child> +diff --git a/data/lxdm.conf.in b/data/lxdm.conf.in +index dd94686..d93f280 100644 +--- a/data/lxdm.conf.in ++++ b/data/lxdm.conf.in +@@ -15,12 +15,19 @@ + ## set this if you don't want to put xauth file at ~/.Xauthority + # xauth_path=/tmp + ++# not ask password for users who have empty password ++# skip_password=1 ++ + ## greeter used to welcome the user + greeter=@FULL_LIBEXECDIR@/lxdm-greeter-gtk + + [server] + ## arg used to start xserver, not fully function + # arg=/usr/bin/X -background vt1 ++# uncomment this if you really want xserver listen to tcp ++# tcp_listen=1 ++# uncoment this if you want reset the xserver after logou ++# reset=1 + + [display] + ## gtk theme used by greeter +diff --git a/data/lxdm.glade b/data/lxdm.glade +index 81175e8..221c2a3 100644 +--- a/data/lxdm.glade ++++ b/data/lxdm.glade +@@ -125,7 +125,9 @@ + </packing> + </child> + <child> +- <object class="GtkComboBoxEntry" id="keyboard"/> ++ <object class="GtkComboBoxEntry" id="keyboard"> ++ <property name="text_column">0</property> ++ </object> + <packing> + <property name="expand">False</property> + <property name="position">3</property> +diff --git a/data/themes/Industrial/greeter-gtk3.ui b/data/themes/Industrial/greeter-gtk3.ui +index 483809c..2f4e631 100644 +--- a/data/themes/Industrial/greeter-gtk3.ui ++++ b/data/themes/Industrial/greeter-gtk3.ui +@@ -1,7 +1,5 @@ + <?xml version="1.0"?> + <interface> +- <!-- interface-requires gtk+ 2.12 --> +- <!-- interface-naming-policy project-wide --> + <object class="GtkWindow" id="lxdm"> + <property name="decorated">False</property> + <child> +@@ -25,7 +23,7 @@ + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xscale">0</property> +- <property name="yscale">0</property> ++ <property name="yscale">1</property> + <child> + <object class="GtkVBox" id="vbox2"> + <property name="visible">True</property> +@@ -34,6 +32,7 @@ + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="pixbuf">login.png</property> ++ <property name="yalign">0.8</property> + </object> + <packing> + <property name="position">0</property> +@@ -42,6 +41,7 @@ + <child> + <object class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> ++ <property name="yalign">0.1</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> +@@ -61,19 +61,22 @@ + </packing> + </child> + <child> +- <object class="GtkIconView" id="user_list"> ++ <object class="GtkScrolledWindow" id="user_list_scrolled"> + <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="item-padding">1</property> +- <property name="margin">2</property> +- <property name="column-spacing">0</property> +- <property name="row-spacing">1</property> ++ <property name="can_focus">False</property> ++ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> ++ <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> ++ <child> ++ <object class="GtkIconView" id="user_list"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="item-padding">1</property> ++ <property name="margin">2</property> ++ <property name="column-spacing">0</property> ++ <property name="row-spacing">1</property> ++ </object> ++ </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">1</property> +- </packing> + </child> + <child> + <object class="GtkEntry" id="login_entry"> +diff --git a/data/themes/Industrial/greeter.ui b/data/themes/Industrial/greeter.ui +index 77a4f8d..3413922 100644 +--- a/data/themes/Industrial/greeter.ui ++++ b/data/themes/Industrial/greeter.ui +@@ -25,7 +25,7 @@ + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xscale">0</property> +- <property name="yscale">0</property> ++ <property name="yscale">1</property> + <child> + <object class="GtkVBox" id="vbox2"> + <property name="visible">True</property> +@@ -34,6 +34,7 @@ + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="pixbuf">login.png</property> ++ <property name="yalign">0.8</property> + </object> + <packing> + <property name="position">0</property> +@@ -42,6 +43,7 @@ + <child> + <object class="GtkAlignment" id="alignment2"> + <property name="visible">True</property> ++ <property name="yalign">0.1</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> +@@ -61,19 +63,22 @@ + </packing> + </child> + <child> +- <object class="GtkIconView" id="user_list"> ++ <object class="GtkScrolledWindow" id="user_list_scrolled"> + <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="item-padding">1</property> +- <property name="margin">2</property> +- <property name="column-spacing">0</property> +- <property name="row-spacing">1</property> ++ <property name="can_focus">False</property> ++ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> ++ <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> ++ <child> ++ <object class="GtkIconView" id="user_list"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="item-padding">1</property> ++ <property name="margin">2</property> ++ <property name="column-spacing">0</property> ++ <property name="row-spacing">1</property> ++ </object> ++ </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">1</property> +- </packing> + </child> + <child> + <object class="GtkEntry" id="login_entry"> +@@ -201,7 +206,9 @@ + </packing> + </child> + <child> +- <object class="GtkComboBoxEntry" id="keyboard"/> ++ <object class="GtkComboBoxEntry" id="keyboard"> ++ <property name="text_column">0</property> ++ </object> + <packing> + <property name="expand">False</property> + <property name="position">3</property> +diff --git a/data/themes/Industrial/gtk.css b/data/themes/Industrial/gtk.css +index eefe846..7621345 100644 +--- a/data/themes/Industrial/gtk.css ++++ b/data/themes/Industrial/gtk.css +@@ -1,20 +1,21 @@ + #lxdm { +- background-image: url("wave.svg") ++ background-image: url("wave.svg"); ++ background-size: 100%; + } + + #bottom_pane { +- background-image: url("shade.png") ++ background-color: rgba(0,0,0,0.24); + } + + #time { + font: Sans 12; +- color: #ffffff ++ color: #ffffff; + } + + #user_list, #login_entry { +- background-image: none ++ background-image: none; + } + + #prompt, #bottom_pane GtkLabel { +- color: #ffffff ++ color: #ffffff; + } +diff --git a/data/themes/Industrial/gtkrc b/data/themes/Industrial/gtkrc +index 9ee55d5..8f1d810 100644 +--- a/data/themes/Industrial/gtkrc ++++ b/data/themes/Industrial/gtkrc +@@ -45,6 +45,6 @@ style "bottom" + + widget "lxdm" style "back" + widget "lxdm.*.time" style "time" +-widget "lxdm.*.prompt" style "prompt" ++widget "*.prompt" style "prompt" + widget "lxdm.*.bottom_pane" style "bottom" + widget_class "GtkWindow.*.GtkEventBox.*.<GtkLabel>" style "bottom" +diff --git a/gnome-shell/LXDM_User_Switch@dgod/extension.js b/gnome-shell/LXDM_User_Switch@dgod/extension.js +new file mode 100644 +index 0000000..5c0498f +--- /dev/null ++++ b/gnome-shell/LXDM_User_Switch@dgod/extension.js +@@ -0,0 +1,28 @@ ++const Main = imports.ui.main; ++const GLib = imports.gi.GLib; ++const PopupMenu = imports.ui.popupMenu; ++ ++let button, menu, evt; ++ ++function _buttonActivate() { ++ Main.overview.hide(); ++ GLib.spawn_command_line_async("lxdm -c USER_SWITCH"); ++} ++ ++function init() { ++} ++ ++function enable() { ++ menu = Main.panel["statusArea"].userMenu; ++ button = menu._loginScreenItem; ++ evt=button.connect('activate', function(){GLib.spawn_command_line_async("lxdm -c USER_SWITCH");}); ++ button.actor.visible=true; ++} ++ ++function disable() { ++ if(evt && button) ++ button.disconnect(evt); ++ evt=undefined; ++ button=undefined; ++ menu=undefined; ++} +diff --git a/gnome-shell/LXDM_User_Switch@dgod/metadata.json b/gnome-shell/LXDM_User_Switch@dgod/metadata.json +new file mode 100644 +index 0000000..a5a19f7 +--- /dev/null ++++ b/gnome-shell/LXDM_User_Switch@dgod/metadata.json +@@ -0,0 +1 @@ ++{"shell-version": ["3.6.0"], "uuid": "LXDM_User_Switch@dgod", "name": "LXDM User Switch", "description": "LXDM User Switch"} +\ No newline at end of file +diff --git a/gnome-shell/LXDM_User_Switch@dgod/stylesheet.css b/gnome-shell/LXDM_User_Switch@dgod/stylesheet.css +new file mode 100644 +index 0000000..e69de29 +diff --git a/lxdm.spec.in b/lxdm.spec.in +index ae5b345..3033d74 100644 +--- a/lxdm.spec.in ++++ b/lxdm.spec.in +@@ -14,7 +14,8 @@ Source0: lxdm-%{version}.tar.gz + + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release} + +-BuildRequires: gtk2-devel pam-devel intltool ++BuildRequires: gtk3-devel pam-devel intltool ++Provides: service(graphical-login) = lxdm + + %description + Light weight X11 display manager +@@ -26,7 +27,7 @@ Light weight X11 display manager + export CFLAGS="$RPM_OPT_FLAGS" + export CXXFLAGS="$RPM_OPT_FLAGS" + +-%configure ++%configure --enable-gtk3 + + %__make + +@@ -64,6 +65,7 @@ rm -rf $RPM_BUILD_ROOT + %{_sysconfdir}/lxdm/Xsession + %config %{_sysconfdir}/lxdm/lxdm.conf + %{_sysconfdir}/pam.d/lxdm ++%{_unitdir}/lxdm.service + + %changelog + +diff --git a/pam/lxdm b/pam/lxdm +index 51ffda4..cffd07b 100644 +--- a/pam/lxdm ++++ b/pam/lxdm +@@ -7,3 +7,4 @@ session include system-auth + session required pam_loginuid.so + session optional pam_console.so + session optional pam_gnome_keyring.so auto_start ++session optional pam_selinux.so +diff --git a/src/Makefile.am b/src/Makefile.am +index 7fdfd99..ebfa29c 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -20,7 +20,7 @@ lxdm_binary_LDADD = \ + $(NULL) + + lxdm_binary_SOURCES = \ +- lxdm.c lxdm.h ui.c lxcom.c lxcom.h xconn.c xconn.h \ ++ lxdm.c lxdm.h ui.c lxcom.c lxcom.h xconn.c xconn.h lxcommon.h \ + $(NULL) + + libexec_PROGRAMS = lxdm-greeter-gdk lxdm-numlock lxdm-greeter-gtk +@@ -49,6 +49,7 @@ lxdm_greeter_gtk_SOURCES = \ + gdm/locarchive.h \ + lxcom.c lxcom.h \ + greeter-utils.c greeter-utils.h \ ++ lxcommon.h \ + $(NULL) + + lxdm_greeter_gdk_CFLAGS = \ +diff --git a/src/config.c b/src/config.c +index 3f92f7b..bee826d 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -125,24 +125,19 @@ static gboolean image_file_valid(const char *filename) + static void update_face_image(GtkWidget *w) + { + GdkPixbuf *pixbuf; +- char *path; +- path=g_build_filename(user->pw_dir,".face",NULL); +- if(access(path,R_OK)) +- { +- g_free(path); +- if(ui_nobody) +- pixbuf=gdk_pixbuf_new_from_file_at_scale(ui_nobody,48,48,FALSE,NULL); +- if(!pixbuf) +- pixbuf=gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), ++ char *path=g_build_filename(user->pw_dir,".face",NULL); ++ pixbuf=gdk_pixbuf_new_from_file_at_scale(path,48,48,FALSE,NULL); ++ g_free(path); ++ if(!pixbuf && ui_nobody) ++ pixbuf=gdk_pixbuf_new_from_file_at_scale(ui_nobody,48,48,FALSE,NULL); ++ if(!pixbuf) ++ pixbuf=gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), + "avatar-default", 48,GTK_ICON_LOOKUP_FORCE_SIZE,NULL); +- } +- else ++ if(pixbuf) + { +- pixbuf=gdk_pixbuf_new_from_file_at_scale(path,48,48,FALSE,NULL); +- g_free(path); ++ gtk_image_set_from_pixbuf(GTK_IMAGE(w),pixbuf); ++ g_object_unref(pixbuf); + } +- gtk_image_set_from_pixbuf(GTK_IMAGE(w),pixbuf); +- g_object_unref(pixbuf); + } + + static void set_face_file(const char *filename) +@@ -484,6 +479,82 @@ void prepare_bg(GtkBuilder *builder) + g_signal_connect(w,"toggled",on_bg_type_toggled,NULL); + } + ++static void on_enable_pane_toggled(GtkToggleButton *button) ++{ ++ int val; ++ val=gtk_toggle_button_get_active(button); ++ g_key_file_set_integer(config,"display","bottom_pane",val); ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"vbox2"); ++ gtk_widget_set_sensitive(w,val?TRUE:FALSE); ++ dirty++; ++} ++ ++static void prepare_enable_pane(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"lxdm-enable-bottom-pane"); ++ val=g_key_file_get_integer(config,"display","bottom_pane",NULL); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),val?TRUE:FALSE); ++ if(!root) gtk_widget_set_sensitive(w,FALSE); ++ g_signal_connect(w,"toggled",G_CALLBACK(on_enable_pane_toggled),NULL); ++} ++ ++static void prepare_vbox2(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"vbox2"); ++ val=g_key_file_get_integer(config,"display","bottom_pane",NULL); ++ if(!root) ++ { ++ gtk_widget_set_sensitive(w,FALSE); ++ } ++ else ++ { ++ gtk_widget_set_sensitive(w,val?TRUE:FALSE); ++ } ++} ++ ++static void on_transparent_pane_toggled(GtkToggleButton *button) ++{ ++ int val; ++ val=gtk_toggle_button_get_active(button); ++ g_key_file_set_integer(config,"display","transparent_pane",val); ++ dirty++; ++} ++ ++static void prepare_transparent_pane(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"lxdm-transparent-pane"); ++ val=g_key_file_get_integer(config,"display","transparent_pane",NULL); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),val?TRUE:FALSE); ++ if(!root) gtk_widget_set_sensitive(w,FALSE); ++ g_signal_connect(w,"toggled",G_CALLBACK(on_transparent_pane_toggled),NULL); ++} ++ ++static void on_hide_sessions_toggled(GtkToggleButton *button) ++{ ++ int val; ++ val=gtk_toggle_button_get_active(button); ++ g_key_file_set_integer(config,"display","hide_sessions",val); ++ dirty++; ++} ++ ++static void prepare_hide_sessions(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"lxdm-hide-sessions"); ++ val=g_key_file_get_integer(config,"display","hide_sessions",NULL); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),val?TRUE:FALSE); ++ if(!root) gtk_widget_set_sensitive(w,FALSE); ++ g_signal_connect(w,"toggled",G_CALLBACK(on_hide_sessions_toggled),NULL); ++} ++ + static void on_show_lang_toggled(GtkToggleButton *button) + { + int val; +@@ -522,6 +593,44 @@ static void prepare_show_keyboard(GtkBuilder *builder) + g_signal_connect(w,"toggled",G_CALLBACK(on_show_keyboard_toggled),NULL); + } + ++static void on_hide_exit_toggled(GtkToggleButton *button) ++{ ++ int val; ++ val=gtk_toggle_button_get_active(button); ++ g_key_file_set_integer(config,"display","hide_exit",val); ++ dirty++; ++} ++ ++static void prepare_hide_exit(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"lxdm-hide-exit"); ++ val=g_key_file_get_integer(config,"display","hide_exit",NULL); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),val?TRUE:FALSE); ++ if(!root) gtk_widget_set_sensitive(w,FALSE); ++ g_signal_connect(w,"toggled",G_CALLBACK(on_hide_exit_toggled),NULL); ++} ++ ++static void on_hide_time_toggled(GtkToggleButton *button) ++{ ++ int val; ++ val=gtk_toggle_button_get_active(button); ++ g_key_file_set_integer(config,"display","hide_time",val); ++ dirty++; ++} ++ ++static void prepare_hide_time(GtkBuilder *builder) ++{ ++ gint val; ++ GtkWidget *w; ++ w=(GtkWidget*)gtk_builder_get_object(builder,"lxdm-hide-time"); ++ val=g_key_file_get_integer(config,"display","hide_time",NULL); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),val?TRUE:FALSE); ++ if(!root) gtk_widget_set_sensitive(w,FALSE); ++ g_signal_connect(w,"toggled",G_CALLBACK(on_hide_time_toggled),NULL); ++} ++ + static void on_show_userlist_toggled(GtkToggleButton *button) + { + int val; +@@ -553,8 +662,14 @@ GtkDialog *dialog_create(void) + prepare_user_name(builder); + prepare_user_autologin(builder); + prepare_bg(builder); ++ prepare_enable_pane(builder); ++ prepare_vbox2(builder); ++ prepare_transparent_pane(builder); ++ prepare_hide_sessions(builder); + prepare_show_lang(builder); + prepare_show_keyboard(builder); ++ prepare_hide_exit(builder); ++ prepare_hide_time(builder); + prepare_show_userlist(builder); + + return dlg; +diff --git a/src/greeter-utils.c b/src/greeter-utils.c +index 78b71dd..6d7055a 100644 +--- a/src/greeter-utils.c ++++ b/src/greeter-utils.c +@@ -42,17 +42,29 @@ int ui_get_geometry(GdkWindow *win,GdkRectangle *rc) + void ui_set_bg(GdkWindow *win,GKeyFile *config) + { + GdkPixbuf *bg_img=NULL; ++#if GTK_CHECK_VERSION(3,4,0) ++ GdkRGBA bg_color; ++#else + GdkColor bg_color; ++#endif + GdkWindow *root=gdk_get_default_root_window(); + char *p=g_key_file_get_string(config,"display","bg",NULL); ++#if GTK_CHECK_VERSION(3,4,0) ++ gdk_rgba_parse(&bg_color,"#222E45"); ++#else + gdk_color_parse("#222E45",&bg_color); ++#endif + if( p && p[0] != '#' ) + { + bg_img = gdk_pixbuf_new_from_file(p, 0); + } + if( p && p[0] == '#' ) + { +- gdk_color_parse(p, &bg_color); ++#if GTK_CHECK_VERSION(3,4,0) ++ gdk_rgba_parse(&bg_color,p); ++#else ++ gdk_color_parse(p,&bg_color); ++#endif + } + g_free(p); + +@@ -95,8 +107,13 @@ void ui_set_bg(GdkWindow *win,GKeyFile *config) + else + { + #ifdef ENABLE_GTK3 ++#if GTK_CHECK_VERSION(3,4,0) ++ if(win) gdk_window_set_background_rgba(win,&bg_color); ++ gdk_window_set_background_rgba(root,&bg_color); ++#else + if(win) gdk_window_set_background(win,&bg_color); + gdk_window_set_background(root,&bg_color); ++#endif + #else + GdkColormap *map; + if(win) +@@ -139,12 +156,20 @@ void ui_add_cursor(void) + XDefineCursor(gdk_x11_get_default_xdisplay(), + GDK_WINDOW_XID(gdk_get_default_root_window()), + GDK_CURSOR_XCURSOR(cur)); ++#if GTK_CHECK_VERSION(3,0,0) ++ g_object_unref(cur); ++#else + gdk_cursor_unref(cur); ++#endif + } + + void ui_set_cursor(GdkWindow *win,int which) + { + GdkCursor *cursor=gdk_cursor_new(which); + gdk_window_set_cursor (win,cursor); ++#if GTK_CHECK_VERSION(3,0,0) ++ g_object_unref(cursor); ++#else + gdk_cursor_unref(cursor); ++#endif + } +diff --git a/src/greeter.c b/src/greeter.c +index 095227b..2c6e5be 100644 +--- a/src/greeter.c ++++ b/src/greeter.c +@@ -25,6 +25,10 @@ + + #include <gtk/gtk.h> + #include <gdk/gdkx.h> ++#include <gdk/gdkkeysyms.h> ++#ifdef ENABLE_GTK3 ++#include <gdk/gdkkeysyms-compat.h> ++#endif + #include <glib/gi18n.h> + #include <X11/XKBlib.h> + +@@ -36,6 +40,7 @@ + + #include "lxcom.h" + #include "greeter-utils.h" ++#include "lxcommon.h" + + enum { + COL_SESSION_NAME, +@@ -50,15 +55,16 @@ enum { + N_LANG_COLS + }; + +-#define VCONFIG_FILE "/var/lib/lxdm/lxdm.conf" + #define XKB_SYMBOL_DIR "/usr/share/X11/xkb/symbols.dir" + + static GtkBuilder* builder; + static GKeyFile *config; + static GKeyFile * var_config; + static GtkWidget* win; ++static GtkWidget* alignment2; + static GtkWidget* prompt; + static GtkWidget* login_entry; ++static GtkWidget* user_list_scrolled; + static GtkWidget* user_list; + + static GtkWidget* sessions; +@@ -110,7 +116,7 @@ static char *get_session_exec(void) + GtkTreeModel* model; + GtkTreeIter it; + gchar *res; +- if(!lang) ++ if(!sessions) + return g_strdup(""); + + if(!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(sessions), &it)) +@@ -120,12 +126,73 @@ static char *get_session_exec(void) + return res; + } + ++static void switch_to_input_user(void) ++{ ++ if(user) ++ { ++ g_free(user); ++ user=NULL; ++ } ++ if(pass) ++ { ++ g_free(pass); ++ pass=NULL; ++ } ++ gtk_label_set_text( GTK_LABEL(prompt), _("User:")); ++ gtk_widget_show(prompt); ++ if(user_list) ++ { ++ gtk_widget_hide(login_entry); ++ if(user_list_scrolled) ++ gtk_widget_show(user_list_scrolled); ++ else ++ gtk_widget_hide(user_list); ++ gtk_widget_grab_focus(user_list); ++ } ++ else ++ { ++ gtk_widget_show(login_entry); ++ gtk_widget_grab_focus(login_entry); ++ } ++} ++ ++static void switch_to_input_passwd(void) ++{ ++ if(user_list!=NULL) ++ { ++ if(user_list_scrolled) ++ gtk_widget_hide(user_list_scrolled); ++ else ++ gtk_widget_hide(user_list); ++ } ++ gtk_label_set_text( GTK_LABEL(prompt), _("Password:") ); ++ gtk_entry_set_text(GTK_ENTRY(login_entry), ""); ++ gtk_entry_set_visibility(GTK_ENTRY(login_entry), FALSE); ++ gtk_widget_show(login_entry); ++ gtk_widget_grab_focus(login_entry); ++} ++ ++static void try_login_user(const char *user) ++{ ++ char *session_exec=get_session_exec(); ++ char *session_lang=get_session_lang(); ++ ++ printf("login user=%s session=%s lang=%s\n", ++ user, session_exec, session_lang); ++ ++ g_free(session_lang); ++ g_free(session_exec); ++ ++} ++ + static void on_entry_activate(GtkEntry* entry) + { + char* tmp; + if( !user ) + { + user = g_strdup( gtk_entry_get_text( GTK_ENTRY(entry) ) ); ++ ++#if 0 + gtk_entry_set_text(GTK_ENTRY(entry), ""); + gtk_label_set_text( GTK_LABEL(prompt), _("Password:") ); + if(strchr(user, ' ')) +@@ -135,6 +202,16 @@ static void on_entry_activate(GtkEntry* entry) + return; + } + gtk_entry_set_visibility(entry, FALSE); ++#endif ++ if(g_key_file_get_integer(config,"base","skip_password",NULL)!=0) ++ { ++ gtk_label_set_text( GTK_LABEL(prompt), ""); ++ try_login_user(user); ++ } ++ else ++ { ++ switch_to_input_passwd(); ++ } + } + else + { +@@ -805,7 +882,10 @@ static void on_user_select(GtkIconView *iconview) + g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL); + g_list_free (list); + gtk_tree_model_get(model,&iter,2,&name,-1); +- gtk_widget_hide(user_list); ++ if(user_list_scrolled) ++ gtk_widget_hide(user_list_scrolled); ++ else ++ gtk_widget_hide(user_list); + if(name && name[0]) + { + if(auto_login && is_autologin_user(name)) +@@ -825,6 +905,13 @@ static void on_user_select(GtkIconView *iconview) + gtk_widget_hide( GTK_WIDGET(login_entry) ); + return; + } ++ if(g_key_file_get_integer(config,"base","skip_password",NULL)!=0) ++ { ++ gtk_label_set_text( GTK_LABEL(prompt), ""); ++ user=name; ++ try_login_user(user); ++ return; ++ } + gtk_entry_set_text(GTK_ENTRY(login_entry),name); + g_free(name); + on_entry_activate(GTK_ENTRY(login_entry)); +@@ -890,6 +977,10 @@ static gboolean load_user_list(GtkWidget *widget) + #else + gtk_icon_view_set_orientation(GTK_ICON_VIEW(widget),GTK_ORIENTATION_HORIZONTAL); + #endif ++ // FIXME: this should be done at greeter-gtk3.ui ++ // but set there will cause "Floating point exception" ++ gtk_icon_view_set_columns(GTK_ICON_VIEW(widget),1); ++ + model=gtk_list_store_new(5,GDK_TYPE_PIXBUF,G_TYPE_STRING, + G_TYPE_STRING,G_TYPE_STRING,G_TYPE_BOOLEAN); + gtk_icon_view_set_model(GTK_ICON_VIEW(widget),GTK_TREE_MODEL(model)); +@@ -906,18 +997,30 @@ static gboolean load_user_list(GtkWidget *widget) + } + if(count>3) + { +- // TODO: better ui needed +- count=3; ++ if(user_list_scrolled) ++ { ++ gtk_alignment_set(GTK_ALIGNMENT(alignment2), 0.5, 0.1, 0, 0.3); ++ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(user_list_scrolled), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); ++ } ++ else ++ count=3; + } + for(i=0;i<count;i++) + { + char *gecos,*face_path,*display; ++ gchar *gecos_escape; + gboolean login; + GdkPixbuf *face=NULL; + gtk_list_store_append(model,&iter); + gecos=g_key_file_get_string(kf,users[i],"gecos",0); + face_path=g_key_file_get_string(kf,users[i],"face",0); + login=g_key_file_get_boolean(kf,users[i],"login",0); ++ if(gecos!=NULL) ++ { ++ char *comma=gecos?strchr(gecos,','):NULL; ++ if (comma) ++ *comma='\0'; ++ } + if(face_path) + face=gdk_pixbuf_new_from_file_at_scale(face_path,48,48,TRUE,NULL); + if(!face) +@@ -929,13 +1032,15 @@ static gboolean load_user_list(GtkWidget *widget) + face=gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), + "avatar-default", 48,GTK_ICON_LOOKUP_FORCE_SIZE,NULL); + } ++ gecos_escape=g_markup_escape_text(gecos?gecos:users[i],-1); + display=g_strdup_printf("<span font_size=\"x-large\">%s</span>%s%s%s%s", +- gecos?gecos:users[i], +- (gecos&&strcmp(gecos,users[i]))?"(":"", ++ gecos_escape, ++ (gecos&&strcmp(gecos,users[i]))?" (":"", + (gecos&&strcmp(gecos,users[i]))?users[i]:"", + (gecos&&strcmp(gecos,users[i]))?")":"", + login?_("\n<i>logged in</i>"):""); + // don't translate it now, not freeze ++ g_free(gecos_escape); + gtk_list_store_set(model,&iter,0,face,1,display,2,users[i],3,gecos,4,login,-1); + if(face) g_object_unref(G_OBJECT(face)); + g_free(display); +@@ -944,16 +1049,17 @@ static gboolean load_user_list(GtkWidget *widget) + } + g_strfreev(users); + g_key_file_free(kf); +- ++ + // add "More ..." + gtk_list_store_append(model,&iter); + gtk_list_store_set(model,&iter,1,_("More ..."),2,"",3,"",4,FALSE,-1); +- ++ + path=gtk_tree_path_new_from_string("0"); + gtk_icon_view_select_path(GTK_ICON_VIEW(widget),path); + gtk_widget_grab_focus(widget); + gtk_icon_view_set_cursor(GTK_ICON_VIEW(widget),path,NULL,FALSE); + gtk_tree_path_free(path); ++ + return TRUE; + } + +@@ -981,6 +1087,13 @@ static void on_screen_size_changed(GdkScreen *screen,GtkWidget *win) + ui_set_bg(window,config); + } + ++static gint login_entry_on_key_press (GtkWidget *widget,GdkEventKey *event) ++{ ++ if(event->keyval == GDK_Escape) ++ switch_to_input_user(); ++ return FALSE; ++} ++ + static void create_win() + { + GSList* objs, *l; +@@ -1029,63 +1142,91 @@ static void create_win() + + } /* otherwise, let gtk theme paint it. */ + ++ alignment2=(GtkWidget*)gtk_builder_get_object(builder,"alignment2"); ++ user_list_scrolled=(GtkWidget*)gtk_builder_get_object(builder,"user_list_scrolled"); + user_list=(GtkWidget*)gtk_builder_get_object(builder,"user_list"); + + prompt = (GtkWidget*)gtk_builder_get_object(builder, "prompt"); + login_entry = (GtkWidget*)gtk_builder_get_object(builder, "login_entry"); ++ if(login_entry!=NULL) ++ { ++ g_signal_connect_after(login_entry,"key-press-event",G_CALLBACK(login_entry_on_key_press),NULL); ++ } + + g_signal_connect(login_entry, "activate", G_CALLBACK(on_entry_activate), NULL); + +- sessions = (GtkWidget*)gtk_builder_get_object(builder, "sessions"); +- gtk_widget_set_name(sessions, "sessions"); +- fix_combobox_entry(sessions); +- load_sessions(); +- +- w = (GtkWidget*)gtk_builder_get_object(builder, "bottom_pane"); +- if( g_key_file_get_integer(config, "display", "bottom_pane", 0) ) ++ if( g_key_file_get_integer(config, "display", "bottom_pane", 0)==1) + { + /* hacks to let GtkEventBox paintable with gtk pixmap engine. */ ++ w = (GtkWidget*)gtk_builder_get_object(builder, "bottom_pane"); ++ if(g_key_file_get_integer(config, "display", "transparent_pane", 0)==1) ++ { ++ } ++ else ++ { + #if GTK_CHECK_VERSION(2,18,0) +- if(gtk_widget_get_app_paintable(w)) ++ if(gtk_widget_get_app_paintable(w)) + #else +- if(GTK_WIDGET_APP_PAINTABLE(w)) ++ if(GTK_WIDGET_APP_PAINTABLE(w)) + #endif + + #if GTK_CHECK_VERSION(3,0,0) +- g_signal_connect(w,"draw",G_CALLBACK(on_evt_box_draw),NULL); ++ g_signal_connect(w,"draw",G_CALLBACK(on_evt_box_draw),NULL); + #else +- g_signal_connect(w, "expose-event", G_CALLBACK(on_evt_box_expose), NULL); ++ g_signal_connect(w, "expose-event", G_CALLBACK(on_evt_box_expose), NULL); + #endif ++ } ++ if( g_key_file_get_integer(config, "display", "hide_sessions", 0)==1) ++ { ++ w = (GtkWidget*)gtk_builder_get_object(builder, "sessions_box"); ++ if(w) gtk_widget_hide(w); ++ } ++ else ++ { ++ sessions = (GtkWidget*)gtk_builder_get_object(builder, "sessions"); ++ gtk_widget_set_name(sessions, "sessions"); ++ fix_combobox_entry(sessions); ++ load_sessions(); ++ } ++ ++ if( g_key_file_get_integer(config, "display", "lang", 0) == 0 ) ++ { ++ w = (GtkWidget*)gtk_builder_get_object(builder, "lang_box"); ++ if(w) gtk_widget_hide(w); ++ } ++ else ++ { ++ lang = (GtkWidget*)gtk_builder_get_object(builder, "lang"); ++ gtk_widget_set_name(lang, "lang"); ++ fix_combobox_entry(lang); ++ load_langs(); ++ } ++ ++ if(g_key_file_get_integer(config, "display", "keyboard", 0)==1) ++ { ++ w=(GtkWidget*)gtk_builder_get_object(builder, "keyboard"); ++ if((load_keyboards(w))!=FALSE) ++ { ++ fix_combobox_entry(w); ++ gtk_widget_show(w); ++ w=(GtkWidget*)gtk_builder_get_object(builder, "label_keyboard"); ++ if(w) gtk_widget_show(w); ++ } ++ } + } + else +- gtk_event_box_set_visible_window(GTK_EVENT_BOX(w), FALSE); +- +- if( g_key_file_get_integer(config, "display", "lang", 0) == 0 ) + { +- w = (GtkWidget*)gtk_builder_get_object(builder, "lang_box"); +- if( w ) +- gtk_widget_hide(w); ++ w = (GtkWidget*)gtk_builder_get_object(builder, "bottom_pane"); ++ gtk_widget_hide(w); + } +- else ++ ++ if(g_key_file_get_integer(config, "display", "hide_time", 0)==1) + { +- lang = (GtkWidget*)gtk_builder_get_object(builder, "lang"); +- gtk_widget_set_name(lang, "lang"); +- fix_combobox_entry(lang); +- load_langs(); ++ w = (GtkWidget*)gtk_builder_get_object(builder, "time"); ++ gtk_widget_hide(w); + } +- +- if(g_key_file_get_integer(config, "display", "keyboard", 0)==1) ++ else + { +- w=(GtkWidget*)gtk_builder_get_object(builder, "keyboard"); +- if((load_keyboards(w))!=FALSE) +- { +- fix_combobox_entry(w); +- gtk_widget_show(w); +- w=(GtkWidget*)gtk_builder_get_object(builder, "label_keyboard"); +- if(w) gtk_widget_show(w); +- } +- } +- + if( (w = (GtkWidget*)gtk_builder_get_object(builder, "time"))!=NULL ) + { + guint timeout = g_timeout_add(1000, (GSourceFunc)on_timeout, w); +@@ -1093,14 +1234,22 @@ static void create_win() + G_CALLBACK(g_source_remove), GUINT_TO_POINTER(timeout)); + on_timeout((GtkLabel*)w); + } ++ } + +- exit_btn = (GtkWidget*)gtk_builder_get_object(builder, "exit"); +- load_exit(); ++ if(g_key_file_get_integer(config, "display", "hide_exit", 0)==1) ++ { ++ w=(GtkWidget*)gtk_builder_get_object(builder, "exit"); ++ gtk_widget_hide(w); ++ } ++ else ++ { ++ exit_btn = (GtkWidget*)gtk_builder_get_object(builder, "exit"); ++ load_exit(); ++ } + + ui_get_geometry(window,&rc); + gtk_window_move(GTK_WINDOW(win),rc.x,rc.y); + gtk_window_set_default_size(GTK_WINDOW(win),rc.width,rc.height); +- ui_set_bg(window,config); + + if(user_list && !g_key_file_get_integer(config,"userlist","disable",NULL) && + load_user_list(user_list)) +@@ -1111,7 +1260,10 @@ static void create_win() + { + if(user_list) + { +- gtk_widget_hide(user_list); ++ if(user_list_scrolled) ++ gtk_widget_hide(user_list_scrolled); ++ else ++ gtk_widget_hide(user_list); + user_list=NULL; + } + } +@@ -1119,6 +1271,8 @@ static void create_win() + ui_add_cursor(); + ui_set_cursor(gtk_widget_get_window(win),GDK_LEFT_PTR); + gtk_widget_show(win); ++ ui_set_bg(window,config); ++ + ui_set_focus(window); + if(!user_list) + gtk_widget_grab_focus(login_entry); +@@ -1142,29 +1296,11 @@ static gboolean on_lxdm_command(GIOChannel *source, GIOCondition condition, gpoi + gtk_main_quit(); + else if( !strncmp(str, "reset", 5) ) + { +- if(user) +- { +- g_free(user); +- user=NULL; +- } +- if(pass) +- { +- g_free(pass); +- pass=NULL; +- } +- gtk_label_set_text( GTK_LABEL(prompt), _("User:")); +- gtk_widget_show(prompt); +- if(user_list) +- { +- gtk_widget_hide(login_entry); +- gtk_widget_show(user_list); +- gtk_widget_grab_focus(user_list); +- } +- else +- { +- gtk_widget_show(login_entry); +- gtk_widget_grab_focus(login_entry); +- } ++ switch_to_input_user(); ++ } ++ else if( !strncmp(str, "password", 8)) ++ { ++ switch_to_input_passwd(); + } + g_free(str); + return TRUE; +diff --git a/src/lxcom.c b/src/lxcom.c +index 02763eb..eef3d1b 100644 +--- a/src/lxcom.c ++++ b/src/lxcom.c +@@ -89,7 +89,7 @@ static gboolean lxcom_prepare (GSource *source,gint *timeout) + + static gboolean lxcom_check(GSource *source) + { +- return TRUE; ++ return (((LXComSource*)source)->poll.revents&G_IO_IN)?TRUE:FALSE; + } + + static gboolean lxcom_dispatch (GSource *source,GSourceFunc callback,gpointer user_data) +@@ -272,6 +272,7 @@ void lxcom_init(const char *sock) + + s->poll.fd=self_server_fd; + s->poll.events=G_IO_IN; ++ s->poll.revents=0; + g_source_add_poll((GSource*)s,&s->poll); + self_source_id=g_source_attach((GSource*)s,NULL); + +diff --git a/src/lxcommon.h b/src/lxcommon.h +new file mode 100644 +index 0000000..24a6c38 +--- /dev/null ++++ b/src/lxcommon.h +@@ -0,0 +1,7 @@ ++#ifndef _LXCOMMON_H_ ++#define _LXCOMMON_H_ ++ ++#define VCONFIG_FILE "/var/lib/lxdm/lxdm.conf" ++ ++#endif /*_LXCOMMON_H_*/ ++ +diff --git a/src/lxdm.c b/src/lxdm.c +index 5c279af..ff06389 100644 +--- a/src/lxdm.c ++++ b/src/lxdm.c +@@ -25,8 +25,12 @@ + #include <config.h> + #endif + #ifndef HAVE_LIBPAM ++#ifdef USE_PAM ++#define HAVE_LIBPAM 1 ++#else + #define HAVE_LIBPAM 0 + #endif ++#endif + + #include <stdio.h> + #include <stdlib.h> +@@ -69,6 +73,7 @@ + #include "lxdm.h" + #include "lxcom.h" + #include "xconn.h" ++#include "lxcommon.h" + + #define LOGFILE "/var/log/lxdm.log" + +@@ -96,6 +101,7 @@ typedef struct{ + + GKeyFile *config; + static int old_tty=1,def_tty = 7,nr_tty=0; ++static int def_display=0; + static GSList *session_list; + + static void lxdm_startx(LXSession *s); +@@ -154,6 +160,30 @@ void stop_pid(int pid) + } + + #if HAVE_LIBPAM ++ ++// just hack to work with some bad pam module ++static guint first_pam_source=2; ++static gboolean clean_pam_func(void) ++{ ++ return FALSE; ++} ++static void clean_pam_glib_source_prepare(pam_handle_t *pamh) ++{ ++ if(pamh) return; ++ first_pam_source=g_idle_add((GSourceFunc)clean_pam_func,NULL); ++} ++static void clean_pam_glib_source_run(void) ++{ ++ int i,end=first_pam_source+256; ++ for(i=first_pam_source;i<end;i++) ++ { ++ if(g_source_remove(i)==TRUE) ++ { ++ first_pam_source=i+1; ++ } ++ } ++} ++ + static void close_pam_session(pam_handle_t *pamh) + { + int err; +@@ -271,7 +301,7 @@ static int lxsession_alloc_tty(void) + static int lxsession_alloc_display(void) + { + int i; +- for(i=0;i<11;i++) ++ for(i=def_display;i<11;i++) + { + if(!display_is_used(i)) + return i; +@@ -467,7 +497,7 @@ static char *lxsession_xserver_command(LXSession *s) + i++; + } + } +-printf("arc %d\n",arc); ++ + arg = g_renew(char *, arg, arc + 10); + if(nr_tty) + { +@@ -477,8 +507,11 @@ printf("arc %d\n",arc); + arg[arc++] = g_strdup_printf(":%d",s->display); + if(s->tty>0) + arg[arc++] = g_strdup_printf("vt%02d", s->tty); +- arg[arc++] = g_strdup("-nolisten"); +- arg[arc++] = g_strdup("tcp"); ++ if(g_key_file_get_integer(config,"server","tcp_listen",0)!=1) ++ { ++ arg[arc++] = g_strdup("-nolisten"); ++ arg[arc++] = g_strdup("tcp"); ++ } + arg[arc] = NULL; + p=g_strjoinv(" ", arg); + g_strfreev(arg); +@@ -518,15 +551,17 @@ void lxdm_get_tty(void) + { + nr_tty=1; + } ++ else if(p[0]==':' && isdigit(p[1])) ++ { ++ def_display=atoi(p+1); ++ } + } + if(!gotvtarg) + { + /* support plymouth */ +- nr_tty = g_file_test("/var/spool/gdm/force-display-on-active-vt", G_FILE_TEST_EXISTS); +- if( nr_tty || g_key_file_get_integer(config, "server", "active_vt", 0) ) ++ if(g_key_file_get_integer(config, "server", "active_vt", 0) ) + /* use the active vt */ + def_tty = old_tty; +- if( nr_tty ) unlink("/var/spool/gdm/force-display-on-active-vt"); + if(plymouth) + { + nr_tty=1; +@@ -557,6 +592,7 @@ static void log_init(void) + if(fd_log == -1) return; + dup2(fd_log, 1); + dup2(fd_log, 2); ++ close(fd_log); + } + + static void log_ignore(const gchar *log_domain, GLogLevelFlags log_level, +@@ -647,6 +683,19 @@ static void replace_env(char** env, const char* name, const char* new_val) + *(penv + 1) = NULL; + } + ++static const char *get_env(char **env, const char *name) ++{ ++ register char** penv; ++ for(penv = env; *penv; ++penv) ++ { ++ if(g_str_has_prefix(*penv, name)) ++ { ++ return *penv+strlen(name); ++ } ++ } ++ return NULL; ++} ++ + #ifndef DISABLE_XAUTH + + static inline void xauth_write_uint16(int fd,uint16_t data) +@@ -665,15 +714,20 @@ static inline void xauth_write_string(int fd,const char *s) + write(fd,s,len); + } + +-static void xauth_write_file(const char *file,char data[16]) ++static void xauth_write_file(const char *file,int dpy,char data[16]) + { + int fd; ++ char addr[128]; ++ char buf[16]; ++ ++ sprintf(buf,"%d",dpy); ++ gethostname(addr,sizeof(addr)); + + fd=open(file,O_CREAT|O_TRUNC|O_WRONLY,0600); + if(!fd==-1) return; +- xauth_write_uint16(fd,252); //FamilyLocalHost +- xauth_write_string(fd,""); +- xauth_write_string(fd,""); ++ xauth_write_uint16(fd,256); //FamilyLocalHost ++ xauth_write_string(fd,addr); ++ xauth_write_string(fd,buf); + xauth_write_string(fd,"MIT-MAGIC-COOKIE-1"); + xauth_write_uint16(fd,16); + write(fd,data,16); +@@ -695,9 +749,9 @@ static void create_server_auth(LXSession *s) + + authfile = g_strdup_printf("/var/run/lxdm/lxdm-:%d.auth",s->display); + +- setenv("XAUTHORITY",authfile,1); ++ //setenv("XAUTHORITY",authfile,1); + remove(authfile); +- xauth_write_file(authfile,s->mcookie); ++ xauth_write_file(authfile,s->display,s->mcookie); + g_free(authfile); + } + +@@ -706,27 +760,35 @@ static void create_client_auth(char *home,char **env) + LXSession *s; + char *authfile; + uid_t user; +- char *path; + +- if((user=getuid())== 0 ) /* root don't need it */ ++ if((user=getuid())==0) /* root don't need it */ + return; + + s=lxsession_find_user(user); + if(!s) + return; +- +- path=g_key_file_get_string(config,"base","xauth_path",NULL); +- if(path) ++ ++ /* pam_mktemp may provide XAUTHORITY to DM, just use it */ ++ if((authfile=(char*)get_env(env,"XAUTHORITY="))!=NULL) + { +- authfile = g_strdup_printf("%s/.Xauth%d", path,getuid()); +- g_free(path); ++ authfile=g_strdup(authfile); + } + else + { +- authfile = g_strdup_printf("%s/.Xauthority", home); ++ char *path; ++ path=g_key_file_get_string(config,"base","xauth_path",NULL); ++ if(path) ++ { ++ authfile = g_strdup_printf("%s/.Xauth%d", path,user); ++ g_free(path); ++ } ++ else ++ { ++ authfile = g_strdup_printf("%s/.Xauthority", home); ++ } + } + remove(authfile); +- xauth_write_file(authfile,s->mcookie); ++ xauth_write_file(authfile,s->display,s->mcookie); + replace_env(env,"XAUTHORITY=",authfile); + g_free(authfile); + } +@@ -748,7 +810,8 @@ static int do_conv(int num, const struct pam_message **msg,struct pam_response * + resp[i]->resp=strdup(user_pass[0]?user_pass[0]:""); + break; + case PAM_PROMPT_ECHO_OFF: +- resp[i]->resp=strdup(user_pass[1]?user_pass[1]:""); ++ //resp[i]->resp=strdup(user_pass[1]?user_pass[1]:""); ++ resp[i]->resp=user_pass[1]?strdup(user_pass[1]):NULL; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: +@@ -762,6 +825,7 @@ static int do_conv(int num, const struct pam_message **msg,struct pam_response * + } + + static struct pam_conv conv={.conv=do_conv,.appdata_ptr=user_pass}; ++ + #endif + + int lxdm_auth_user(char *user, char *pass, struct passwd **ppw) +@@ -789,7 +853,7 @@ int lxdm_auth_user(char *user, char *pass, struct passwd **ppw) + g_debug("user %s not found\n",user); + return AUTH_BAD_USER; + } +- if( !pass ) ++ if( !pass && !g_key_file_get_integer(config,"base","skip_password",NULL)) + { + *ppw = pw; + g_debug("user %s auth ok\n",user); +@@ -808,7 +872,7 @@ int lxdm_auth_user(char *user, char *pass, struct passwd **ppw) + real = sp->sp_pwdp; + if( !real || !real[0] ) + { +- if( !pass[0] ) ++ if( !pass || !pass[0] ) + { + *ppw = pw; + g_debug("user %s auth with no password ok\n",user); +@@ -837,6 +901,7 @@ int lxdm_auth_user(char *user, char *pass, struct passwd **ppw) + exit(0); + } + if(s->pamh) pam_end(s->pamh,0); ++ clean_pam_glib_source_prepare(NULL); + if(PAM_SUCCESS != pam_start("lxdm", pw->pw_name, &conv, &s->pamh)) + { + s->pamh=NULL; +@@ -874,6 +939,7 @@ void setup_pam_session(LXSession *s,struct passwd *pw,char *session_name) + int err; + char x[256]; + ++ clean_pam_glib_source_prepare(s->pamh); + if(!s->pamh && PAM_SUCCESS != pam_start("lxdm", pw->pw_name, &conv, &s->pamh)) + { + s->pamh = NULL; +@@ -886,6 +952,15 @@ void setup_pam_session(LXSession *s,struct passwd *pw,char *session_name) + pam_set_item(s->pamh, PAM_XDISPLAY, getenv("DISPLAY") ); + #endif + ++#if !defined(DISABLE_XAUTH) && defined(PAM_XAUTHDATA) ++ struct pam_xauth_data value; ++ value.name="MIT-MAGIC-COOKIE-1"; ++ value.namelen=18; ++ value.data=s->mcookie; ++ value.datalen=sizeof(s->mcookie); ++ pam_set_item (s->pamh, PAM_XAUTHDATA, &value); ++#endif ++ + if(session_name && session_name[0]) + { + char *env; +@@ -896,18 +971,27 @@ void setup_pam_session(LXSession *s,struct passwd *pw,char *session_name) + err = pam_open_session(s->pamh, 0); /* FIXME pam session failed */ + if( err != PAM_SUCCESS ) + g_warning( "pam open session error \"%s\"\n", pam_strerror(s->pamh, err)); ++ ++ clean_pam_glib_source_run(); + } + +-void append_pam_environ(pam_handle_t *pamh,char **env) ++static char **append_pam_environ(pam_handle_t *pamh,char **env) + { +- int i,j,n; ++ int i,j,n,a; + char **penv; +- if(!pamh) return; ++ if(!pamh) return env; + penv=pam_getenvlist(pamh); +- if(!penv) return; ++ if(!penv) return env; ++ a=g_strv_length(penv); ++ if(a==0) ++ { ++ free(penv); ++ return env; ++ } ++ env=g_renew(char *,env,g_strv_length(env)+1+a+10); + for(i=0;penv[i]!=NULL;i++) + { +- //printf("PAM %s\n",penv[i]); ++ fprintf(stderr,"PAM %s\n",penv[i]); + n=strcspn(penv[i],"=")+1; + for(j=0;env[j]!=NULL;j++) + { +@@ -923,6 +1007,7 @@ void append_pam_environ(pam_handle_t *pamh,char **env) + free(penv[i]); + } + free(penv); ++ return env; + } + + #endif +@@ -945,6 +1030,12 @@ static void close_left_fds(void) + close(fd); + } + free(list); ++ ++ int fd = open("/dev/null", O_WRONLY); ++ if(fd == -1) return; ++ dup2(fd, 1); ++ dup2(fd, 2); ++ close(fd); + } + + void switch_user(struct passwd *pw, char *run, char **env) +@@ -1200,6 +1291,11 @@ static void on_session_stop(void *data,int pid, int status) + { + lxsession_free(s); + } ++ else if(g_key_file_get_integer(config,"server","reset",NULL)==1) ++ { ++ lxsession_free(s); ++ lxsession_greeter(); ++ } + gchar *argv[] = { "/etc/lxdm/PostLogout", NULL }; + g_spawn_async(NULL, argv, s->env, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + } +@@ -1212,7 +1308,7 @@ gboolean lxdm_get_session_info(char *session,char **pname,char **pexec) + name=g_key_file_get_string(config, "base", "session", 0); + if(!name && getenv("PREFERRED")) + name = g_strdup(getenv("PREFERRED")); +- if(!session && getenv("DESKTOP")) ++ if(!name && getenv("DESKTOP")) + name = g_strdup(getenv("DESKTOP")); + if(!name) name=g_strdup("LXDE"); + } +@@ -1291,7 +1387,7 @@ static void lxdm_save_login(char *session,char *lang) + lang=""; + var=g_key_file_new(); + g_key_file_set_list_separator(var, ' '); +- g_key_file_load_from_file(var,"/var/lib/lxdm/lxdm.conf",0,NULL); ++ g_key_file_load_from_file(var,VCONFIG_FILE,0,NULL); + old=g_key_file_get_string(var,"base","last_session",0); + if(0!=g_strcmp0(old,session)) + { +@@ -1343,7 +1439,7 @@ static void lxdm_save_login(char *session,char *lang) + char* data = g_key_file_to_data(var, &len, NULL); + mkdir("/var/lib/lxdm",0755); + chmod("/var/lib/lxdm",0755); +- g_file_set_contents("/var/lib/lxdm/lxdm.conf", data, len, NULL); ++ g_file_set_contents(VCONFIG_FILE, data, len, NULL); + g_free(data); + } + g_key_file_free(var); +@@ -1451,9 +1547,20 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option) + "x11-display", &n, + "is-local",&is_local, + NULL)) +- setenv("XDG_SESSION_COOKIE", ck_connector_get_cookie(s->ckc), 1); ++ { ++ setenv("XDG_SESSION_COOKIE", ck_connector_get_cookie(s->ckc), 1); ++ } ++ else ++ { ++ g_message("create ConsoleKit session fail\n"); ++ } ++ } ++ else ++ { ++ g_message("create ConsoleKit connector fail\n"); + } + #endif ++ + char** env, *path; + int n_env,i; + n_env = g_strv_length(environ); +@@ -1488,7 +1595,7 @@ void lxdm_do_login(struct passwd *pw, char *session, char *lang, char *option) + if(s->child==0) + { + #if HAVE_LIBPAM +- append_pam_environ(s->pamh,env); ++ env=append_pam_environ(s->pamh,env); + pam_end(s->pamh,0); + #endif + switch_user(pw, session_exec, env); +@@ -1519,7 +1626,7 @@ void lxdm_do_shutdown(void) + char *cmd; + cmd = g_key_file_get_string(config, "cmd", "shutdown", 0); + if( !cmd ) cmd = g_strdup("shutdown -h now"); +- g_spawn_command_line_sync("/etc/lxdm/PreReboot",0,0,0,0); ++ g_spawn_command_line_sync("/etc/lxdm/PreShutdown",0,0,0,0); + g_spawn_command_line_async(cmd,0); + g_free(cmd); + lxdm_quit_self(0); +@@ -1548,10 +1655,30 @@ int lxdm_do_auto_login(void) + if(count==1) + pass = g_key_file_get_string(config, "base", "password", 0); + #endif ++ ++ /* get defaults from last login */ ++ GKeyFile *var_config = g_key_file_new(); ++ g_key_file_set_list_separator(var_config, ' '); ++ g_key_file_load_from_file(var_config,VCONFIG_FILE,G_KEY_FILE_KEEP_COMMENTS, NULL); ++ ++ char* last_session = g_key_file_get_string(var_config, "base", "last_session", NULL); ++ if(last_session != NULL && last_session[0] == 0) ++ { ++ g_free(last_session); ++ last_session = NULL; ++ } ++ ++ char* last_lang = g_key_file_get_string(var_config, "base", "last_lang", NULL); ++ ++ g_key_file_free(var_config); ++ + for(i=0;i<count;i++) + { + char *user,*session=NULL,*lang=NULL,*option=NULL; + p=users[i]; ++ /* autologin users starting with '@' get own config section with ++ * user=, session= and lang= entry ++ */ + if(p[0]=='@') + { + option=p+1; +@@ -1559,9 +1686,14 @@ int lxdm_do_auto_login(void) + session=g_key_file_get_string(config,option,"session",0); + lang=g_key_file_get_string(config,option,"lang",0); + } ++ /* autologin users not starting with '@' get user, session, lang section ++ * from last login ++ */ + else + { + user=g_strdup(p); ++ session=g_strdup(last_session); ++ lang=g_strdup(last_lang); + } + ret=lxdm_auth_user(user, pass, &pw); + if(ret==AUTH_SUCCESS) +@@ -1571,9 +1703,11 @@ int lxdm_do_auto_login(void) + } + g_free(user);g_free(session);g_free(lang); + } ++ g_free(last_lang); ++ g_free(last_session); + g_strfreev(users); + g_free(pass); +- return success;; ++ return success; + } + + static void log_sigsegv(void) +@@ -1677,8 +1811,23 @@ GKeyFile *lxdm_user_list(void) + g_key_file_set_comment(kf,NULL,NULL,"lxdm user list",NULL); + while((pw=getpwent())!=NULL) + { ++ char *valid_shell; ++ gboolean ret; ++ + if(strstr(pw->pw_shell, "nologin")) + continue; ++ ++ ret = FALSE; ++ setusershell(); ++ while ((valid_shell = getusershell()) != NULL) { ++ if (g_strcmp0 (pw->pw_shell, valid_shell) != 0) ++ continue; ++ ret = TRUE; ++ } ++ endusershell(); ++ if(!ret) ++ continue; ++ + if(strncmp(pw->pw_dir,"/home/",6)) + { + if(!strv_find(white,pw->pw_name)) +diff --git a/src/ui.c b/src/ui.c +index 2691a03..cd6d7de 100644 +--- a/src/ui.c ++++ b/src/ui.c +@@ -20,8 +20,6 @@ + */ + + +-#include <X11/Xlib.h> +- + #include <string.h> + #include <poll.h> + #include <grp.h> +@@ -153,7 +151,7 @@ static gboolean on_greeter_input(GIOChannel *source, GIOCondition condition, gpo + char *pass = greeter_param(str, "pass"); + char *session = greeter_param(str, "session"); + char *lang = greeter_param(str, "lang"); +- if( user && pass ) ++ if( user/* && pass */) + { + struct passwd *pw; + int ret = lxdm_auth_user(user, pass, &pw); +@@ -163,7 +161,12 @@ static gboolean on_greeter_input(GIOChannel *source, GIOCondition condition, gpo + lxdm_do_login(pw, session, lang,NULL); + } + else +- xwrite(greeter_pipe[0], "reset\n", 6); ++ { ++ if(pass!=NULL) ++ xwrite(greeter_pipe[0], "reset\n", 6); ++ else ++ xwrite(greeter_pipe[0], "password\n", 9); ++ } + } + g_free(user); + g_free(pass); +diff --git a/systemd/Makefile.am b/systemd/Makefile.am +new file mode 100644 +index 0000000..b568c5a +--- /dev/null ++++ b/systemd/Makefile.am +@@ -0,0 +1,10 @@ ++NULL= ++ ++lxdm_systemddir = @systemdsystemunitdir@ ++lxdm_systemd_DATA = \ ++ lxdm.service \ ++ $(NULL) ++ ++EXTRA_DIST = \ ++ $(lxdm_systemd_DATA) \ ++ $(NULL) +diff --git a/systemd/lxdm.service b/systemd/lxdm.service +new file mode 100644 +index 0000000..bf4a0a8 +--- /dev/null ++++ b/systemd/lxdm.service +@@ -0,0 +1,12 @@ ++[Unit] ++Description=LXDE Display Manager ++Conflicts=getty@tty1.service plymouth-quit.service ++After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service ++ ++[Service] ++ExecStart=/usr/sbin/lxdm ++Restart=always ++IgnoreSIGPIPE=no ++ ++[Install] ++Alias=display-manager.service diff --git a/community/lxdm/lxdm.install b/community/lxdm/lxdm.install index 3bbb59a2e..a8bc882dc 100644 --- a/community/lxdm/lxdm.install +++ b/community/lxdm/lxdm.install @@ -1,22 +1,17 @@ post_install() { - getent group lxdm >/dev/null && groupmod -g 121 lxdm || groupadd -g 121 lxdm - getent passwd lxdm >/dev/null && usermod -u 121 -g 121 lxdm || useradd -r -d /var/lib/lxdm -u 121 -g 121 lxdm - chown -R 121:121 /var/lib/lxdm - chgrp 121 /etc/lxdm/lxdm.conf - chmod +r /etc/lxdm/lxdm.conf - systemd-tmpfiles --create lxdm.conf + getent group lxdm > /dev/null 2>&1 && \ + groupmod -g 121 lxdm > /dev/null 2>&1 || \ + groupadd -g 121 lxdm + getent passwd lxdm > /dev/null 2>&1 && \ + usermod -c 'Lightweight X11 Display Manager' -u 121 -g 121 -d /var/lib/lxdm -s /sbin/nologin lxdm > /dev/null 2>&1 || \ + useradd -c 'Lightweight X11 Display Manager' -u 121 -g 121 -d /var/lib/lxdm -s /sbin/nologin lxdm + passwd -l lxdm > /dev/null } post_upgrade() { - post_install $1 - if [[ $(vercmp $2 0.4.1-22) < 0 ]]; then - groupmod -g 121 lxdm - usermod -g 121 -u 121 lxdm - fi + post_install } post_remove() { - userdel -f lxdm - groupdel lxdm - true + getent passwd lxdm > /dev/null 2>&1 && userdel lxdm } |