diff options
Diffstat (limited to 'kdm/kfrontend')
106 files changed, 17489 insertions, 0 deletions
diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am new file mode 100644 index 000000000..8f123509d --- /dev/null +++ b/kdm/kfrontend/Makefile.am @@ -0,0 +1,66 @@ +# use 'make GENKDMCONF_FLAGS=... install' to override +GENKDMCONF_FLAGS = + +SUBDIRS = themer themes pics sessions + +AM_CPPFLAGS = -I$(srcdir)/../backend -I.. -I$(top_srcdir)/kcontrol/background \ + -I$(top_srcdir)/kdmlib $(all_includes) + +bin_PROGRAMS = kdm_config kdm_greet krootimage genkdmconf kdmctl + +kdm_config_SOURCES = kdm_config.c +kdm_config_LDADD = $(LIBRESOLV) $(LIBSOCKET) $(LIBPOSIX4) + +kdm_greet_SOURCES = \ + kdm_greet.c \ + kdmconfig.cpp \ + kdmclock.cpp \ + kconsole.cpp \ + kfdialog.cpp \ + kgdialog.cpp \ + kchooser.cpp \ + kgverify.cpp \ + kdmshutdown.cpp \ + kgreeter.cpp \ + kgapp.cpp +kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH) +kdm_greet_LDADD = themer/libkdmthemer.a $(LIB_KDEUI) $(XTESTLIB) $(LIBPOSIX4) + +krootimage_SOURCES = krootimage.cpp +krootimage_LDFLAGS = $(all_libraries) $(KDE_RPATH) +krootimage_LDADD = $(top_builddir)/kcontrol/background/libbgnd.la $(LIB_KIO) + +METASOURCES = AUTO + +genkdmconf_SOURCES = genkdmconf.c +genkdmconf_LDFLAGS = $(X_LDFLAGS) $(X_RPATH) +genkdmconf_LDADD = $(LIB_X11) + +kdmctl_SOURCES = kdmctl.c +kdmctl_LDADD = $(LIBSOCKET) + +install-data-local: genkdmconf + ./genkdmconf --in $(DESTDIR)$(kde_confdir)/kdm --no-in-notice --face-src $(srcdir)/pics $(GENKDMCONF_FLAGS) + +messages: + $(XGETTEXT) `find . -name "*.cpp"` -o $(podir)/kdmgreet.pot + +noinst_HEADERS = \ + kdm_greet.h \ + kdmconfig.h \ + kdmclock.h \ + kconsole.h \ + kfdialog.h \ + kgdialog.h \ + kchooser.h \ + kgverify.h \ + kdmshutdown.h \ + kgreeter.h \ + kgapp.h \ + \ + krootimage.h + +kdm_greet_COMPILE_FIRST = ../config.ci +kdm_config_COMPILE_FIRST = ../config.ci +genkdmconf_COMPILE_FIRST = ../config.ci + diff --git a/kdm/kfrontend/genkdmconf.c b/kdm/kfrontend/genkdmconf.c new file mode 100644 index 000000000..5c0cb91e0 --- /dev/null +++ b/kdm/kfrontend/genkdmconf.c @@ -0,0 +1,2899 @@ +/* + +Create a suitable configuration for kdm taking old xdm/kdm +installations into account + +Copyright (C) 2001-2005 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <X11/Xlib.h> +#include <X11/Xresource.h> + +#include <config.h> + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <stdarg.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <utime.h> +#include <dirent.h> +#include <errno.h> +#include <pwd.h> +#include <time.h> +#include <limits.h> +#include <sys/stat.h> +#include <sys/param.h> +#ifdef BSD +# include <utmp.h> +#endif + +#include "config.ci" + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +# define ATTR_UNUSED __attribute__((unused)) +#else +# define ATTR_UNUSED +#endif + +#if defined(__sun) && !defined(__sun__) +# define __sun__ +#endif + +#define as(ar) ((int)(sizeof(ar)/sizeof(ar[0]))) + +#define __stringify(x) #x +#define stringify(x) __stringify(x) + +#define RCVERSTR stringify(RCVERMAJOR) "." stringify(RCVERMINOR) + +static int old_scripts, no_old_scripts, old_confs, no_old, + no_backup, no_in_notice, use_destdir, mixed_scripts; +static const char *newdir = KDMCONF, *facesrc = KDMDATA "/pics/users", + *oldxdm, *oldkde; + +static int oldver; + + +typedef struct StrList { + struct StrList *next; + const char *str; +} StrList; + + +static void * +mmalloc( size_t sz ) +{ + void *ptr; + + if (!(ptr = malloc( sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static void * +mcalloc( size_t sz ) +{ + void *ptr; + + if (!(ptr = calloc( 1, sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static void * +mrealloc( void *optr, size_t sz ) +{ + void *ptr; + + if (!(ptr = realloc( optr, sz ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + +static char * +mstrdup( const char *optr ) +{ + char *ptr; + + if (!optr) + return 0; + if (!(ptr = strdup( optr ))) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + return ptr; +} + + +#define NO_LOGGER +#define STATIC static +#include <printf.c> + +typedef struct { + char *buf; + int clen, blen, tlen; +} OCABuf; + +static void +OutCh_OCA( void *bp, char c ) +{ + OCABuf *ocabp = (OCABuf *)bp; + + ocabp->tlen++; + if (ocabp->clen >= ocabp->blen) { + ocabp->blen = ocabp->blen * 3 / 2 + 100; + ocabp->buf = mrealloc( ocabp->buf, ocabp->blen ); + } + ocabp->buf[ocabp->clen++] = c; +} + +static int +VASPrintf( char **strp, const char *fmt, va_list args ) +{ + OCABuf ocab = { 0, 0, 0, -1 }; + + DoPr( OutCh_OCA, &ocab, fmt, args ); + OutCh_OCA( &ocab, 0 ); + *strp = realloc( ocab.buf, ocab.clen ); + if (!*strp) + *strp = ocab.buf; + return ocab.tlen; +} + +static int +ASPrintf( char **strp, const char *fmt, ... ) +{ + va_list args; + int len; + + va_start( args, fmt ); + len = VASPrintf( strp, fmt, args ); + va_end( args ); + return len; +} + +static void +StrCat( char **strp, const char *fmt, ... ) +{ + char *str, *tstr; + va_list args; + int el; + + va_start( args, fmt ); + el = VASPrintf( &str, fmt, args ); + va_end( args ); + if (*strp) { + int ol = strlen( *strp ); + tstr = mmalloc( el + ol + 1 ); + memcpy( tstr, *strp, ol ); + memcpy( tstr + ol, str, el + 1 ); + free( *strp ); + free( str ); + *strp = tstr; + } else + *strp = str; +} + + +#define WANT_CLOSE 1 + +typedef struct File { + char *buf, *eof, *cur; +#if defined(HAVE_MMAP) && defined(WANT_CLOSE) + int ismapped; +#endif +} File; + +static int +readFile( File *file, const char *fn ) +{ + off_t flen; + int fd; + + if ((fd = open( fn, O_RDONLY )) < 0) + return 0; + + flen = lseek( fd, 0, SEEK_END ); +#ifdef HAVE_MMAP +# ifdef WANT_CLOSE + file->ismapped = 0; +# endif + file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); +# ifdef WANT_CLOSE + if (file->buf) + file->ismapped = 1; + else +# else + if (!file->buf) +# endif +#endif + { + file->buf = mmalloc( flen + 1 ); + lseek( fd, 0, SEEK_SET ); + if (read( fd, file->buf, flen ) != flen) { + free( file->buf ); + close( fd ); + fprintf( stderr, "Cannot read file\n" ); + return 0; /* maybe better abort? */ + } + } + file->eof = file->buf + flen; + close( fd ); + return 1; +} + +#ifdef WANT_CLOSE +static void +freeBuf( File *file ) +{ +# ifdef HAVE_MMAP + if (file->ismapped) + munmap( file->buf, file->eof - file->buf ); + else +# endif + free( file->buf ); +} +#endif + +static int +isTrue( const char *val ) +{ + return !strcmp( val, "true" ) || + !strcmp( val, "yes" ) || + !strcmp( val, "on" ) || + atoi( val ); +} + +static int +mkdirp( const char *name, int mode, const char *what, int existok ) +{ + char *mfname = mstrdup( name ); + int i; + struct stat st; + + for (i = 1; mfname[i]; i++) + if (mfname[i] == '/') { + mfname[i] = 0; + if (stat( mfname, &st )) { + if (mkdir( mfname, 0755 )) { + fprintf( stderr, "Cannot create parent %s of %s directory %s: %s\n", + mfname, what, name, strerror( errno ) ); + free( mfname ); + return 0; + } + chmod( mfname, 0755 ); + } + mfname[i] = '/'; + } + free( mfname ); + if (stat( name, &st )) { + if (mkdir( name, mode )) { + fprintf( stderr, "Cannot create %s directory %s: %s\n", + what, name, strerror( errno ) ); + return 0; + } + chmod( name, mode ); + return 1; + } + return existok; +} + + +static void +displace( const char *fn ) +{ + if (!no_backup) { + char bn[PATH_MAX + 4]; + sprintf( bn, "%s.bak", fn ); /* won't overflow if only existing paths are passed */ + rename( fn, bn ); + } else + unlink( fn ); +} + + +static char * +locate( const char *exe ) +{ + int len; + char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; + + if (!(path = getenv( "PATH" ))) + return 0; + len = strlen( exe ); + name = nambuf + PATH_MAX - len; + memcpy( name, exe, len + 1 ); + *--name = '/'; + do { + if (!(pathe = strchr( path, ':' ))) + pathe = path + strlen( path ); + len = pathe - path; + if (len && !(len == 1 && *path == '.')) { + thenam = name - len; + if (thenam >= nambuf) { + memcpy( thenam, path, len ); + if (!access( thenam, X_OK )) + return mstrdup( thenam ); + } + } + path = pathe; + } while (*path++ != '\0'); + return 0; +} + + +/* + * target data to be written to kdmrc + */ + +typedef struct Entry { + struct Entry *next; + struct Ent *spec; + const char *value; + int active:1; + int written:1; +} Entry; + +typedef struct Section { + struct Section *next; + struct Sect *spec; + const char *name; + const char *comment; + Entry *ents; +} Section; + +static Section *config; /* the kdmrc data to be written */ + +/* + * Specification of the (currently possible) kdmrc entries + */ + +typedef struct Ent { + const char *key; + int prio; + void (*func)( Entry *ce, Section *cs ); + const char *comment; +} Ent; + +typedef struct Sect { + const char *name; + Ent *ents; + int nents; +} Sect; + +static Sect *findSect( const char *name ); +static Ent *findEnt( Sect *sect, const char *key ); + +/* + * Functions to manipulate the current kdmrc data + */ + +static const char * +getfqval( const char *sect, const char *key, const char *defval ) +{ + Section *cs; + Entry *ce; + + for (cs = config; cs; cs = cs->next) + if (!strcmp( cs->name, sect )) { + for (ce = cs->ents; ce; ce = ce->next) + if (!strcmp( ce->spec->key, key )) { + if (ce->active && ce->written) + return ce->value; + break; + } + break; + } + return defval; +} + +static void +putfqval( const char *sect, const char *key, const char *value ) +{ + Section *cs, **csp; + Entry *ce, **cep; + + if (!value) + return; + + for (csp = &config; (cs = *csp); csp = &(cs->next)) + if (!strcmp( sect, cs->name )) + goto havesec; + cs = mcalloc( sizeof(*cs) ); + ASPrintf( (char **)&cs->name, "%s", sect ); + cs->spec = findSect( sect ); + *csp = cs; + havesec: + + for (cep = &(cs->ents); (ce = *cep); cep = &(ce->next)) + if (!strcmp( key, ce->spec->key )) + goto haveent; + ce = mcalloc( sizeof(*ce) ); + ce->spec = findEnt( cs->spec, key ); + *cep = ce; + haveent: + ASPrintf( (char **)&ce->value, "%s", value ); + ce->written = ce->active = 1; +} + +static const char *csect; + +#define setsect(se) csect = se + +static void +putval( const char *key, const char *value ) +{ + putfqval( csect, key, value ); +} + + +static void +wrconf( FILE *f ) +{ + Section *cs; + Entry *ce; + StrList *sl = 0, *sp; + const char *cmt; + + putfqval( "General", "ConfigVersion", RCVERSTR ); + for (cs = config; cs; cs = cs->next) { + fprintf( f, "%s[%s]\n", + cs->comment ? cs->comment : "\n", cs->name ); + for (ce = cs->ents; ce; ce = ce->next) { + if (ce->spec->comment) { + cmt = ce->spec->comment; + for (sp = sl; sp; sp = sp->next) + if (sp->str == cmt) { + cmt = "# See above\n"; + goto havit; + } + if (!(sp = malloc( sizeof(*sp) ))) + fprintf( stderr, "Warning: Out of memory\n" ); + else { + sp->str = cmt; + sp->next = sl; sl = sp; + } + } else + cmt = ""; + havit: + fprintf( f, "%s%s%s=%s\n", + cmt, ce->active ? "" : "#", ce->spec->key, ce->value ); + } + } +} + + +/* + * defaults + */ +#ifdef XDMCP +static const char def_xaccess[] = +"# Xaccess - Access control file for XDMCP connections\n" +"#\n" +"# To control Direct and Broadcast access:\n" +"#\n" +"# pattern\n" +"#\n" +"# To control Indirect queries:\n" +"#\n" +"# pattern list of hostnames and/or macros ...\n" +"#\n" +"# To use the chooser:\n" +"#\n" +"# pattern CHOOSER BROADCAST\n" +"#\n" +"# or\n" +"#\n" +"# pattern CHOOSER list of hostnames and/or macros ...\n" +"#\n" +"# To define macros:\n" +"#\n" +"# %name list of hosts ...\n" +"#\n" +"# The first form tells xdm which displays to respond to itself.\n" +"# The second form tells xdm to forward indirect queries from hosts matching\n" +"# the specified pattern to the indicated list of hosts.\n" +"# The third form tells xdm to handle indirect queries using the chooser;\n" +"# the chooser is directed to send its own queries out via the broadcast\n" +"# address and display the results on the terminal.\n" +"# The fourth form is similar to the third, except instead of using the\n" +"# broadcast address, it sends DirectQuerys to each of the hosts in the list\n" +"#\n" +"# In all cases, xdm uses the first entry which matches the terminal;\n" +"# for IndirectQuery messages only entries with right hand sides can\n" +"# match, for Direct and Broadcast Query messages, only entries without\n" +"# right hand sides can match.\n" +"#\n" +"\n" +"* #any host can get a login window\n" +"\n" +"#\n" +"# To hardwire a specific terminal to a specific host, you can\n" +"# leave the terminal sending indirect queries to this host, and\n" +"# use an entry of the form:\n" +"#\n" +"\n" +"#terminal-a host-a\n" +"\n" +"\n" +"#\n" +"# The nicest way to run the chooser is to just ask it to broadcast\n" +"# requests to the network - that way new hosts show up automatically.\n" +"# Sometimes, however, the chooser can't figure out how to broadcast,\n" +"# so this may not work in all environments.\n" +"#\n" +"\n" +"* CHOOSER BROADCAST #any indirect host can get a chooser\n" +"\n" +"#\n" +"# If you'd prefer to configure the set of hosts each terminal sees,\n" +"# then just uncomment these lines (and comment the CHOOSER line above)\n" +"# and edit the %hostlist line as appropriate\n" +"#\n" +"\n" +"#%hostlist host-a host-b\n" +"\n" +"#* CHOOSER %hostlist #\n"; +#endif + +#ifdef XDMCP +static const char def_willing[] = +"#! /bin/sh\n" +"# The output of this script is displayed in the chooser window\n" +"# (instead of \"Willing to manage\").\n" +"\n" +"load=`uptime|sed -e 's/^.*load[^0-9]*//'`\n" +"nrusers=`who|cut -c 1-8|sort -u|wc -l|sed 's/^[ \t]*//'`\n" +"s=\"\"; [ \"$nrusers\" != 1 ] && s=s\n" +"\n" +"echo \"${nrusers} user${s}, load: ${load}\"\n"; +#endif + +static const char def_setup[] = +"#! /bin/sh\n" +"# Xsetup - run as root before the login dialog appears\n" +"\n" +"#xconsole -geometry 480x130-0-0 -notify -verbose -fn fixed -exitOnFail -file /dev/xconsole &\n"; + +static const char def_startup[] = +"#! /bin/sh\n" +"# Xstartup - run as root before session starts\n" +"\n" +"# By convention, both xconsole and xterm -C check that the\n" +"# console is owned by the invoking user and is readable before attaching\n" +"# the console output. This way a random user can invoke xterm -C without\n" +"# causing serious grief; still, it can cause havoc, so xconsole is started\n" +"# by Xsetup usually.\n" +"# This is not required if you use PAM with the pam_console module.\n" +"#\n" +"#chown $USER /dev/console\n" +"\n" +#ifdef _AIX +"# We create a pseudodevice for finger. (host:0 becomes xdm/host_0)\n" +"# Without it, finger errors out with \"Can't stat /dev/host:0\".\n" +"#\n" +"#devname=`echo $DISPLAY | cut -c1-8`\n" +"#if [ ! -d /dev/xdm ]; then\n" +"# mkdir /dev/xdm\n" +"# chmod 755 /dev/xdm\n" +"#fi\n" +"#touch /dev/xdm/$devname\n" +"#chmod 644 /dev/xdm/$devname\n" +"#exec sessreg -a -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" +#else +"#exec sessreg -a -l $DISPLAY -h \"`echo $DISPLAY | cut -d: -f1`\"" +# ifdef BSD +" -x " KDMCONF "/Xservers" +# endif +#endif /* _AIX */ +" $USER\n" +"\n# NOTE: The session is aborted if the last command returns non-zero.\n"; + +static const char def_reset[] = +"#! /bin/sh\n" +"# Xreset - run as root after session exits\n" +"\n" +"# Reassign ownership of the console to root, this should disallow\n" +"# assignment of console output to any random users's xterm. See Xstartup.\n" +"#\n" +"#chown root /dev/console\n" +"#chmod 622 /dev/console\n" +"\n" +#ifdef _AIX +"#devname=`echo $DISPLAY | cut -c1-8`\n" +"#exec sessreg -d -l xdm/$devname -h \"`echo $DISPLAY | cut -d: -f1`\"" +#else +"#exec sessreg -d -l $DISPLAY -h \"`echo $DISPLAY | cut -d: -f1`\"" +# ifdef BSD +" -x " KDMCONF "/Xservers" +# endif +#endif /* _AIX */ +" $USER\n"; + +static const char def_session1[] = +"#! /bin/sh\n" +"# Xsession - run as user\n" +"\n" +"session=$1\n" +"\n" +"# Note that the respective logout scripts are not sourced.\n" +"case $SHELL in\n" +" */bash)\n" +" [ -z \"$BASH\" ] && exec $SHELL $0 \"$@\"\n" +" set +o posix\n" +" [ -f /etc/profile ] && . /etc/profile\n" +" if [ -f $HOME/.bash_profile ]; then\n" +" . $HOME/.bash_profile\n" +" elif [ -f $HOME/.bash_login ]; then\n" +" . $HOME/.bash_login\n" +" elif [ -f $HOME/.profile ]; then\n" +" . $HOME/.profile\n" +" fi\n" +" ;;\n" +" */zsh)\n" +" [ -z \"$ZSH_NAME\" ] && exec $SHELL $0 \"$@\"\n" +" emulate -R zsh\n" +" [ -d /etc/zsh ] && zdir=/etc/zsh || zdir=/etc\n" +" zhome=${ZDOTDIR:-$HOME}\n" +" # zshenv is always sourced automatically.\n" +" [ -f $zdir/zprofile ] && . $zdir/zprofile\n" +" [ -f $zhome/.zprofile ] && . $zhome/.zprofile\n" +" [ -f $zdir/zlogin ] && . $zdir/zlogin\n" +" [ -f $zhome/.zlogin ] && . $zhome/.zlogin\n" +" ;;\n" +" */csh|*/tcsh)\n" +" # [t]cshrc is always sourced automatically.\n" +" # Note that sourcing csh.login after .cshrc is non-standard.\n" +" xsess_tmp="; +static const char def_session2[] = +"\n" +" $SHELL -c \"if (-f /etc/csh.login) source /etc/csh.login; if (-f ~/.login) source ~/.login; /bin/sh -c export -p >! $xsess_tmp\"\n" +" . $xsess_tmp\n" +" rm -f $xsess_tmp\n" +" ;;\n" +" *) # Plain sh, ksh, and anything we don't know.\n" +" [ -f /etc/profile ] && . /etc/profile\n" +" [ -f $HOME/.profile ] && . $HOME/.profile\n" +" ;;\n" +"esac\n" +"\n" +"[ -f /etc/xprofile ] && . /etc/xprofile\n" +"[ -f $HOME/.xprofile ] && . $HOME/.xprofile\n" +"\n" +"case $session in\n" +" \"\")\n" +" exec xmessage -center -buttons OK:0 -default OK \"Sorry, $DESKTOP_SESSION is no valid session.\"\n" +" ;;\n" +" failsafe)\n" +" exec xterm -geometry 80x24-0-0\n" +" ;;\n" +" custom)\n" +" exec $HOME/.xsession\n" +" ;;\n" +" default)\n" +" exec " KDE_BINDIR "/startkde\n" +" ;;\n" +" *)\n" +" eval exec \"$session\"\n" +" ;;\n" +"esac\n" +"exec xmessage -center -buttons OK:0 -default OK \"Sorry, cannot execute $session. Check $DESKTOP_SESSION.desktop.\"\n"; + +static const char def_background[] = +"[Desktop0]\n" +"BackgroundMode=Flat\n" +"BlendBalance=100\n" +"BlendMode=NoBlending\n" +"ChangeInterval=60\n" +"Color1=0,0,200\n" +"Color2=192,192,192\n" +"CurrentWallpaper=0\n" +"LastChange=0\n" +"MinOptimizationDepth=1\n" +"MultiWallpaperMode=NoMulti\n" +"Pattern=fish\n" +"Program=\n" +"ReverseBlending=false\n" +"UseSHM=false\n" +"Wallpaper=default_blue.jpg\n" +"WallpaperList=\n" +"WallpaperMode=Scaled\n"; + +static char * +prepName( const char *fn ) +{ + const char *tname; + char *nname; + + tname = strrchr( fn, '/' ); + ASPrintf( &nname, "%s/%s", newdir, tname ? tname + 1 : fn ); + displace( nname ); + return nname; +} + +static FILE * +Create( const char *fn, int mode ) +{ + char *nname; + FILE *f; + + nname = prepName( fn ); + if (!(f = fopen( nname, "w" ))) { + fprintf( stderr, "Cannot create %s\n", nname ); + exit( 1 ); + } + chmod( nname, mode ); + free( nname ); + return f; +} + +static void +WriteOut( const char *fn, int mode, time_t stamp, const char *buf, size_t len ) +{ + char *nname; + int fd; + struct utimbuf utim; + + nname = prepName( fn ); + if ((fd = creat( nname, mode )) < 0) { + fprintf( stderr, "Cannot create %s\n", nname ); + exit( 1 ); + } + write( fd, buf, len ); + close( fd ); + if (stamp) { + utim.actime = utim.modtime = stamp; + utime( nname, &utim ); + } + free( nname ); +} + + +/* returns static array! */ +static const char * +resect( const char *sec, const char *name ) +{ + static char sname[64]; + char *p; + + if ((p = strrchr( sec, '-' ))) { + sprintf( sname, "%.*s-%s", p - sec, sec, name ); + return sname; + } else + return name; +} + +static int +inNewDir( const char *name ) +{ + return !memcmp( name, KDMCONF "/", sizeof(KDMCONF) ); +} + +static int +inList( StrList *sp, const char *s ) +{ + for (; sp; sp = sp->next) + if (!strcmp( sp->str, s )) + return 1; + return 0; +} + +static void +addStr( StrList **sp, const char *s ) +{ + for (; *sp; sp = &(*sp)->next) + if (!strcmp( (*sp)->str, s )) + return; + *sp = mcalloc( sizeof(**sp) ); + ASPrintf( (char **)&(*sp)->str, "%s", s ); +} + +StrList *aflist, *uflist, *eflist, *cflist, *lflist; + +/* file is part of new config */ +static void +addedFile( const char *fn ) +{ + addStr( &aflist, fn ); +} + +/* file from old config was parsed */ +static void +usedFile( const char *fn ) +{ + addStr( &uflist, fn ); +} + +/* file from old config was copied with slight modifications */ +static void +editedFile( const char *fn ) +{ + addStr( &eflist, fn ); +} + +/* file from old config was copied verbatim */ +static void +copiedFile( const char *fn ) +{ + addStr( &cflist, fn ); +} + +/* file from old config is still being used */ +static void +linkedFile( const char *fn ) +{ + addStr( &lflist, fn ); +} + +/* + * XXX this stuff is highly borked. it does not handle collisions at all. + */ +static int +copyfile( Entry *ce, const char *tname, int mode, int (*proc)( File * ) ) +{ + const char *tptr; + char *nname; + File file; + int rt; + + if (!*ce->value) + return 1; + + tptr = strrchr( tname, '/' ); + ASPrintf( &nname, KDMCONF "/%s", tptr ? tptr + 1 : tname ); + if (inList( cflist, ce->value ) || + inList( eflist, ce->value ) || + inList( lflist, ce->value )) + { + rt = 1; + goto doret; + } + if (!readFile( &file, ce->value )) { + fprintf( stderr, "Warning: cannot copy file %s\n", ce->value ); + rt = 0; + } else { + if (!proc || !proc( &file )) { + if (!use_destdir && !strcmp( ce->value, nname )) + linkedFile( nname ); + else { + struct stat st; + stat( ce->value, &st ); + WriteOut( nname, mode, st.st_mtime, file.buf, file.eof - file.buf ); + copiedFile( ce->value ); + } + } else { + WriteOut( nname, mode, 0, file.buf, file.eof - file.buf ); + editedFile( ce->value ); + } + if (strcmp( ce->value, nname ) && inNewDir( ce->value ) && !use_destdir) + displace( ce->value ); + addedFile( nname ); + rt = 1; + } + doret: + ce->value = nname; + return rt; +} + +static void +dlinkfile( const char *name ) +{ + File file; + + if (!readFile( &file, name )) { + fprintf( stderr, "Warning: cannot read file %s\n", name ); + return; + } + if (inNewDir( name ) && use_destdir) { + struct stat st; + stat( name, &st ); + WriteOut( name, st.st_mode, st.st_mtime, file.buf, file.eof - file.buf ); + copiedFile( name ); + } else + linkedFile( name ); + addedFile( name ); +} + +static void +linkfile( Entry *ce ) +{ + if (ce->written && *ce->value) + dlinkfile( ce->value ); +} + +static void +writefile( const char *tname, int mode, const char *cont ) +{ + WriteOut( tname, mode, 0, cont, strlen( cont ) ); + addedFile( tname ); +} + + +char *background; + +static void +handBgCfg( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* can be only the X-*-Greeter one */ + writefile( def_BackgroundCfg, 0644, + background ? background : def_background ); +#if 0 /* risk of kcontrol clobbering the original file */ + else if (old_confs) + linkfile( ce ); +#endif + else { + if (!copyfile( ce, ce->value, 0644, 0 )) { + if (!strcmp( cs->name, "X-*-Greeter" )) + writefile( def_BackgroundCfg, 0644, def_background ); + ce->active = 0; + } + } +} + + +#ifdef HAVE_VTS +static char * +mem_mem( char *mem, int lmem, const char *smem, int lsmem ) +{ + for (; lmem >= lsmem; mem++, lmem--) + if (!memcmp( mem, smem, lsmem )) + return mem + lsmem; + return 0; +} + +static int maxTTY, TTYmask; + +static void +getInitTab( void ) +{ + File it; + char *p, *eol, *ep; + int tty; + + if (maxTTY) + return; + if (readFile( &it, "/etc/inittab" )) { + usedFile( "/etc/inittab" ); + for (p = it.buf; p < it.eof; p = eol + 1) { + for (eol = p; eol < it.eof && *eol != '\n'; eol++); + if (*p != '#') { + if ((ep = mem_mem( p, eol - p, " tty", 4 )) && + ep < eol && isdigit( *ep )) + { + if (ep + 1 == eol || isspace( *(ep + 1) )) + tty = *ep - '0'; + else if (isdigit( *(ep + 1) ) && + (ep + 2 == eol || isspace( *(ep + 2) ))) + tty = (*ep - '0') * 10 + (*(ep + 1) - '0'); + else + continue; + TTYmask |= 1 << (tty - 1); + if (tty > maxTTY) + maxTTY = tty; + } + } + } + freeBuf( &it ); + } + if (!maxTTY) { + maxTTY = 6; + TTYmask = 0x3f; + } +} +#endif + + +/* TODO: handle solaris' local_uid specs */ + +static char * +ReadWord( File *file, int EOFatEOL ) +{ + char *wordp, *wordBuffer; + int quoted; + char c; + + rest: + wordp = wordBuffer = file->cur; + mloop: + quoted = 0; + qloop: + if (file->cur == file->eof) { + doeow: + if (wordp == wordBuffer) + return 0; + retw: + *wordp = '\0'; + return wordBuffer; + } + c = *file->cur++; + switch (c) { + case '#': + if (quoted) + break; + do { + if (file->cur == file->eof) + goto doeow; + c = *file->cur++; + } while (c != '\n'); + case '\0': + case '\n': + if (EOFatEOL && !quoted) { + file->cur--; + goto doeow; + } + if (wordp != wordBuffer) { + file->cur--; + goto retw; + } + goto rest; + case ' ': + case '\t': + if (wordp != wordBuffer) + goto retw; + goto rest; + case '\\': + if (!quoted) { + quoted = 1; + goto qloop; + } + break; + } + *wordp++ = c; + goto mloop; +} + +/* backslashes are double-escaped - for KConfig and for parseArgs */ +static const char * +joinArgs( StrList *argv ) +{ + StrList *av; + const char *s, *rs; + char *str; + int slen; + + if (!argv) + return ""; + for (slen = 0, av = argv; slen++, av; av = av->next) { + int nq = 0; + for (s = av->str; *s; s++, slen++) + if (isspace( *s ) || *s == '\'') + nq = 2; + else if (*s == '"') + slen += 2; + else if (*s == '\\') + slen += 3; + slen += nq; + } + rs = str = mmalloc( slen ); + for (av = argv; av; av = av->next) { + int nq = 0; + for (s = av->str; *s; s++) + if (isspace( *s ) || *s == '\'') + nq = 2; + if (av != argv) + *str++ = ' '; + if (nq) + *str++ = '"'; + for (s = av->str; *s; s++) { + if (*s == '\\') + *str++ = '\\'; + if (*s == '"' || *s == '\\') { + *str++ = '\\'; + *str++ = '\\'; + } + *str++ = *s; + } + if (nq) + *str++ = '"'; + } + *str = 0; + return rs; +} + +# define dLocation 1 +# define dLocal 0 +# define dForeign 1 + +static struct displayMatch { + const char *name; + int len, type; +} displayTypes[] = { + { "local", 5, dLocal }, + { "foreign", 7, dForeign }, +}; + +static int +parseDisplayType( const char *string, const char **atPos ) +{ + struct displayMatch *d; + + *atPos = 0; + for (d = displayTypes; d < displayTypes + as(displayTypes); d++) { + if (!memcmp( d->name, string, d->len ) && + (!string[d->len] || string[d->len] == '@')) + { + if (string[d->len] == '@' && string[d->len + 1]) + *atPos = string + d->len + 1; + return d->type; + } + } + return -1; +} + +typedef struct serverEntry { + struct serverEntry *next; + const char *name, *class2, *console, *argvs, *arglvs; + StrList *argv, *arglv; + int type, reserve, vt; +} ServerEntry; + +static void +absorb_xservers( const char *sect ATTR_UNUSED, char **value ) +{ + ServerEntry *se, *se1, *serverList, **serverPtr; + const char *word, *word2; + char *sdpys, *rdpys; + StrList **argp, **arglp, *ap, *ap2; + File file; + int nldpys = 0, nrdpys = 0, dpymask = 0; + int cpcmd, cpcmdl; +#ifdef HAVE_VTS + int dn, cpvt, mtty; +#endif + + if (**value == '/') { + if (!readFile( &file, *value )) + return; + usedFile( *value ); + } else { + file.buf = *value; + file.eof = *value + strlen( *value ); + } + file.cur = file.buf; + + serverPtr = &serverList; +#ifdef HAVE_VTS + bustd: +#endif + while ((word = ReadWord( &file, 0 ))) { + se = mcalloc( sizeof(*se) ); + se->name = word; + if (!(word = ReadWord( &file, 1 ))) + continue; + se->type = parseDisplayType( word, &se->console ); + if (se->type < 0) { + se->class2 = word; + if (!(word = ReadWord( &file, 1 ))) + continue; + se->type = parseDisplayType( word, &se->console ); + if (se->type < 0) { + while (ReadWord( &file, 1 )); + continue; + } + } + word = ReadWord( &file, 1 ); + if (word && !strcmp( word, "reserve" )) { + se->reserve = 1; + word = ReadWord( &file, 1 ); + } + if (((se->type & dLocation) == dLocal) != (word != 0)) + continue; + argp = &se->argv; + arglp = &se->arglv; + while (word) { +#ifdef HAVE_VTS + if (word[0] == 'v' && word[1] == 't') + se->vt = atoi( word + 2 ); + else if (!strcmp( word, "-crt" )) { /* SCO style */ + if (!(word = ReadWord( &file, 1 )) || + memcmp( word, "/dev/tty", 8 )) + goto bustd; + se->vt = atoi( word + 8 ); + } else +#endif + if (strcmp( word, se->name )) { + ap = mmalloc( sizeof(*ap) ); + ap->str = word; + if (!strcmp( word, "-nolisten" )) { + if (!(word2 = ReadWord( &file, 1 ))) + break; + ap2 = mmalloc( sizeof(*ap2) ); + ap2->str = word2; + ap->next = ap2; + if (!strcmp( word2, "unix" )) { + *argp = ap; + argp = &ap2->next; + } else { + *arglp = ap; + arglp = &ap2->next; + } + } else { + *argp = ap; + argp = &ap->next; + } + } + word = ReadWord( &file, 1 ); + } + *argp = *arglp = 0; + if ((se->type & dLocation) == dLocal) { + nldpys++; + dpymask |= 1 << atoi( se->name + 1 ); + if (se->reserve) + nrdpys++; + } + *serverPtr = se; + serverPtr = &se->next; + } + *serverPtr = 0; + +#ifdef HAVE_VTS + /* don't copy only if all local displays are ordered and have a vt */ + cpvt = 0; + getInitTab(); + for (se = serverList, mtty = maxTTY; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + mtty++; + if (se->vt != mtty) { + cpvt = 1; + break; + } + } +#endif + + for (se = serverList; se; se = se->next) { + se->argvs = joinArgs( se->argv ); + se->arglvs = joinArgs( se->arglv ); + } + + se1 = 0, cpcmd = cpcmdl = 0; + for (se = serverList; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + if (!se1) + se1 = se; + else { + if (strcmp( se1->argvs, se->argvs )) + cpcmd = 1; + if (strcmp( se1->arglvs, se->arglvs )) + cpcmdl = 1; + } + } + if (se1) { + putfqval( "X-:*-Core", "ServerCmd", se1->argvs ); + putfqval( "X-:*-Core", "ServerArgsLocal", se1->arglvs ); + for (se = serverList; se; se = se->next) + if ((se->type & dLocation) == dLocal) { + char sec[32]; + sprintf( sec, "X-%s-Core", se->name ); + if (cpcmd) + putfqval( sec, "ServerCmd", se->argvs ); + if (cpcmdl) + putfqval( sec, "ServerArgsLocal", se->arglvs ); +#ifdef HAVE_VTS + if (cpvt && se->vt) { + char vt[8]; + sprintf( vt, "%d", se->vt ); + putfqval( sec, "ServerVT", vt ); + } +#else + if (se->console) + putfqval( sec, "ServerTTY", se->console ); +#endif + } + } + + sdpys = rdpys = 0; + for (se = serverList; se; se = se->next) + StrCat( se->reserve ? &rdpys : &sdpys, + se->class2 ? ",%s_%s" : ",%s", se->name, se->class2 ); + +#ifdef HAVE_VTS + /* add reserve dpys */ + if (nldpys < 4 && nldpys && !nrdpys) + for (; nldpys < 4; nldpys++) { + for (dn = 0; dpymask & (1 << dn); dn++); + dpymask |= (1 << dn); + StrCat( &rdpys, ",:%d", dn ); + } +#endif + + putfqval( "General", "StaticServers", sdpys ? sdpys + 1 : "" ); + putfqval( "General", "ReserveServers", rdpys ? rdpys + 1 : "" ); + + if (**value == '/' && inNewDir( *value ) && !use_destdir) + displace( *value ); +} + +#ifdef HAVE_VTS +static void +upd_servervts( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { /* there is only the Global one */ +#ifdef __linux__ /* XXX actually, sysvinit */ + getInitTab(); + ASPrintf( (char **)&ce->value, "-%d", maxTTY + 1 ); + ce->active = ce->written = 1; +#endif + } +} + +static void +upd_consolettys( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { /* there is only the Global one */ +#ifdef __linux__ /* XXX actually, sysvinit */ + char *buf; + int i; + + getInitTab(); + for (i = 0, buf = 0; i < 16; i++) + if (TTYmask & (1 << i)) + StrCat( &buf, ",tty%d", i + 1 ); + if (buf) { + ce->value = buf + 1; + ce->active = ce->written = 1; + } +#endif + } +} +#endif + +#ifdef XDMCP +static void +cp_keyfile( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* there is only the Global one */ + return; + if (old_confs) + linkfile( ce ); + else + if (!copyfile( ce, "kdmkeys", 0600, 0 )) + ce->active = 0; +} + +static void +mk_xaccess( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* there is only the Global one */ + writefile( def_Xaccess, 0644, def_xaccess ); + else if (old_confs) + linkfile( ce ); + else + copyfile( ce, "Xaccess", 0644, 0 ); /* don't handle error, it will disable Xdmcp automatically */ +} + +static void +mk_willing( Entry *ce, Section *cs ATTR_UNUSED ) +{ + const char *fname; + + if (!ce->active) /* there is only the Global one */ + goto dflt; + else { + if (!(fname = strchr( ce->value, '/' ))) + return; /* obviously in-line (or empty) */ + if (old_scripts || inNewDir( fname )) + dlinkfile( fname ); + else { + dflt: + ce->value = KDMCONF "/Xwilling"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_willing ); + } + } +} +#endif + +/* +static int +edit_resources( File *file ) +{ + // XXX remove any login*, chooser*, ... resources + return 0; +} +*/ + +static void +cp_resources( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) /* the X-*-Greeter one */ + return; + if (old_confs) + linkfile( ce ); + else + if (!copyfile( ce, ce->value, 0644, 0/*edit_resources*/ )) + ce->active = 0; +} + +static int +delstr( File *fil, const char *pat ) +{ + char *p, *pp, *bpp; + const char *pap, *paap; + + *fil->eof = 0; + for (p = fil->buf; *p; p++) { + for (pp = p, pap = pat; ; ) { + if (!*pap) { + *p = '\n'; + memcpy( p + 1, pp, fil->eof - pp + 1 ); + fil->eof -= pp - p - 1; + return 1; + } else if (!memcmp( pap, "*/", 2 )) { + paap = pap += 2; + while (!isspace( *pap )) + pap++; + if (*pp != '/') + break; + for (;;) + for (bpp = ++pp; *pp != '/'; pp++) + if (!*pp || isspace( *pp )) + goto wbrk; + wbrk: + if ((pp - bpp != pap - paap) || memcmp( bpp, paap, pap - paap )) + break; + } else if (*pap == '\t') { + pap++; + while (*pp == ' ' || *pp == '\t') + pp++; + } else if (*pap == '[') { + pap++; + for (;;) { + if (!*pap) { + fprintf( stderr, "Internal error: unterminated char set\n" ); + exit( 1 ); + } + if (*pap == *pp) { + while (*++pap != ']') + if (!*pap) { + fprintf( stderr, "Internal error: unterminated char set\n" ); + exit( 1 ); + } + pap++; + pp++; + break; + } + if (*++pap == ']') + goto no; + } + } else { + if (*pap == '\n') + while (*pp == ' ' || *pp == '\t') + pp++; + if (*pap != *pp) + break; + pap++; + pp++; + } + } + no: ; + } + return 0; +} + +/* XXX + the UseBackground voodoo will horribly fail, if multiple sections link + to the same Xsetup file +*/ + +static int mod_usebg; + +static int +edit_setup( File *file ) +{ + int chg = + delstr( file, "\n" + "(\n" + " PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n" + " */kdmdesktop\t&\n" + " echo $! >$PIDFILE\n" + " wait $!\n" + " rm $PIDFILE\n" + ")\t&\n" ) | + delstr( file, "\n" + "*/kdmdesktop\t&\n" ) | + delstr( file, "\n" + "kdmdesktop\t&\n" ) | + delstr( file, "\n" + "kdmdesktop\n" ); + putval( "UseBackground", chg ? "true" : "false" ); + return chg; +} + +static void +mk_setup( Entry *ce, Section *cs ) +{ + setsect( resect( cs->name, "Greeter" ) ); + if (old_scripts || mixed_scripts) { + if (mod_usebg && *ce->value) + putval( "UseBackground", "false" ); + linkfile( ce ); + } else { + if (ce->active && inNewDir( ce->value )) { + if (mod_usebg) + copyfile( ce, ce->value, 0755, edit_setup ); + else + linkfile( ce ); + } else { + ce->value = KDMCONF "/Xsetup"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_setup ); + } + } +} + +static int +edit_startup( File *file ) +{ + int chg1 = 0, chg2 = 0; + + if (mod_usebg && + (delstr( file, "\n" + "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n" + "if [[] -f $PIDFILE ] ; then\n" + " kill `cat $PIDFILE`\n" + "fi\n" ) || + delstr( file, "\n" + "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n" + "test -f $PIDFILE && kill `cat $PIDFILE`\n" ))) + chg1 = 1; + if (oldver < 0x0203) { + chg2 = +#ifdef _AIX + delstr( file, "\n" +"# We create a pseudodevice for finger. (host:0 becomes [kx]dm/host_0)\n" ); +"# Without it, finger errors out with \"Can't stat /dev/host:0\".\n" +"#\n" +"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" +" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" +" hostname=`echo $DISPLAY | /usr/bin/cut -d':' -f1`\n" +"\n" +" if [[] -z \"$devname\" ]; then\n" +" devname=\"unknown\"\n" +" fi\n" +" if [[] ! -d /dev/[kx]dm ]; then\n" +" /usr/bin/mkdir /dev/[kx]dm\n" +" /usr/bin/chmod 755 /dev/[kx]dm\n" +" fi\n" +" /usr/bin/touch /dev/[kx]dm/$devname\n" +" /usr/bin/chmod 644 /dev/[kx]dm/$devname\n" +"\n" +" if [[] -z \"$hostname\" ]; then\n" +" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname $USER\n" +" else\n" +" exec /usr/lib/X11/xdm/sessreg -a -l [kx]dm/$devname -h $hostname $USER\n" +" fi\n" +"fi\n") | +#else +# ifdef BSD + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | +# endif +#endif /* _AIX */ + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY" +#ifdef BSD +" -x */Xservers" +#endif +" $USER\n" ) | + delstr( file, "\n" +"exec sessreg -a -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); + putval( "UseSessReg", chg2 ? "true" : "false"); + } + return chg1 | chg2; +} + +static void +mk_startup( Entry *ce, Section *cs ) +{ + setsect( cs->name ); + if (old_scripts || mixed_scripts) + linkfile( ce ); + else { + if (ce->active && inNewDir( ce->value )) { + if (mod_usebg || oldver < 0x0203) + copyfile( ce, ce->value, 0755, edit_startup ); + else + linkfile( ce ); + } else { + ce->value = KDMCONF "/Xstartup"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_startup ); + } + } +} + +static int +edit_reset( File *file ) +{ + return +#ifdef _AIX + delstr( file, "\n" +"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n" +" devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n" +" exec /usr/lib/X11/xdm/sessreg -d -l [kx]dm/$devname $USER\n" +"fi\n" ) | +#else +# ifdef BSD + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) | +# endif +#endif /* _AIX */ + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY" +# ifdef BSD +" -x */Xservers" +# endif +" $USER\n" ) | + delstr( file, "\n" +"exec sessreg -d -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" ); +} + +static void +mk_reset( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (old_scripts || mixed_scripts) + linkfile( ce ); + else { + if (ce->active && inNewDir( ce->value )) { + if (oldver < 0x0203) + copyfile( ce, ce->value, 0755, edit_reset ); + else + linkfile( ce ); + } else { + ce->value = KDMCONF "/Xreset"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_reset ); + } + } +} + +static void +mk_session( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *def_session; + const char *tmpf; + + if ((old_scripts || (ce->active && inNewDir( ce->value ))) && + oldver >= 0x202) + linkfile( ce ); + else { + tmpf = locate( "mktemp" ) ? + "`mktemp /tmp/xsess-env-XXXXXX`" : + locate( "tempfile" ) ? + "`tempfile`" : + "$HOME/.xsession-env-$DISPLAY"; + ASPrintf( &def_session, "%s%s%s", def_session1, tmpf, def_session2 ); + ce->value = KDMCONF "/Xsession"; + ce->active = ce->written = 1; + writefile( ce->value, 0755, def_session ); + } +} + +static void +upd_language( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!strcmp( ce->value, "C" )) + ce->value = (char *)"en_US"; +} + +static void +upd_guistyle( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!strcmp( ce->value, "Motif+" )) + ce->value = (char *)"MotifPlus"; + else if (!strcmp( ce->value, "KDE" )) + ce->value = (char *)"Default"; +} + +static void +upd_showusers( Entry *ce, Section *cs ) +{ + if (!strcmp( ce->value, "All" )) + ce->value = (char *)"NotHidden"; + else if (!strcmp( ce->value, "None" )) { + if (ce->active) + putfqval( cs->name, "UserList", "false" ); + ce->value = (char *)"Selected"; + ce->active = 0; + ce->written = 1; + } +} + +static const char *defminuid, *defmaxuid; + +static void +upd_minshowuid( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ce->value = defminuid; + ce->active = ce->written = 1; + } +} + +static void +upd_maxshowuid( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ce->value = defmaxuid; + ce->active = ce->written = 1; + } +} + +static void +upd_hiddenusers( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *nv; + const char *msu, *pt, *et; + struct passwd *pw; + unsigned minuid, maxuid; + char nbuf[128]; + + if (!ce->active) + return; + + msu = getfqval( cs->name, "MinShowUID", "0" ); + sscanf( msu, "%u", &minuid ); + msu = getfqval( cs->name, "MaxShowUID", "65535" ); + sscanf( msu, "%u", &maxuid ); + + nv = 0; + pt = ce->value; + for (;;) { + et = strpbrk( pt, ";," ); + if (et) { + memcpy( nbuf, pt, et - pt ); + nbuf[et - pt] = 0; + } else + strcpy( nbuf, pt ); + if ((pw = getpwnam( nbuf ))) { + if (!pw->pw_uid || + (pw->pw_uid >= minuid && pw->pw_uid <= maxuid)) + { + if (nv) + StrCat( &nv, ",%s", nbuf ); + else + nv = mstrdup( nbuf ); + } + } + if (!et) + break; + pt = et + 1; + } + ce->value = nv ? nv : ""; +} + +static void +upd_forgingseed( Entry *ce, Section *cs ATTR_UNUSED ) +{ + if (!ce->active) { + ASPrintf( (char **)&ce->value, "%d", time( 0 ) ); + ce->active = ce->written = 1; + } +} + +static void +upd_fifodir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + const char *dir; + struct stat st; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_FifoDir; + stat( dir, &st ); + chmod( dir, st.st_mode | 0755 ); +} + +static void +upd_datadir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *oldsts, *newsts; + const char *dir; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_DataDir; + if (mkdirp( dir, 0755, "data", 0 ) && oldkde) { + ASPrintf( &oldsts, "%s/kdm/kdmsts", oldkde ); + ASPrintf( &newsts, "%s/kdmsts", dir ); + rename( oldsts, newsts ); + } +} + +static void +CopyFile( const char *from, const char *to ) +{ + File file; + int fd; + + if (readFile( &file, from )) { + if ((fd = creat( to, 0644 )) >= 0) { + write( fd, file.buf, file.eof - file.buf ); + close( fd ); + } + freeBuf( &file ); + } +} + +static void +upd_facedir( Entry *ce, Section *cs ATTR_UNUSED ) +{ + char *oldpic, *newpic, *defpic, *rootpic; + const char *dir; + struct passwd *pw; + + if (use_destdir) + return; + dir = ce->active ? ce->value : def_FaceDir; + if (mkdirp( dir, 0755, "user face", 0 )) { + ASPrintf( &defpic, "%s/.default.face.icon", dir ); + ASPrintf( &rootpic, "%s/root.face.icon", dir ); + if (oldkde) { + setpwent(); + while ((pw = getpwent())) + if (strcmp( pw->pw_name, "root" )) { + ASPrintf( &oldpic, "%s/../apps/kdm/pics/users/%s.png", + oldkde, pw->pw_name ); + ASPrintf( &newpic, "%s/%s.face.icon", dir, pw->pw_name ); + rename( oldpic, newpic ); + free( newpic ); + free( oldpic ); + } + endpwent(); + ASPrintf( &oldpic, "%s/../apps/kdm/pics/users/default.png", oldkde ); + if (!rename( oldpic, defpic )) + defpic = 0; + ASPrintf( &oldpic, "%s/../apps/kdm/pics/users/root.png", oldkde ); + if (!rename( oldpic, rootpic )) + rootpic = 0; + } + if (defpic) { + ASPrintf( &oldpic, "%s/default1.png", facesrc ); + CopyFile( oldpic, defpic ); + } + if (rootpic) { + ASPrintf( &oldpic, "%s/root1.png", facesrc ); + CopyFile( oldpic, rootpic ); + } + } +} + +CONF_GEN_ENTRIES + +static Sect * +findSect( const char *name ) +{ + const char *p; + int i; + + p = strrchr( name, '-' ); + if (!p) + p = name; + for (i = 0; i < as(allSects); i++) + if (!strcmp( allSects[i]->name, p )) + return allSects[i]; + fprintf( stderr, "Internal error: unknown section %s\n", name ); + exit( 1 ); +} + +static Ent * +findEnt( Sect *sect, const char *key ) +{ + int i; + + for (i = 0; i < sect->nents; i++) + if (!strcmp( sect->ents[i].key, key )) + return sect->ents + i; + fprintf( stderr, "Internal error: unknown key %s in section %s\n", + key, sect->name ); + exit( 1 ); +} + + +/* + * defaults + */ + +typedef struct DEnt { + const char *key; + const char *value; + int active; +} DEnt; + +typedef struct DSect { + const char *name; + DEnt *ents; + int nents; + const char *comment; +} DSect; + +CONF_GEN_EXAMPLE + +static void +mkdefconf( void ) +{ + Section *cs, **csp; + Entry *ce, **cep; + int sc, ec; + + for (csp = &config, sc = 0; sc < as(dAllSects); csp = &(cs->next), sc++) { + cs = mcalloc( sizeof(*cs) ); + *csp = cs; + cs->spec = findSect( dAllSects[sc].name ); + cs->name = dAllSects[sc].name; + cs->comment = dAllSects[sc].comment; + for (cep = &(cs->ents), ec = 0; ec < dAllSects[sc].nents; + cep = &(ce->next), ec++) + { + ce = mcalloc( sizeof(*ce) ); + *cep = ce; + ce->spec = findEnt( cs->spec, dAllSects[sc].ents[ec].key ); + ce->value = dAllSects[sc].ents[ec].value; + ce->active = dAllSects[sc].ents[ec].active; + } + } +} + + +/* + * read rc file structure + */ + +typedef struct REntry { + struct REntry *next; + const char *key; + char *value; +} REntry; + +typedef struct RSection { + struct RSection *next; + const char *name; + REntry *ents; +} RSection; + +static RSection * +ReadConf( const char *fname ) +{ + char *nstr; + char *s, *e, *st, *en, *ek, *sl; + RSection *rootsec = 0, *cursec; + REntry *curent; + int nlen; + int line, sectmoan; + File file; + + if (!readFile( &file, fname )) + return 0; + usedFile( fname ); + + for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { + line++; + + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + + if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { + sktoeol: + while ((s < file.eof) && (*s != '\n')) + s++; + continue; + } + sl = s; + + if (*s == '[') { + while ((s < file.eof) && (*s != '\n')) + s++; + e = s - 1; + while ((e > sl) && isspace( *e )) + e--; + if (*e != ']') { + fprintf( stderr, "Invalid section header at %s:%d\n", + fname, line ); + continue; + } + sectmoan = 0; + nstr = sl + 1; + nlen = e - nstr; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (!memcmp( nstr, cursec->name, nlen ) && + !cursec->name[nlen]) + { +#if 0 /* not our business ... */ + fprintf( stderr, "Warning: Multiple occurrences of section " + "[%.*s] in %s. Consider merging them.\n", + nlen, nstr, fname ); +#endif + goto secfnd; + } + cursec = mmalloc( sizeof(*cursec) ); + ASPrintf( (char **)&cursec->name, "%.*s", nlen, nstr ); + cursec->ents = 0; + cursec->next = rootsec; + rootsec = cursec; + secfnd: + continue; + } + + if (!cursec) { + if (sectmoan) { + sectmoan = 0; + fprintf( stderr, "Entry outside any section at %s:%d", + fname, line ); + } + goto sktoeol; + } + + for (; (s < file.eof) && (*s != '\n'); s++) + if (*s == '=') + goto haveeq; + fprintf( stderr, "Invalid entry (missing '=') at %s:%d\n", fname, line ); + continue; + + haveeq: + for (ek = s - 1;; ek--) { + if (ek < sl) { + fprintf( stderr, "Invalid entry (empty key) at %s:%d\n", + fname, line ); + goto sktoeol; + } + if (!isspace( *ek )) + break; + } + + s++; + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + st = s; + while ((s < file.eof) && (*s != '\n')) + s++; + for (en = s - 1; en >= st && isspace( *en ); en--); + + nstr = sl; + nlen = ek - sl + 1; + for (curent = cursec->ents; curent; curent = curent->next) + if (!memcmp( nstr, curent->key, nlen ) && + !curent->key[nlen]) { + fprintf( stderr, "Multiple occurrences of key '%s' in section " + "[%s] of %s.\n", curent->key, cursec->name, fname ); + goto keyfnd; + } + curent = mmalloc( sizeof(*curent) ); + ASPrintf( (char **)&curent->key, "%.*s", nlen, nstr ); + ASPrintf( (char **)&curent->value, "%.*s", en - st + 1, st ); + curent->next = cursec->ents; + cursec->ents = curent; + keyfnd: + continue; + } + return rootsec; +} + + +static int +mergeKdmRcOld( const char *path ) +{ + char *p; + struct stat st; + + ASPrintf( &p, "%s/kdmrc", path ); + if (stat( p, &st )) { + free( p ); + return 0; + } + printf( "Information: ignoring old kdmrc %s from kde < 2.2\n", p ); + free( p ); + return 1; +} + +typedef struct { + const char *sect, *key, *def; + int (*cond)( void ); +} FDefs; + +static void +applydefs( FDefs *chgdef, int ndefs, const char *path ) +{ + char *p; + int i; + + for (i = 0; i < ndefs; i++) + if (!getfqval( chgdef[i].sect, chgdef[i].key, 0 ) && + (!chgdef[i].cond || chgdef[i].cond())) + { + ASPrintf( &p, chgdef[i].def, path ); + putfqval( chgdef[i].sect, chgdef[i].key, p ); + free( p ); + } +} + +#ifdef XDMCP +static FDefs kdmdefs_all[] = { +{ "Xdmcp", "Xaccess", "%s/kdm/Xaccess", 0 }, +{ "Xdmcp", "Willing", "", 0 }, +}; +#endif + +static FDefs kdmdefs_eq_22[] = { +{ "General", "PidFile", "/var/run/xdm.pid", 0 }, +{ "X-*-Core", "Setup", "%s/kdm/Xsetup", 0 }, +{ "X-*-Core", "Startup", "%s/kdm/Xstartup", 0 }, +{ "X-*-Core", "Reset", "%s/kdm/Xreset", 0 }, +{ "X-*-Core", "Session", "%s/kdm/Xsession", 0 }, +}; + +#ifdef XDMCP +static int +if_xdmcp (void) +{ + return isTrue( getfqval( "Xdmcp", "Enable", "true" ) ); +} + +static FDefs kdmdefs_le_30[] = { +{ "Xdmcp", "KeyFile", "%s/kdm/kdmkeys", if_xdmcp }, +}; +#endif + +/* HACK: misused by is22conf() below */ +static FDefs kdmdefs_ge_30[] = { +{ "X-*-Core", "Setup", "", 0 }, +{ "X-*-Core", "Startup", "", 0 }, +{ "X-*-Core", "Reset", "", 0 }, +{ "X-*-Core", "Session", XBINDIR "/xterm -ls -T", 0 }, +}; + +static int +if_usebg (void) +{ + return isTrue( getfqval( "X-*-Greeter", "UseBackground", "true" ) ); +} + +static FDefs kdmdefs_ge_31[] = { +{ "X-*-Greeter","BackgroundCfg","%s/kdm/backgroundrc", if_usebg }, +}; + +static int +is22conf( const char *path ) +{ + char *p; + const char *val; + int i, sl; + + sl = ASPrintf( &p, "%s/kdm/", path ); + /* safe bet, i guess ... */ + for (i = 0; i < 4; i++) { + val = getfqval( "X-*-Core", kdmdefs_ge_30[i].key, 0 ); + if (val && !memcmp( val, p, sl )) { + free( p ); + return 0; + } + } + free( p ); + return 1; +} + +typedef struct KUpdEnt { + const char *okey, *nsec, *nkey; + void (*func)( const char *sect, char **value ); +} KUpdEnt; + +typedef struct KUpdSec { + const char *osec; + KUpdEnt *ents; + int nents; +} KUpdSec; + +#ifdef XDMCP +static void +P_EnableChooser( const char *sect ATTR_UNUSED, char **value ) +{ + *value = (char *)(isTrue( *value ) ? "DefaultLocal" : "LocalOnly"); +} +#endif + +static void +P_UseLilo( const char *sect ATTR_UNUSED, char **value ) +{ + *value = (char *)(isTrue( *value ) ? "Lilo" : "None"); +} + +CONF_GEN_KMERGE + +static int +mergeKdmRcNewer( const char *path ) +{ + char *p; + const char *cp, *sec, *key; + RSection *rootsect, *cs; + REntry *ce; + int i, j; + static char sname[64]; + + ASPrintf( &p, "%s/kdm/kdmrc", path ); + if (!(rootsect = ReadConf( p ))) { + free( p ); + return 0; + } + printf( "Information: reading current kdmrc %s (from kde >= 2.2.x)\n", p ); + free( p ); + + for (cs = rootsect; cs; cs = cs->next) { + if (!strcmp( cs->name, "Desktop0" )) { + background = mstrdup( "[Desktop0]\n" ); + for (ce = cs->ents; ce; ce = ce->next) + StrCat( &background, "%s=%s\n", ce->key, ce->value ); + } else { + cp = strrchr( cs->name, '-' ); + if (!cp) + cp = cs->name; + else if (cs->name[0] != 'X' || cs->name[1] != '-') + goto dropsec; + for (i = 0; i < as(kupsects); i++) + if (!strcmp( cp, kupsects[i].osec )) { + for (ce = cs->ents; ce; ce = ce->next) { + for (j = 0; j < kupsects[i].nents; j++) + if (!strcmp( ce->key, kupsects[i].ents[j].okey )) { + if (kupsects[i].ents[j].nsec == (char *)-1) { + kupsects[i].ents[j].func( 0, &ce->value ); + goto gotkey; + } + if (!kupsects[i].ents[j].nsec) + sec = cs->name; + else { + sec = sname; + sprintf( sname, "%.*s-%s", cp - cs->name, cs->name, + kupsects[i].ents[j].nsec ); + } + if (!kupsects[i].ents[j].nkey) + key = ce->key; + else + key = kupsects[i].ents[j].nkey; + if (kupsects[i].ents[j].func) + kupsects[i].ents[j].func( sec, &ce->value ); + putfqval( sec, key, ce->value ); + goto gotkey; + } + printf( "Information: dropping key %s from section [%s]\n", + ce->key, cs->name ); + gotkey: ; + } + goto gotsec; + } + dropsec: + printf( "Information: dropping section [%s]\n", cs->name ); + gotsec: ; + } + } + +#ifdef XDMCP + applydefs( kdmdefs_all, as(kdmdefs_all), path ); +#endif + if (!*(cp = getfqval( "General", "ConfigVersion", "" ))) { /* < 3.1 */ + mod_usebg = 1; + if (is22conf( path )) { + /* work around 2.2.x defaults borkedness */ + applydefs( kdmdefs_eq_22, as(kdmdefs_eq_22), path ); + printf( "Information: current kdmrc is from kde 2.2\n" ); + } else { + applydefs( kdmdefs_ge_30, as(kdmdefs_ge_30), path ); + printf( "Information: current kdmrc is from kde 3.0\n" ); + } +#ifdef XDMCP + /* work around minor <= 3.0.x defaults borkedness */ + applydefs( kdmdefs_le_30, as(kdmdefs_le_30), path ); +#endif + } else { + int ma, mi; + sscanf( cp, "%d.%d", &ma, &mi ); + oldver = (ma << 8) | mi; + printf( "Information: current kdmrc is from kde >= 3.1 (config version %d.%d)\n", ma, mi ); + applydefs( kdmdefs_ge_30, as(kdmdefs_ge_30), path ); + applydefs( kdmdefs_ge_31, as(kdmdefs_ge_31), path ); + } + + return 1; +} + + +typedef struct XResEnt { + const char *xname; + const char *ksec, *kname; + void (*func)( const char *sect, char **value ); +} XResEnt; + +static void +handleXdmVal( const char *dpy, const char *key, char *value, + const XResEnt *ents, int nents ) +{ + const char *kname; + int i; + char knameb[80], sname[80]; + + for (i = 0; i < nents; i++) + if (!strcmp( key, ents[i].xname ) || + (key[0] == toupper( ents[i].xname[0] ) && + !strcmp( key + 1, ents[i].xname + 1 ))) + { + if (ents[i].ksec == (char *)-1) { + ents[i].func (0, &value); + break; + } + sprintf( sname, ents[i].ksec, dpy ); + if (ents[i].kname) + kname = ents[i].kname; + else { + kname = knameb; + sprintf( knameb, "%c%s", + toupper( ents[i].xname[0] ), ents[i].xname + 1 ); + } + if (ents[i].func) + ents[i].func( sname, &value ); + putfqval( sname, kname, value ); + break; + } +} + +static void +P_List( const char *sect ATTR_UNUSED, char **value ) +{ + int is, d, s; + char *st; + + for (st = *value, is = d = s = 0; st[s]; s++) + if (st[s] == ' ' || st[s] == '\t') { + if (!is) + st[d++] = ','; + is = 1; + } else { + st[d++] = st[s]; + is = 0; + } + st[d] = 0; +} + +static void +P_authDir( const char *sect ATTR_UNUSED, char **value ) +{ + int l; + + l = strlen( *value ); + if (l < 4) { + *value = 0; + return; + } + if ((*value)[l-1] == '/') + (*value)[--l] = 0; + if (!strncmp( *value, "/tmp/", 5 ) || + !strncmp( *value, "/var/tmp/", 9 )) + { + printf( "Warning: Resetting inappropriate value %s for AuthDir to default\n", + *value ); + *value = 0; + return; + } + if ((l >= 4 && !strcmp( *value + l - 4, "/tmp" )) || + (l >= 6 && !strcmp( *value + l - 6, "/xauth" )) || + (l >= 8 && !strcmp( *value + l - 8, "/authdir" )) || + (l >= 10 && !strcmp( *value + l - 10, "/authfiles" ))) + return; + ASPrintf( value, "%s/authdir", *value ); +} + +static void +P_openDelay( const char *sect, char **value ) +{ + putfqval( sect, "ServerTimeout", *value ); +} + +static void +P_noPassUsers( const char *sect, char **value ATTR_UNUSED ) +{ + putfqval( sect, "NoPassEnable", "true" ); +} + +static void +P_autoUser( const char *sect, char **value ATTR_UNUSED ) +{ + putfqval( sect, "AutoLoginEnable", "true" ); +} + +#ifdef XDMCP +static void +P_requestPort( const char *sect, char **value ) +{ + if (!strcmp( *value, "0" )) { + *value = 0; + putfqval( sect, "Enable", "false" ); + } else + putfqval( sect, "Enable", "true" ); +} +#endif + +static int kdmrcmode = 0644; + +static void +P_autoPass( const char *sect ATTR_UNUSED, char **value ATTR_UNUSED ) +{ + kdmrcmode = 0600; +} + +CONF_GEN_XMERGE + +static XrmQuark XrmQString, empty = NULLQUARK; + +static Bool +DumpEntry( XrmDatabase *db ATTR_UNUSED, + XrmBindingList bindings, + XrmQuarkList quarks, + XrmRepresentation *type, + XrmValuePtr value, + XPointer data ATTR_UNUSED ) +{ + const char *dpy, *key; + int el, hasu; + char dpybuf[80]; + + if (*type != XrmQString) + return False; + if (*bindings == XrmBindLoosely || + strcmp( XrmQuarkToString (*quarks), "DisplayManager" )) + return False; + bindings++, quarks++; + if (!*quarks) + return False; + if (*bindings != XrmBindLoosely && !quarks[1]) { /* DM.foo */ + key = XrmQuarkToString (*quarks); + handleXdmVal( 0, key, value->addr, globents, as(globents) ); + return False; + } else if (*bindings == XrmBindLoosely && !quarks[1]) { /* DM*bar */ + dpy = "*"; + key = XrmQuarkToString (*quarks); + } else if (*bindings != XrmBindLoosely && quarks[1] && + *bindings != XrmBindLoosely && !quarks[2]) + { /* DM.foo.bar */ + dpy = dpybuf + 4; + strcpy( dpybuf + 4, XrmQuarkToString (*quarks) ); + for (hasu = 0, el = 4; dpybuf[el]; el++) + if (dpybuf[el] == '_') + hasu = 1; + if (!hasu/* && isupper (dpy[0])*/) { + dpy = dpybuf; + memcpy( dpybuf, "*:*_", 4 ); + } else { + for (; --el >= 0; ) + if (dpybuf[el] == '_') { + dpybuf[el] = ':'; + for (; --el >= 4; ) + if (dpybuf[el] == '_') + dpybuf[el] = '.'; + break; + } + } + key = XrmQuarkToString (quarks[1]); + } else + return False; + handleXdmVal( dpy, key, value->addr, dpyents, as(dpyents) ); + return False; +} + +static FDefs xdmdefs[] = { +#ifdef XDMCP +{ "Xdmcp", "Xaccess", "%s/Xaccess", 0 }, +{ "Xdmcp", "Willing", "", 0 }, +#endif +{ "X-*-Core", "Setup", "", 0 }, +{ "X-*-Core", "Startup", "", 0 }, +{ "X-*-Core", "Reset", "", 0 }, +{ "X-*-Core", "Session", "", 0 }, +}; + +static int +mergeXdmCfg( const char *path ) +{ + char *p; + XrmDatabase db; + + ASPrintf( &p, "%s/xdm-config", path ); + if ((db = XrmGetFileDatabase( p ))) { + printf( "Information: reading current xdm config file %s\n", p ); + usedFile( p ); + free( p ); + XrmEnumerateDatabase( db, &empty, &empty, XrmEnumAllLevels, + DumpEntry, (XPointer)0 ); + applydefs( xdmdefs, as(xdmdefs), path ); + mod_usebg = 1; + return 1; + } + free( p ); + return 0; +} + +static void +fwrapprintf( FILE *f, const char *msg, ... ) +{ + char *txt, *ftxt, *line; + va_list ap; + int col, lword, fspace; + + va_start( ap, msg ); + VASPrintf( &txt, msg, ap ); + va_end( ap ); + ftxt = 0; + for (line = txt, col = 0, lword = fspace = -1; line[col]; ) { + if (line[col] == '\n') { + StrCat( &ftxt, "%.*s", ++col, line ); + line += col; + col = 0; + lword = fspace = -1; + continue; + } else if (line[col] == ' ') { + if (lword >= 0) { + fspace = col; + lword = -1; + } + } else { + if (lword < 0) + lword = col; + if (col >= 78 && fspace >= 0) { + StrCat( &ftxt, "%.*s\n", fspace, line ); + line += lword; + col -= lword; + lword = 0; + fspace = -1; + } + } + col++; + } + free( txt ); + fputs( ftxt, f ); + free( ftxt ); +} + + +static const char *oldkdes[] = { + KDE_CONFDIR, + "/opt/kde3/share/config", + "/usr/local/kde3/share/config", + + "/opt/kde/share/config", + "/usr/local/kde/share/config", + "/usr/local/share/config", + "/usr/share/config", + + "/opt/kde2/share/config", + "/usr/local/kde2/share/config", +}; + +static const char *oldxdms[] = { + "/etc/X11/xdm", + XLIBDIR "/xdm", +}; + +int main( int argc, char **argv ) +{ + const char **where; + char *newkdmrc; + FILE *f; + StrList *fp; + Section *cs; + Entry *ce, **cep; + int i, ap, newer, locals, foreigns; + int no_old_xdm = 0, no_old_kde = 0; + struct stat st; + char *nname; + + for (ap = 1; ap < argc; ap++) { + if (!strcmp( argv[ap], "--help" )) { + printf( +"genkdmconf - generate configuration files for kdm\n" +"\n" +"If an older xdm/kdm configuration is found, its config files are \"absorbed\";\n" +"if it lives in the new target directory, its scripts are reused (and possibly\n" +"modified) as well, otherwise the scripts are ignored and default scripts are\n" +"installed.\n" +"\n" +"options:\n" +" --in /path/to/new/kdm-config-dir\n" +" In which directory to put the new configuration. You can use this\n" +" to support a $(DESTDIR), but not to change the final location of\n" +" the installation - the paths inside the files are not affected.\n" +" Default is " KDMCONF ".\n" +" --old-xdm /path/to/old/xdm-dir\n" +" Where to look for the config files of an xdm/older kdm.\n" +" Default is to scan /etc/X11/kdm, $XLIBDIR/kdm, /etc/X11/xdm,\n" +" $XLIBDIR/xdm; there in turn look for kdm-config and xdm-config.\n" +" Note that you possibly need to use --no-old-kde to make this take effect.\n" +" --old-kde /path/to/old/kde-config-dir\n" +" Where to look for the kdmrc of an older kdm.\n" +" Default is to scan " KDE_CONFDIR " and\n" +" {/usr,/usr/local,{/opt,/usr/local}/{kde3,kde,kde2,kde1}}/share/config.\n" +" --no-old\n" +" Don't look at older xdm/kdm configurations, just create default config.\n" +" --no-old-xdm\n" +" Don't look at older xdm configurations.\n" +" --no-old-kde\n" +" Don't look at older kdm configurations.\n" +" --old-scripts\n" +" Directly use all scripts from the older xdm/kdm configuration.\n" +" --no-old-scripts\n" +" Don't use scripts from the older xdm/kdm configuration even if it lives\n" +" in the new target directory.\n" +" --old-confs\n" +" Directly use all ancillary config files from the older xdm/kdm\n" +" configuration. This is usually a bad idea.\n" +" --no-backup\n" +" Overwrite/delete old config files instead of backing them up.\n" +" --no-in-notice\n" +" Don't put the notice about --in being used into the generated README.\n" +); + exit( 0 ); + } + if (!strcmp( argv[ap], "--no-old" )) { + no_old = 1; + continue; + } + if (!strcmp( argv[ap], "--old-scripts" )) { + old_scripts = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-scripts" )) { + no_old_scripts = 1; + continue; + } + if (!strcmp( argv[ap], "--old-confs" )) { + old_confs = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-xdm" )) { + no_old_xdm = 1; + continue; + } + if (!strcmp( argv[ap], "--no-old-kde" )) { + no_old_kde = 1; + continue; + } + if (!strcmp( argv[ap], "--no-backup" )) { + no_backup = 1; + continue; + } + if (!strcmp( argv[ap], "--no-in-notice" )) { + no_in_notice = 1; + continue; + } + where = 0; + if (!strcmp( argv[ap], "--in" )) + where = &newdir; + else if (!strcmp( argv[ap], "--old-xdm" )) + where = &oldxdm; + else if (!strcmp( argv[ap], "--old-kde" )) + where = &oldkde; + else if (!strcmp( argv[ap], "--face-src" )) + where = &facesrc; + else { + fprintf( stderr, "Unknown command line option '%s', try --help\n", argv[ap] ); + exit( 1 ); + } + if (ap + 1 == argc || argv[ap + 1][0] == '-') { + fprintf( stderr, "Missing argument to option '%s', try --help\n", argv[ap] ); + exit( 1 ); + } + *where = argv[++ap]; + } + if (memcmp( newdir, KDMCONF, sizeof(KDMCONF) )) + use_destdir = 1; + + if (!mkdirp( newdir, 0755, "target", 1 )) + exit( 1 ); + + mkdefconf(); + newer = 0; + if (no_old) { + DIR *dir; + if ((dir = opendir( newdir ))) { + struct dirent *ent; + char bn[PATH_MAX]; + while ((ent = readdir( dir ))) { + int l; + if (!strcmp( ent->d_name, "." ) || !strcmp( ent->d_name, ".." )) + continue; + l = sprintf( bn, "%s/%s", newdir, ent->d_name ); /* cannot overflow (kernel would not allow the creation of a longer path) */ + if (!stat( bn, &st ) && !S_ISREG( st.st_mode )) + continue; + if (no_backup || !memcmp( bn + l - 4, ".bak", 5 )) + unlink( bn ); + else + displace( bn ); + } + closedir( dir ); + } + } else { + if (oldkde) { + if (!(newer = mergeKdmRcNewer( oldkde )) && !mergeKdmRcOld( oldkde )) + fprintf( stderr, + "Cannot read old kdmrc at specified location\n" ); + } else if (!no_old_kde) { + for (i = 0; i < as(oldkdes); i++) { + if ((newer = mergeKdmRcNewer( oldkdes[i] )) || + mergeKdmRcOld( oldkdes[i] )) { + oldkde = oldkdes[i]; + break; + } + } + } + if (!newer && !no_old_xdm) { + XrmInitialize(); + XrmQString = XrmPermStringToQuark( "String" ); + if (oldxdm) { + if (!mergeXdmCfg( oldxdm )) + fprintf( stderr, + "Cannot read old kdm-config/xdm-config at specified location\n" ); + } else + for (i = 0; i < as(oldxdms); i++) + if (mergeXdmCfg( oldxdms[i] )) { + oldxdm = oldxdms[i]; + break; + } + } else + oldxdm = 0; + } + if (no_old_scripts) + goto no_old_s; + if (!old_scripts) { + locals = foreigns = 0; + for (cs = config; cs; cs = cs->next) + if (!strcmp( cs->spec->name, "-Core" )) { + for (ce = cs->ents; ce; ce = ce->next) + if (ce->active && + (!strcmp( ce->spec->key, "Setup" ) || + !strcmp( ce->spec->key, "Startup" ) || + !strcmp( ce->spec->key, "Reset" ))) + { + if (inNewDir( ce->value )) + locals = 1; + else + foreigns = 1; + } + } + if (foreigns) { + if (locals) { + fprintf( stderr, + "Warning: both local and foreign scripts referenced. " + "Won't touch any.\n" ); + mixed_scripts = 1; + } else { + no_old_s: + for (cs = config; cs; cs = cs->next) { + if (!strcmp( cs->spec->name, "Xdmcp" )) { + for (ce = cs->ents; ce; ce = ce->next) + if (!strcmp( ce->spec->key, "Willing" )) + ce->active = ce->written = 0; + } else if (!strcmp( cs->spec->name, "-Core" )) { + for (cep = &cs->ents; (ce = *cep); ) { + if (ce->active && + (!strcmp( ce->spec->key, "Setup" ) || + !strcmp( ce->spec->key, "Startup" ) || + !strcmp( ce->spec->key, "Reset" ) || + !strcmp( ce->spec->key, "Session" ))) + { + if (!memcmp( cs->name, "X-*-", 4 )) + ce->active = ce->written = 0; + else { + *cep = ce->next; + free( ce ); + continue; + } + } + cep = &ce->next; + } + } + } + } + } + } +#ifdef __linux__ + if (!stat( "/etc/debian_version", &st )) { /* debian */ + defminuid = "1000"; + defmaxuid = "29999"; + } else if (!stat( "/usr/portage", &st )) { /* gentoo */ + defminuid = "1000"; + defmaxuid = "65000"; + } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */ + defminuid = "500"; + defmaxuid = "65000"; + } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */ + defminuid = "100"; + defmaxuid = "65000"; + } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */ + defminuid = "500"; + defmaxuid = "65000"; + } +#else + defminuid = "1000"; + defmaxuid = "65000"; +#endif + for (i = 0; i < CONF_MAX_PRIO; i++) + for (cs = config; cs; cs = cs->next) + for (ce = cs->ents; ce; ce = ce->next) + if (ce->spec->func && i == ce->spec->prio) + ce->spec->func( ce, cs ); + ASPrintf( &newkdmrc, "%s/kdmrc", newdir ); + f = Create( newkdmrc, kdmrcmode ); + wrconf( f ); + fclose( f ); + + ASPrintf( &nname, "%s/README", newdir ); + f = Create( nname, 0644 ); + fprintf( f, +"This automatically generated configuration consists of the following files:\n" ); + fprintf( f, "- " KDMCONF "/kdmrc\n" ); + for (fp = aflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + if (use_destdir && !no_in_notice) + fwrapprintf( f, +"All files destined for " KDMCONF " were actually saved in %s; " +"this config won't be workable until moved in place.\n", newdir ); + if (uflist || eflist || cflist || lflist) { + fprintf( f, +"\n" +"This config was derived from existing files. As the used algorithms are\n" +"pretty dumb, it may be broken.\n" ); + if (uflist) { + fprintf( f, +"Information from these files was extracted:\n" ); + for (fp = uflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (lflist) { + fprintf( f, +"These files were directly incorporated:\n" ); + for (fp = lflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (cflist) { + fprintf( f, +"These files were copied verbatim:\n" ); + for (fp = cflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (eflist) { + fprintf( f, +"These files were copied with modifications:\n" ); + for (fp = eflist; fp; fp = fp->next) + fprintf( f, "- %s\n", fp->str ); + } + if (!no_backup && !use_destdir) + fprintf( f, +"Old files that would have been overwritten were renamed to <oldname>.bak.\n" ); + } + fprintf( f, +"\nTry 'genkdmconf --help' if you want to generate another configuration.\n" +"\nYou may delete this README.\n" ); + fclose( f ); + + return 0; +} diff --git a/kdm/kfrontend/kchooser.cpp b/kdm/kfrontend/kchooser.cpp new file mode 100644 index 000000000..6d0b20350 --- /dev/null +++ b/kdm/kfrontend/kchooser.cpp @@ -0,0 +1,227 @@ +/* + +chooser widget for KDM + +Copyright (C) 2002-2003 Oswald Buddenhagen <ossi@kde.org> +based on the chooser (C) 1999 by Harald Hoyer <Harald.Hoyer@RedHat.de> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#ifdef XDMCP + +#include "kchooser.h" +#include "kconsole.h" +#include "kdmconfig.h" +#include "kdm_greet.h" + +#include <klocale.h> + +#include <qlayout.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qpopupmenu.h> +#include <qsocketnotifier.h> +#include <qlistview.h> +#include <qlineedit.h> + +#include <stdlib.h> // for free() + +class ChooserListViewItem : public QListViewItem { + public: + ChooserListViewItem( QListView* parent, int _id, const QString& nam, const QString& sts ) + : QListViewItem( parent, nam, sts ) { id = _id; }; + + int id; +}; + + +ChooserDlg::ChooserDlg() + : inherited() +{ + completeMenu( LOGIN_REMOTE_ONLY, ex_greet, i18n("&Local Login"), ALT+Key_L ); + + QBoxLayout *vbox = new QVBoxLayout( this, 10, 10 ); + + QLabel *title = new QLabel( i18n("XDMCP Host Menu"), this ); + title->setAlignment( AlignCenter ); + vbox->addWidget( title ); + + host_view = new QListView( this, "hosts" ); + host_view->addColumn( i18n("Hostname") ); + host_view->setColumnWidth( 0, fontMetrics().width( "login.crap.net" ) ); + host_view->addColumn( i18n("Status") ); + host_view->setMinimumWidth( fontMetrics().width( "login.crap.com Display not authorized to connect this server" ) ); + host_view->setResizeMode( QListView::LastColumn ); + host_view->setAllColumnsShowFocus( true ); + vbox->addWidget( host_view ); + + iline = new QLineEdit( this ); + iline->setEnabled( TRUE ); + QLabel *itxt = new QLabel( iline, i18n("Hos&t:"), this ); + QPushButton *addButton = new QPushButton( i18n("A&dd"), this ); + connect( addButton, SIGNAL(clicked()), SLOT(addHostname()) ); + QBoxLayout *hibox = new QHBoxLayout( vbox, 10 ); + hibox->addWidget( itxt ); + hibox->addWidget( iline ); + hibox->addWidget( addButton ); + + // Buttons + QPushButton *acceptButton = new QPushButton( i18n("&Accept"), this ); + acceptButton->setDefault( true ); + QPushButton *pingButton = new QPushButton( i18n("&Refresh"), this ); + + QBoxLayout *hbox = new QHBoxLayout( vbox, 20 ); + hbox->addWidget( acceptButton ); + hbox->addWidget( pingButton ); + hbox->addStretch( 1 ); + + if (optMenu) { + QPushButton *menuButton = new QPushButton( i18n("&Menu"), this ); + menuButton->setPopup( optMenu ); + hbox->addWidget( menuButton ); + hbox->addStretch( 1 ); + } + +// QPushButton *helpButton = new QPushButton( i18n("&Help"), this ); +// hbox->addWidget( helpButton ); + +#ifdef WITH_KDM_XCONSOLE + if (consoleView) + vbox->addWidget( consoleView ); +#endif + + sn = new QSocketNotifier( rfd, QSocketNotifier::Read, this ); + connect( sn, SIGNAL(activated( int )), SLOT(slotReadPipe()) ); + + connect( pingButton, SIGNAL(clicked()), SLOT(pingHosts()) ); + connect( acceptButton, SIGNAL(clicked()), SLOT(accept()) ); +// connect( helpButton, SIGNAL(clicked()), SLOT(slotHelp()) ); + connect( host_view, SIGNAL(doubleClicked(QListViewItem *)), SLOT(accept()) ); + + adjustGeometry(); +} + +/* +void ChooserDlg::slotHelp() +{ + KMessageBox::information(0, + i18n("Choose a host, you want to work on,\n" + "in the list or add one.\n\n" + "After this box, you must press cancel\n" + "in the Host Menu to enter a host. :(")); + iline->setFocus(); +} +*/ + +void ChooserDlg::addHostname() +{ + if (!iline->text().isEmpty()) { + GSendInt( G_Ch_RegisterHost ); + GSendStr( iline->text().latin1() ); + iline->clear(); + } +} + +void ChooserDlg::pingHosts() +{ + GSendInt( G_Ch_Refresh ); +} + +void ChooserDlg::accept() +{ + if (focusWidget() == iline) { + if (!iline->text().isEmpty()) { + GSendInt( G_Ch_DirectChoice ); + GSendStr( iline->text().latin1() ); + iline->clear(); + } + return; + } else /*if (focusWidget() == host_view)*/ { + QListViewItem *item = host_view->currentItem(); + if (item) { + GSendInt( G_Ready ); + GSendInt( ((ChooserListViewItem *)item)->id ); + ::exit( EX_NORMAL ); + } + } +} + +void ChooserDlg::reject() +{ +} + +QString ChooserDlg::recvStr() +{ + char *arr = GRecvStr(); + if (arr) { + QString str = QString::fromLatin1( arr ); + free( arr ); + return str; + } else + return i18n("<unknown>"); +} + +QListViewItem *ChooserDlg::findItem( int id ) +{ + QListViewItem *itm; + for (QListViewItemIterator it( host_view ); (itm = it.current()); ++it) + if (((ChooserListViewItem *)itm)->id == id) + return itm; + return 0; +} + +void ChooserDlg::slotReadPipe() +{ + int id; + QString nam, sts; + + int cmd = GRecvInt(); + switch (cmd) { + case G_Ch_AddHost: + case G_Ch_ChangeHost: + id = GRecvInt(); + nam = recvStr(); + sts = recvStr(); + GRecvInt(); /* swallow willing for now */ + if (cmd == G_Ch_AddHost) + host_view->insertItem( + new ChooserListViewItem( host_view, id, nam, sts ) ); + else { + QListViewItem *itm = findItem( id ); + itm->setText( 0, nam ); + itm->setText( 1, sts ); + } + break; + case G_Ch_RemoveHost: + delete findItem( GRecvInt() ); + break; + case G_Ch_BadHost: + KFMsgBox::box( this, QMessageBox::Warning, i18n("Unknown host %1").arg( recvStr() ) ); + break; + case G_Ch_Exit: + done( ex_exit ); + break; + default: /* XXX huuh ...? */ + break; + } +} + +#include "kchooser.moc" + +#endif diff --git a/kdm/kfrontend/kchooser.h b/kdm/kfrontend/kchooser.h new file mode 100644 index 000000000..93ede2694 --- /dev/null +++ b/kdm/kfrontend/kchooser.h @@ -0,0 +1,59 @@ +/* + +chooser widget for KDM + +Copyright (C) 2002-2003 Oswald Buddenhagen <ossi@kde.org> +based on the chooser (C) 1999 by Harald Hoyer <Harald.Hoyer@RedHat.de> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef KCHOOSER_H +#define KCHOOSER_H + +#include "kgdialog.h" + +class QSocketNotifier; +class QPopupMenu; +class QLineEdit; +class QListView; +class QListViewItem; + +class ChooserDlg : public KGDialog { + Q_OBJECT + typedef KGDialog inherited; + + public: + ChooserDlg(); + + public slots: + void slotReadPipe(); + void addHostname(); +// void slotHelp(); + void pingHosts(); + void accept(); + void reject(); + + private: + QString recvStr(); + QListViewItem *findItem( int id ); + + QListView *host_view; + QLineEdit *iline; + QSocketNotifier *sn; +}; + +#endif /* KCHOOSER_H */ diff --git a/kdm/kfrontend/kconsole.cpp b/kdm/kfrontend/kconsole.cpp new file mode 100644 index 000000000..b101712da --- /dev/null +++ b/kdm/kfrontend/kconsole.cpp @@ -0,0 +1,183 @@ +/* + +xconsole widget for KDM + +Copyright (C) 2002-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#ifdef WITH_KDM_XCONSOLE + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/ioctl.h> + +#ifdef HAVE_TERMIOS_H +/* for HP-UX (some versions) the extern C is needed, and for other + platforms it doesn't hurt */ +extern "C" { +#include <termios.h> +} +#endif +#if !defined(__osf__) +#ifdef HAVE_TERMIO_H +/* needed at least on AIX */ +#include <termio.h> +#endif +#endif + +#if defined (_HPUX_SOURCE) +#define _TERMIOS_INCLUDED +#include <bsdtty.h> +#endif + + +#include "kconsole.h" +#include "kdmconfig.h" +#include "kdm_greet.h" + +#include <klocale.h> +#include <kpty.h> + +#include <qsocketnotifier.h> + +KConsole::KConsole( QWidget *_parent ) + : inherited( _parent ) + , pty( 0 ) + , notifier( 0 ) + , fd( -1 ) +{ + setReadOnly( true ); + setWordWrap( NoWrap ); + setTextFormat( PlainText ); + + if (!OpenConsole()) + append( i18n("Cannot open console") ); +} + +KConsole::~KConsole() +{ + CloseConsole(); +} + +int +KConsole::OpenConsole() +{ +#ifdef TIOCCONS + static const char on = 1; +#endif + + if (*_logSource) { + if ((fd = open( _logSource, O_RDONLY | O_NONBLOCK )) >= 0) + goto gotcon; + LogError( "Cannot open log source %s, " + "falling back to /dev/console.\n", _logSource ); + } + + pty = new KPty; + if (!pty->open()) { + delete pty; + pty = 0; + return 0; + } + +#ifdef TIOCCONS + if (ioctl( pty->slaveFd(), TIOCCONS, &on ) < 0) { + perror( "ioctl TIOCCONS" ); + delete pty; + pty = 0; + return 0; + } +#else + int consfd; + if ((consfd = open( "/dev/console", O_RDONLY )) < 0) { + perror( "opening /dev/console" ); + delete pty; + pty = 0; + return 0; + } + if (ioctl( consfd, SRIOCSREDIR, slave_fd ) < 0) { + perror( "ioctl SRIOCSREDIR" ); + ::close( consfd ); + delete pty; + pty = 0; + return 0; + } + ::close( consfd ); +#endif + fd = pty->masterFd(); + + gotcon: + notifier = new QSocketNotifier( fd, QSocketNotifier::Read, this ); + connect( notifier, SIGNAL(activated( int )), SLOT(slotData()) ); + return 1; +} + +void +KConsole::CloseConsole() +{ + delete notifier; + notifier = 0; + if (pty) { + delete pty; + pty = 0; + } else + ::close( fd ); + fd = -1; +} + +void +KConsole::slotData() +{ + int n; + char buffer[1024]; + + if ((n = read( fd, buffer, sizeof(buffer) )) <= 0) { + CloseConsole(); + if (!n) + if (!OpenConsole()) + append( i18n("\n*** Cannot open console log source ***") ); + } else { + bool as = !verticalScrollBar()->isVisible() || + (verticalScrollBar()->value() == + verticalScrollBar()->maxValue()); + QString str( QString::fromLocal8Bit( buffer, n ).remove( '\r' ) ); + int pos, opos; + for (opos = 0; (pos = str.find( '\n', opos )) >= 0; opos = pos + 1) { + if (paragraphs() == 100) + removeParagraph( 0 ); + if (!leftover.isEmpty()) { + append( leftover + str.mid( opos, pos - opos ) ); + leftover = QString::null; + } else + append( str.mid( opos, pos - opos ) ); + } + leftover += str.mid( opos ); + if (as) + scrollToBottom(); + } +} + +#include "kconsole.moc" + +#endif diff --git a/kdm/kfrontend/kconsole.h b/kdm/kfrontend/kconsole.h new file mode 100644 index 000000000..8a3515173 --- /dev/null +++ b/kdm/kfrontend/kconsole.h @@ -0,0 +1,53 @@ +/* + +xconsole widget for KDM + +Copyright (C) 2002-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef KCONSOLE_H +#define KCONSOLE_H + +#include <qtextedit.h> + +class QSocketNotifier; +class KPty; + +class KConsole : public QTextEdit { + Q_OBJECT + typedef QTextEdit inherited; + + public: + KConsole( QWidget *_parent = 0 ); + ~KConsole(); + + private slots: + void slotData(); + + private: + int OpenConsole(); + void CloseConsole(); + + KPty *pty; + QSocketNotifier *notifier; + QString leftover; + int fd; +}; + +#endif // KCONSOLE_H diff --git a/kdm/kfrontend/kdm_config.c b/kdm/kfrontend/kdm_config.c new file mode 100644 index 000000000..5d188e33d --- /dev/null +++ b/kdm/kfrontend/kdm_config.c @@ -0,0 +1,1470 @@ +/* + +Read options from kdmrc + +Copyright (C) 2001-2005 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <grp.h> +#ifdef _POSIX_PRIORITY_SCHEDULING +# include <sched.h> +#endif + +#include <X11/X.h> +#ifdef FamilyInternet6 +# define IPv6 +#endif + +#include <greet.h> +#include <config.ci> + +/* + * Section/Entry definition structs + */ + +typedef struct Ent { + const char *name; + int id; + void *ptr; + const char *def; +} Ent; + +typedef struct Sect { + const char *name; + Ent *ents; + int numents; +} Sect; + +/* + * Parsed ini file structs + */ + +typedef struct Entry { + struct Entry *next; + const char *val; + Ent *ent; + int vallen; + int line; +} Entry; + +typedef struct Section { + struct Section *next; + Entry *entries; + Sect *sect; + const char *name, *dname, *dhost, *dnum, *dclass; + int nlen, dlen, dhostl, dnuml, dclassl; +} Section; + + +/* + * Split up display-name/-class for fast comparison + */ +typedef struct DSpec { + const char *dhost, *dnum, *dclass; + int dhostl, dnuml, dclassl; +} DSpec; + + +/* + * Config value storage structures + */ + +typedef struct Value { + const char *ptr; + int len; +} Value; + +typedef struct Val { + Value val; + int id; +} Val; + +typedef struct ValArr { + Val *ents; + int nents, esiz, nchars, nptrs; +} ValArr; + + +static void *Malloc( size_t size ); +static void *Realloc( void *ptr, size_t size ); + +#define PRINT_QUOTES +#define LOG_NAME "kdm_config" +#define LOG_DEBUG_MASK DEBUG_CONFIG +#define LOG_PANIC_EXIT 1 +#define STATIC static +#include <printf.c> + + +static void * +Malloc( size_t size ) +{ + void *ret; + + if (!(ret = malloc( size ))) + LogOutOfMem(); + return ret; +} + +static void * +Realloc( void *ptr, size_t size ) +{ + void *ret; + + if (!(ret = realloc( ptr, size )) && size) + LogOutOfMem(); + return ret; +} + + +static void +MkDSpec( DSpec *spec, const char *dname, const char *dclass ) +{ + spec->dhost = dname; + for (spec->dhostl = 0; dname[spec->dhostl] != ':'; spec->dhostl++); + spec->dnum = dname + spec->dhostl + 1; + spec->dnuml = strlen( spec->dnum ); + spec->dclass = dclass; + spec->dclassl = strlen( dclass ); +} + + +static int rfd, wfd; + +static int +Reader( void *buf, int count ) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +static void +GRead( void *buf, int count ) +{ + if (Reader( buf, count ) != count) + LogPanic( "Can't read from core\n" ); +} + +static void +GWrite( const void *buf, int count ) +{ + if (write( wfd, buf, count ) != count) + LogPanic( "Can't write to core\n" ); +#ifdef _POSIX_PRIORITY_SCHEDULING + if ((debugLevel & DEBUG_HLPCON)) + sched_yield(); +#endif +} + +static void +GSendInt( int val ) +{ + GWrite( &val, sizeof(val) ); +} + +static void +GSendStr( const char *buf ) +{ + if (buf) { + int len = strlen( buf ) + 1; + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); + } else + GWrite( &buf, sizeof(int)); +} + +static void +GSendNStr( const char *buf, int len ) +{ + int tlen = len + 1; + GWrite( &tlen, sizeof(tlen) ); + GWrite( buf, len ); + GWrite( "", 1 ); +} + +#ifdef XDMCP +static void +GSendArr( int len, const char *data ) +{ + GWrite( &len, sizeof(len) ); + GWrite( data, len ); +} +#endif + +static int +GRecvCmd( int *val ) +{ + if (Reader( val, sizeof(*val) ) != sizeof(*val)) + return 0; + return 1; +} + +static int +GRecvInt() +{ + int val; + + GRead( &val, sizeof(val) ); + return val; +} + +static char * +GRecvStr() +{ + int len; + char *buf; + + len = GRecvInt(); + if (!len) + return 0; + if (!(buf = malloc( len ))) + LogPanic( "No memory for read buffer" ); + GRead( buf, len ); + return buf; +} + + +/* #define WANT_CLOSE 1 */ + +typedef struct File { + char *buf, *eof, *cur; +#if defined(HAVE_MMAP) && defined(WANT_CLOSE) + int ismapped; +#endif +} File; + +static int +readFile( File *file, const char *fn, const char *what ) +{ + int fd; + off_t flen; + + if ((fd = open( fn, O_RDONLY )) < 0) { + LogInfo( "Cannot open %s file %s\n", what, fn ); + return 0; + } + + flen = lseek( fd, 0, SEEK_END ); +#ifdef HAVE_MMAP +# ifdef WANT_CLOSE + file->ismapped = 0; +# endif + file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 ); +# ifdef WANT_CLOSE + if (file->buf) + file->ismapped = 1; + else +# else + if (!file->buf) +# endif +#endif + { + if (!(file->buf = Malloc( flen + 1 ))) { + close( fd ); + return 0; + } + lseek( fd, 0, SEEK_SET ); + if (read( fd, file->buf, flen ) != flen) { + free( file->buf ); + LogError( "Cannot read %s file %s\n", what, fn ); + close( fd ); + return 0; + } + } + file->eof = (file->cur = file->buf) + flen; + close( fd ); + return 1; +} + +#ifdef WANT_CLOSE +static void +freeBuf( File *file ) +{ +# ifdef HAVE_MMAP + if (file->ismapped) + munmap( file->buf, file->eof - file->buf + 1 ); + else +# endif + free( file->buf ); +} +#endif + +CONF_READ_VARS + +#define C_MTYPE_MASK 0x30000000 +# define C_PATH 0x10000000 /* C_TYPE_STR is a path spec */ +# define C_BOOL 0x10000000 /* C_TYPE_INT is a boolean */ +# define C_ENUM 0x20000000 /* C_TYPE_INT is an enum (option) */ +# define C_GRP 0x30000000 /* C_TYPE_INT is a group spec */ +#define C_INTERNAL 0x40000000 /* don't expose to core */ +#define C_CONFIG 0x80000000 /* process only for finding deps */ + +#ifdef XDMCP +static int +PrequestPort( Value *retval ) +{ + if (!VxdmcpEnable.ptr) { + retval->ptr = (char *)0; + return 1; + } + return 0; +} +#endif + +static Value + emptyStr = { "", 1 }, + nullValue = { 0, 0 }, + emptyArgv = { (char *)&nullValue, 0 }; + +static int +PnoPassUsers( Value *retval ) +{ + if (!VnoPassEnable.ptr) { + *retval = emptyArgv; + return 1; + } + return 0; +} + +static int +PautoLoginX( Value *retval ) +{ + if (!VautoLoginEnable.ptr) { + *retval = emptyStr; + return 1; + } + return 0; +} + +CONF_READ_ENTRIES + +static const char *kdmrc = KDMCONF "/kdmrc"; + +static Section *rootsec; + +static void +ReadConf() +{ + const char *nstr, *dstr, *cstr, *dhost, *dnum, *dclass; + char *s, *e, *st, *en, *ek, *sl, *pt; + Section *cursec; + Entry *curent; + Ent *ce; + int nlen, dlen, clen, dhostl, dnuml, dclassl; + int i, line, sectmoan, restl; + File file; + static int confread; + + if (confread) + return; + confread = 1; + + Debug( "reading config %s ...\n", kdmrc ); + if (!readFile( &file, kdmrc, "master configuration" )) + return; + + for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) { + line++; + + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + + if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) { + sktoeol: + while ((s < file.eof) && (*s != '\n')) + s++; + continue; + } + sl = s; + + if (*s == '[') { + sectmoan = 0; + while ((s < file.eof) && (*s != '\n')) + s++; + e = s - 1; + while ((e > sl) && isspace( *e )) + e--; + if (*e != ']') { + cursec = 0; + LogError( "Invalid section header at %s:%d\n", kdmrc, line ); + continue; + } + nstr = sl + 1; + nlen = e - nstr; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (nlen == cursec->nlen && + !memcmp( nstr, cursec->name, nlen )) + { + LogInfo( "Multiple occurrences of section [%.*s] in %s. " + "Consider merging them.\n", nlen, nstr, kdmrc ); + goto secfnd; + } + if (nstr[0] == 'X' && nstr[1] == '-') { + cstr = nstr + nlen; + clen = 0; + while (++clen, *--cstr != '-'); + if (cstr == nstr + 1) + goto illsec; + dstr = nstr + 2; + dlen = nlen - clen - 2; + dhost = dstr; + dhostl = 0; + for (restl = dlen; restl; restl--) { + if (dhost[dhostl] == ':') { + dnum = dhost + dhostl + 1; + dnuml = 0; + for (restl--; restl; restl--) { + if (dnum[dnuml] == '_') { + dclass = dnum + dnuml + 1; + dclassl = restl; + goto gotall; + } + dnuml++; + } + goto gotnum; + } + dhostl++; + } + dnum = "*"; + dnuml = 1; + gotnum: + dclass = "*"; + dclassl = 1; + gotall: ; + } else { + if (nstr[0] == '-') + goto illsec; + dstr = 0; + dlen = 0; + dhost = 0; + dhostl = 0; + dnum = 0; + dnuml = 0; + dclass = 0; + dclassl = 0; + cstr = nstr; + clen = nlen; + } + for (i = 0; i < as(allSects); i++) + if ((int)strlen( allSects[i]->name ) == clen && + !memcmp( allSects[i]->name, cstr, clen )) + goto newsec; + illsec: + cursec = 0; + LogError( "Unrecognized section name [%.*s] at %s:%d\n", + nlen, nstr, kdmrc, line ); + continue; + newsec: + if (!(cursec = Malloc( sizeof(*cursec) ))) + return; + cursec->name = nstr; + cursec->nlen = nlen; + cursec->dname = dstr; + cursec->dlen = dlen; + cursec->dhost = dhost; + cursec->dhostl = dhostl; + cursec->dnum = dnum; + cursec->dnuml = dnuml; + cursec->dclass = dclass; + cursec->dclassl = dclassl; + cursec->sect = allSects[i]; + cursec->entries = 0; + cursec->next = rootsec; + rootsec = cursec; + /*Debug( "now in section [%.*s], dpy '%.*s', core '%.*s'\n", + nlen, nstr, dlen, dstr, clen, cstr );*/ + secfnd: + continue; + } + + if (!cursec) { + if (sectmoan) { + sectmoan = 0; + LogError( "Entry outside any section at %s:%d", kdmrc, line ); + } + goto sktoeol; + } + + for (; (s < file.eof) && (*s != '\n'); s++) + if (*s == '=') + goto haveeq; + LogError( "Invalid entry (missing '=') at %s:%d\n", kdmrc, line ); + continue; + + haveeq: + for (ek = s - 1; ; ek--) { + if (ek < sl) { + LogError( "Invalid entry (empty key) at %s:%d\n", kdmrc, line ); + goto sktoeol; + } + if (!isspace( *ek )) + break; + } + + s++; + while ((s < file.eof) && isspace( *s ) && (*s != '\n')) + s++; + for (pt = st = en = s; s < file.eof && *s != '\n'; s++) { + if (*s == '\\') { + s++; + if (s >= file.eof || *s == '\n') { + LogError( "Trailing backslash at %s:%d\n", kdmrc, line ); + break; + } + switch (*s) { + case 's': *pt++ = ' '; break; + case 't': *pt++ = '\t'; break; + case 'n': *pt++ = '\n'; break; + case 'r': *pt++ = '\r'; break; + case '\\': *pt++ = '\\'; break; + default: *pt++ = '\\'; *pt++ = *s; break; + } + en = pt; + } else { + *pt++ = *s; + if (*s != ' ' && *s != '\t') + en = pt; + } + } + + nstr = sl; + nlen = ek - sl + 1; + /*Debug( "read entry '%.*s'='%.*s'\n", nlen, nstr, en - st, st );*/ + for (i = 0; i < cursec->sect->numents; i++) { + ce = cursec->sect->ents + i; + if ((int)strlen( ce->name ) == nlen && + !memcmp( ce->name, nstr, nlen )) + goto keyok; + } + LogError( "Unrecognized key '%.*s' in section [%.*s] at %s:%d\n", + nlen, nstr, cursec->nlen, cursec->name, kdmrc, line ); + continue; + keyok: + for (curent = cursec->entries; curent; curent = curent->next) + if (ce == curent->ent) { + LogError( "Multiple occurrences of key '%s' in section [%.*s]" + " of %s\n", + ce->name, cursec->nlen, cursec->name, kdmrc ); + goto keyfnd; + } + if (!(curent = Malloc( sizeof(*curent) ))) + return; + curent->ent = ce; + curent->line = line; + curent->val = st; + curent->vallen = en - st; + curent->next = cursec->entries; + cursec->entries = curent; + keyfnd: + continue; + } +} + +static Entry * +FindGEnt( int id ) +{ + Section *cursec; + Entry *curent; + + for (cursec = rootsec; cursec; cursec = cursec->next) + if (!cursec->dname) + for (curent = cursec->entries; curent; curent = curent->next) + if (curent->ent->id == id) { + Debug( "line %d: %s = %'.*s\n", + curent->line, curent->ent->name, + curent->vallen, curent->val ); + return curent; + } + return 0; +} + +/* Display name match scoring: + * - class (any/exact) -> 0/1 + * - number (any/exact) -> 0/2 + * - host (any/nonempty/trail/exact) -> 0/4/8/12 + */ +static Entry * +FindDEnt( int id, DSpec *dspec ) +{ + Section *cursec, *bestsec; + Entry *curent, *bestent; + int score, bestscore; + + bestscore = -1, bestent = 0; + for (cursec = rootsec; cursec; cursec = cursec->next) + if (cursec->dname) { + score = 0; + if (cursec->dclassl != 1 || cursec->dclass[0] != '*') { + if (cursec->dclassl == dspec->dclassl && + !memcmp( cursec->dclass, dspec->dclass, dspec->dclassl )) + score = 1; + else + continue; + } + if (cursec->dnuml != 1 || cursec->dnum[0] != '*') { + if (cursec->dnuml == dspec->dnuml && + !memcmp( cursec->dnum, dspec->dnum, dspec->dnuml )) + score += 2; + else + continue; + } + if (cursec->dhostl != 1 || cursec->dhost[0] != '*') { + if (cursec->dhostl == 1 && cursec->dhost[0] == '+') { + if (dspec->dhostl) + score += 4; + else + continue; + } else if (cursec->dhost[0] == '.') { + if (cursec->dhostl < dspec->dhostl && + !memcmp( cursec->dhost, + dspec->dhost + dspec->dhostl - cursec->dhostl, + cursec->dhostl )) + score += 8; + else + continue; + } else { + if (cursec->dhostl == dspec->dhostl && + !memcmp( cursec->dhost, dspec->dhost, dspec->dhostl )) + score += 12; + else + continue; + } + } + if (score > bestscore) { + for (curent = cursec->entries; curent; curent = curent->next) + if (curent->ent->id == id) { + bestent = curent; + bestsec = cursec; + bestscore = score; + break; + } + } + } + if (bestent) + Debug( "line %d: %.*s:%.*s_%.*s/%s = %'.*s\n", bestent->line, + bestsec->dhostl, bestsec->dhost, + bestsec->dnuml, bestsec->dnum, + bestsec->dclassl, bestsec->dclass, + bestent->ent->name, bestent->vallen, bestent->val ); + return bestent; +} + +static const char * +CvtValue( Ent *et, Value *retval, int vallen, const char *val, char **eopts ) +{ + Value *ents; + int i, b, e, tlen, nents, esiz; + char buf[80]; + + switch (et->id & C_TYPE_MASK) { + case C_TYPE_INT: + for (i = 0; i < vallen && i < (int)sizeof(buf) - 1; i++) + buf[i] = tolower( val[i] ); + buf[i] = 0; + if ((et->id & C_MTYPE_MASK) == C_BOOL) { + if (!strcmp( buf, "true" ) || + !strcmp( buf, "on" ) || + !strcmp( buf, "yes" ) || + !strcmp( buf, "1" )) + retval->ptr = (char *)1; + else if (!strcmp( buf, "false" ) || + !strcmp( buf, "off" ) || + !strcmp( buf, "no" ) || + !strcmp( buf, "0" )) + retval->ptr = (char *)0; + else + return "boolean"; + return 0; + } else if ((et->id & C_MTYPE_MASK) == C_ENUM) { + for (i = 0; eopts[i]; i++) + if (!memcmp( eopts[i], val, vallen ) && !eopts[i][vallen]) { + retval->ptr = (char *)i; + return 0; + } + return "option"; + } else if ((et->id & C_MTYPE_MASK) == C_GRP) { + struct group *ge; + if ((ge = getgrnam( buf ))) { + retval->ptr = (char *)ge->gr_gid; + return 0; + } + } + retval->ptr = 0; + if (sscanf( buf, "%li", &retval->ptr ) != 1) + return "integer"; + return 0; + case C_TYPE_STR: + retval->ptr = val; + retval->len = vallen + 1; + if ((et->id & C_MTYPE_MASK) == C_PATH) + if (vallen && val[vallen-1] == '/') + retval->len--; + return 0; + case C_TYPE_ARGV: + if (!(ents = Malloc( sizeof(Value) * (esiz = 10) ))) + return 0; + for (nents = 0, tlen = 0, i = 0; ; i++) { + for (; i < vallen && isspace( val[i] ); i++); + for (b = i; i < vallen && val[i] != ','; i++); + if (b == i) + break; + for (e = i; e > b && isspace( val[e - 1] ); e--); + if (esiz < nents + 2) { + Value *entsn = Realloc( ents, + sizeof(Value) * (esiz = esiz * 2 + 1) ); + if (!nents) + break; + ents = entsn; + } + ents[nents].ptr = val + b; + ents[nents].len = e - b; + nents++; + tlen += e - b + 1; + } + ents[nents].ptr = 0; + retval->ptr = (char *)ents; + retval->len = tlen; + return 0; + default: + LogError( "Internal error: unknown value type in id %#x\n", et->id ); + return 0; + } +} + +static void +GetValue( Ent *et, DSpec *dspec, Value *retval, char **eopts ) +{ + Entry *ent; + const char *errs; + +/* Debug( "Getting value %#x\n", et->id );*/ + if (dspec) + ent = FindDEnt( et->id, dspec ); + else + ent = FindGEnt( et->id ); + if (ent) { + if (!(errs = CvtValue( et, retval, ent->vallen, ent->val, eopts ))) + return; + LogError( "Invalid %s value '%.*s' at %s:%d\n", + errs, ent->vallen, ent->val, kdmrc, ent->line ); + } + Debug( "default: %s = %'s\n", et->name, et->def ); + if ((errs = CvtValue( et, retval, strlen( et->def ), et->def, eopts ))) + LogError( "Internal error: invalid default %s value '%s' for key %s\n", + errs, et->def, et->name ); +} + +static int +AddValue( ValArr *va, int id, Value *val ) +{ + int nu; + +/* Debug( "Addig value %#x\n", id );*/ + if (va->nents == va->esiz) { + va->ents = Realloc( va->ents, sizeof(Val) * (va->esiz += 50) ); + if (!va->ents) + return 0; + } + va->ents[va->nents].id = id; + va->ents[va->nents].val = *val; + va->nents++; + switch (id & C_TYPE_MASK) { + case C_TYPE_INT: + break; + case C_TYPE_STR: + va->nchars += val->len; + break; + case C_TYPE_ARGV: + va->nchars += val->len; + for (nu = 0; ((Value *)val->ptr)[nu++].ptr; ); + va->nptrs += nu; + break; + } + return 1; +} + +static void +CopyValues( ValArr *va, Sect *sec, DSpec *dspec, int isconfig ) +{ + Value val; + int i; + + Debug( "getting values for section class [%s]\n", sec->name ); + for (i = 0; i < sec->numents; i++) { +/*Debug ("value %#x\n", sec->ents[i].id);*/ + if ((sec->ents[i].id & (int)C_CONFIG) != isconfig) + ; + else if (sec->ents[i].id & C_INTERNAL) { + GetValue( sec->ents + i, dspec, ((Value *)sec->ents[i].ptr), 0 ); + } else { + if (((sec->ents[i].id & C_MTYPE_MASK) == C_ENUM) || + !sec->ents[i].ptr || + !((int (*)( Value * ))sec->ents[i].ptr)(&val)) { + GetValue( sec->ents + i, dspec, &val, + (char **)sec->ents[i].ptr ); + } + if (!AddValue( va, sec->ents[i].id, &val )) + break; + } + } + return; +} + +static void +SendValues( ValArr *va ) +{ + Value *cst; + int i, nu; + + GSendInt( va->nents ); + GSendInt( va->nptrs ); + GSendInt( 0/*va->nints*/ ); + GSendInt( va->nchars ); + for (i = 0; i < va->nents; i++) { + GSendInt( va->ents[i].id & ~C_PRIVATE ); + switch (va->ents[i].id & C_TYPE_MASK) { + case C_TYPE_INT: + GSendInt( (int)va->ents[i].val.ptr ); + break; + case C_TYPE_STR: + GSendNStr( va->ents[i].val.ptr, va->ents[i].val.len - 1 ); + break; + case C_TYPE_ARGV: + cst = (Value *)va->ents[i].val.ptr; + for (nu = 0; cst[nu].ptr; nu++); + GSendInt( nu ); + for (; cst->ptr; cst++) + GSendNStr( cst->ptr, cst->len ); + break; + } + } +} + + +#ifdef XDMCP +static char * +ReadWord( File *file, int *len, int EOFatEOL ) +{ + char *wordp, *wordBuffer; + int quoted; + char c; + + rest: + wordp = wordBuffer = file->cur; + mloop: + quoted = 0; + qloop: + if (file->cur == file->eof) { + doeow: + if (wordp == wordBuffer) + return 0; + retw: + *wordp = '\0'; + *len = wordp - wordBuffer; + return wordBuffer; + } + c = *file->cur++; + switch (c) { + case '#': + if (quoted) + break; + do { + if (file->cur == file->eof) + goto doeow; + c = *file->cur++; + } while (c != '\n'); + case '\0': + case '\n': + if (EOFatEOL && !quoted) { + file->cur--; + goto doeow; + } + if (wordp != wordBuffer) { + file->cur--; + goto retw; + } + goto rest; + case ' ': + case '\t': + if (wordp != wordBuffer) + goto retw; + goto rest; + case '\\': + if (!quoted) { + quoted = 1; + goto qloop; + } + break; + } + *wordp++ = c; + goto mloop; +} + +#define ALIAS_CHARACTER '%' +#define EQUAL_CHARACTER '=' +#define NEGATE_CHARACTER '!' +#define CHOOSER_STRING "CHOOSER" +#define BROADCAST_STRING "BROADCAST" +#define NOBROADCAST_STRING "NOBROADCAST" +#define LISTEN_STRING "LISTEN" +#define WILDCARD_STRING "*" + +typedef struct hostEntry { + struct hostEntry *next; + int type; + union _hostOrAlias { + char *aliasPattern; + char *hostPattern; + struct _display { + int connectionType; + int hostAddrLen; + char *hostAddress; + } displayAddress; + } entry; +} HostEntry; + +typedef struct listenEntry { + struct listenEntry *next; + int iface; + int mcasts; + int nmcasts; +} ListenEntry; + +typedef struct aliasEntry { + struct aliasEntry *next; + char *name; + HostEntry **pHosts; + int hosts; + int nhosts; + int hasBad; +} AliasEntry; + +typedef struct aclEntry { + struct aclEntry *next; + HostEntry **pEntries; + int entries; + int nentries; + HostEntry **pHosts; + int hosts; + int nhosts; + int flags; +} AclEntry; + + +static int +HasGlobCharacters( char *s ) +{ + for (;;) + switch (*s++) { + case '?': + case '*': + return 1; + case '\0': + return 0; + } +} + +#define PARSE_ALL 0 +#define PARSE_NO_BCAST 1 +#define PARSE_NO_PAT 2 +#define PARSE_NO_ALIAS 4 + +static int +ParseHost( int *nHosts, HostEntry ***hostPtr, int *nChars, + char *hostOrAlias, int len, int parse ) +{ +#if defined(IPv6) && defined(AF_INET6) + struct addrinfo *ai; +#else + struct hostent *hostent; +#endif + void *addr; + int addr_type, addr_len; + + if (!(**hostPtr = (HostEntry *)Malloc( sizeof(HostEntry)))) + return 0; + if (!(parse & PARSE_NO_BCAST) && !strcmp( hostOrAlias, BROADCAST_STRING )) + { + (**hostPtr)->type = HOST_BROADCAST; + } + else if (!(parse & PARSE_NO_ALIAS) && *hostOrAlias == ALIAS_CHARACTER) + { + (**hostPtr)->type = HOST_ALIAS; + (**hostPtr)->entry.aliasPattern = hostOrAlias + 1; + *nChars += len; + } + else if (!(parse & PARSE_NO_PAT) && HasGlobCharacters( hostOrAlias )) + { + (**hostPtr)->type = HOST_PATTERN; + (**hostPtr)->entry.hostPattern = hostOrAlias; + *nChars += len + 1; + } + else + { + (**hostPtr)->type = HOST_ADDRESS; +#if defined(IPv6) && defined(AF_INET6) + if (getaddrinfo( hostOrAlias, NULL, NULL, &ai )) +#else + if (!(hostent = gethostbyname( hostOrAlias ))) +#endif + { + LogWarn( "XDMCP ACL: unresolved host %'s\n", hostOrAlias ); + free( (char *)(**hostPtr) ); + return 0; + } +#if defined(IPv6) && defined(AF_INET6) + addr_type = ai->ai_addr->sa_family; + if (ai->ai_family == AF_INET) { + addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr; + addr_len = sizeof(struct in_addr); + } else /*if (ai->ai_addr->sa_family == AF_INET6)*/ { + addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; + addr_len = sizeof(struct in6_addr); + } +#else + addr_type = hostent->h_addrtype; + addr = hostent->h_addr; + addr_len = hostent->h_length; +#endif + if (!((**hostPtr)->entry.displayAddress.hostAddress = + Malloc( addr_len ))) + { +#if defined(IPv6) && defined(AF_INET6) + freeaddrinfo( ai ); +#endif + free( (char *)(**hostPtr) ); + return 0; + } + memcpy( (**hostPtr)->entry.displayAddress.hostAddress, addr, addr_len ); + *nChars += addr_len; + (**hostPtr)->entry.displayAddress.hostAddrLen = addr_len; + (**hostPtr)->entry.displayAddress.connectionType = addr_type; +#if defined(IPv6) && defined(AF_INET6) + freeaddrinfo( ai ); +#endif + } + *hostPtr = &(**hostPtr)->next; + (*nHosts)++; + return 1; +} + +/* Returns non-0 if string is matched by pattern. Does case folding. */ +static int +patternMatch( const char *string, const char *pattern ) +{ + int p, s; + + if (!string) + string = ""; + + for (;;) { + s = *string++; + switch (p = *pattern++) { + case '*': + if (!*pattern) + return 1; + for (string--; *string; string++) + if (patternMatch( string, pattern )) + return 1; + return 0; + case '?': + if (s == '\0') + return 0; + break; + case '\0': + return s == '\0'; + case '\\': + p = *pattern++; + /* fall through */ + default: + if (tolower( p ) != tolower( s )) + return 0; + } + } +} + +#define MAX_DEPTH 32 + +#define CHECK_NOT 1 +#define CHECK_NO_PAT 2 + +static int +checkHostlist( HostEntry **hosts, int nh, AliasEntry *aliases, int na, + int depth, int flags ) +{ + HostEntry *h; + AliasEntry *a; + int hn, an, am; + + for (h = *hosts, hn = 0; hn < nh; hn++, h = h->next) + if (h->type == HOST_ALIAS) { + if (depth == MAX_DEPTH) { + LogError( "XDMCP ACL: alias recursion involving %%%s\n", + h->entry.aliasPattern ); + return 1; + } + for (a = aliases, an = 0, am = 0; an < na; an++, a = a->next) + if (patternMatch( a->name, h->entry.aliasPattern )) { + am = 1; + if ((flags & CHECK_NOT) && a->hasBad) { + LogError( "XDMCP ACL: alias %%%s with unresolved hosts " + "in denying rule\n", a->name ); + return 1; + } + if (checkHostlist( a->pHosts, a->nhosts, aliases, na, + depth + 1, flags )) + return 1; + } + if (!am) { + if (flags & CHECK_NOT) { + LogError( "XDMCP ACL: unresolved alias pattern %%%s " + "in denying rule\n", h->entry.aliasPattern ); + return 1; + } else + LogWarn( "XDMCP ACL: unresolved alias pattern %%%s\n", + h->entry.aliasPattern ); + } + } else if (h->type == HOST_PATTERN && (flags & CHECK_NO_PAT)) + LogWarn( "XDMCP ACL: wildcarded pattern %'s in host-only context\n", + h->entry.hostPattern ); + return 0; +} + +static void +ReadAccessFile( const char *fname ) +{ + HostEntry *hostList, **hostPtr = &hostList; + AliasEntry *aliasList, **aliasPtr = &aliasList; + AclEntry *acList, **acPtr = &acList, *acl; + ListenEntry *listenList, **listenPtr = &listenList; + char *displayOrAlias, *hostOrAlias; + File file; + int nHosts, nAliases, nAcls, nListens, nChars, error, bad; + int i, len; + + nHosts = nAliases = nAcls = nListens = nChars = error = 0; + if (!readFile( &file, fname, "XDMCP access control" )) + goto sendacl; + while ((displayOrAlias = ReadWord( &file, &len, FALSE ))) { + if (*displayOrAlias == ALIAS_CHARACTER) + { + if (!(*aliasPtr = (AliasEntry *)Malloc( sizeof(AliasEntry)))) { + error = 1; + break; + } + (*aliasPtr)->name = displayOrAlias + 1; + nChars += len; + (*aliasPtr)->hosts = nHosts; + (*aliasPtr)->pHosts = hostPtr; + (*aliasPtr)->nhosts = 0; + (*aliasPtr)->hasBad = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST )) + (*aliasPtr)->nhosts++; + else + (*aliasPtr)->hasBad = 1; + } + aliasPtr = &(*aliasPtr)->next; + nAliases++; + } + else if (!strcmp( displayOrAlias, LISTEN_STRING )) + { + if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) { + error = 1; + break; + } + (*listenPtr)->iface = nHosts; + if (!(hostOrAlias = ReadWord( &file, &len, TRUE )) || + !strcmp( hostOrAlias, WILDCARD_STRING ) || + !ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) + { + (*listenPtr)->iface = -1; + } + (*listenPtr)->mcasts = nHosts; + (*listenPtr)->nmcasts = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (ParseHost( &nHosts, &hostPtr, &nChars, hostOrAlias, len, + PARSE_NO_BCAST|PARSE_NO_PAT|PARSE_NO_ALIAS )) + (*listenPtr)->nmcasts++; + } + listenPtr = &(*listenPtr)->next; + nListens++; + } + else + { + if (!(*acPtr = (AclEntry *)Malloc( sizeof(AclEntry)))) { + error = 1; + break; + } + (*acPtr)->flags = 0; + if (*displayOrAlias == NEGATE_CHARACTER) { + (*acPtr)->flags |= a_notAllowed; + displayOrAlias++; + } else if (*displayOrAlias == EQUAL_CHARACTER) + displayOrAlias++; + (*acPtr)->entries = nHosts; + (*acPtr)->pEntries = hostPtr; + (*acPtr)->nentries = 1; + if (!ParseHost( &nHosts, &hostPtr, &nChars, displayOrAlias, len, + PARSE_NO_BCAST )) + { + bad = 1; + if ((*acPtr)->flags & a_notAllowed) { + LogError( "XDMCP ACL: unresolved host in denying rule\n" ); + error = 1; + } + } else + bad = 0; + (*acPtr)->hosts = nHosts; + (*acPtr)->pHosts = hostPtr; + (*acPtr)->nhosts = 0; + while ((hostOrAlias = ReadWord( &file, &len, TRUE ))) { + if (!strcmp( hostOrAlias, CHOOSER_STRING )) + (*acPtr)->flags |= a_useChooser; + else if (!strcmp( hostOrAlias, NOBROADCAST_STRING )) + (*acPtr)->flags |= a_notBroadcast; + else { + if (ParseHost( &nHosts, &hostPtr, &nChars, + hostOrAlias, len, PARSE_NO_PAT )) + (*acPtr)->nhosts++; + } + } + if (!bad) { + acPtr = &(*acPtr)->next; + nAcls++; + } + } + } + + if (!nListens) { + if (!(*listenPtr = (ListenEntry *)Malloc( sizeof(ListenEntry)))) + error = 1; + else { + (*listenPtr)->iface = -1; + (*listenPtr)->mcasts = nHosts; + (*listenPtr)->nmcasts = 0; +#if defined(IPv6) && defined(AF_INET6) && defined(XDM_DEFAULT_MCAST_ADDR6) + if (ParseHost( &nHosts, &hostPtr, &nChars, + XDM_DEFAULT_MCAST_ADDR6, + sizeof(XDM_DEFAULT_MCAST_ADDR6)-1, + PARSE_ALL )) + (*listenPtr)->nmcasts++; +#endif + nListens++; + } + } + + for (acl = acList, i = 0; i < nAcls; i++, acl = acl->next) + if (checkHostlist( acl->pEntries, acl->nentries, aliasList, nAliases, + 0, (acl->flags & a_notAllowed) ? CHECK_NOT : 0 ) || + checkHostlist( acl->pHosts, acl->nhosts, aliasList, nAliases, + 0, CHECK_NO_PAT )) + error = 1; + + if (error) { + nHosts = nAliases = nAcls = nListens = nChars = 0; + sendacl: + LogError( "No XDMCP requests will be granted\n" ); + } + GSendInt( nHosts ); + GSendInt( nListens ); + GSendInt( nAliases ); + GSendInt( nAcls ); + GSendInt( nChars ); + for (i = 0; i < nHosts; i++, hostList = hostList->next) { + GSendInt( hostList->type ); + switch (hostList->type) { + case HOST_ALIAS: + GSendStr( hostList->entry.aliasPattern ); + break; + case HOST_PATTERN: + GSendStr( hostList->entry.hostPattern ); + break; + case HOST_ADDRESS: + GSendArr( hostList->entry.displayAddress.hostAddrLen, + hostList->entry.displayAddress.hostAddress ); + GSendInt( hostList->entry.displayAddress.connectionType ); + break; + } + } + for (i = 0; i < nListens; i++, listenList = listenList->next) { + GSendInt( listenList->iface ); + GSendInt( listenList->mcasts ); + GSendInt( listenList->nmcasts ); + } + for (i = 0; i < nAliases; i++, aliasList = aliasList->next) { + GSendStr( aliasList->name ); + GSendInt( aliasList->hosts ); + GSendInt( aliasList->nhosts ); + } + for (i = 0; i < nAcls; i++, acList = acList->next) { + GSendInt( acList->entries ); + GSendInt( acList->nentries ); + GSendInt( acList->hosts ); + GSendInt( acList->nhosts ); + GSendInt( acList->flags ); + } +} +#endif + + +int main( int argc ATTR_UNUSED, char **argv ) +{ + DSpec dspec; + ValArr va; + char *ci, *disp, *dcls, *cfgfile; + int what; + + if (!(ci = getenv( "CONINFO" ))) { + fprintf( stderr, "This program is part of kdm and should not be run manually.\n" ); + return 1; + } + if (sscanf( ci, "%d %d", &rfd, &wfd ) != 2) + return 1; + + InitLog(); + + if ((debugLevel = GRecvInt()) & DEBUG_WCONFIG) + sleep( 100 ); + +/* Debug ("parsing command line\n");*/ + if (**++argv) + kdmrc = *argv; +/* + while (*++argv) { + } +*/ + + for (;;) { +/* Debug ("Awaiting command ...\n");*/ + if (!GRecvCmd( &what )) + break; + switch (what) { + case GC_Files: +/* Debug ("GC_Files\n");*/ + ReadConf(); + CopyValues( 0, &secGeneral, 0, C_CONFIG ); +#ifdef XDMCP + CopyValues( 0, &secXdmcp, 0, C_CONFIG ); + GSendInt( 2 ); +#else + GSendInt( 1 ); +#endif + GSendStr( kdmrc ); + GSendInt( -1 ); +#ifdef XDMCP + GSendNStr( VXaccess.ptr, VXaccess.len - 1 ); + GSendInt( 0 ); +#endif + for (; (what = GRecvInt()) != -1; ) + switch (what) { + case GC_gGlobal: + case GC_gDisplay: + GSendInt( 0 ); + break; +#ifdef XDMCP + case GC_gXaccess: + GSendInt( 1 ); + break; +#endif + default: + GSendInt( -1 ); + break; + } + break; + case GC_GetConf: +/* Debug( "GC_GetConf\n" );*/ + memset( &va, 0, sizeof(va) ); + what = GRecvInt(); + cfgfile = GRecvStr(); + switch (what) { + case GC_gGlobal: +/* Debug( "GC_gGlobal\n" );*/ + Debug( "getting global config\n" ); + ReadConf(); + CopyValues( &va, &secGeneral, 0, 0 ); +#ifdef XDMCP + CopyValues( &va, &secXdmcp, 0, 0 ); +#endif + CopyValues( &va, &secShutdown, 0, 0 ); + SendValues( &va ); + break; + case GC_gDisplay: +/* Debug( "GC_gDisplay\n" );*/ + disp = GRecvStr(); +/* Debug( " Display %s\n", disp );*/ + dcls = GRecvStr(); +/* Debug( " Class %s\n", dcls );*/ + Debug( "getting config for display %s, class %s\n", disp, dcls ); + MkDSpec( &dspec, disp, dcls ? dcls : "" ); + ReadConf(); + CopyValues( &va, &sec_Core, &dspec, 0 ); + CopyValues( &va, &sec_Greeter, &dspec, 0 ); + free( disp ); + if (dcls) + free( dcls ); + SendValues( &va ); + break; +#ifdef XDMCP + case GC_gXaccess: + ReadAccessFile( cfgfile ); + break; +#endif + default: + Debug( "Unsupported config category %#x\n", what ); + } + free( cfgfile ); + break; + default: + Debug( "Unknown config command %#x\n", what ); + } + } + +/* Debug( "Config reader exiting ..." );*/ + return EX_NORMAL; +} diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c new file mode 100644 index 000000000..6abc2c057 --- /dev/null +++ b/kdm/kfrontend/kdm_greet.c @@ -0,0 +1,787 @@ +/* + +KDE Greeter module for xdm + +Copyright (C) 2001-2003 Oswald Buddenhagen <ossi@kde.org> + +This file contains code from the old xdm core, +Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#include "kdm_greet.h" +#include "kdmconfig.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> +#include <string.h> +#include <signal.h> +#include <setjmp.h> +#include <ctype.h> +#include <time.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#ifdef _POSIX_PRIORITY_SCHEDULING +# include <sched.h> +#endif + +#if defined(HAVE_XTEST) || defined(HAVE_XKB) +# include <X11/Xlib.h> +# include <X11/keysym.h> +#endif + +#ifdef HAVE_XTEST +# include <X11/extensions/XTest.h> +#endif + +#ifdef HAVE_XKB +# include <X11/XKBlib.h> +#endif + +extern void LogOutOfMem( void ); + +static void * +Realloc( void *ptr, size_t size ) +{ + void *ret; + + if (!(ret = realloc( ptr, size )) && size) + LogOutOfMem(); + return ret; +} + +#define PRINT_QUOTES +#define PRINT_ARRAYS +#define LOG_NAME "kdm_greet" +#define LOG_DEBUG_MASK DEBUG_GREET +#define LOG_PANIC_EXIT 1 +#define STATIC +#include <printf.c> + +static void +GDebug( const char *fmt, ... ) +{ + va_list args; + + if (debugLevel & DEBUG_HLPCON) { + va_start( args, fmt ); + Logger( DM_DEBUG, fmt, args ); + va_end( args ); + } +} + + +char *dname; + +int rfd; +static int wfd, mrfd, mwfd, srfd, swfd; +static const char *who; + +void +GSet( int master ) +{ + if (master) + rfd = mrfd, wfd = mwfd, who = "core (master)"; + else + rfd = srfd, wfd = swfd, who = "core"; + +} + +static int +Reader( void *buf, int count ) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = read( rfd, (void *)((char *)buf + rlen), count - rlen ); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +static void +GRead( void *buf, int count ) +{ + if (Reader( buf, count ) != count) + LogPanic( "Can't read from %s\n", who ); +} + +static void +GWrite( const void *buf, int count ) +{ + if (write( wfd, buf, count ) != count) + LogPanic( "Can't write to %s\n", who ); +#ifdef _POSIX_PRIORITY_SCHEDULING + if ((debugLevel & DEBUG_HLPCON)) + sched_yield(); +#endif +} + +void +GSendInt( int val ) +{ + GDebug( "Sending int %d (%#x) to %s\n", val, val, who ); + GWrite( &val, sizeof(val) ); +} + +void +GSendStr( const char *buf ) +{ + int len = buf ? strlen( buf ) + 1 : 0; + GDebug( "Sending string %'s to %s\n", buf, who ); + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); +} + +/* +static void +GSendNStr( const char *buf, int len ) +{ + int tlen = len + 1; + GDebug( "Sending string %'.*s to %s\n", len, buf, who ); + GWrite( &tlen, sizeof(tlen) ); + GWrite( buf, len ); + GWrite( "", 1 ); +} +*/ + +void +GSendArr( int len, const char *buf ) +{ + GDebug( "Sending array %02[:*hhx to %s\n", len, buf, who ); + GWrite( &len, sizeof(len) ); + GWrite( buf, len ); +} + +int +GRecvInt() +{ + int val; + + GDebug( "Receiving int from %s ...\n", who ); + GRead( &val, sizeof(val) ); + GDebug( " -> %d (%#x)\n", val, val ); + return val; +} + +static char * +iGRecvArr( int *rlen ) +{ + int len; + char *buf; + + GRead( &len, sizeof(len) ); + *rlen = len; + GDebug( " -> %d bytes\n", len ); + if (!len) + return (char *)0; + if (!(buf = malloc( len ))) + LogPanic( "No memory for read buffer\n" ); + GRead( buf, len ); + return buf; +} + +char * +GRecvStr() +{ + int len; + char *buf; + + GDebug( "Receiving string from %s ...\n", who ); + buf = iGRecvArr( &len ); + GDebug( " -> %'.*s\n", len, buf ); + return buf; +} + +char ** +GRecvStrArr( int *rnum ) +{ + int num; + char **argv, **cargv; + + GDebug( "Receiving string array from %s ...\n", who ); + GRead( &num, sizeof(num) ); + GDebug( " -> %d strings\n", num ); + if (rnum) + *rnum = num; + if (!num) + return (char **)0; + if (!(argv = malloc( num * sizeof(char *)))) + LogPanic( "No memory for read buffer\n" ); + for (cargv = argv; --num >= 0; cargv++) + *cargv = GRecvStr(); + return argv; +} + +char * +GRecvArr( int *num ) +{ + char *arr; + + GDebug( "Receiving array from %s ...\n", who ); + GRead( num, sizeof(*num) ); + GDebug( " -> %d bytes\n", *num ); + if (!*num) + return (char *)0; + if (!(arr = malloc( *num ))) + LogPanic( "No memory for read buffer\n" ); + GRead( arr, *num ); + GDebug( " -> %02[*hhx\n", *num, arr ); + return arr; +} + +static void +ReqCfg( int id ) +{ + GSendInt( G_GetCfg ); + GSendInt( id ); + switch (GRecvInt()) { + case GE_NoEnt: + LogPanic( "Config value %#x not available\n", id ); + case GE_BadType: + LogPanic( "Core does not know type of config value %#x\n", id ); + } +} + +int +GetCfgInt( int id ) +{ + ReqCfg( id ); + return GRecvInt(); +} + +char * +GetCfgStr( int id ) +{ + ReqCfg( id ); + return GRecvStr(); +} + +char ** +GetCfgStrArr( int id, int *len ) +{ + ReqCfg( id ); + return GRecvStrArr( len ); +} + +static void +disposeSession( dpySpec *sess ) +{ + free( sess->display ); + free( sess->from ); + if (sess->user) + free( sess->user ); + if (sess->session) + free( sess->session ); +} + +dpySpec * +fetchSessions( int flags ) +{ + dpySpec *sess, *sessions = 0, tsess; + + GSet( 1 ); + GSendInt( G_List ); + GSendInt( flags ); + next: + while ((tsess.display = GRecvStr())) { + tsess.from = GRecvStr(); +#ifdef HAVE_VTS + tsess.vt = GRecvInt(); +#endif + tsess.user = GRecvStr(); + tsess.session = GRecvStr(); + tsess.flags = GRecvInt(); + if ((tsess.flags & isTTY) && *tsess.from) + for (sess = sessions; sess; sess = sess->next) + if (sess->user && !strcmp( sess->user, tsess.user ) && + !strcmp( sess->from, tsess.from )) + { + sess->count++; + disposeSession( &tsess ); + goto next; + } + if (!(sess = malloc( sizeof(*sess) ))) + LogPanic( "Out of memory\n" ); + tsess.count = 1; + tsess.next = sessions; + *sess = tsess; + sessions = sess; + } + GSet( 0 ); + return sessions; +} + +void +disposeSessions( dpySpec *sess ) +{ + while (sess) { + dpySpec *nsess = sess->next; + disposeSession( sess ); + free( sess ); + sess = nsess; + } +} + +void +freeStrArr( char **arr ) +{ + char **tarr; + + if (arr) { + for (tarr = arr; *tarr; tarr++) + free( *tarr ); + free( arr ); + } +} + + +static int +ignoreErrors( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) +{ + Debug( "ignoring X error\n" ); + return 0; +} + +/* + * this is mostly bogus -- but quite useful. I wish the protocol + * had some way of enumerating and identifying clients, that way + * this code wouldn't have to be this kludgy. + */ + +static void +killWindows( Display *dpy, Window window ) +{ + Window root, parent, *children; + unsigned child, nchildren = 0; + + while (XQueryTree( dpy, window, &root, &parent, &children, &nchildren ) + && nchildren > 0) + { + for (child = 0; child < nchildren; child++) { + Debug( "XKillClient 0x%lx\n", (unsigned long)children[child] ); + XKillClient( dpy, children[child] ); + } + XFree( (char *)children ); + } +} + +static jmp_buf resetJmp; + +static void +abortReset( int n ATTR_UNUSED ) +{ + longjmp (resetJmp, 1); +} + +/* + * this display connection better not have any windows... + */ + +static void +pseudoReset( Display *dpy ) +{ + int screen; + + if (setjmp( resetJmp )) { + LogError( "pseudoReset timeout\n" ); + } else { + (void)signal( SIGALRM, abortReset ); + (void)alarm( 30 ); + XSetErrorHandler( ignoreErrors ); + for (screen = 0; screen < ScreenCount( dpy ); screen++) { + Debug( "pseudoReset screen %d\n", screen ); + killWindows( dpy, RootWindow( dpy, screen ) ); + } + Debug( "before XSync\n" ); + XSync( dpy, False ); + (void)alarm( 0 ); + } + signal( SIGALRM, SIG_DFL ); + XSetErrorHandler( (XErrorHandler)0 ); + Debug( "pseudoReset done\n" ); +} + + +static jmp_buf syncJump; + +static void +syncTimeout( int n ATTR_UNUSED ) +{ + longjmp( syncJump, 1 ); +} + +void +SecureDisplay( Display *dpy ) +{ + Debug( "SecureDisplay %s\n", dname ); + (void)signal( SIGALRM, syncTimeout ); + if (setjmp( syncJump )) { + LogError( "Display %s could not be secured\n", dname ); + exit( EX_RESERVER_DPY ); + } + (void)alarm( (unsigned)_grabTimeout ); + Debug( "Before XGrabServer %s\n", dname ); + XGrabServer( dpy ); + Debug( "XGrabServer succeeded %s\n", dname ); + if (XGrabKeyboard( dpy, DefaultRootWindow( dpy ), True, GrabModeAsync, + GrabModeAsync, CurrentTime ) != GrabSuccess) + { + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + LogError( "Keyboard on display %s could not be secured\n", dname ); + sleep( 10 ); + exit( EX_RESERVER_DPY ); + } + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + pseudoReset( dpy ); + if (!_grabServer) + { + XUngrabServer( dpy ); + XSync( dpy, 0 ); + } + Debug( "done secure %s\n", dname ); +#ifdef HAVE_XKBSETPERCLIENTCONTROLS + /* + * Activate the correct mapping for modifiers in XKB extension as + * grabbed keyboard has its own mapping by default + */ + { + int opcode, evbase, errbase, majret, minret; + unsigned int value = XkbPCF_GrabsUseXKBStateMask; + if (XkbQueryExtension( dpy, &opcode, &evbase, + &errbase, &majret, &minret )) + XkbSetPerClientControls( dpy, value, &value ); + } +#endif +} + +void +UnsecureDisplay( Display *dpy ) +{ + Debug( "Unsecure display %s\n", dname ); + if (_grabServer) { + XUngrabServer( dpy ); + XSync( dpy, 0 ); + } +} + +static jmp_buf pingTime; + +static int +PingLostIOErr( Display *dpy ATTR_UNUSED ) +{ + longjmp( pingTime, 1 ); +} + +static void +PingLostSig( int n ATTR_UNUSED ) +{ + longjmp( pingTime, 1 ); +} + +int +PingServer( Display *dpy ) +{ + int (*oldError)( Display * ); + void (*oldSig)( int ); + int oldAlarm; + + oldError = XSetIOErrorHandler( PingLostIOErr ); + oldAlarm = alarm( 0 ); + oldSig = signal( SIGALRM, PingLostSig ); + (void)alarm( _pingTimeout * 60 ); + if (!setjmp( pingTime )) { + Debug( "Ping server\n" ); + XSync( dpy, 0 ); + } else { + Debug( "Server dead\n" ); + (void)alarm( 0 ); + (void)signal( SIGALRM, SIG_DFL ); + XSetIOErrorHandler( oldError ); + return 0; + } + (void)alarm( 0 ); + (void)signal( SIGALRM, oldSig ); + (void)alarm( oldAlarm ); + Debug( "Server alive\n" ); + XSetIOErrorHandler( oldError ); + return 1; +} + +/* + * Modifier changing code based on kdebase/kxkb/kcmmisc.cpp + * + * XTest part: Copyright (C) 2000-2001 Lubos Lunak <l.lunak@kde.org> + * XKB part: Copyright (C) 2001-2002 Oswald Buddenhagen <ossi@kde.org> + * + */ + +#ifdef HAVE_XKB +static int +xkb_init( Display *dpy ) +{ + int xkb_opcode, xkb_event, xkb_error; + int xkb_lmaj = XkbMajorVersion; + int xkb_lmin = XkbMinorVersion; + return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin ) && + XkbQueryExtension( dpy, &xkb_opcode, &xkb_event, + &xkb_error, &xkb_lmaj, &xkb_lmin ); +} + +static unsigned int +xkb_modifier_mask_work( XkbDescPtr xkb, const char *name ) +{ + int i; + + if (!xkb->names) + return 0; + for (i = 0; i < XkbNumVirtualMods; i++) { + char *modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] ); + if (modStr != NULL && strcmp( name, modStr ) == 0) { + unsigned int mask; + XkbVirtualModsToReal( xkb, 1 << i, &mask ); + return mask; + } + } + return 0; +} + +static unsigned int +xkb_modifier_mask( Display *dpy, const char *name ) +{ + XkbDescPtr xkb; + + if ((xkb = XkbGetKeyboard( dpy, XkbAllComponentsMask, XkbUseCoreKbd ))) { + unsigned int mask = xkb_modifier_mask_work( xkb, name ); + XkbFreeKeyboard( xkb, 0, True ); + return mask; + } + return 0; +} + +static int +xkb_get_modifier_state( Display *dpy, const char *name ) +{ + unsigned int mask; + XkbStateRec state; + + if (!(mask = xkb_modifier_mask( dpy, name ))) + return 0; + XkbGetState( dpy, XkbUseCoreKbd, &state ); + return (mask & state.locked_mods) != 0; +} + +static int +xkb_set_modifier( Display *dpy, const char *name, int sts ) +{ + unsigned int mask; + + if (!(mask = xkb_modifier_mask( dpy, name ))) + return 0; + XkbLockModifiers( dpy, XkbUseCoreKbd, mask, sts ? mask : 0 ); + return 1; +} +#endif /* HAVE_XKB */ + +#ifdef HAVE_XTEST +static int +xtest_get_modifier_state( Display *dpy, int key ) +{ + XModifierKeymap *map; + KeyCode modifier_keycode; + unsigned int i, mask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + + if ((modifier_keycode = XKeysymToKeycode( dpy, key )) == NoSymbol) + return 0; + map = XGetModifierMapping( dpy ); + for (i = 0; i < 8; ++i) + if (map->modifiermap[map->max_keypermod * i] == modifier_keycode) { + XFreeModifiermap( map ); + XQueryPointer( dpy, DefaultRootWindow( dpy ), + &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, + &mask ); + return (mask & (1 << i)) != 0; + } + XFreeModifiermap( map ); + return 0; +} + +static void +xtest_fake_keypress( Display *dpy, int key ) +{ + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), True, CurrentTime ); + XTestFakeKeyEvent( dpy, XKeysymToKeycode( dpy, key ), False, CurrentTime ); +} +#endif /* HAVE_XTEST */ + +#ifdef HAVE_XKB +static int havexkb; +#endif +static int nummodified, oldnumstate, newnumstate; +static Display *dpy; + +void +setup_modifiers( Display *mdpy, int numlock ) +{ + if (numlock == 2) + return; + newnumstate = numlock; + nummodified = 1; + dpy = mdpy; +#ifdef HAVE_XKB + if (xkb_init( mdpy )) { + havexkb = 1; + oldnumstate = xkb_get_modifier_state( mdpy, "NumLock" ); + xkb_set_modifier( mdpy, "NumLock", numlock ); + return; + } +#endif +#ifdef HAVE_XTEST + oldnumstate = xtest_get_modifier_state( mdpy, XK_Num_Lock ); + if (oldnumstate != numlock) + xtest_fake_keypress( mdpy, XK_Num_Lock ); +#endif +} + +void +restore_modifiers( void ) +{ +#ifdef HAVE_XTEST + int numstat; +#endif + + if (!nummodified) + return; +#ifdef HAVE_XKB + if (havexkb) { + if (xkb_get_modifier_state( dpy, "NumLock" ) == newnumstate) + xkb_set_modifier( dpy, "NumLock", oldnumstate ); + return; + } +#endif +#ifdef HAVE_XTEST + numstat = xtest_get_modifier_state( dpy, XK_Num_Lock ); + if (numstat == newnumstate && newnumstate != oldnumstate) + xtest_fake_keypress( dpy, XK_Num_Lock ); +#endif +} + +void +setCursor( Display *mdpy, int window, int shape ) +{ + Cursor xcursor; + + if ((xcursor = XCreateFontCursor( mdpy, shape ))) { + XDefineCursor( mdpy, window, xcursor ); + XFreeCursor( mdpy, xcursor ); + XFlush( mdpy ); + } +} + +static void +sigterm( int n ATTR_UNUSED ) +{ + exit( EX_NORMAL ); +} + +static char *savhome; + +static void +cleanup( void ) +{ + char buf[128]; + + if (strcmp( savhome, getenv( "HOME" ) ) || memcmp( savhome, "/tmp/", 5 )) + LogError( "Internal error: memory corruption detected\n" ); /* no panic: recursion */ + else { + sprintf( buf, "rm -rf %s", savhome ); + system( buf ); + } +} + +extern void kg_main( const char *argv0 ); + +int +main( int argc ATTR_UNUSED, char **argv ) +{ + char *ci; + int i; + char qtrc[40]; + + if (!(ci = getenv( "CONINFO" ))) { + fprintf( stderr, "This program is part of kdm and should not be run manually.\n" ); + return 1; + } + if (sscanf( ci, "%d %d %d %d", &srfd, &swfd, &mrfd, &mwfd ) != 4) + return 1; + fcntl( srfd, F_SETFD, FD_CLOEXEC ); + fcntl( swfd, F_SETFD, FD_CLOEXEC ); + fcntl( mrfd, F_SETFD, FD_CLOEXEC ); + fcntl( mwfd, F_SETFD, FD_CLOEXEC ); + GSet( 0 ); + + InitLog(); + + if ((debugLevel = GRecvInt()) & DEBUG_WGREET) + sleep( 100 ); + + signal( SIGTERM, sigterm ); + + dname = getenv( "DISPLAY" ); + + init_config(); + + /* for QSettings */ + srand( time( 0 ) ); + for (i = 0; i < 10000; i++) { + sprintf( qtrc, "/tmp/%010d", rand() ); + if (!mkdir( qtrc, 0700 )) + goto okay; + } + LogPanic( "Cannot create $HOME\n" ); + okay: + if (setenv( "HOME", qtrc, 1 )) + LogPanic( "Cannot set $HOME\n" ); + if (!(savhome = strdup( qtrc ))) + LogPanic( "Cannot save $HOME\n" ); + atexit( cleanup ); + + setenv( "LC_ALL", _language, 1 ); + + kg_main( argv[0] ); + + return EX_NORMAL; +} diff --git a/kdm/kfrontend/kdm_greet.h b/kdm/kfrontend/kdm_greet.h new file mode 100644 index 000000000..df325c28d --- /dev/null +++ b/kdm/kfrontend/kdm_greet.h @@ -0,0 +1,91 @@ +/* + +KDE Greeter module for xdm + +Copyright (C) 2001-2003 Oswald Buddenhagen <ossi@kde.org> + +This file contains code from the old xdm core, +Copyright 1988, 1998 Keith Packard, MIT X Consortium/The Open Group + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef _KDM_GREET_H_ +#define _KDM_GREET_H_ + +#include <greet.h> /* for the ATTR_ defines */ +#include <config.ci> /* for the HAVE_VTS define */ + +#ifdef __cplusplus +extern "C" { +#endif + +void GSet( int master ); +void GSendInt( int val ); +void GSendStr( const char *buf ); +/*void GSendNStr( const char *buf, int len );*/ +void GSendArr( int len, const char *buf ); +int GRecvInt( void ); +char *GRecvStr( void ); +char **GRecvStrArr( int *len ); +char *GRecvArr( int *len ); + +int GetCfgInt( int id ); +char *GetCfgStr( int id ); +char **GetCfgStrArr( int id, int *len ); + +typedef struct dpySpec { + struct dpySpec *next; + char *display, *from, *user, *session; +#ifdef HAVE_VTS + int vt; +#endif + int flags; + int count; +} dpySpec; + +dpySpec *fetchSessions( int flags ); +void disposeSessions( dpySpec *sess ); + +void freeStrArr( char **arr ); + +void Debug( const char *fmt, ... ); +void LogInfo( const char *fmt, ... ); +void LogWarn( const char *fmt, ... ); +void LogError( const char *fmt, ... ); +void LogPanic( const char *fmt, ... ) ATTR_NORETURN; + +struct _XDisplay; + +void SecureDisplay( struct _XDisplay *dpy ); +void UnsecureDisplay( struct _XDisplay *dpy ); +int PingServer( struct _XDisplay *dpy ); + +void setup_modifiers( struct _XDisplay *mdpy, int numlock ); +void restore_modifiers( void ); + +void setCursor( struct _XDisplay *mdpy, int window, int shape ); + + +extern int rfd; /* for select() loops */ + +extern char *dname; /* d->name */ + +#ifdef __cplusplus +} +#endif + +#endif /* _KDM_GREET_H_ */ diff --git a/kdm/kfrontend/kdmclock.cpp b/kdm/kfrontend/kdmclock.cpp new file mode 100644 index 000000000..88bc33aaa --- /dev/null +++ b/kdm/kfrontend/kdmclock.cpp @@ -0,0 +1,176 @@ +/* + +clock module for kdm + +Copyright (C) 2000 Espen Sand, espen@kde.org + Based on work by NN(yet to be determined) +flicker free code by Remi Guyomarch <rguyom@mail.dotcom.fr> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kdmclock.h" + +//#include <kapplication.h> +//#include <kconfig.h> + +#include <qdatetime.h> +#include <qpixmap.h> +#include <qpainter.h> +#include <qtimer.h> + +KdmClock::KdmClock( QWidget *parent, const char *name ) + : inherited( parent, name ) +{ + // start timer + QTimer *timer = new QTimer( this ); + connect( timer, SIGNAL(timeout()), SLOT(timeout()) ); + timer->start( 1000 ); + + // reading rc file + //KConfig *config = kapp->config(); + + //config->setGroup( "Option" ); + mDate = false;//config->readNumEntry( "date", FALSE ); + mSecond = true;//config->readNumEntry( "second", TRUE ); + mDigital = false;//config->readNumEntry( "digital", FALSE ); + mBorder = false;//config->readNumEntry( "border", FALSE ); + + //config->setGroup( "Font" ); + mFont.setFamily( QString::fromLatin1("Utopia")/*config->readEntry( "Family", "Utopia")*/ ); + mFont.setPointSize( 51/*config->readNumEntry( "Point Size", 51)*/ ); + mFont.setWeight( 75/*config->readNumEntry( "Weight", 75)*/ ); + mFont.setItalic( TRUE/*config->readNumEntry( "Italic",TRUE )*/ ); + mFont.setBold( TRUE/*config->readNumEntry( "Bold",TRUE )*/ ); + + setFixedSize( 100, 100 ); + + if (mBorder) { + setLineWidth( 1 ); + setFrameStyle( Box|Plain ); + //setFrameStyle( WinPanel|Sunken ); + } + +/* + if (!mDigital) { + if (height() < width()) + resize( height(), height() ); + else + resize( width() ,width() ); + } +*/ + + //setBackgroundOrigin( WindowOrigin ); + mBackgroundBrush = backgroundBrush(); + setBackgroundMode( NoBackground ); + repaint(); +} + + +void KdmClock::showEvent( QShowEvent * ) +{ + repaint(); +} + + +void KdmClock::timeout() +{ + repaint(); +} + +void KdmClock::paintEvent( QPaintEvent * ) +{ + if (!isVisible()) + return; + + QPainter p( this ); + drawFrame( &p ); + + QPixmap pm( contentsRect().size() ); + QPainter paint; + paint.begin( &pm ); + paint.fillRect( contentsRect(), mBackgroundBrush ); + + // get current time + QTime time = QTime::currentTime(); + +/* + if (mDigital) { + QString buf; + if (mSecond) + buf.sprintf( "%02d:%02d:%02d", time.hour(), time.minute(), + time.second() ); + else + buf.sprintf( "%02d:%02d", time.hour(), time.minute() ); + mFont.setPointSize( QMIN( (int)(width()/buf.length()*1.5),height() ) ); + paint.setFont( mFont ); + paint.setPen( backgroundColor() ); + paint.drawText( contentsRect(),AlignHCenter|AlignVCenter, buf,-1,0,0 ); + } else { +*/ + QPointArray pts; + QPoint cp = contentsRect().center() - QPoint( 2,2 ); + int d = QMIN( contentsRect().width()-15,contentsRect().height()-15 ); + paint.setPen( foregroundColor() ); + paint.setBrush( foregroundColor() ); + + QWMatrix matrix; + matrix.translate( cp.x(), cp.y() ); + matrix.scale( d/1000.0F, d/1000.0F ); + + // Hour + float h_angle = 30*(time.hour()%12-3) + time.minute()/2; + matrix.rotate( h_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 ); + paint.drawPolygon( pts ); + matrix.rotate( -h_angle ); + + // Minute + float m_angle = (time.minute()-15)*6; + matrix.rotate( m_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 ); + paint.drawPolygon( pts ); + matrix.rotate( -m_angle ); + + // Second + float s_angle = (time.second()-15)*6; + matrix.rotate( s_angle ); + paint.setWorldMatrix( matrix ); + pts.setPoints( 4,0,0,0,0,400,0,0,0 ); + if (mSecond) + paint.drawPolygon( pts ); + matrix.rotate( -s_angle ); + + // quadrante + for (int i=0 ; i < 60 ; i++) { + paint.setWorldMatrix( matrix ); + if ((i % 5) == 0) + paint.drawLine( 450,0, 500,0 ); // draw hour lines + else + paint.drawPoint( 480,0 ); // draw second lines + matrix.rotate( 6 ); + } + +// } // if (mDigital) + paint.end(); + + // flicker free code by Remi Guyomarch <rguyom@mail.dotcom.fr> + bitBlt( this, contentsRect().topLeft(), &pm ); +} + +#include "kdmclock.moc" diff --git a/kdm/kfrontend/kdmclock.h b/kdm/kfrontend/kdmclock.h new file mode 100644 index 000000000..92ce97733 --- /dev/null +++ b/kdm/kfrontend/kdmclock.h @@ -0,0 +1,52 @@ +/* + +clock module for kdm + +Copyright (C) 2000 Espen Sand, espen@kde.org + Based on work by NN (yet to be determined) + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef _KDM_CLOCK_H_ +#define _KDM_CLOCK_H_ + +#include <qframe.h> + +class KdmClock : public QFrame { + Q_OBJECT + typedef QFrame inherited; + + public: + KdmClock( QWidget *parent=0, const char *name=0 ); + + protected: + virtual void showEvent( QShowEvent * ); + virtual void paintEvent( QPaintEvent * ); + + private slots: + void timeout(); + + private: + QBrush mBackgroundBrush; + QFont mFont; + bool mSecond; + bool mDigital; + bool mDate; + bool mBorder; +}; + +#endif diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp new file mode 100644 index 000000000..5d8d24e91 --- /dev/null +++ b/kdm/kfrontend/kdmconfig.cpp @@ -0,0 +1,177 @@ +/* + +Config for kdm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kdmconfig.h" +#include "kdm_greet.h" + +#include <kapplication.h> +#include <klocale.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/utsname.h> + +CONF_GREET_DEFS + +QString _stsFile; +bool _isLocal; +bool _authorized; + +static QString +GetCfgQStr( int id ) +{ + char *tmp = GetCfgStr( id ); + QString qs = QString::fromUtf8( tmp ); + free( tmp ); + return qs; +} + +static QStringList +GetCfgQStrList( int id ) +{ + int i, len; + char **tmp = GetCfgStrArr( id, &len ); + QStringList qsl; + for (i = 0; i < len - 1; i++) { + qsl.append( QString::fromUtf8( tmp[i] ) ); + free( tmp[i] ); + } + free( tmp ); + return qsl; +} + +// Based on kconfigbase.cpp +static QFont +Str2Font( const QString &aValue ) +{ + uint nFontBits; + QFont aRetFont; + QString chStr; + + QStringList sl = QStringList::split( QString::fromLatin1(","), aValue ); + + if (sl.count() == 1) { + /* X11 font spec */ + aRetFont = QFont( aValue ); + aRetFont.setRawMode( true ); + } else if (sl.count() == 10) { + /* qt3 font spec */ + aRetFont.fromString( aValue ); + } else if (sl.count() == 6) { + /* backward compatible kde2 font spec */ + aRetFont = QFont( sl[0], sl[1].toInt(), sl[4].toUInt() ); + + aRetFont.setStyleHint( (QFont::StyleHint)sl[2].toUInt() ); + + nFontBits = sl[5].toUInt(); + aRetFont.setItalic( (nFontBits & 0x01) != 0 ); + aRetFont.setUnderline( (nFontBits & 0x02) != 0 ); + aRetFont.setStrikeOut( (nFontBits & 0x04) != 0 ); + aRetFont.setFixedPitch( (nFontBits & 0x08) != 0 ); + aRetFont.setRawMode( (nFontBits & 0x20) != 0 ); + } + aRetFont.setStyleStrategy( (QFont::StyleStrategy) + (QFont::PreferMatch | + (_antiAliasing ? QFont::PreferAntialias : QFont::NoAntialias)) ); + + return aRetFont; +} + +extern "C" +void init_config( void ) +{ + CONF_GREET_INIT + + _isLocal = GetCfgInt( C_isLocal ); + _hasConsole = _hasConsole && _isLocal && GetCfgInt( C_hasConsole ); + _authorized = GetCfgInt( C_isAuthorized ); + + _stsFile = _dataDir + "/kdmsts"; + + // Greet String + char hostname[256], *ptr; + hostname[0] = '\0'; + if (!gethostname( hostname, sizeof(hostname) )) + hostname[sizeof(hostname)-1] = '\0'; + struct utsname tuname; + uname( &tuname ); + QString gst = _greetString; + _greetString = QString::null; + int i, j, l = gst.length(); + for (i = 0; i < l; i++) { + if (gst[i] == '%') { + switch (gst[++i].cell()) { + case '%': _greetString += gst[i]; continue; + case 'd': ptr = dname; break; + case 'h': ptr = hostname; break; + case 'n': ptr = tuname.nodename; + for (j = 0; ptr[j]; j++) + if (ptr[j] == '.') { + ptr[j] = 0; + break; + } + break; + case 's': ptr = tuname.sysname; break; + case 'r': ptr = tuname.release; break; + case 'm': ptr = tuname.machine; break; + default: _greetString += i18n("[fix kdmrc!]"); continue; + } + _greetString += QString::fromLocal8Bit( ptr ); + } else + _greetString += gst[i]; + } +} + + +/* out-of-place utility function */ +void +decodeSess( dpySpec *sess, QString &user, QString &loc ) +{ + if (sess->flags & isTTY) { + user = + i18n( "%1: TTY login", "%1: %n TTY logins", sess->count ) + .arg( sess->user ); + loc = +#ifdef HAVE_VTS + sess->vt ? + QString("vt%1").arg( sess->vt ) : +#endif + QString::fromLatin1( *sess->from ? sess->from : sess->display ); + } else { + user = + !sess->user ? + i18n("Unused") : + *sess->user ? + i18n("user: session type", "%1: %2") + .arg( sess->user ).arg( sess->session ) : + i18n("... host", "X login on %1").arg( sess->session ); + loc = +#ifdef HAVE_VTS + sess->vt ? + QString("%1, vt%2").arg( sess->display ).arg( sess->vt ) : +#endif + QString::fromLatin1( sess->display ); + } +} diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h new file mode 100644 index 000000000..3077a2ce0 --- /dev/null +++ b/kdm/kfrontend/kdmconfig.h @@ -0,0 +1,55 @@ +/* + +Configuration for kdm + +Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KDMCONFIG_H +#define KDMCONFIG_H + +#include <config.h> + +#include "config.ci" + +#ifdef __cplusplus + +#include <qstring.h> +#include <qstringlist.h> +#include <qfont.h> + +extern QString _stsFile; +extern bool _isLocal; +extern bool _authorized; + +CONF_GREET_CPP_DECLS + +// this file happens to be included everywhere, so just put it here +struct dpySpec; +void decodeSess( dpySpec *sess, QString &user, QString &loc ); + +extern "C" +#endif +void init_config( void ); + +CONF_GREET_C_DECLS + +#endif /* KDMCONFIG_H */ diff --git a/kdm/kfrontend/kdmctl.c b/kdm/kfrontend/kdmctl.c new file mode 100644 index 000000000..72e133162 --- /dev/null +++ b/kdm/kfrontend/kdmctl.c @@ -0,0 +1,236 @@ +/* + +KDM remote control application + +Copyright (C) 2004 Oswald Buddenhagen <ossi@kde.org> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <sys/socket.h> +#include <sys/un.h> + +static int +openctl( int fd, int err, const char *ctl, const char *dpy ) +{ + struct sockaddr_un sa; + + sa.sun_family = AF_UNIX; + if (dpy) + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl-%s/socket", ctl, dpy ); + else + snprintf( sa.sun_path, sizeof(sa.sun_path), + "%s/dmctl/socket", ctl ); + if (!connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) + return 1; + if (err) + fprintf( stderr, "Cannot connect socket '%s'.\n", sa.sun_path ); + return 0; +} + +static const char * +readcfg( const char *cfg ) +{ + FILE *fp; + const char *ctl; + char *ptr, *ptr2; + char buf[1024]; + + if (!(fp = fopen( cfg, "r" ))) { + fprintf( stderr, + "Cannot open kdm config file '%s'.\n", + cfg ); + return 0; + } + ctl = "/var/run/xdmctl"; + while (fgets( buf, sizeof(buf), fp )) + if (!strncmp( buf, "FifoDir", 7 )) { + ptr = buf + 7; + while (*ptr && isspace( *ptr )) + ptr++; + if (*ptr++ != '=') + continue; + while (*ptr && isspace( *ptr )) + ptr++; + for (ptr2 = buf + strlen( buf ); + ptr2 > ptr && isspace( *(ptr2 - 1) ); + ptr2--); + *ptr2 = 0; + ctl = strdup( ptr ); + break; + } + fclose( fp ); + return ctl; +} + +static int +exe( int fd, const char *in, int len ) +{ + char buf[4096]; + + if (write( fd, in, len ) != len) { + fprintf( stderr, "Cannot send command\n" ); + return 1; + } + if ((len = read( fd, buf, sizeof(buf) )) <= 0) { + fprintf( stderr, "Cannot receive reply\n" ); + return 1; + } + if (len == sizeof(buf) && buf[sizeof(buf) - 1] != '\n') + fprintf( stderr, "Warning: reply is too long\n" ); + fwrite( buf, 1, len, stdout ); + if (len == sizeof(buf) && buf[sizeof(buf) - 1] != '\n') + puts( "[...]" ); + return 0; +} + +static int +run( int fd, char **argv ) +{ + unsigned len, l; + char buf[1024]; + + if (!*argv) + return exe( fd, "caps\n", 5 ); + if (!strcmp( *argv, "-" )) { + for (;;) { + if (isatty( 0 )) { + fputs( "> ", stdout ); + fflush( stdout ); + } + if (!fgets( buf, sizeof(buf), stdin )) + return 0; + if (exe( fd, buf, strlen( buf ) )) + return 1; + } + } else { + len = strlen( *argv ); + if (len >= sizeof(buf)) + goto bad; + memcpy( buf, *argv, len ); + while (*++argv) { + l = strlen( *argv ); + if (len + l + 1 >= sizeof(buf)) + goto bad; + buf[len++] = '\t'; + memcpy( buf + len, *argv, l ); + len += l; + } + buf[len++] = '\n'; + return exe( fd, buf, len ); + bad: + fprintf( stderr, "Command too long\n" ); + return 1; + } +} + +int +main( int argc, char **argv ) +{ + char *dpy = getenv( "DISPLAY" ); + const char *ctl = getenv( "DM_CONTROL" ); + const char *cfg = KDE_CONFDIR "/kdm/kdmrc"; + char *ptr; + int fd; + + (void)argc; + while (*++argv) { + ptr = *argv; + if (*ptr != '-' || !*(ptr + 1)) + break; + ptr++; + if (*ptr == '-') + ptr++; + if (!strcmp( ptr, "h" ) || !strcmp( ptr, "help" )) { + puts( +"Usage: kdmctl [options] [command [command arguments]]\n" +"\n" +"Options are:\n" +" -h -help This help message.\n" +" -g -global Use global control socket even if $DISPLAY is set\n" +" -d -display Override $DISPLAY\n" +" -s -sockets Override $DM_CONTROL\n" +" -c -config Use alternative kdm config file\n" +"\n" +"The directory in which the sockets are located is determined this way:\n" +"- the -s option is examined\n" +"- the $DM_CONTROL variable is examined\n" +"- the kdm config file is searched for the FifoDir key\n" +"- /var/run/xdmctl and /var/run are tried\n" +"\n" +"If $DISPLAY is set (or -d was specified) and -g was not specified, the\n" +"display-specific control socket will be used, otherwise the global one.\n" +"\n" +"Tokens in the command and the reply are tab-separated.\n" +"Command arguments can be specified as separate command line parameters,\n" +"in which case they are simply concatenated with tabs in between.\n" +"\n" +"If the command is '-', kdmctl reads commands from stdin.\n" +"The default command is 'caps'.\n" + ); + return 0; + } else if (!strcmp( ptr, "g" ) || !strcmp( ptr, "global" )) + dpy = 0; + else if (!strcmp( ptr, "d" ) || !strcmp( ptr, "display" )) { + if (!argv[1]) + goto needarg; + dpy = *++argv; + } else if (!strcmp( ptr, "s" ) || !strcmp( ptr, "sockets" )) { + if (!argv[1]) + goto needarg; + ctl = *++argv; + } else if (!strcmp( ptr, "c" ) || !strcmp( ptr, "config" )) { + if (!argv[1]) { + needarg: + fprintf( stderr, "Option '%s' needs argument.\n", + ptr ); + return 1; + } + cfg = *++argv; + } else { + fprintf( stderr, "Unknown option '%s'.\n", ptr ); + return 1; + } + } + if ((!ctl || !*ctl) && *cfg) + ctl = readcfg( cfg ); + if ((fd = socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) { + fprintf( stderr, "Cannot create UNIX socket\n" ); + return 1; + } + if (dpy && (ptr = strchr( dpy, ':' )) && (ptr = strchr( ptr, '.' ))) + *ptr = 0; + if (ctl && *ctl) { + if (!openctl( fd, 1, ctl, dpy )) + return 1; + } else { + if (!openctl( fd, 0, "/var/run/xdmctl", dpy ) && + !openctl( fd, 0, "/var/run", dpy )) + { + fprintf( stderr, "No command socket found.\n" ); + return 1; + } + } + return run( fd, argv ); +} diff --git a/kdm/kfrontend/kdmshutdown.cpp b/kdm/kfrontend/kdmshutdown.cpp new file mode 100644 index 000000000..dfd8558e2 --- /dev/null +++ b/kdm/kfrontend/kdmshutdown.cpp @@ -0,0 +1,714 @@ +/* + +Shutdown dialog + +Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003,2005 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kdmshutdown.h" +#include "kdm_greet.h" + +#include <kapplication.h> +#include <kseparator.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include <kprocio.h> +#include <kdialog.h> +#include <kstandarddirs.h> +#include <kuser.h> + +#include <qcombobox.h> +#include <qvbuttongroup.h> +#include <qstyle.h> +#include <qlayout.h> +#include <qaccel.h> +#include <qpopupmenu.h> +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qdatetime.h> +#include <qlistview.h> +#include <qheader.h> +#include <qdatetime.h> + +#define KDmh KDialog::marginHint() +#define KDsh KDialog::spacingHint() + +#include <stdlib.h> + +int KDMShutdownBase::curPlugin = -1; +PluginList KDMShutdownBase::pluginList; + +KDMShutdownBase::KDMShutdownBase( int _uid, QWidget *_parent ) + : inherited( _parent ) + , box( new QVBoxLayout( this, KDmh, KDsh ) ) +#ifdef HAVE_VTS + , willShut( true ) +#endif + , mayNuke( false ) + , doesNuke( false ) + , mayOk( true ) + , maySched( false ) + , rootlab( 0 ) + , verify( 0 ) + , needRoot( -1 ) + , uid( _uid ) +{ +} + +KDMShutdownBase::~KDMShutdownBase() +{ + hide(); + delete verify; +} + +void +KDMShutdownBase::complete( QWidget *prevWidget ) +{ + QSizePolicy fp( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + if (uid && + ((willShut && _allowShutdown == SHUT_ROOT) || + (mayNuke && _allowNuke == SHUT_ROOT))) + { + rootlab = new QLabel( i18n("Root authorization required."), this ); + box->addWidget( rootlab ); + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( _pluginsShutdown ); + } + verify = new KGStdVerify( this, this, + prevWidget, "root", + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Shutdown ); + verify->selectPlugin( curPlugin ); + box->addLayout( verify->getLayout() ); + QAccel *accel = new QAccel( this ); + accel->insertItem( ALT+Key_A, 0 ); + connect( accel, SIGNAL(activated( int )), SLOT(slotActivatePlugMenu()) ); + } + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + QBoxLayout *hlay = new QHBoxLayout( box, KDsh ); + hlay->addStretch( 1 ); + if (mayOk) { + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + connect( okButton, SIGNAL(clicked()), SLOT(accept()) ); + } + if (maySched) { + KPushButton *schedButton = + new KPushButton( KGuiItem( i18n("&Schedule...") ), this ); + schedButton->setSizePolicy( fp ); + hlay->addWidget( schedButton ); + hlay->addStretch( 1 ); + connect( schedButton, SIGNAL(clicked()), SLOT(slotSched()) ); + } + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + if (!mayOk) + cancelButton->setDefault( true ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) ); + + updateNeedRoot(); +} + +void +KDMShutdownBase::slotActivatePlugMenu() +{ + if (needRoot) { + QPopupMenu *cmnu = verify->getPlugMenu(); + if (!cmnu) + return; + QSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - QPoint( sh.width(), sh.height() ) ); + } +} + +void +KDMShutdownBase::accept() +{ + if (needRoot == 1) + verify->accept(); + else + accepted(); +} + +void +KDMShutdownBase::slotSched() +{ + done( Schedule ); +} + +void +KDMShutdownBase::updateNeedRoot() +{ + int nNeedRoot = uid && + (((willShut && _allowShutdown == SHUT_ROOT) || + (_allowNuke == SHUT_ROOT && doesNuke))); + if (verify && nNeedRoot != needRoot) { + if (needRoot == 1) + verify->abort(); + needRoot = nNeedRoot; + rootlab->setEnabled( needRoot ); + verify->setEnabled( needRoot ); + if (needRoot) + verify->start(); + } +} + +void +KDMShutdownBase::accepted() +{ + inherited::done( needRoot ? (int)Authed : (int)Accepted ); +} + +void +KDMShutdownBase::verifyPluginChanged( int id ) +{ + curPlugin = id; + adjustSize(); +} + +void +KDMShutdownBase::verifyOk() +{ + accepted(); +} + +void +KDMShutdownBase::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +KDMShutdownBase::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +KDMShutdownBase::verifySetUser( const QString & ) +{ +} + + +static void +doShutdown( int type, const char *os ) +{ + GSet( 1 ); + GSendInt( G_Shutdown ); + GSendInt( type ); + GSendInt( 0 ); + GSendInt( 0 ); + GSendInt( SHUT_FORCE ); + GSendInt( 0 ); /* irrelevant, will timeout immediately anyway */ + GSendStr( os ); + GSet( 0 ); +} + + + +KDMShutdown::KDMShutdown( int _uid, QWidget *_parent ) + : inherited( _uid, _parent ) +{ + QSizePolicy fp( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + QHBoxLayout *hlay = new QHBoxLayout( box, KDsh ); + + howGroup = new QVButtonGroup( i18n("Shutdown Type"), this ); + hlay->addWidget( howGroup, 0, AlignTop ); + + QRadioButton *rb; + rb = new KDMRadioButton( i18n("&Turn off computer"), howGroup ); + rb->setChecked( true ); + rb->setFocus(); + + restart_rb = new KDMRadioButton( i18n("&Restart computer"), howGroup ); + + connect( rb, SIGNAL(doubleClicked()), SLOT(accept()) ); + connect( restart_rb, SIGNAL(doubleClicked()), SLOT(accept()) ); + + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { /* XXX show dialog on failure */ + char **tlist = GRecvStrArr( 0 ); + int defaultTarget = GRecvInt(); + oldTarget = GRecvInt(); + QWidget *hlp = new QWidget( howGroup ); + targets = new QComboBox( hlp ); + for (int i = 0; tlist[i]; i++) + targets->insertItem( QString::fromLocal8Bit( tlist[i] ) ); + freeStrArr( tlist ); + targets->setCurrentItem( oldTarget == -1 ? defaultTarget : oldTarget ); + QHBoxLayout *hb = new QHBoxLayout( hlp, 0, KDsh ); + int spc = kapp->style().pixelMetric( QStyle::PM_ExclusiveIndicatorWidth ) + + howGroup->insideSpacing(); + hb->addSpacing( spc ); + hb->addWidget( targets ); + connect( targets, SIGNAL(activated( int )), SLOT(slotTargetChanged()) ); + } + GSet( 0 ); + + howGroup->setSizePolicy( fp ); + + schedGroup = new QGroupBox( i18n("Scheduling"), this ); + hlay->addWidget( schedGroup, 0, AlignTop ); + + le_start = new QLineEdit( schedGroup ); + QLabel *lab1 = new QLabel( le_start, i18n("&Start:"), schedGroup ); + + le_timeout = new QLineEdit( schedGroup ); + QLabel *lab2 = new QLabel( le_timeout, i18n("T&imeout:"), schedGroup ); + + cb_force = new QCheckBox( i18n("&Force after timeout"), schedGroup ); + if (_allowNuke != SHUT_NONE) { + connect( cb_force, SIGNAL(clicked()), SLOT(slotWhenChanged()) ); + mayNuke = true; + } else + cb_force->setEnabled( false ); + + QGridLayout *grid = new QGridLayout( schedGroup, 0, 0, KDmh, KDsh ); + grid->addRowSpacing( 0, schedGroup->fontMetrics().height() - 5 ); + grid->addWidget( lab1, 1, 0, AlignRight ); + grid->addWidget( le_start, 1, 1 ); + grid->addWidget( lab2, 2, 0, AlignRight ); + grid->addWidget( le_timeout, 2, 1 ); + grid->addMultiCellWidget( cb_force, 3,3, 0,1 ); + + schedGroup->setSizePolicy( fp ); + + le_start->setText( "0" ); + if (_defSdMode == SHUT_SCHEDULE) + le_timeout->setText( "-1" ); + else { + le_timeout->setText( "0" ); + if (_defSdMode == SHUT_FORCENOW && cb_force->isEnabled()) + cb_force->setChecked( true ); + } + + complete( schedGroup ); +} + +static int +get_date( const char *str ) +{ + KProcIO prc; + prc << "/bin/date" << "+%s" << "-d" << str; + prc.start( KProcess::Block, false ); + QString dstr; + if (prc.readln( dstr, false, 0 ) < 0) + return -1; + return dstr.toInt(); +} + +void +KDMShutdown::accept() +{ + if (le_start->text() == "0" || le_start->text() == "now") + sch_st = time( 0 ); + else if (le_start->text()[0] == '+') + sch_st = time( 0 ) + le_start->text().toInt(); + else if ((sch_st = get_date( le_start->text().latin1() )) < 0) { + MsgBox( errorbox, i18n("Entered start date is invalid.") ); + le_start->setFocus(); + return; + } + if (le_timeout->text() == "-1" || le_timeout->text().startsWith( "inf" )) + sch_to = TO_INF; + else if (le_timeout->text()[0] == '+') + sch_to = sch_st + le_timeout->text().toInt(); + else if ((sch_to = get_date( le_timeout->text().latin1() )) < 0) { + MsgBox( errorbox, i18n("Entered timeout date is invalid.") ); + le_timeout->setFocus(); + return; + } + + inherited::accept(); +} + +void +KDMShutdown::slotTargetChanged() +{ + restart_rb->setChecked( true ); +} + +void +KDMShutdown::slotWhenChanged() +{ + doesNuke = cb_force->isChecked(); + updateNeedRoot(); +} + +void +KDMShutdown::accepted() +{ + GSet( 1 ); + GSendInt( G_Shutdown ); + GSendInt( restart_rb->isChecked() ? SHUT_REBOOT : SHUT_HALT ); + GSendInt( sch_st ); + GSendInt( sch_to ); + GSendInt( cb_force->isChecked() ? SHUT_FORCE : SHUT_CANCEL ); + GSendInt( _allowShutdown == SHUT_ROOT ? 0 : -2 ); + GSendStr( (restart_rb->isChecked() && + targets && targets->currentItem() != oldTarget) ? + targets->currentText().local8Bit().data() : 0 ); + GSet( 0 ); + inherited::accepted(); +} + +void +KDMShutdown::scheduleShutdown( QWidget *_parent ) +{ + GSet( 1 ); + GSendInt( G_QueryShutdown ); + int how = GRecvInt(); + int start = GRecvInt(); + int timeout = GRecvInt(); + int force = GRecvInt(); + int uid = GRecvInt(); + char *os = GRecvStr(); + GSet( 0 ); + if (how) { + int ret = + KDMCancelShutdown( how, start, timeout, force, uid, os, + _parent ).exec(); + if (!ret) + return; + doShutdown( 0, 0 ); + uid = ret == Authed ? 0 : -1; + } else + uid = -1; + if (os) + free( os ); + KDMShutdown( uid, _parent ).exec(); +} + + +KDMRadioButton::KDMRadioButton( const QString &label, QWidget *parent ) + : inherited( label, parent ) +{ +} + +void +KDMRadioButton::mouseDoubleClickEvent( QMouseEvent * ) +{ + emit doubleClicked(); +} + + +KDMDelayedPushButton::KDMDelayedPushButton( const KGuiItem &item, + QWidget *parent, + const char *name ) + : inherited( item, parent, name ) + , pop( 0 ) +{ + connect( this, SIGNAL(pressed()), SLOT(slotPressed()) ); + connect( this, SIGNAL(released()), SLOT(slotReleased()) ); + connect( &popt, SIGNAL(timeout()), SLOT(slotTimeout()) ); +} + +void KDMDelayedPushButton::setPopup( QPopupMenu *p ) +{ + pop = p; + setIsMenuButton( p != 0 ); +} + +void KDMDelayedPushButton::slotPressed() +{ + if (pop) + popt.start( QApplication::startDragTime() ); +} + +void KDMDelayedPushButton::slotReleased() +{ + popt.stop(); +} + +void KDMDelayedPushButton::slotTimeout() +{ + popt.stop(); + pop->popup( mapToGlobal( rect().bottomLeft() ) ); + setDown( false ); +} + + +KDMSlimShutdown::KDMSlimShutdown( QWidget *_parent ) + : inherited( _parent ) + , targetList( 0 ) +{ + QHBoxLayout *hbox = new QHBoxLayout( this, KDmh, KDsh ); + + QFrame *lfrm = new QFrame( this ); + lfrm->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + hbox->addWidget( lfrm, AlignCenter ); + QLabel *icon = new QLabel( lfrm ); + icon->setPixmap( QPixmap( locate( "data", "kdm/pics/shutdown.jpg" ) ) ); + QVBoxLayout *iconlay = new QVBoxLayout( lfrm ); + iconlay->addWidget( icon ); + + QVBoxLayout *buttonlay = new QVBoxLayout( hbox, KDsh ); + + buttonlay->addStretch( 1 ); + + KPushButton *btnHalt = new + KPushButton( KGuiItem( i18n("&Turn Off Computer"), "exit" ), this ); + buttonlay->addWidget( btnHalt ); + connect( btnHalt, SIGNAL(clicked()), SLOT(slotHalt()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); + + KDMDelayedPushButton *btnReboot = new + KDMDelayedPushButton( KGuiItem( i18n("&Restart Computer"), "reload" ), this ); + buttonlay->addWidget( btnReboot ); + connect( btnReboot, SIGNAL(clicked()), SLOT(slotReboot()) ); + + GSet( 1 ); + GSendInt( G_ListBootOpts ); + if (GRecvInt() == BO_OK) { + targetList = GRecvStrArr( 0 ); + /*int def =*/ GRecvInt(); + int cur = GRecvInt(); + QPopupMenu *targets = new QPopupMenu( this ); + for (int i = 0; targetList[i]; i++) { + QString t( QString::fromLocal8Bit( targetList[i] ) ); + targets->insertItem( i == cur ? + i18n("current option in boot loader", + "%1 (current)").arg( t ) : + t, i ); + } + btnReboot->setPopup( targets ); + connect( targets, SIGNAL(activated(int)), SLOT(slotReboot(int)) ); + } + GSet( 0 ); + + buttonlay->addStretch( 1 ); + + if (_scheduledSd != SHUT_NEVER) { + KPushButton *btnSched = new + KPushButton( KGuiItem( i18n("&Schedule...") ), this ); + buttonlay->addWidget( btnSched ); + connect( btnSched, SIGNAL(clicked()), SLOT(slotSched()) ); + + buttonlay->addStretch( 1 ); + } + + buttonlay->addWidget( new KSeparator( this ) ); + + buttonlay->addSpacing( 0 ); + + KPushButton *btnBack = new KPushButton( KStdGuiItem::cancel(), this ); + buttonlay->addWidget( btnBack ); + connect( btnBack, SIGNAL(clicked()), SLOT(reject()) ); + + buttonlay->addSpacing( KDialog::spacingHint() ); +} + +KDMSlimShutdown::~KDMSlimShutdown() +{ + freeStrArr( targetList ); +} + +void +KDMSlimShutdown::slotSched() +{ + reject(); + KDMShutdown::scheduleShutdown(); +} + +void +KDMSlimShutdown::slotHalt() +{ + if (checkShutdown( SHUT_HALT, 0 )) + doShutdown( SHUT_HALT, 0 ); +} + +void +KDMSlimShutdown::slotReboot() +{ + if (checkShutdown( SHUT_REBOOT, 0 )) + doShutdown( SHUT_REBOOT, 0 ); +} + +void +KDMSlimShutdown::slotReboot( int opt ) +{ + if (checkShutdown( SHUT_REBOOT, targetList[opt] )) + doShutdown( SHUT_REBOOT, targetList[opt] ); +} + +bool +KDMSlimShutdown::checkShutdown( int type, const char *os ) +{ + reject(); + dpySpec *sess = fetchSessions( lstRemote | lstTTY ); + if (!sess && _allowShutdown != SHUT_ROOT) + return true; + int ret = KDMConfShutdown( -1, sess, type, os ).exec(); + disposeSessions( sess ); + if (ret == Schedule) { + KDMShutdown::scheduleShutdown(); + return false; + } + return ret; +} + +void +KDMSlimShutdown::externShutdown( int type, const char *os, int uid ) +{ + dpySpec *sess = fetchSessions( lstRemote | lstTTY ); + int ret = KDMConfShutdown( uid, sess, type, os ).exec(); + disposeSessions( sess ); + if (ret == Schedule) + KDMShutdown( uid ).exec(); + else if (ret) + doShutdown( type, os ); +} + + +KDMConfShutdown::KDMConfShutdown( int _uid, dpySpec *sess, int type, const char *os, + QWidget *_parent ) + : inherited( _uid, _parent ) +{ +#ifdef HAVE_VTS + if (type == SHUT_CONSOLE) + willShut = false; +#endif + box->addWidget( new QLabel( QString( "<qt><center><b><nobr>" + "%1%2" + "</nobr></b></center><br></qt>" ) + .arg( (type == SHUT_HALT) ? + i18n("Turn Off Computer") : +#ifdef HAVE_VTS + (type == SHUT_CONSOLE) ? + i18n("Switch to Console") : +#endif + i18n("Restart Computer") ) + .arg( os ? + i18n("<br>(Next boot: %1)") + .arg( QString::fromLocal8Bit( os ) ) : + QString::null ), + this ) ); + + if (sess) { + if (willShut && _scheduledSd != SHUT_NEVER) + maySched = true; + mayNuke = doesNuke = true; + if (_allowNuke == SHUT_NONE) + mayOk = false; + QLabel *lab = new QLabel( mayOk ? + i18n("Abort active sessions:") : + i18n("No permission to abort active sessions:"), + this ); + box->addWidget( lab ); + QListView *lv = new QListView( this ); + lv->setSelectionMode( QListView::NoSelection ); + lv->setAllColumnsShowFocus( true ); + lv->header()->setResizeEnabled( false ); + lv->addColumn( i18n("Session") ); + lv->addColumn( i18n("Location") ); + QListViewItem *itm; + int ns = 0; + QString user, loc; + do { + decodeSess( sess, user, loc ); + itm = new QListViewItem( lv, user, loc ); + sess = sess->next, ns++; + } while (sess); + int fw = lv->frameWidth() * 2; + lv->setFixedHeight( fw + lv->header()->height() + + itm->height() * (ns < 3 ? 3 : ns > 10 ? 10 : ns) ); + box->addWidget( lv ); + complete( lv ); + } else + complete( 0 ); +} + + +KDMCancelShutdown::KDMCancelShutdown( int how, int start, int timeout, + int force, int uid, const char *os, + QWidget *_parent ) + : inherited( -1, _parent ) +{ + if (force == SHUT_FORCE) { + if (_allowNuke == SHUT_NONE) + mayOk = false; + else if (_allowNuke == SHUT_ROOT) + mayNuke = doesNuke = true; + } + QLabel *lab = new QLabel( mayOk ? + i18n("Abort pending shutdown:") : + i18n("No permission to abort pending shutdown:"), + this ); + box->addWidget( lab ); + QDateTime qdt; + QString strt, end; + if (start < time( 0 )) + strt = i18n("now"); + else { + qdt.setTime_t( start ); + strt = qdt.toString( LocalDate ); + } + if (timeout == TO_INF) + end = i18n("infinite"); + else { + qdt.setTime_t( timeout ); + end = qdt.toString( LocalDate ); + } + QString trg = + i18n("Owner: %1" + "\nType: %2%5" + "\nStart: %3" + "\nTimeout: %4") + .arg( uid == -2 ? + i18n("console user") : + uid == -1 ? + i18n("control socket") : + KUser( uid ).loginName() ) + .arg( how == SHUT_HALT ? + i18n("turn off computer") : + i18n("restart computer") ) + .arg( strt ).arg( end ) + .arg( os ? + i18n("\nNext boot: %1").arg( QString::fromLocal8Bit( os ) ) : + QString::null ); + if (timeout != TO_INF) + trg += i18n("\nAfter timeout: %1") + .arg( force == SHUT_FORCE ? + i18n("abort all sessions") : + force == SHUT_FORCEMY ? + i18n("abort own sessions") : + i18n("cancel shutdown") ); + lab = new QLabel( trg, this ); + box->addWidget( lab ); + complete( 0 ); +} + +#include "kdmshutdown.moc" diff --git a/kdm/kfrontend/kdmshutdown.h b/kdm/kfrontend/kdmshutdown.h new file mode 100644 index 000000000..9020b1513 --- /dev/null +++ b/kdm/kfrontend/kdmshutdown.h @@ -0,0 +1,196 @@ +/* + +Shutdown dialog + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003,2005 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KDMSHUTDOWN_H +#define KDMSHUTDOWN_H + +#include "kdmconfig.h" // for HAVE_VTS +#include "kgverify.h" + +#include <kpushbutton.h> + +#include <qradiobutton.h> + +class QLabel; +class KPushButton; +class QButtonGroup; +class QGroupBox; +class QComboBox; +class QCheckBox; +class QLineEdit; + +enum { Authed = QDialog::Accepted + 1, Schedule }; + +class KDMShutdownBase : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + + public: + KDMShutdownBase( int _uid, QWidget *_parent ); + virtual ~KDMShutdownBase(); + + protected slots: + virtual void accept(); + + protected: + virtual void accepted(); + + protected: + void updateNeedRoot(); + void complete( QWidget *prevWidget ); + + QVBoxLayout *box; +#ifdef HAVE_VTS + bool willShut; +#else + static const bool willShut = true; +#endif + bool mayNuke, doesNuke, mayOk, maySched; + + private slots: + void slotSched(); + void slotActivatePlugMenu(); + + private: + KPushButton *okButton, *cancelButton; + QLabel *rootlab; + KGStdVerify *verify; + int needRoot, uid; + + static int curPlugin; + static PluginList pluginList; + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const QString &user ); +}; + + +class KDMShutdown : public KDMShutdownBase { + Q_OBJECT + typedef KDMShutdownBase inherited; + + public: + KDMShutdown( int _uid, QWidget *_parent = 0 ); + static void scheduleShutdown( QWidget *_parent = 0 ); + + protected slots: + virtual void accept(); + + protected: + virtual void accepted(); + + private slots: + void slotTargetChanged(); + void slotWhenChanged(); + + private: + QButtonGroup *howGroup; + QGroupBox *schedGroup; + QRadioButton *restart_rb; + QLineEdit *le_start, *le_timeout; + QCheckBox *cb_force; + QComboBox *targets; + int oldTarget; + int sch_st, sch_to; + +}; + +class KDMRadioButton : public QRadioButton { + Q_OBJECT + typedef QRadioButton inherited; + + public: + KDMRadioButton( const QString &label, QWidget *parent ); + + private: + virtual void mouseDoubleClickEvent( QMouseEvent * ); + + signals: + void doubleClicked(); + +}; + +class KDMDelayedPushButton : public KPushButton { + Q_OBJECT + typedef KPushButton inherited; + + public: + KDMDelayedPushButton( const KGuiItem &item, QWidget *parent, const char *name = 0 ); + void setPopup( QPopupMenu *pop ); + + private slots: + void slotTimeout(); + void slotPressed(); + void slotReleased(); + + private: + QPopupMenu *pop; + QTimer popt; +}; + +class KDMSlimShutdown : public FDialog { + Q_OBJECT + typedef FDialog inherited; + + public: + KDMSlimShutdown( QWidget *_parent = 0 ); + ~KDMSlimShutdown(); + static void externShutdown( int type, const char *os, int uid ); + + private slots: + void slotHalt(); + void slotReboot(); + void slotReboot( int ); + void slotSched(); + + private: + bool checkShutdown( int type, const char *os ); + char **targetList; + +}; + +class KDMConfShutdown : public KDMShutdownBase { + Q_OBJECT + typedef KDMShutdownBase inherited; + + public: + KDMConfShutdown( int _uid, struct dpySpec *sess, int type, const char *os, + QWidget *_parent = 0 ); +}; + +class KDMCancelShutdown : public KDMShutdownBase { + Q_OBJECT + typedef KDMShutdownBase inherited; + + public: + KDMCancelShutdown( int how, int start, int timeout, int force, int uid, + const char *os, QWidget *_parent ); +}; + +#endif /* KDMSHUTDOWN_H */ diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp new file mode 100644 index 000000000..e3bb9d9c8 --- /dev/null +++ b/kdm/kfrontend/kfdialog.cpp @@ -0,0 +1,149 @@ +/* + +Dialog class that handles input focus in absence of a wm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kfdialog.h" +#include "kdmconfig.h" + +#include <klocale.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include <qlabel.h> +#include <qlayout.h> +#include <qapplication.h> +#include <qcursor.h> + +FDialog::FDialog( QWidget *parent, bool framed ) + : inherited( parent, 0, true/*, framed ? 0 : WStyle_NoBorder*/ ) +{ + if (framed) { + winFrame = new QFrame( this, 0, WNoAutoErase ); + winFrame->setFrameStyle( QFrame::WinPanel | QFrame::Raised ); + winFrame->setLineWidth( 2 ); + } else + winFrame = 0; +} + +void +FDialog::resizeEvent( QResizeEvent *e ) +{ + inherited::resizeEvent( e ); + if (winFrame) { + winFrame->resize( size() ); + winFrame->erase(); + } +} + +void +FDialog::adjustGeometry() +{ + QDesktopWidget *dsk = qApp->desktop(); + + if (_greeterScreen < 0) + _greeterScreen = _greeterScreen == -2 ? + dsk->screenNumber( QPoint( dsk->width() - 1, 0 ) ) : + dsk->screenNumber( QPoint( 0, 0 ) ); + + QRect scr = dsk->screenGeometry( _greeterScreen ); + if (!winFrame) + setFixedSize( scr.size() ); + else { + setMaximumSize( scr.size() * .9 ); + adjustSize(); + } + + if (parentWidget()) + return; + + QRect grt( rect() ); + if (winFrame) { + unsigned x = 50, y = 50; + sscanf( _greeterPos, "%u,%u", &x, &y ); + grt.moveCenter( QPoint( scr.x() + scr.width() * x / 100, + scr.y() + scr.height() * y / 100 ) ); + int di; + if ((di = scr.right() - grt.right()) < 0) + grt.moveBy( di, 0 ); + if ((di = scr.left() - grt.left()) > 0) + grt.moveBy( di, 0 ); + if ((di = scr.bottom() - grt.bottom()) < 0) + grt.moveBy( 0, di ); + if ((di = scr.top() - grt.top()) > 0) + grt.moveBy( 0, di ); + setGeometry( grt ); + } + + if (dsk->screenNumber( QCursor::pos() ) != _greeterScreen) + QCursor::setPos( grt.center() ); +} + +struct WinList { + struct WinList *next; + QWidget *win; +}; + +int +FDialog::exec() +{ + static WinList *wins; + WinList *win; + + win = new WinList; + win->win = this; + win->next = wins; + wins = win; + show(); + setActiveWindow(); + inherited::exec(); + hide(); + wins = win->next; + delete win; + if (wins) + wins->win->setActiveWindow(); + return result(); +} + +void +FDialog::box( QWidget *parent, QMessageBox::Icon type, const QString &text ) +{ + KFMsgBox dlg( parent, type, text.stripWhiteSpace() ); + dlg.exec(); +} + +KFMsgBox::KFMsgBox( QWidget *parent, QMessageBox::Icon type, const QString &text ) + : inherited( parent ) +{ + QLabel *label1 = new QLabel( this ); + label1->setPixmap( QMessageBox::standardIcon( type ) ); + QLabel *label2 = new QLabel( text, this ); + KPushButton *button = new KPushButton( KStdGuiItem::ok(), this ); + button->setDefault( true ); + button->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); + connect( button, SIGNAL(clicked()), SLOT(accept()) ); + + QGridLayout *grid = new QGridLayout( this, 2, 2, 10 ); + grid->addWidget( label1, 0, 0, Qt::AlignCenter ); + grid->addWidget( label2, 0, 1, Qt::AlignCenter ); + grid->addMultiCellWidget( button, 1,1, 0,1, Qt::AlignCenter ); +} diff --git a/kdm/kfrontend/kfdialog.h b/kdm/kfrontend/kfdialog.h new file mode 100644 index 000000000..7ab456f22 --- /dev/null +++ b/kdm/kfrontend/kfdialog.h @@ -0,0 +1,63 @@ +/* + +Dialog class that handles input focus in absence of a wm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef FDIALOG_H +#define FDIALOG_H + +#include <qdialog.h> +#include <qmessagebox.h> + +class QFrame; + +class FDialog : public QDialog { + typedef QDialog inherited; + + public: + FDialog( QWidget *parent = 0, bool framed = true ); + virtual int exec(); + + static void box( QWidget *parent, QMessageBox::Icon type, + const QString &text ); +#define errorbox QMessageBox::Critical +#define sorrybox QMessageBox::Warning +#define infobox QMessageBox::Information + void MsgBox( QMessageBox::Icon typ, const QString &msg ) { box( this, typ, msg ); } + + protected: + virtual void resizeEvent( QResizeEvent *e ); + void adjustGeometry(); + + private: + QFrame *winFrame; +}; + +class KFMsgBox : public FDialog { + typedef FDialog inherited; + + public: + KFMsgBox( QWidget *parent, QMessageBox::Icon type, const QString &text ); +}; + +#endif /* FDIALOG_H */ diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp new file mode 100644 index 000000000..711853c37 --- /dev/null +++ b/kdm/kfrontend/kgapp.cpp @@ -0,0 +1,253 @@ +/* + +Greeter module for xdm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kdm_greet.h" +#include "kdmshutdown.h" +#include "kdmconfig.h" +#include "kgapp.h" +#include "kgreeter.h" +#ifdef XDMCP +# include "kchooser.h" +#endif + +#include <kprocess.h> +#include <kcmdlineargs.h> +#include <kcrash.h> +#include <kstandarddirs.h> +#include <ksimpleconfig.h> + +#include <qtimer.h> +#include <qcursor.h> +#include <qpalette.h> + +#include <stdlib.h> // free(), exit() +#include <unistd.h> // alarm() + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <X11/cursorfont.h> + +extern "C" { + +static void +sigAlarm( int ) +{ + exit( EX_RESERVER_DPY ); +} + +} + +GreeterApp::GreeterApp() +{ + pingInterval = _isLocal ? 0 : _pingInterval; + if (pingInterval) { + struct sigaction sa; + sigemptyset( &sa.sa_mask ); + sa.sa_flags = 0; + sa.sa_handler = sigAlarm; + sigaction( SIGALRM, &sa, 0 ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time + startTimer( pingInterval * 60000 ); + } +} + +void +GreeterApp::timerEvent( QTimerEvent * ) +{ + alarm( 0 ); + if (!PingServer( qt_xdisplay() )) + ::exit( EX_RESERVER_DPY ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time +} + +bool +GreeterApp::x11EventFilter( XEvent * ev ) +{ + KeySym sym; + + switch (ev->type) { + case FocusIn: + case FocusOut: + // Hack to tell dialogs to take focus when the keyboard is grabbed + ev->xfocus.mode = NotifyNormal; + break; + case KeyPress: + sym = XLookupKeysym( &ev->xkey, 0 ); + if (sym != XK_Return && !IsModifierKey( sym )) + emit activity(); + break; + case ButtonPress: + emit activity(); + /* fall through */ + case ButtonRelease: + // Hack to let the RMB work as LMB + if (ev->xbutton.button == 3) + ev->xbutton.button = 1; + /* fall through */ + case MotionNotify: + if (ev->xbutton.state & Button3Mask) + ev->xbutton.state = (ev->xbutton.state & ~Button3Mask) | Button1Mask; + break; + } + return false; +} + +extern bool kde_have_kipc; + +extern "C" { + +static int +xIOErr( Display * ) +{ + exit( EX_RESERVER_DPY ); +} + +void +kg_main( const char *argv0 ) +{ + static char *argv[] = { (char *)"kdmgreet", 0 }; + KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true ); + + kde_have_kipc = false; + KApplication::disableAutoDcopRegistration(); + KCrash::setSafer( true ); + GreeterApp app; + XSetIOErrorHandler( xIOErr ); + + Display *dpy = qt_xdisplay(); + + if (!_GUIStyle.isEmpty()) + app.setStyle( _GUIStyle ); + + _colorScheme = locate( "data", "kdisplay/color-schemes/" + _colorScheme + ".kcsrc" ); + if (!_colorScheme.isEmpty()) { + KSimpleConfig config( _colorScheme, true ); + config.setGroup( "Color Scheme" ); + app.setPalette( app.createApplicationPalette( &config, 7 ) ); + } + + app.setFont( _normalFont ); + + setup_modifiers( dpy, _numLockStatus ); + SecureDisplay( dpy ); + KProcess *proc = 0; + if (!_grabServer) { + if (_useBackground) { + proc = new KProcess; + *proc << QCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "krootimage"; + *proc << _backgroundCfg; + proc->start(); + } + GSendInt( G_SetupDpy ); + GRecvInt(); + } + + GSendInt( G_Ready ); + + setCursor( dpy, app.desktop()->winId(), XC_left_ptr ); + + for (;;) { + int rslt, cmd = GRecvInt(); + + if (cmd == G_ConfShutdown) { + int how = GRecvInt(), uid = GRecvInt(); + char *os = GRecvStr(); + KDMSlimShutdown::externShutdown( how, os, uid ); + if (os) + free( os ); + GSendInt( G_Ready ); + _autoLoginDelay = 0; + continue; + } + + if (cmd == G_ErrorGreet) { + if (KGVerify::handleFailVerify( qApp->desktop()->screen( _greeterScreen ) )) + break; + _autoLoginDelay = 0; + cmd = G_Greet; + } + + KProcess *proc2 = 0; + app.setOverrideCursor( Qt::WaitCursor ); + FDialog *dialog; +#ifdef XDMCP + if (cmd == G_Choose) { + dialog = new ChooserDlg; + GSendInt( G_Ready ); /* tell chooser to go into async mode */ + GRecvInt(); /* ack */ + } else +#endif + { + if ((cmd != G_GreetTimed && !_autoLoginAgain) || + _autoLoginUser.isEmpty()) + _autoLoginDelay = 0; + if (_useTheme && !_theme.isEmpty()) { + KThemedGreeter *tgrt; + dialog = tgrt = new KThemedGreeter; + if (!tgrt->isOK()) { + delete tgrt; + dialog = new KStdGreeter; + } + } else + dialog = new KStdGreeter; + if (*_preloader) { + proc2 = new KProcess; + *proc2 << _preloader; + proc2->start(); + } + } + app.restoreOverrideCursor(); + Debug( "entering event loop\n" ); + rslt = dialog->exec(); + Debug( "left event loop\n" ); + delete dialog; + delete proc2; +#ifdef XDMCP + switch (rslt) { + case ex_greet: + GSendInt( G_DGreet ); + continue; + case ex_choose: + GSendInt( G_DChoose ); + continue; + default: + break; + } +#endif + break; + } + + KGVerify::done(); + + delete proc; + UnsecureDisplay( dpy ); + restore_modifiers(); + + XSetInputFocus( qt_xdisplay(), PointerRoot, PointerRoot, CurrentTime ); +} + +} // extern "C" + +#include "kgapp.moc" diff --git a/kdm/kfrontend/kgapp.h b/kdm/kfrontend/kgapp.h new file mode 100644 index 000000000..9174cd5c8 --- /dev/null +++ b/kdm/kfrontend/kgapp.h @@ -0,0 +1,49 @@ +/* + +Greeter module for xdm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KGAPP_H +#define KGAPP_H + +#include <kapplication.h> + +class GreeterApp : public KApplication { + Q_OBJECT + typedef KApplication inherited; + + public: + GreeterApp(); + virtual bool x11EventFilter( XEvent * ); + + protected: + virtual void timerEvent( QTimerEvent * ); + + signals: + void activity(); + + private: + int pingInterval; +}; + +#endif /* KGAPP_H */ diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp new file mode 100644 index 000000000..636b20dec --- /dev/null +++ b/kdm/kfrontend/kgdialog.cpp @@ -0,0 +1,238 @@ +/* + +Base class for various kdm greeter dialogs + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kgdialog.h" +#include "kgverify.h" +#include "kconsole.h" +#include "kdmshutdown.h" +#include "kdm_greet.h" + +#include <klocale.h> + +#include <qaccel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qpopupmenu.h> +#include <qapplication.h> + +#include <stdlib.h> + +KGDialog::KGDialog( bool themed ) : inherited( 0, !themed ) +{ +#ifdef WITH_KDM_XCONSOLE + consoleView = _showLog ? new KConsole( this ) : 0; +#endif + + optMenu = 0; + verify = 0; +} + +void +#ifdef XDMCP +KGDialog::completeMenu( int _switchIf, int _switchCode, const QString &_switchMsg, int _switchAccel ) +#else +KGDialog::completeMenu() +#endif +{ +#ifdef HAVE_VTS + if (_isLocal) { + dpyMenu = new QPopupMenu( this ); + int id = inserten( i18n("Sw&itch User"), ALT+Key_I, dpyMenu ); + connect( dpyMenu, SIGNAL(activated( int )), + SLOT(slotDisplaySelected( int )) ); + connect( dpyMenu, SIGNAL(aboutToShow()), + SLOT(slotPopulateDisplays()) ); + QAccel *accel = new QAccel( this ); + accel->insertItem( ALT+CTRL+Key_Insert, id ); + connect( accel, SIGNAL(activated( int )), SLOT(slotActivateMenu( int )) ); + } +#endif + + if (_allowClose) + inserten( _isLocal ? i18n("R&estart X Server") : i18n("Clos&e Connection"), + ALT+Key_E, SLOT(slotExit()) ); + +#ifdef XDMCP + if (_isLocal && _loginMode != _switchIf) { + switchCode = _switchCode; + inserten( _switchMsg, _switchAccel, SLOT(slotSwitch()) ); + } +#endif + + if (_hasConsole) + inserten( i18n("Co&nsole Login"), ALT+Key_N, SLOT(slotConsole()) ); + + if (_allowShutdown != SHUT_NONE) { + inserten( i18n("&Shutdown..."), ALT+Key_S, SLOT(slotShutdown( int )) ); + QAccel *accel = new QAccel( this ); + accel->insertItem( ALT+CTRL+Key_Delete ); + connect( accel, SIGNAL(activated( int )), SLOT(slotShutdown( int )) ); + accel = new QAccel( this ); + accel->insertItem( SHIFT+ALT+CTRL+Key_PageUp, SHUT_REBOOT ); + connect( accel, SIGNAL(activated( int )), SLOT(slotShutdown( int )) ); + accel = new QAccel( this ); + accel->insertItem( SHIFT+ALT+CTRL+Key_PageDown, SHUT_HALT ); + connect( accel, SIGNAL(activated( int )), SLOT(slotShutdown( int )) ); + } +} + +void +KGDialog::ensureMenu() +{ + if (!optMenu) { + optMenu = new QPopupMenu( this ); + optMenu->setCheckable( false ); + needSep = false; + } else if (needSep) { + optMenu->insertSeparator(); + needSep = false; + } +} + +void +KGDialog::inserten( const QString& txt, int accel, const char *member ) +{ + ensureMenu(); + optMenu->insertItem( txt, this, member, accel ); +} + +int +KGDialog::inserten( const QString& txt, int accel, QPopupMenu *cmnu ) +{ + ensureMenu(); + int id = optMenu->insertItem( txt, cmnu ); + optMenu->setAccel( accel, id ); + optMenu->connectItem( id, this, SLOT(slotActivateMenu( int )) ); + optMenu->setItemParameter( id, id ); + return id; +} + +void +KGDialog::slotActivateMenu( int id ) +{ + QPopupMenu *cmnu = optMenu->findItem( id )->popup(); + QSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - QPoint( sh.width(), sh.height() ) ); +} + +void +KGDialog::slotExit() +{ + if (verify) + verify->abort(); + ::exit( EX_RESERVER_DPY ); +} + +void +KGDialog::slotSwitch() +{ +#ifdef XDMCP + // workaround for Qt bug + QTimer::singleShot( 0, this, SLOT(slotReallySwitch()) ); +#endif +} + +void +KGDialog::slotReallySwitch() +{ +#ifdef XDMCP + done( switchCode ); +#endif +} + +void +KGDialog::slotConsole() +{ +#ifdef HAVE_VTS + dpySpec *sess = fetchSessions( 0 ); + if (sess) { + if (verify) + verify->suspend(); + int ret = KDMConfShutdown( -1, sess, SHUT_CONSOLE, 0 ).exec(); + if (verify) + verify->resume(); + disposeSessions( sess ); + if (!ret) + return; + } +#else + if (verify) + verify->abort(); +#endif + GSet( 1 ); + GSendInt( G_Console ); + GSet( 0 ); +} + +void +KGDialog::slotShutdown( int id ) +{ + if (verify) + verify->suspend(); + if (id < 0) { + if (_scheduledSd == SHUT_ALWAYS) + KDMShutdown::scheduleShutdown( this ); + else + KDMSlimShutdown( this ).exec(); + } else + KDMSlimShutdown::externShutdown( id, 0, -1 ); + if (verify) + verify->resume(); +} + +void +KGDialog::slotDisplaySelected( int vt ) +{ +#ifdef HAVE_VTS + GSet( 1 ); + GSendInt( G_Activate ); + GSendInt( vt ); + GSet( 0 ); +#else + (void)vt; +#endif +} + +void +KGDialog::slotPopulateDisplays() +{ +#ifdef HAVE_VTS + dpyMenu->clear(); + dpySpec *sessions = fetchSessions( lstPassive | lstTTY ); + QString user, loc; + for (dpySpec *sess = sessions; sess; sess = sess->next) { + decodeSess( sess, user, loc ); + int id = dpyMenu->insertItem( + i18n("session (location)", "%1 (%2)").arg( user ).arg( loc ), + sess->vt ? sess->vt : -1 ); + if (!sess->vt) + dpyMenu->setItemEnabled( id, false ); + if (sess->flags & isSelf) + dpyMenu->setItemChecked( id, true ); + } + disposeSessions( sessions ); +#endif +} + +#include "kgdialog.moc" diff --git a/kdm/kfrontend/kgdialog.h b/kdm/kfrontend/kgdialog.h new file mode 100644 index 000000000..05a4be5cf --- /dev/null +++ b/kdm/kfrontend/kgdialog.h @@ -0,0 +1,87 @@ +/* + +Base class for various kdm greeter dialogs + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KGDIALOG_H +#define KGDIALOG_H + +#include <config.h> // for WITH_KDM_XCONSOLE + +#include "kdmconfig.h" +#include "kfdialog.h" + +class QPopupMenu; +class QGridLayout; +class KConsole; +class KGVerify; + +#define ex_exit 1 +#define ex_greet 2 +#define ex_choose 3 + +class KGDialog : public FDialog { + Q_OBJECT + typedef FDialog inherited; + + public: + KGDialog( bool themed = false ); + + public slots: + void slotActivateMenu( int id ); + void slotExit(); + void slotSwitch(); + void slotReallySwitch(); + void slotConsole(); + void slotShutdown( int id ); + + protected: +#ifdef XDMCP + void completeMenu( int _switchIf, int _switchCode, const QString &_switchMsg, int _switchAccel ); +#else + void completeMenu(); +#endif + void inserten( const QString& txt, int accel, const char *member ); + int inserten( const QString& txt, int accel, QPopupMenu *cmnu ); + + bool needSep; + QPopupMenu *optMenu; + KGVerify *verify; +#ifdef WITH_KDM_XCONSOLE + KConsole *consoleView; +#endif + + private slots: + void slotDisplaySelected( int vt ); + void slotPopulateDisplays(); + + private: + void ensureMenu(); + +#ifdef HAVE_VTS + QPopupMenu *dpyMenu; +#endif + int switchCode; +}; + +#endif /* KGDIALOG_H */ diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp new file mode 100644 index 000000000..574f4e340 --- /dev/null +++ b/kdm/kfrontend/kgreeter.cpp @@ -0,0 +1,998 @@ +/* + +Greeter widget for kdm + +Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "kgreeter.h" +#include "kconsole.h" +#include "kdmconfig.h" +#include "kdmclock.h" +#include "kdm_greet.h" +#include "themer/kdmthemer.h" +#include "themer/kdmitem.h" +#include "themer/kdmlabel.h" + +#include <kapplication.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kseparator.h> +#include <klistview.h> +#include <ksimpleconfig.h> +#include <kstringhandler.h> + +#undef Unsorted // x headers suck - make qdir.h work with --enable-final +#include <qdir.h> +#include <qfile.h> +#include <qbuffer.h> +#include <qmemarray.h> +#include <qimage.h> +#include <qmovie.h> +#include <qpopupmenu.h> +#include <qtimer.h> +#include <qheader.h> +#include <qstyle.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qaccel.h> +#include <qeventloop.h> + +#include <pwd.h> +#include <grp.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> + +#include <X11/Xlib.h> + +class UserListView : public KListView { + public: + UserListView( QWidget *parent = 0, const char *name = 0 ) + : KListView( parent, name ) + , cachedSizeHint( -1, 0 ) + { + setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored ); + header()->hide(); + addColumn( QString::null ); + setColumnAlignment( 0, AlignVCenter ); + setResizeMode( QListView::LastColumn ); + } + + mutable QSize cachedSizeHint; + + protected: + virtual QSize sizeHint() const + { + if (!cachedSizeHint.isValid()) { + constPolish(); + uint maxw = 0; + for (QListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { + uint thisw = itm->width( fontMetrics(), this, 0 ); + if (thisw > maxw) + maxw = thisw; + } + cachedSizeHint.setWidth( + style().pixelMetric( QStyle::PM_ScrollBarExtent ) + + frameWidth() * 2 + maxw ); + } + return cachedSizeHint; + } +}; + + +int KGreeter::curPlugin = -1; +PluginList KGreeter::pluginList; + +KGreeter::KGreeter( bool framed ) + : inherited( framed ) + , dName( dname ) + , userView( 0 ) + , userList( 0 ) + , nNormals( 0 ) + , nSpecials( 0 ) + , curPrev( -1 ) + , curSel( -1 ) + , prevValid( true ) + , needLoad( false ) +{ + stsFile = new KSimpleConfig( _stsFile ); + stsFile->setGroup( "PrevUser" ); + + if (_userList) { + userView = new UserListView( this ); + connect( userView, SIGNAL(clicked( QListViewItem * )), + SLOT(slotUserClicked( QListViewItem * )) ); + connect( userView, SIGNAL(doubleClicked( QListViewItem * )), + SLOT(accept()) ); + } + if (_userCompletion) + userList = new QStringList; + if (userView || userList) + insertUsers(); + + sessMenu = new QPopupMenu( this ); + connect( sessMenu, SIGNAL(activated( int )), + SLOT(slotSessionSelected( int )) ); + insertSessions(); + + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( _pluginsLogin ); + } +} + +KGreeter::~KGreeter() +{ + hide(); + delete userList; + delete verify; + delete stsFile; +} + +class UserListViewItem : public KListViewItem { + public: + UserListViewItem( UserListView *parent, const QString &text, + const QPixmap &pixmap, const QString &username ) + : KListViewItem( parent ) + , login( username ) + { + setPixmap( 0, pixmap ); + setMultiLinesEnabled( true ); + setText( 0, text ); + parent->cachedSizeHint.setWidth( -1 ); + } + + QString login; +}; + +#define FILE_LIMIT_ICON 20 +#define FILE_LIMIT_IMAGE 200 + +void +KGreeter::insertUser( const QImage &default_pix, + const QString &username, struct passwd *ps ) +{ + if (userList) + userList->append( username ); + if (!userView) + return; + + int dp = 0, nd = 0; + if (_faceSource == FACE_USER_ONLY || + _faceSource == FACE_PREFER_USER) + dp = 1; + if (_faceSource != FACE_USER_ONLY && + _faceSource != FACE_ADMIN_ONLY) + nd = 1; + QImage p; + do { + dp ^= 1; + QCString fn = !dp ? + QCString( ps->pw_dir ) + '/' : + QFile::encodeName( _faceDir + '/' + username ); + fn += ".face.icon"; + int fd, ico; + if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) { + fn.truncate( fn.length() - 5 ); + if ((fd = open( fn.data(), O_RDONLY | O_NONBLOCK )) < 0) + continue; + ico = 0; + } else + ico = 1; + QFile f; + f.open( IO_ReadOnly, fd ); + int fs = f.size(); + if (fs > (ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE) * 1000) { + LogWarn( "%s exceeds file size limit (%dkB)\n", + fn.data(), ico ? FILE_LIMIT_ICON : FILE_LIMIT_IMAGE ); + continue; + } + QByteArray fc( fs ); + int rfs = f.readBlock( fc.data(), fs ); + ::close( fd ); + fc.resize( rfs > 0 ? rfs : 0 ); + QBuffer buf( fc ); + buf.open( IO_ReadOnly ); + QImageIO ir; + ir.setIODevice( &buf ); + if (!ir.read()) { + LogInfo( "%s is no valid image\n", fn.data() ); + continue; + } + p = ir.image(); + QSize ns( 48, 48 ); + if (p.size() != ns) + p = p.convertDepth( 32 ).smoothScale( ns, QImage::ScaleMin ); + goto gotit; + } while (--nd >= 0); + p = default_pix; + gotit: + QString realname = KStringHandler::from8Bit( ps->pw_gecos ); + realname.truncate( realname.find( ',' ) ); + if (realname.isEmpty() || realname == username) + new UserListViewItem( userView, username, QPixmap( p ), username ); + else { + realname.append( "\n" ).append( username ); + new UserListViewItem( userView, realname, QPixmap( p ), username ); + } +} + +class KCStringList : public QValueList<QCString> { + public: + bool contains( const char *str ) const + { + for (ConstIterator it = begin(); it != end(); ++it) + if (*it == str) + return true; + return false; + } +}; + +class UserList { + public: + UserList( char **in ); + bool hasUser( const char *str ) const { return users.contains( str ); } + bool hasGroup( gid_t gid ) const + { return groups.find( gid ) != groups.end(); } + bool hasGroups() const { return !groups.isEmpty(); } + KCStringList users; + + private: + QValueList<gid_t> groups; +}; + +UserList::UserList( char **in ) +{ + struct group *grp; + + for (; *in; in++) + if (**in == '@') { + if ((grp = getgrnam( *in + 1 ))) { + for (; *grp->gr_mem; grp->gr_mem++) + users.append( *grp->gr_mem ); + groups.append( grp->gr_gid ); + } + } else + users.append( *in ); +} + +void +KGreeter::insertUsers() +{ + struct passwd *ps; + + // XXX remove seteuid-voodoo when we run as nobody + if (!(ps = getpwnam( "nobody" ))) + return; + if (setegid( ps->pw_gid )) + return; + if (seteuid( ps->pw_uid )) { + setegid(0); + return; + } + + QImage default_pix; + if (userView) { + if (!default_pix.load( _faceDir + "/.default.face.icon" )) + if (!default_pix.load( _faceDir + "/.default.face" )) + LogError( "Can't open default user face\n" ); + QSize ns( 48, 48 ); + if (default_pix.size() != ns) + default_pix = + default_pix.convertDepth( 32 ).smoothScale( ns, QImage::ScaleMin ); + } + if (_showUsers == SHOW_ALL) { + UserList noUsers( _noUsers ); + QDict<int> dupes( 1000 ); + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && + (ps->pw_uid >= (unsigned)_lowUserId || + !ps->pw_uid && _showRoot) && + ps->pw_uid <= (unsigned)_highUserId && + !noUsers.hasUser( ps->pw_name ) && + !noUsers.hasGroup( ps->pw_gid )) + { + QString username( QFile::decodeName( ps->pw_name ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + insertUser( default_pix, username, ps ); + } + } + } + } else { + UserList users( _users ); + if (users.hasGroups()) { + QDict<int> dupes( 1000 ); + for (setpwent(); (ps = getpwent()) != 0;) { + if (*ps->pw_dir && *ps->pw_shell && + (ps->pw_uid >= (unsigned)_lowUserId || + !ps->pw_uid && _showRoot) && + ps->pw_uid <= (unsigned)_highUserId && + (users.hasUser( ps->pw_name ) || + users.hasGroup( ps->pw_gid ))) + { + QString username( QFile::decodeName( ps->pw_name ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + insertUser( default_pix, username, ps ); + } + } + } + } else { + KCStringList::ConstIterator it = users.users.begin(); + for (; it != users.users.end(); ++it) + if ((ps = getpwnam( (*it).data() )) && + (ps->pw_uid || _showRoot)) + insertUser( default_pix, QFile::decodeName( *it ), ps ); + } + } + endpwent(); + if (_sortUsers) { + if (userView) + userView->sort(); + if (userList) + userList->sort(); + } + + // XXX remove seteuid-voodoo when we run as nobody + seteuid( 0 ); + setegid( 0 ); +} + +void +KGreeter::putSession( const QString &type, const QString &name, bool hid, const char *exe ) +{ + int prio = exe ? (!strcmp( exe, "default" ) ? 0 : + !strcmp( exe, "custom" ) ? 1 : + !strcmp( exe, "failsafe" ) ? 3 : 2) : 2; + for (uint i = 0; i < sessionTypes.size(); i++) + if (sessionTypes[i].type == type) { + sessionTypes[i].prio = prio; + return; + } + sessionTypes.append( SessType( name, type, hid, prio ) ); +} + +void +KGreeter::insertSessions() +{ + for (char **dit = _sessionsDirs; *dit; ++dit) { + QStringList ents = QDir( *dit ).entryList(); + for (QStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it) + if ((*it).endsWith( ".desktop" )) { + KSimpleConfig dsk( QString( *dit ).append( '/' ).append( *it ) ); + dsk.setGroup( "Desktop Entry" ); + putSession( (*it).left( (*it).length() - 8 ), + dsk.readEntry( "Name" ), + (dsk.readBoolEntry( "Hidden", false ) || + (dsk.hasKey( "TryExec" ) && + KStandardDirs::findExe( dsk.readEntry( "TryExec" ) ).isEmpty())), + dsk.readEntry( "Exec" ).latin1() ); + } + } + putSession( "default", i18n("Default"), false, "default" ); + putSession( "custom", i18n("Custom"), false, "custom" ); + putSession( "failsafe", i18n("Failsafe"), false, "failsafe" ); + qBubbleSort( sessionTypes ); + for (uint i = 0; i < sessionTypes.size() && !sessionTypes[i].hid; i++) { + sessMenu->insertItem( sessionTypes[i].name, i ); + switch (sessionTypes[i].prio) { + case 0: case 1: nSpecials++; break; + case 2: nNormals++; break; + } + } +} + +void +KGreeter::slotUserEntered() +{ + if (userView) { + QListViewItem *item; + for (item = userView->firstChild(); item; item = item->nextSibling()) + if (((UserListViewItem *)item)->login == curUser) { + userView->setSelected( item, true ); + userView->ensureItemVisible( item ); + goto oke; + } + userView->clearSelection(); + } + oke: + if (isVisible()) + slotLoadPrevWM(); + else + QTimer::singleShot( 0, this, SLOT(slotLoadPrevWM()) ); +} + +void +KGreeter::slotUserClicked( QListViewItem *item ) +{ + if (item) { + curUser = ((UserListViewItem *)item)->login; + verify->setUser( curUser ); + slotLoadPrevWM(); + } +} + +void +KGreeter::slotSessionSelected( int id ) +{ + if (id != curSel) { + sessMenu->setItemChecked( curSel, false ); + sessMenu->setItemChecked( id, true ); + curSel = id; + verify->gplugActivity(); + } +} + +void +KGreeter::reject() +{ + verify->reject(); +} + +void +KGreeter::accept() +{ + if (userView && userView->hasFocus()) + slotUserClicked( userView->currentItem() ); + else + verify->accept(); +} + +void // private +KGreeter::setPrevWM( int wm ) +{ + if (curPrev != wm) { + if (curPrev != -1) + sessMenu->changeItem( curPrev, sessionTypes[curPrev].name ); + if (wm != -1) + sessMenu->changeItem( wm, sessionTypes[wm].name + i18n(" (previous)") ); + curPrev = wm; + } +} + +void +KGreeter::slotLoadPrevWM() +{ + int len, i, b; + unsigned long crc, by; + QCString name; + char *sess; + + if (verify->coreLock) { + needLoad = true; + return; + } + needLoad = false; + + prevValid = true; + name = curUser.local8Bit(); + GSendInt( G_ReadDmrc ); + GSendStr( name.data() ); + GRecvInt(); // ignore status code ... + if ((len = name.length())) { + GSendInt( G_GetDmrc ); + GSendStr( "Session" ); + sess = GRecvStr(); + if (!sess) { /* no such user */ + if (!userView && !userList) { // don't fake if user list shown + prevValid = false; + /* simple crc32 */ + for (crc = _forgingSeed, i = 0; i < len; i++) { + by = (crc & 255) ^ name[i]; + for (b = 0; b < 8; b++) + by = (by >> 1) ^ (-(by & 1) & 0xedb88320); + crc = (crc >> 8) ^ by; + } + /* forge a session with this hash - default & custom more probable */ + /* XXX - this should do a statistical analysis of the real users */ +#if 1 + setPrevWM( crc % (nSpecials * 2 + nNormals) % (nSpecials + nNormals) ); +#else + i = crc % (nSpecials * 2 + nNormals); + if (i < nNormals) + setPrevWM( i + nSpecials ); + else + setPrevWM( (i - nNormals) / 2 ); +#endif + return; + } + } else { + for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++) + if (sessionTypes[i].type == sess) { + free( sess ); + setPrevWM( i ); + return; + } + if (curSel == -1) + MsgBox( sorrybox, i18n("Your saved session type '%1' is not valid any more.\n" + "Please select a new one, otherwise 'default' will be used.").arg( sess ) ); + free( sess ); + prevValid = false; + } + } + setPrevWM( -1 ); +} + +void // protected +KGreeter::pluginSetup() +{ + int field = 0; + QString ent, pn( verify->pluginName() ), dn( dName + '_' + pn ); + + if (_preselUser != PRESEL_PREV) + stsFile->deleteEntry( verify->entitiesLocal() ? dName : dn, false ); + if (_preselUser != PRESEL_NONE && verify->entityPresettable()) { + if (verify->entitiesLocal()) + ent = _preselUser == PRESEL_PREV ? + stsFile->readEntry( dName ) : _defaultUser; + else + ent = _preselUser == PRESEL_PREV ? + stsFile->readEntry( dn ) : + verify->getConf( 0, (pn + ".DefaultEntity").latin1(), QVariant() ).toString(); + field = verify->entitiesFielded() ? + verify->getConf( 0, (pn + ".FocusField").latin1(), QVariant( 0 ) ).toInt() : + _focusPasswd; + } + verify->presetEntity( ent, field ); + if (userList) + verify->loadUsers( *userList ); +} + +void +KGreeter::verifyPluginChanged( int id ) +{ + curPlugin = id; + pluginSetup(); +} + +void +KGreeter::verifyClear() +{ + curUser = QString::null; + slotUserEntered(); + slotSessionSelected( -1 ); +} + +void +KGreeter::verifyOk() +{ + if (_preselUser == PRESEL_PREV && verify->entityPresettable()) + stsFile->writeEntry( verify->entitiesLocal() ? + dName : + dName + '_' + verify->pluginName(), + verify->getEntity() ); + if (curSel != -1) { + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( sessionTypes[curSel].type.utf8() ); + } else if (!prevValid) { + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( "default" ); + } + GSendInt( G_Ready ); + done( ex_exit ); +} + +void +KGreeter::verifyFailed() +{ + if (needLoad) + slotLoadPrevWM(); +} + +void +KGreeter::verifySetUser( const QString &user ) +{ + curUser = user; + slotUserEntered(); +} + + +KStdGreeter::KStdGreeter() + : KGreeter() + , clock( 0 ) + , pixLabel( 0 ) +{ + QBoxLayout *main_box; +#ifdef WITH_KDM_XCONSOLE + if (consoleView) { + QBoxLayout *ex_box = new QVBoxLayout( this, 10, 10 ); + main_box = new QHBoxLayout( ex_box, 10 ); + ex_box->addWidget( consoleView ); + } else +#endif + main_box = new QHBoxLayout( this, 10, 10 ); + + if (userView) + main_box->addWidget( userView ); + + QBoxLayout *inner_box = new QVBoxLayout( main_box, 10 ); + + if (!_authorized && _authComplain) { + QLabel *complainLabel = new QLabel( + i18n("Warning: this is an unsecured session"), this ); + QToolTip::add( complainLabel, + i18n("This display requires no X authorization.\n" + "This means that anybody can connect to it,\n" + "open windows on it or intercept your input.") ); + complainLabel->setAlignment( AlignCenter ); + complainLabel->setFont( _failFont ); + complainLabel->setPaletteForegroundColor( Qt::red ); + inner_box->addWidget( complainLabel ); + } + if (!_greetString.isEmpty()) { + QLabel *welcomeLabel = new QLabel( _greetString, this ); + welcomeLabel->setAlignment( AlignCenter ); + welcomeLabel->setFont( _greetFont ); + inner_box->addWidget( welcomeLabel ); + } + + switch (_logoArea) { + case LOGO_CLOCK: + clock = new KdmClock( this, "clock" ); + break; + case LOGO_LOGO: + { + QMovie movie( _logo ); + kapp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers, 100 ); + QPixmap pixmap; + if (!movie.framePixmap().isNull() || pixmap.load( _logo )) { + pixLabel = new QLabel( this ); + if (!movie.framePixmap().isNull()) { + pixLabel->setMovie( movie ); + if (!movie.framePixmap().hasAlpha()) + pixLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + } else { + pixLabel->setPixmap( pixmap ); + if (!pixmap.hasAlpha()) + pixLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + } + pixLabel->setIndent( 0 ); + } + } + break; + } + + if (userView) { + if (clock) + inner_box->addWidget( clock, 0, AlignCenter ); + else if (pixLabel) + inner_box->addWidget( pixLabel, 0, AlignCenter ); + } else { + if (clock) + main_box->addWidget( clock, 0, AlignCenter ); + else if (pixLabel) + main_box->addWidget( pixLabel, 0, AlignCenter ); + } + + goButton = new QPushButton( i18n("L&ogin"), this ); + goButton->setDefault( true ); + connect( goButton, SIGNAL(clicked()), SLOT(accept()) ); + menuButton = new QPushButton( i18n("&Menu"), this ); + //helpButton + + QWidget *prec; + if (userView) + prec = userView; +#ifdef WITH_KDM_XCONSOLE + else if (consoleView) + prec = consoleView; +#endif + else + prec = menuButton; + KGStdVerify *sverify = + new KGStdVerify( this, this, prec, QString::null, + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Login ); + inner_box->addLayout( sverify->getLayout() ); + QPopupMenu *plugMenu = sverify->getPlugMenu(); + sverify->selectPlugin( curPlugin ); + verify = sverify; + + inner_box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + QBoxLayout *hbox2 = new QHBoxLayout( inner_box, 10 ); + hbox2->addWidget( goButton ); + hbox2->addStretch( 1 ); + hbox2->addWidget( menuButton ); + hbox2->addStretch( 1 ); + + if (sessMenu->count() > 1) { + inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); + needSep = true; + } + + if (plugMenu) { + inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); + needSep = true; + } + +#ifdef XDMCP + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); +#else + completeMenu(); +#endif + + if (optMenu) + menuButton->setPopup( optMenu ); + else + menuButton->hide(); + + pluginSetup(); + + verify->start(); +} + +void +KStdGreeter::pluginSetup() +{ + inherited::pluginSetup(); + if (userView) { + if (verify->entitiesLocal() && verify->entityPresettable()) + userView->show(); + else + userView->hide(); + } + adjustGeometry(); + update(); +} + +void +KStdGreeter::verifyFailed() +{ + goButton->setEnabled( false ); + menuButton->setEnabled( false ); + if (userView) + userView->setEnabled( false ); + inherited::verifyFailed(); +} + +void +KStdGreeter::verifyRetry() +{ + goButton->setEnabled( true ); + menuButton->setEnabled( true ); + if (userView) + userView->setEnabled( true ); +} + + +KThemedGreeter::KThemedGreeter() + : KGreeter( true ) + , themer( 0 ) +// , clock( 0 ) +{ + // We do all painting ourselves + setBackgroundMode( NoBackground ); + // Allow tracking the mouse position + setMouseTracking( true ); + + adjustGeometry(); + + themer = new KdmThemer( _theme, "console", this ); + if (!themer->isOK()) { + delete themer; + themer = 0; + return; + } + + connect( themer, SIGNAL(activated( const QString & )), + SLOT(slotThemeActivated( const QString & )) ); + + console_rect = themer->findNode( "xconsole" ); // kdm ext + userlist_rect = themer->findNode( "userlist" ); + caps_warning = themer->findNode( "caps-lock-warning" ); + xauth_warning = themer->findNode( "xauth-warning" ); // kdm ext + pam_error = themer->findNode( "pam-error" ); + timed_label = themer->findNode( "timed-label" ); + if (pam_error && pam_error->isA( "KdmLabel" )) + static_cast<KdmLabel*>(pam_error)->setText( i18n("Login Failed.") ); + + KdmItem *itm; + if ((itm = themer->findNode( "pam-message" ))) // done via msgboxes + itm->hide( true ); + if ((itm = themer->findNode( "language_button" ))) // not implemented yet + itm->hide( true ); + +#ifdef WITH_KDM_XCONSOLE + if (console_rect) { + if (consoleView) + console_rect->setWidget( consoleView ); + else + console_rect->hide( true ); + } +#endif + + if (xauth_warning && (_authorized || !_authComplain)) + xauth_warning->hide( true ); + +// if (!_greetString.isEmpty()) { +// } +// clock = new KdmClock( this, "clock" ); + + QWidget *prec; + if (userView) + prec = userView; +#ifdef WITH_KDM_XCONSOLE + else if (consoleView) + prec = consoleView; +#endif + else + prec = 0; + KGThemedVerify *tverify = + new KGThemedVerify( this, themer, this, prec, QString::null, + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Login ); + QPopupMenu *plugMenu = tverify->getPlugMenu(); + tverify->selectPlugin( curPlugin ); + verify = tverify; + + session_button = 0; + if ((itm = themer->findNode( "session_button" ))) { + if (sessMenu->count() <= 1) + itm->hide( true ); + else { + session_button = itm; + QAccel *accel = new QAccel( this ); + accel->insertItem( ALT+Key_T, 0 ); + connect( accel, SIGNAL(activated( int )), SLOT(slotSessMenu()) ); + } + } else { + if (sessMenu->count() > 1) { + inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); + needSep = true; + } + } + + if (plugMenu) { + inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); + needSep = true; + } + +#ifdef XDMCP + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); +#else + completeMenu(); +#endif + + system_button = themer->findNode( "system_button" ); + QAccel *accel = new QAccel( this ); + accel->insertItem( ALT+Key_M, 0 ); + connect( accel, SIGNAL(activated( int )), SLOT(slotActionMenu()) ); + + pluginSetup(); + + verify->start(); +} + +bool +KThemedGreeter::event( QEvent *e ) +{ + if (themer) + themer->widgetEvent( e ); + return inherited::event( e ); +} + +void +KThemedGreeter::pluginSetup() +{ + inherited::pluginSetup(); + + if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) { + userlist_rect->setWidget( userView ); + userView->show(); + } else { + if (userView) + userView->hide(); + if (userlist_rect) + userlist_rect->hide( true ); + } + + update(); +} + +void +KThemedGreeter::verifyFailed() +{ +// goButton->setEnabled( false ); + inherited::verifyFailed(); +} + +void +KThemedGreeter::verifyRetry() +{ +// goButton->setEnabled( true ); +} + +QString KThemedGreeter::timedUser = QString::null; +int KThemedGreeter::timedDelay = -1; + +void +KThemedGreeter::updateStatus( bool fail, bool caps, int timedleft ) +{ + if (pam_error) { + if (fail) + pam_error->show( true ); + else + pam_error->hide( true ); + } + if (caps_warning) { + if (caps) + caps_warning->show( true ); + else + caps_warning->hide( true ); + } + if (timed_label) { + if (timedleft) { + if (timedleft != timedDelay) { + timedDelay = timedleft; + timedUser = curUser; + timed_label->show( true ); + timed_label->update(); + } + } else { + timedDelay = -1; + timed_label->hide( true ); + } + } +} + +void +KThemedGreeter::slotThemeActivated( const QString &id ) +{ + if (id == "login_button") + accept(); + else if (id == "session_button") + slotSessMenu(); + else if (id == "system_button") + slotActionMenu(); +} + +void +KThemedGreeter::slotSessMenu() +{ + sessMenu->popup( mapToGlobal( session_button->rect().center() ) ); +} + +void +KThemedGreeter::slotActionMenu() +{ + if (system_button) + optMenu->popup( mapToGlobal( system_button->rect().center() ) ); + else + optMenu->popup( mapToGlobal( rect().center() ) ); +} + +void +KThemedGreeter::keyPressEvent( QKeyEvent *e ) +{ + inherited::keyPressEvent( e ); + if (!(e->state() & KeyButtonMask) && + (e->key() == Key_Return || e->key() == Key_Enter)) + accept(); +} + +#include "kgreeter.moc" diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h new file mode 100644 index 000000000..32191fafe --- /dev/null +++ b/kdm/kfrontend/kgreeter.h @@ -0,0 +1,164 @@ +/* + +Greeter widget for kdm + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KGREETER_H +#define KGREETER_H + +#include "kgverify.h" +#include "kgdialog.h" + +class KdmClock; +class UserListView; +class KdmThemer; +class KdmItem; + +class KListView; +class KSimpleConfig; + +class QLabel; +class QPushButton; +class QPopupMenu; +class QListViewItem; + +struct SessType { + QString name, type; + bool hid; + int prio; + + SessType() {} + SessType( const QString &n, const QString &t, bool h, int p ) : + name( n ), type( t ), hid( h ), prio( p ) {} + bool operator<( const SessType &st ) { + return hid != st.hid ? hid < st.hid : + prio != st.prio ? prio < st.prio : + name < st.name; + } +}; + +class KGreeter : public KGDialog, public KGVerifyHandler { + Q_OBJECT + typedef KGDialog inherited; + + public: + KGreeter( bool themed = false ); + ~KGreeter(); + + public slots: + void accept(); + void reject(); + void slotUserClicked( QListViewItem * ); + void slotSessionSelected( int ); + void slotUserEntered(); + + protected: + void installUserList(); + void insertUser( const QImage &, const QString &, struct passwd * ); + void insertUsers(); + void putSession( const QString &, const QString &, bool, const char * ); + void insertSessions(); + virtual void pluginSetup(); + void setPrevWM( int ); + + QString curUser, dName; + KSimpleConfig *stsFile; + UserListView *userView; + QStringList *userList; + QPopupMenu *sessMenu; + QValueVector<SessType> sessionTypes; + int nNormals, nSpecials; + int curPrev, curSel; + bool prevValid; + bool needLoad; + + static int curPlugin; + static PluginList pluginList; + + private slots: + void slotLoadPrevWM(); + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyClear(); + virtual void verifyOk(); + virtual void verifyFailed(); +// virtual void verifyRetry(); + virtual void verifySetUser( const QString &user ); +}; + +class KStdGreeter : public KGreeter { + Q_OBJECT + typedef KGreeter inherited; + + public: + KStdGreeter(); + + protected: + virtual void pluginSetup(); + + private: + KdmClock *clock; + QLabel *pixLabel; + QPushButton *goButton; + QPushButton *menuButton; + + public: // from KGVerifyHandler + virtual void verifyFailed(); + virtual void verifyRetry(); +}; + +class KThemedGreeter : public KGreeter { + Q_OBJECT + typedef KGreeter inherited; + + public: + KThemedGreeter(); + bool isOK() { return themer != 0; } + static QString timedUser; + static int timedDelay; + + public slots: + void slotThemeActivated( const QString &id ); + void slotSessMenu(); + void slotActionMenu(); + + protected: + virtual void updateStatus( bool fail, bool caps, int timedleft ); + virtual void pluginSetup(); + virtual void keyPressEvent( QKeyEvent * ); + virtual bool event( QEvent *e ); + + private: +// KdmClock *clock; + KdmThemer *themer; + KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label, + *console_rect, *userlist_rect, + *session_button, *system_button; + + public: // from KGVerifyHandler + virtual void verifyFailed(); + virtual void verifyRetry(); +}; + +#endif /* KGREETER_H */ diff --git a/kdm/kfrontend/kgverify.cpp b/kdm/kfrontend/kgverify.cpp new file mode 100644 index 000000000..f9bb77ff8 --- /dev/null +++ b/kdm/kfrontend/kgverify.cpp @@ -0,0 +1,1211 @@ +/* + +Shell for kdm conversation plugins + +Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#include "kgverify.h" +#include "kdmconfig.h" +#include "kdm_greet.h" + +#include "themer/kdmthemer.h" +#include "themer/kdmitem.h" + +#include <kapplication.h> +#include <klocale.h> +#include <klibloader.h> +#include <kseparator.h> +#include <kstdguiitem.h> +#include <kpushbutton.h> + +#include <qregexp.h> +#include <qpopupmenu.h> +#include <qlayout.h> +#include <qfile.h> +#include <qlabel.h> + +#include <pwd.h> +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> + +#include <X11/Xlib.h> // for updateLockStatus() +#include <fixx11h.h> // ... and make eventFilter() work again + +#define FULL_GREET_TO 40 // normal inactivity timeout +#define TIMED_GREET_TO 20 // inactivity timeout when persisting timed login +#define MIN_TIMED_TO 5 // minimal timed login delay +#define DEAD_TIMED_TO 2 // <enter> dead time after re-activating timed login +#define SECONDS 1000 // reduce to 100 to speed up testing + +void KGVerifyHandler::verifyClear() +{ +} + +void KGVerifyHandler::updateStatus( bool, bool, int ) +{ +} + +KGVerify::KGVerify( KGVerifyHandler *_handler, KdmThemer *_themer, + QWidget *_parent, QWidget *_predecessor, + const QString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited() + , coreLock( 0 ) + , fixedEntity( _fixedUser ) + , pluginList( _pluginList ) + , handler( _handler ) + , themer( _themer ) + , parent( _parent ) + , predecessor( _predecessor ) + , plugMenu( 0 ) + , curPlugin( -1 ) + , timedLeft( 0 ) + , func( _func ) + , ctx( _ctx ) + , enabled( true ) + , running( false ) + , suspended( false ) + , failed( false ) + , isClear( true ) +{ + connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) ); + connect( kapp, SIGNAL(activity()), SLOT(slotActivity()) ); + + _parent->installEventFilter( this ); +} + +KGVerify::~KGVerify() +{ + Debug( "delete %s\n", pName.data() ); + delete greet; +} + +QPopupMenu * +KGVerify::getPlugMenu() +{ + // assert( !cont ); + if (!plugMenu) { + uint np = pluginList.count(); + if (np > 1) { + plugMenu = new QPopupMenu( parent ); + connect( plugMenu, SIGNAL(activated( int )), + SLOT(slotPluginSelected( int )) ); + for (uint i = 0; i < np; i++) + plugMenu->insertItem( i18n(greetPlugins[pluginList[i]].info->name), pluginList[i] ); + } + } + return plugMenu; +} + +bool // public +KGVerify::entitiesLocal() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Local; +} + +bool // public +KGVerify::entitiesFielded() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Fielded; +} + +bool // public +KGVerify::entityPresettable() const +{ + return greetPlugins[pluginList[curPlugin]].info->flags & kgreeterplugin_info::Presettable; +} + +bool // public +KGVerify::isClassic() const +{ + return !strcmp( greetPlugins[pluginList[curPlugin]].info->method, "classic" ); +} + +QString // public +KGVerify::pluginName() const +{ + QString name( greetPlugins[pluginList[curPlugin]].library->fileName() ); + uint st = name.findRev( '/' ) + 1; + uint en = name.find( '.', st ); + if (en - st > 7 && QConstString( name.unicode() + st, 7 ).string() == "kgreet_") + st += 7; + return name.mid( st, en - st ); +} + +static void +showWidgets( QLayoutItem *li ) +{ + QWidget *w; + QLayout *l; + + if ((w = li->widget())) + w->show(); + else if ((l = li->layout())) { + QLayoutIterator it = l->iterator(); + for (QLayoutItem *itm = it.current(); itm; itm = ++it) + showWidgets( itm ); + } +} + +void // public +KGVerify::selectPlugin( int id ) +{ + if (pluginList.isEmpty()) { + MsgBox( errorbox, i18n("No greeter widget plugin loaded. Check the configuration.") ); + ::exit( EX_UNMANAGE_DPY ); + } + curPlugin = id; + if (plugMenu) + plugMenu->setItemChecked( id, true ); + pName = ("greet_" + pluginName()).latin1(); + Debug( "new %s\n", pName.data() ); + greet = greetPlugins[pluginList[id]].info->create( this, themer, parent, predecessor, fixedEntity, func, ctx ); + timeable = _autoLoginDelay && entityPresettable() && isClassic(); +} + +void // public +KGVerify::loadUsers( const QStringList &users ) +{ + Debug( "%s->loadUsers(...)\n", pName.data() ); + greet->loadUsers( users ); +} + +void // public +KGVerify::presetEntity( const QString &entity, int field ) +{ + presEnt = entity; + presFld = field; +} + +bool // private +KGVerify::applyPreset() +{ + if (!presEnt.isEmpty()) { + Debug( "%s->presetEntity(%\"s, %d)\n", pName.data(), + presEnt.latin1(), presFld ); + greet->presetEntity( presEnt, presFld ); + if (entitiesLocal()) { + curUser = presEnt; + handler->verifySetUser( presEnt ); + } + return true; + } + return false; +} + +bool // private +KGVerify::scheduleAutoLogin( bool initial ) +{ + if (timeable) { + Debug( "%s->presetEntity(%\"s, -1)\n", pName.data(), + _autoLoginUser.latin1(), -1 ); + greet->presetEntity( _autoLoginUser, -1 ); + curUser = _autoLoginUser; + handler->verifySetUser( _autoLoginUser ); + timer.start( 1000 ); + if (initial) { + timedLeft = _autoLoginDelay; + deadTicks = 0; + } else { + timedLeft = QMAX( _autoLoginDelay - TIMED_GREET_TO, MIN_TIMED_TO ); + deadTicks = DEAD_TIMED_TO; + } + updateStatus(); + running = false; + isClear = true; + return true; + } + return false; +} + +void // private +KGVerify::performAutoLogin() +{ +// timer.stop(); + GSendInt( G_AutoLogin ); + handleVerify(); +} + +QString // public +KGVerify::getEntity() const +{ + Debug( "%s->getEntity()\n", pName.data() ); + QString ent = greet->getEntity(); + Debug( " entity: %s\n", ent.latin1() ); + return ent; +} + +void +KGVerify::setUser( const QString &user ) +{ + // assert( fixedEntity.isEmpty() ); + curUser = user; + Debug( "%s->setUser(%\"s)\n", pName.data(), user.latin1() ); + greet->setUser( user ); + gplugActivity(); +} + +void +KGVerify::start() +{ + authTok = (func == KGreeterPlugin::ChAuthTok); + cont = false; + if (func == KGreeterPlugin::Authenticate && ctx == KGreeterPlugin::Login) { + if (scheduleAutoLogin( true )) { + if (!_autoLoginAgain) + _autoLoginDelay = 0, timeable = false; + return; + } else + applyPreset(); + } + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + if (!(func == KGreeterPlugin::Authenticate || + ctx == KGreeterPlugin::ChangeTok || + ctx == KGreeterPlugin::ExChangeTok)) + { + cont = true; + handleVerify(); + } +} + +void +KGVerify::abort() +{ + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + running = false; +} + +void +KGVerify::suspend() +{ + // assert( !cont ); + if (running) { + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + } + suspended = true; + updateStatus(); + timer.suspend(); +} + +void +KGVerify::resume() +{ + timer.resume(); + suspended = false; + updateLockStatus(); + if (running) { + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } else if (delayed) { + delayed = false; + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } +} + +void // not a slot - called manually by greeter +KGVerify::accept() +{ + Debug( "%s->next()\n", pName.data() ); + greet->next(); +} + +void // private +KGVerify::doReject( bool initial ) +{ + // assert( !cont ); + if (running) { + Debug( "%s->abort()\n", pName.data() ); + greet->abort(); + } + handler->verifyClear(); + Debug( "%s->clear()\n", pName.data() ); + greet->clear(); + curUser = QString::null; + if (!scheduleAutoLogin( initial )) { + isClear = !(isClear && applyPreset()); + if (running) { + Debug( "%s->start()\n", pName.data() ); + greet->start(); + } + if (!failed) + timer.stop(); + } +} + +void // not a slot - called manually by greeter +KGVerify::reject() +{ + doReject( true ); +} + +void +KGVerify::setEnabled( bool on ) +{ + Debug( "%s->setEnabled(%s)\n", pName.data(), on ? "true" : "false" ); + greet->setEnabled( on ); + enabled = on; + updateStatus(); +} + +void // private +KGVerify::slotTimeout() +{ + if (failed) { + failed = false; + updateStatus(); + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + handler->verifyRetry(); + if (suspended) + delayed = true; + else { + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + slotActivity(); + gplugActivity(); + if (cont) + handleVerify(); + } + } else if (timedLeft) { + deadTicks--; + if (!--timedLeft) + performAutoLogin(); + else + timer.start( 1000 ); + updateStatus(); + } else { + // assert( ctx == Login ); + isClear = true; + doReject( false ); + } +} + +void +KGVerify::slotActivity() +{ + if (timedLeft) { + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + Debug( "%s->start()\n", pName.data() ); + greet->start(); + running = true; + timedLeft = 0; + updateStatus(); + timer.start( TIMED_GREET_TO * SECONDS ); + } else if (timeable) + timer.start( TIMED_GREET_TO * SECONDS ); +} + + +void // private static +KGVerify::VMsgBox( QWidget *parent, const QString &user, + QMessageBox::Icon type, const QString &mesg ) +{ + FDialog::box( parent, type, user.isEmpty() ? + mesg : i18n("Authenticating %1...\n\n").arg( user ) + mesg ); +} + +static const char *msgs[]= { + I18N_NOOP( "You are required to change your password immediately (password aged)." ), + I18N_NOOP( "You are required to change your password immediately (root enforced)." ), + I18N_NOOP( "You are not allowed to login at the moment." ), + I18N_NOOP( "Home folder not available." ), + I18N_NOOP( "Logins are not allowed at the moment.\nTry again later." ), + I18N_NOOP( "Your login shell is not listed in /etc/shells." ), + I18N_NOOP( "Root logins are not allowed." ), + I18N_NOOP( "Your account has expired; please contact your system administrator." ) +}; + +void // private static +KGVerify::VErrBox( QWidget *parent, const QString &user, const char *msg ) +{ + QMessageBox::Icon icon; + QString mesg; + + if (!msg) { + mesg = i18n("A critical error occurred.\n" + "Please look at KDM's logfile(s) for more information\n" + "or contact your system administrator."); + icon = errorbox; + } else { + mesg = QString::fromLocal8Bit( msg ); + QString mesg1 = mesg + '.'; + for (uint i = 0; i < as(msgs); i++) + if (mesg1 == msgs[i]) { + mesg = i18n(msgs[i]); + break; + } + icon = sorrybox; + } + VMsgBox( parent, user, icon, mesg ); +} + +void // private static +KGVerify::VInfoBox( QWidget *parent, const QString &user, const char *msg ) +{ + QString mesg = QString::fromLocal8Bit( msg ); + QRegExp rx( "^Warning: your account will expire in (\\d+) day" ); + if (rx.search( mesg ) >= 0) { + int expire = rx.cap( 1 ).toInt(); + mesg = expire ? + i18n("Your account expires tomorrow.", + "Your account expires in %n days.", expire) : + i18n("Your account expires today."); + } else { + rx.setPattern( "^Warning: your password will expire in (\\d+) day" ); + if (rx.search( mesg ) >= 0) { + int expire = rx.cap( 1 ).toInt(); + mesg = expire ? + i18n("Your password expires tomorrow.", + "Your password expires in %n days.", expire) : + i18n("Your password expires today."); + } + } + VMsgBox( parent, user, infobox, mesg ); +} + +bool // public static +KGVerify::handleFailVerify( QWidget *parent ) +{ + Debug( "handleFailVerify ...\n" ); + char *msg = GRecvStr(); + QString user = QString::fromLocal8Bit( msg ); + free( msg ); + + for (;;) { + int ret = GRecvInt(); + + // non-terminal status + switch (ret) { + /* case V_PUT_USER: cannot happen - we are in "classic" mode */ + /* case V_PRE_OK: cannot happen - not in ChTok dialog */ + /* case V_CHTOK: cannot happen - called by non-interactive verify */ + case V_CHTOK_AUTH: + Debug( " V_CHTOK_AUTH\n" ); + { + QStringList pgs( _pluginsLogin ); + pgs += _pluginsShutdown; + QStringList::ConstIterator it; + for (it = pgs.begin(); it != pgs.end(); ++it) + if (*it == "classic" || *it == "modern") { + pgs = *it; + goto gotit; + } else if (*it == "generic") { + pgs = "modern"; + goto gotit; + } + pgs = "classic"; + gotit: + KGChTok chtok( parent, user, init( pgs ), 0, + KGreeterPlugin::AuthChAuthTok, + KGreeterPlugin::Login ); + return chtok.exec(); + } + case V_MSG_ERR: + Debug( " V_MSG_ERR\n" ); + msg = GRecvStr(); + Debug( " message %\"s\n", msg ); + VErrBox( parent, user, msg ); + if (msg) + free( msg ); + continue; + case V_MSG_INFO: + Debug( " V_MSG_INFO\n" ); + msg = GRecvStr(); + Debug( " message %\"s\n", msg ); + VInfoBox( parent, user, msg ); + free( msg ); + continue; + } + + // terminal status + switch (ret) { + case V_OK: + Debug( " V_OK\n" ); + return true; + case V_AUTH: + Debug( " V_AUTH\n" ); + VMsgBox( parent, user, sorrybox, i18n("Authentication failed") ); + return false; + case V_FAIL: + Debug( " V_FAIL\n" ); + return false; + default: + LogPanic( "Unknown V_xxx code %d from core\n", ret ); + } + } +} + +void // private +KGVerify::handleVerify() +{ + QString user; + + Debug( "handleVerify ...\n" ); + for (;;) { + char *msg; + int ret, echo, ndelay; + KGreeterPlugin::Function nfunc; + + ret = GRecvInt(); + + // requests + coreLock = 1; + switch (ret) { + case V_GET_TEXT: + Debug( " V_GET_TEXT\n" ); + msg = GRecvStr(); + Debug( " prompt %\"s\n", msg ); + echo = GRecvInt(); + Debug( " echo = %d\n", echo ); + ndelay = GRecvInt(); + Debug( " ndelay = %d\n%s->textPrompt(...)\n", ndelay, pName.data() ); + greet->textPrompt( msg, echo, ndelay ); + if (msg) + free( msg ); + return; + case V_GET_BINARY: + Debug( " V_GET_BINARY\n" ); + msg = GRecvArr( &ret ); + Debug( " %d bytes prompt\n", ret ); + ndelay = GRecvInt(); + Debug( " ndelay = %d\n%s->binaryPrompt(...)\n", ndelay, pName.data() ); + greet->binaryPrompt( msg, ndelay ); + if (msg) + free( msg ); + return; + } + + // non-terminal status + coreLock = 2; + switch (ret) { + case V_PUT_USER: + Debug( " V_PUT_USER\n" ); + msg = GRecvStr(); + curUser = user = QString::fromLocal8Bit( msg ); + // greet needs this to be able to return something useful from + // getEntity(). but the backend is still unable to tell a domain ... + Debug( " %s->setUser(%\"s)\n", pName.data(), user.latin1() ); + greet->setUser( curUser ); + handler->verifySetUser( curUser ); + if (msg) + free( msg ); + continue; + case V_PRE_OK: // this is only for func == AuthChAuthTok + Debug( " V_PRE_OK\n" ); + // With the "classic" method, the wrong user simply cannot be + // authenticated, even with the generic plugin. Other methods + // could do so, but this applies only to ctx == ChangeTok, which + // is not implemented yet. + authTok = true; + cont = true; + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + continue; + case V_CHTOK_AUTH: + Debug( " V_CHTOK_AUTH\n" ); + nfunc = KGreeterPlugin::AuthChAuthTok; + user = curUser; + goto dchtok; + case V_CHTOK: + Debug( " V_CHTOK\n" ); + nfunc = KGreeterPlugin::ChAuthTok; + user = QString::null; + dchtok: + { + timer.stop(); + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + KGChTok chtok( parent, user, pluginList, curPlugin, nfunc, KGreeterPlugin::Login ); + if (!chtok.exec()) + goto retry; + handler->verifyOk(); + return; + } + case V_MSG_ERR: + Debug( " V_MSG_ERR\n" ); + msg = GRecvStr(); + Debug( " %s->textMessage(%\"s, true)\n", pName.data(), msg ); + if (!greet->textMessage( msg, true )) { + Debug( " message passed\n" ); + VErrBox( parent, user, msg ); + } else + Debug( " message swallowed\n" ); + if (msg) + free( msg ); + continue; + case V_MSG_INFO: + Debug( " V_MSG_INFO\n" ); + msg = GRecvStr(); + Debug( " %s->textMessage(%\"s, false)\n", pName.data(), msg ); + if (!greet->textMessage( msg, false )) { + Debug( " message passed\n" ); + VInfoBox( parent, user, msg ); + } else + Debug( " message swallowed\n" ); + free( msg ); + continue; + } + + // terminal status + coreLock = 0; + running = false; + timer.stop(); + + if (ret == V_OK) { + Debug( " V_OK\n" ); + if (!fixedEntity.isEmpty()) { + Debug( " %s->getEntity()\n", pName.data() ); + QString ent = greet->getEntity(); + Debug( " entity %\"s\n", ent.latin1() ); + if (ent != fixedEntity) { + Debug( "%s->failed()\n", pName.data() ); + greet->failed(); + MsgBox( sorrybox, + i18n("Authenticated user (%1) does not match requested user (%2).\n") + .arg( ent ).arg( fixedEntity ) ); + goto retry; + } + } + Debug( "%s->succeeded()\n", pName.data() ); + greet->succeeded(); + handler->verifyOk(); + return; + } + + Debug( "%s->failed()\n", pName.data() ); + greet->failed(); + + if (ret == V_AUTH) { + Debug( " V_AUTH\n" ); + failed = true; + updateStatus(); + handler->verifyFailed(); + timer.start( 1500 + kapp->random()/(RAND_MAX/1000) ); + return; + } + if (ret != V_FAIL) + LogPanic( "Unknown V_xxx code %d from core\n", ret ); + Debug( " V_FAIL\n" ); + retry: + Debug( "%s->revive()\n", pName.data() ); + greet->revive(); + running = true; + Debug( "%s->start()\n", pName.data() ); + greet->start(); + if (!cont) + return; + user = QString::null; + } +} + +void +KGVerify::gplugReturnText( const char *text, int tag ) +{ + Debug( "%s: gplugReturnText(%\"s, %d)\n", pName.data(), + tag & V_IS_SECRET ? "<masked>" : text, tag ); + GSendStr( text ); + if (text) { + GSendInt( tag ); + handleVerify(); + } else + coreLock = 0; +} + +void +KGVerify::gplugReturnBinary( const char *data ) +{ + if (data) { + unsigned const char *up = (unsigned const char *)data; + int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); + Debug( "%s: gplugReturnBinary(%d bytes)\n", pName.data(), len ); + GSendArr( len, data ); + handleVerify(); + } else { + Debug( "%s: gplugReturnBinary(NULL)\n", pName.data() ); + GSendArr( 0, 0 ); + coreLock = 0; + } +} + +void +KGVerify::gplugSetUser( const QString &user ) +{ + Debug( "%s: gplugSetUser(%\"s)\n", pName.data(), user.latin1() ); + curUser = user; + handler->verifySetUser( user ); +} + +void +KGVerify::gplugStart() +{ + // XXX handle func != Authenticate + Debug( "%s: gplugStart()\n", pName.data() ); + GSendInt( ctx == KGreeterPlugin::Shutdown ? G_VerifyRootOK : G_Verify ); + GSendStr( greetPlugins[pluginList[curPlugin]].info->method ); + handleVerify(); +} + +void +KGVerify::gplugActivity() +{ + Debug( "%s: gplugActivity()\n", pName.data() ); + if (func == KGreeterPlugin::Authenticate && + ctx == KGreeterPlugin::Login) + { + isClear = false; + if (!timeable) + timer.start( FULL_GREET_TO * SECONDS ); + } +} + +void +KGVerify::gplugMsgBox( QMessageBox::Icon type, const QString &text ) +{ + Debug( "%s: gplugMsgBox(%d, %\"s)\n", pName.data(), type, text.latin1() ); + MsgBox( type, text ); +} + +bool +KGVerify::eventFilter( QObject *o, QEvent *e ) +{ + switch (e->type()) { + case QEvent::KeyPress: + if (timedLeft) { + QKeyEvent *ke = (QKeyEvent *)e; + if (ke->key() == Key_Return || ke->key() == Key_Enter) { + if (deadTicks <= 0) { + timedLeft = 0; + performAutoLogin(); + } + return true; + } + } + /* fall through */ + case QEvent::KeyRelease: + updateLockStatus(); + /* fall through */ + default: + break; + } + return inherited::eventFilter( o, e ); +} + +void +KGVerify::updateLockStatus() +{ + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer( qt_xdisplay(), DefaultRootWindow( qt_xdisplay() ), + &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, + &lmask ); + capsLocked = lmask & LockMask; + updateStatus(); +} + +void +KGVerify::MsgBox( QMessageBox::Icon typ, const QString &msg ) +{ + timer.suspend(); + FDialog::box( parent, typ, msg ); + timer.resume(); +} + + +QVariant // public static +KGVerify::getConf( void *, const char *key, const QVariant &dflt ) +{ + if (!qstrcmp( key, "EchoMode" )) + return QVariant( _echoMode ); + else { + QString fkey = QString::fromLatin1( key ) + '='; + for (QStringList::ConstIterator it = _pluginOptions.begin(); + it != _pluginOptions.end(); ++it) + if ((*it).startsWith( fkey )) + return (*it).mid( fkey.length() ); + return dflt; + } +} + +QValueVector<GreeterPluginHandle> KGVerify::greetPlugins; + +PluginList +KGVerify::init( const QStringList &plugins ) +{ + PluginList pluginList; + + for (QStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) { + GreeterPluginHandle plugin; + QString path = KLibLoader::self()->findLibrary( + ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() ); + if (path.isEmpty()) { + LogError( "GreeterPlugin %s does not exist\n", (*it).latin1() ); + continue; + } + uint i, np = greetPlugins.count(); + for (i = 0; i < np; i++) + if (greetPlugins[i].library->fileName() == path) + goto next; + if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) { + LogError( "Cannot load GreeterPlugin %s (%s)\n", (*it).latin1(), path.latin1() ); + continue; + } + if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) { + LogError( "GreeterPlugin %s (%s) is no valid greet widget plugin\n", + (*it).latin1(), path.latin1() ); + plugin.library->unload(); + continue; + } + plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" ); + if (!plugin.info->init( QString::null, getConf, 0 )) { + LogError( "GreeterPlugin %s (%s) refuses to serve\n", + (*it).latin1(), path.latin1() ); + plugin.library->unload(); + continue; + } + Debug( "GreeterPlugin %s (%s) loaded\n", (*it).latin1(), plugin.info->name ); + greetPlugins.append( plugin ); + next: + pluginList.append( i ); + } + return pluginList; +} + +void +KGVerify::done() +{ + for (uint i = 0; i < greetPlugins.count(); i++) { + if (greetPlugins[i].info->done) + greetPlugins[i].info->done(); + greetPlugins[i].library->unload(); + } +} + + +KGStdVerify::KGStdVerify( KGVerifyHandler *_handler, QWidget *_parent, + QWidget *_predecessor, const QString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited( _handler, 0, _parent, _predecessor, _fixedUser, + _pluginList, _func, _ctx ) + , failedLabelState( 0 ) +{ + grid = new QGridLayout; + grid->setAlignment( AlignCenter ); + + failedLabel = new QLabel( parent ); + failedLabel->setFont( _failFont ); + grid->addWidget( failedLabel, 1, 0, AlignCenter ); + + updateLockStatus(); +} + +KGStdVerify::~KGStdVerify() +{ + grid->removeItem( greet->getLayoutItem() ); +} + +void // public +KGStdVerify::selectPlugin( int id ) +{ + inherited::selectPlugin( id ); + grid->addItem( greet->getLayoutItem(), 0, 0 ); + showWidgets( greet->getLayoutItem() ); +} + +void // private slot +KGStdVerify::slotPluginSelected( int id ) +{ + if (failed) + return; + if (id != curPlugin) { + plugMenu->setItemChecked( curPlugin, false ); + parent->setUpdatesEnabled( false ); + grid->removeItem( greet->getLayoutItem() ); + Debug( "delete %s\n", pName.data() ); + delete greet; + selectPlugin( id ); + handler->verifyPluginChanged( id ); + if (running) + start(); + parent->setUpdatesEnabled( true ); + } +} + +void +KGStdVerify::updateStatus() +{ + int nfls; + + if (!enabled) + nfls = 1; + else if (failed) + nfls = 2; + else if (timedLeft) + nfls = -timedLeft; + else if (!suspended && capsLocked) + nfls = 3; + else + nfls = 1; + + if (failedLabelState != nfls) { + failedLabelState = nfls; + if (nfls < 0) { + failedLabel->setPaletteForegroundColor( Qt::black ); + failedLabel->setText( i18n( "Automatic login in 1 second...", + "Automatic login in %n seconds...", + timedLeft ) ); + } else { + switch (nfls) { + default: + failedLabel->clear(); + break; + case 3: + failedLabel->setPaletteForegroundColor( Qt::red ); + failedLabel->setText( i18n("Warning: Caps Lock on") ); + break; + case 2: + failedLabel->setPaletteForegroundColor( Qt::black ); + failedLabel->setText( authTok ? + i18n("Change failed") : + fixedEntity.isEmpty() ? + i18n("Login failed") : + i18n("Authentication failed") ); + break; + } + } + } +} + +KGThemedVerify::KGThemedVerify( KGVerifyHandler *_handler, + KdmThemer *_themer, + QWidget *_parent, QWidget *_predecessor, + const QString &_fixedUser, + const PluginList &_pluginList, + KGreeterPlugin::Function _func, + KGreeterPlugin::Context _ctx ) + : inherited( _handler, _themer, _parent, _predecessor, _fixedUser, + _pluginList, _func, _ctx ) +{ + updateLockStatus(); +} + +KGThemedVerify::~KGThemedVerify() +{ +} + +void // public +KGThemedVerify::selectPlugin( int id ) +{ + inherited::selectPlugin( id ); + QLayoutItem *l; + KdmItem *n; + if (themer && (l = greet->getLayoutItem())) { + if (!(n = themer->findNode( "talker" ))) + MsgBox( errorbox, + i18n("Theme not usable with authentication method '%1'.") + .arg( i18n(greetPlugins[pluginList[id]].info->name) ) ); + else { + n->setLayoutItem( l ); + showWidgets( l ); + } + } + if (themer) + themer->updateGeometry( true ); +} + +void // private slot +KGThemedVerify::slotPluginSelected( int id ) +{ + if (failed) + return; + if (id != curPlugin) { + plugMenu->setItemChecked( curPlugin, false ); + Debug( "delete %s\n", pName.data() ); + delete greet; + selectPlugin( id ); + handler->verifyPluginChanged( id ); + if (running) + start(); + } +} + +void +KGThemedVerify::updateStatus() +{ + handler->updateStatus( enabled && failed, + enabled && !suspended && capsLocked, + timedLeft ); +} + + +KGChTok::KGChTok( QWidget *_parent, const QString &user, + const PluginList &pluginList, int curPlugin, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ) + : inherited( _parent ) + , verify( 0 ) +{ + QSizePolicy fp( QSizePolicy::Fixed, QSizePolicy::Fixed ); + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + + verify = new KGStdVerify( this, this, cancelButton, user, pluginList, func, ctx ); + verify->selectPlugin( curPlugin ); + + QVBoxLayout *box = new QVBoxLayout( this, 10 ); + + box->addWidget( new QLabel( i18n("Changing authentication token"), this ), 0, AlignHCenter ); + + box->addLayout( verify->getLayout() ); + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + QHBoxLayout *hlay = new QHBoxLayout( box ); + hlay->addStretch( 1 ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + + connect( okButton, SIGNAL(clicked()), SLOT(accept()) ); + connect( cancelButton, SIGNAL(clicked()), SLOT(reject()) ); + + QTimer::singleShot( 0, verify, SLOT(start()) ); +} + +KGChTok::~KGChTok() +{ + hide(); + delete verify; +} + +void +KGChTok::accept() +{ + verify->accept(); +} + +void +KGChTok::verifyPluginChanged( int ) +{ + // cannot happen +} + +void +KGChTok::verifyOk() +{ + inherited::accept(); +} + +void +KGChTok::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +KGChTok::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +KGChTok::verifySetUser( const QString & ) +{ + // cannot happen +} + + +////// helper class, nuke when qtimer supports suspend()/resume() + +QXTimer::QXTimer() + : inherited( 0 ) + , left( -1 ) +{ + connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) ); +} + +void +QXTimer::start( int msec ) +{ + left = msec; + timer.start( left, true ); + gettimeofday( &stv, 0 ); +} + +void +QXTimer::stop() +{ + timer.stop(); + left = -1; +} + +void +QXTimer::suspend() +{ + if (timer.isActive()) { + timer.stop(); + struct timeval tv; + gettimeofday( &tv, 0 ); + left -= (tv.tv_sec - stv.tv_sec) * 1000 + (tv.tv_usec - stv.tv_usec) / 1000; + if (left < 0) + left = 0; + } +} + +void +QXTimer::resume() +{ + if (left >= 0 && !timer.isActive()) { + timer.start( left, true ); + gettimeofday( &stv, 0 ); + } +} + +void +QXTimer::slotTimeout() +{ + left = 0; + emit timeout(); +} + + +#include "kgverify.moc" diff --git a/kdm/kfrontend/kgverify.h b/kdm/kfrontend/kgverify.h new file mode 100644 index 000000000..a0d285e3d --- /dev/null +++ b/kdm/kfrontend/kgverify.h @@ -0,0 +1,248 @@ +/* + +Shell for kdm conversation plugins + +Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> +Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org> + + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + + +#ifndef KGVERIFY_H +#define KGVERIFY_H + +#include "kgreeterplugin.h" +#include "kfdialog.h" + +#include <qlayout.h> +#include <qtimer.h> +#include <qvaluevector.h> + +#include <sys/time.h> +#include <time.h> + +// helper class, nuke when qt supports suspend()/resume() +class QXTimer : public QObject { + Q_OBJECT + typedef QObject inherited; + + public: + QXTimer(); + void start( int msec ); + void stop(); + void suspend(); + void resume(); + + signals: + void timeout(); + + private slots: + void slotTimeout(); + + private: + QTimer timer; + struct timeval stv; + long left; +}; + +class KGVerifyHandler { + public: + virtual void verifyPluginChanged( int id ) = 0; + virtual void verifyClear(); + virtual void verifyOk() = 0; + virtual void verifyFailed() = 0; + virtual void verifyRetry() = 0; + virtual void verifySetUser( const QString &user ) = 0; + virtual void updateStatus( bool fail, bool caps, int left ); // for themed only +}; + +class QWidget; +class QLabel; +class QPopupMenu; +class QTimer; +class KPushButton; +class KLibrary; + +struct GreeterPluginHandle { + KLibrary *library; + kgreeterplugin_info *info; +}; + +typedef QValueVector<int> PluginList; + +class KGVerify : public QObject, public KGreeterPluginHandler { + Q_OBJECT + typedef QObject inherited; + + public: + KGVerify( KGVerifyHandler *handler, KdmThemer *themer, + QWidget *parent, QWidget *predecessor, + const QString &fixedEntity, const PluginList &pluginList, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + virtual ~KGVerify(); + QPopupMenu *getPlugMenu(); + void loadUsers( const QStringList &users ); + void presetEntity( const QString &entity, int field ); + QString getEntity() const; + void setUser( const QString &user ); + /* virtual */ void selectPlugin( int id ); + bool entitiesLocal() const; + bool entitiesFielded() const; + bool entityPresettable() const; + bool isClassic() const; + QString pluginName() const; + void setEnabled( bool on ); + void abort(); + void suspend(); + void resume(); + void accept(); + void reject(); + + int coreLock; + + static bool handleFailVerify( QWidget *parent ); + static PluginList init( const QStringList &plugins ); + static void done(); + + public slots: + void start(); + + protected: + bool eventFilter( QObject *, QEvent * ); + void MsgBox( QMessageBox::Icon typ, const QString &msg ); + void setTimer(); + void updateLockStatus(); + virtual void updateStatus() = 0; + void handleVerify(); + + QXTimer timer; + QString fixedEntity, presEnt, curUser; + PluginList pluginList; + KGVerifyHandler *handler; + KdmThemer *themer; + QWidget *parent, *predecessor; + KGreeterPlugin *greet; + QPopupMenu *plugMenu; + int curPlugin, presFld, timedLeft, deadTicks; + QCString pName; + KGreeterPlugin::Function func; + KGreeterPlugin::Context ctx; + bool capsLocked; + bool enabled, running, suspended, failed, delayed, cont; + bool authTok, isClear, timeable; + + static void VMsgBox( QWidget *parent, const QString &user, QMessageBox::Icon type, const QString &mesg ); + static void VErrBox( QWidget *parent, const QString &user, const char *msg ); + static void VInfoBox( QWidget *parent, const QString &user, const char *msg ); + + static QValueVector<GreeterPluginHandle> greetPlugins; + + private: + bool applyPreset(); + void performAutoLogin(); + bool scheduleAutoLogin( bool initial ); + void doReject( bool initial ); + + private slots: + //virtual void slotPluginSelected( int id ) = 0; + void slotTimeout(); + void slotActivity(); + + public: // from KGreetPluginHandler + virtual void gplugReturnText( const char *text, int tag ); + virtual void gplugReturnBinary( const char *data ); + virtual void gplugSetUser( const QString &user ); + virtual void gplugStart(); + virtual void gplugActivity(); + virtual void gplugMsgBox( QMessageBox::Icon type, const QString &text ); + + static QVariant getConf( void *ctx, const char *key, const QVariant &dflt ); +}; + +class KGStdVerify : public KGVerify { + Q_OBJECT + typedef KGVerify inherited; + + public: + KGStdVerify( KGVerifyHandler *handler, QWidget *parent, + QWidget *predecessor, const QString &fixedEntity, + const PluginList &pluginList, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + virtual ~KGStdVerify(); + QLayout *getLayout() const { return grid; } + void selectPlugin( int id ); + + protected: + void updateStatus(); + + private: + QGridLayout *grid; + QLabel *failedLabel; + int failedLabelState; + + private slots: + void slotPluginSelected( int id ); +}; + +class KGThemedVerify : public KGVerify { + Q_OBJECT + typedef KGVerify inherited; + + public: + KGThemedVerify( KGVerifyHandler *handler, KdmThemer *themer, + QWidget *parent, QWidget *predecessor, + const QString &fixedEntity, + const PluginList &pluginList, + KGreeterPlugin::Function func, + KGreeterPlugin::Context ctx ); + virtual ~KGThemedVerify(); + void selectPlugin( int id ); + + protected: + void updateStatus(); + + private slots: + void slotPluginSelected( int id ); +}; + +class KGChTok : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + + public: + KGChTok( QWidget *parent, const QString &user, + const PluginList &pluginList, int curPlugin, + KGreeterPlugin::Function func, KGreeterPlugin::Context ctx ); + ~KGChTok(); + + public slots: + void accept(); + + private: + KPushButton *okButton, *cancelButton; + KGStdVerify *verify; + + public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const QString &user ); +}; + +#endif /* KGVERIFY_H */ diff --git a/kdm/kfrontend/krootimage.cpp b/kdm/kfrontend/krootimage.cpp new file mode 100644 index 000000000..c630d9fa7 --- /dev/null +++ b/kdm/kfrontend/krootimage.cpp @@ -0,0 +1,122 @@ +/* + +Copyright (C) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> +Copyright (C) 2002,2004 Oswald Buddenhagen <ossi@kde.org> + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License version 2 as published by the Free Software Foundation. + +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; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. + +*/ + +#include <config.h> + +#include <kcmdlineargs.h> +#include <ksimpleconfig.h> +#include <klocale.h> + +#include <qfile.h> + +#include "krootimage.h" + +#include <X11/Xlib.h> + +#include <stdlib.h> + +static const char description[] = + I18N_NOOP( "Fancy desktop background for kdm" ); + +static const char version[] = "v2.0"; + +static KCmdLineOptions options[] = { + { "+config", I18N_NOOP( "Name of the configuration file" ), 0 }, + KCmdLineLastOption +}; + + +MyApplication::MyApplication( const char *conf ) + : KApplication(), + renderer( 0, new KSimpleConfig( QFile::decodeName( conf ) ) ) +{ + connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) ); + connect( &renderer, SIGNAL(imageDone( int )), this, SLOT(renderDone()) ); + renderer.enableTiling( true ); // optimize + renderer.changeWallpaper(); // cannot do it when we're killed, so do it now + timer.start( 60000 ); + renderer.start(); +} + + +void +MyApplication::renderDone() +{ + desktop()->setBackgroundPixmap( renderer.pixmap() ); + desktop()->repaint( true ); + renderer.saveCacheFile(); + renderer.cleanup(); + for (unsigned i=0; i<renderer.numRenderers(); ++i) + { + KBackgroundRenderer * r = renderer.renderer(i); + if (r->backgroundMode() == KBackgroundSettings::Program || + (r->multiWallpaperMode() != KBackgroundSettings::NoMulti && + r->multiWallpaperMode() != KBackgroundSettings::NoMultiRandom)) + return; + } + quit(); +} + +void +MyApplication::slotTimeout() +{ + bool change = false; + + if (renderer.needProgramUpdate()) { + renderer.programUpdate(); + change = true; + } + + if (renderer.needWallpaperChange()) { + renderer.changeWallpaper(); + change = true; + } + + if (change) + renderer.start(); +} + +int +main( int argc, char *argv[] ) +{ + KApplication::disableAutoDcopRegistration(); + + KLocale::setMainCatalogue( "kdesktop" ); + KCmdLineArgs::init( argc, argv, "krootimage", I18N_NOOP( "KRootImage" ), description, version ); + KCmdLineArgs::addCmdLineOptions( options ); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (!args->count()) + args->usage(); + MyApplication app( args->arg( 0 ) ); + args->clear(); + + app.exec(); + + app.flushX(); + + // Keep color resources after termination + XSetCloseDownMode( qt_xdisplay(), RetainTemporary ); + + return 0; +} + +#include "krootimage.moc" diff --git a/kdm/kfrontend/krootimage.h b/kdm/kfrontend/krootimage.h new file mode 100644 index 000000000..608cfa3a1 --- /dev/null +++ b/kdm/kfrontend/krootimage.h @@ -0,0 +1,48 @@ +/* + +Copyright (C) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> +Copyright (C) 2002,2004 Oswald Buddenhagen <ossi@kde.org> + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public +License version 2 as published by the Free Software Foundation. + +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; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. + +*/ + +#ifndef __KDMDESKTOP_H__ +#define __KDMDESKTOP_H__ + + +#include <kapplication.h> +#include <qtimer.h> + +#include <bgrender.h> + + +class MyApplication : public KApplication +{ + Q_OBJECT + + public: + MyApplication( const char * ); + + private slots: + void renderDone(); + void slotTimeout(); + + private: + KVirtualBGRenderer renderer; + QTimer timer; +}; + +#endif diff --git a/kdm/kfrontend/pics/Makefile.am b/kdm/kfrontend/pics/Makefile.am new file mode 100644 index 000000000..d6b8957e8 --- /dev/null +++ b/kdm/kfrontend/pics/Makefile.am @@ -0,0 +1,9 @@ + +picsdir = $(kde_datadir)/kdm/pics +pics_DATA = kdelogo.png kdelogo-crystal.png shutdown.jpg + +usersdir = $(picsdir)/users +users_DATA = default1.png default2.png default3.png root1.png + + +EXTRA_DIST = $(pics_DATA) $(users_DATA) diff --git a/kdm/kfrontend/pics/default1.png b/kdm/kfrontend/pics/default1.png Binary files differnew file mode 100644 index 000000000..ef3aef3f9 --- /dev/null +++ b/kdm/kfrontend/pics/default1.png diff --git a/kdm/kfrontend/pics/default2.png b/kdm/kfrontend/pics/default2.png Binary files differnew file mode 100644 index 000000000..194acfe2c --- /dev/null +++ b/kdm/kfrontend/pics/default2.png diff --git a/kdm/kfrontend/pics/default3.png b/kdm/kfrontend/pics/default3.png Binary files differnew file mode 100644 index 000000000..a8663b15e --- /dev/null +++ b/kdm/kfrontend/pics/default3.png diff --git a/kdm/kfrontend/pics/kdelogo-crystal.png b/kdm/kfrontend/pics/kdelogo-crystal.png Binary files differnew file mode 100644 index 000000000..592a7e321 --- /dev/null +++ b/kdm/kfrontend/pics/kdelogo-crystal.png diff --git a/kdm/kfrontend/pics/kdelogo.png b/kdm/kfrontend/pics/kdelogo.png Binary files differnew file mode 100644 index 000000000..bd4e199e5 --- /dev/null +++ b/kdm/kfrontend/pics/kdelogo.png diff --git a/kdm/kfrontend/pics/root1.png b/kdm/kfrontend/pics/root1.png Binary files differnew file mode 100644 index 000000000..fced75c11 --- /dev/null +++ b/kdm/kfrontend/pics/root1.png diff --git a/kdm/kfrontend/pics/shutdown.jpg b/kdm/kfrontend/pics/shutdown.jpg Binary files differnew file mode 100644 index 000000000..f1353c54b --- /dev/null +++ b/kdm/kfrontend/pics/shutdown.jpg diff --git a/kdm/kfrontend/sessions/9wm.desktop b/kdm/kfrontend/sessions/9wm.desktop new file mode 100644 index 000000000..d17276782 --- /dev/null +++ b/kdm/kfrontend/sessions/9wm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=9wm +TryExec=9wm +Name=9WM +Name[cy]= 9WM +Name[eo]=9FA +Name[hi]=9डबल्यू-एम +Name[ta]=9 WM +Name[te]=9 డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง gWM +Comment=An emulation of the Plan 9 window manager 8-1/2 +Comment[af]='n Nabootsing van die 'Plan 9' venster bestuurder +Comment[be]=Эмуляцыя кіраўніка вокнаў 8-1/2 для Plan 9 +Comment[bn]=প্ল্যান ৯ উইণ্ডো ম্যানেজার ৮-১/২ -এর এমুলেশন +Comment[bs]=Simulacija Plan 9 window managera 8-1/2 +Comment[ca]=Una emulació del gestor de finestres Plan 9 +Comment[cs]=Emulace Plane 9 správce oken 8-1/2 +Comment[csb]=Emùlacëjô menedżera òknów Plan 9 - 8-1/2 +Comment[cy]=Efelychiad o 8-1/2, y trefnydd ffenestri Plan 9 +Comment[da]=En emulering af Plan 9 vindueshåndteringen 8-1/2 +Comment[de]=Emulation des Plan 9-Fenstermanagers 8-1/2 +Comment[el]=Μια προσομοίωση του Plan 9 διαχειριστή παραθύρων 8-1/2 +Comment[eo]=KDE-fenestroadministrilo de plano 9 +Comment[es]=Una emulación del gestor de ventanas Plan 9 8-1/2 +Comment[et]=Plan 9 aknahalduri 8-1/2 emuleerimine +Comment[eu]=Plan 9 8-1/2 leiho kudeatzailearen emulazioa +Comment[fa]=تقلیدی از نقشۀ مدیر پنجره ۹. ۸-۱/ ۲ +Comment[fi]=Emulaatio Plan9-ikkunaohjelmasta 8-1/2 +Comment[fr]=Une émulation du gestionnaire de fenêtres Plan 9 8-1/2 +Comment[fy]=In emulator foar de Plan9 finstersbehearder 8-1/2 +Comment[gl]=Unha emulación do xestor de fiestras de Plan9 +Comment[he]=מדמה של מנהל חלונות Plan 9 8-1/2 +Comment[hi]=प्लान 9 विंडो प्रबंधक 8-1/2 का एक एमुलेशन +Comment[hr]=Emulacija Plan 9 upravitelja prozora 8-1/2 +Comment[hu]=A Plan 9 operációs rendszer 8-1/2 nevű ablakkezelőjének emulálása +Comment[is]=Eftirlíking af Plan 9 gluggastjóranum 8-1/2 +Comment[it]=Un emulatore del window manager 8-1/2 Plan 9 +Comment[ja]=Plan9 ウィンドウマネージャのエミュレーション 8-1/2 +Comment[ka]=Plan 9 ფანჯრის მმართველის ემულატორი +Comment[kk]=Plan 9 терезе менеджерінің эмуляторы +Comment[km]=ការត្រាប់តាមកម្មវិធីគ្រប់គ្រងបង្អួច Plan 9 8-1/2 +Comment[ko]=Plan 9 창 관리자 8-1/2 에뮬레이션 +Comment[lt]=Plan 9 langų tvarkyklės emuliatorius 8-1/2 +Comment[lv]=Plan 9 logu menedžera emulators 8-1/2 +Comment[mk]=Емулација на менаџерот на прозорци Plan 9 8-1/2 +Comment[ms]=Pelagakan Plan 9 pengurus tetingkap 8-1/2 +Comment[mt]=Emulazzjoni tal-window manager "Plan 9" 8½ +Comment[nb]=En emulering av vindusbehandleren 8 ½ fra Plan 9 +Comment[nds]=Emuleert den Plan-9-Finsterpleger 8-1/2 +Comment[ne]=योजना 9 सञ्झ्याल प्रबन्धक 8-1/2 को इमुलेसन +Comment[nl]=Een emulator voor de Plan9 windowmanager 8-1/2 +Comment[nn]=Emulering av vindaugssjefen 8 ½ frå Plan 9 +Comment[pa]=ਪਲੇਨ 9 ਝਰੋਖਾ ਮੈਨੇਜਰ 8-1/2 ਦਾ ਸਮਰੂਪ +Comment[pl]=Emulacja menedżera okien Plan 9 - 8-1/2 +Comment[pt]=Uma emulação do gestor de janelas do Plan 9 8-1/2 +Comment[pt_BR]=Uma emulação do gerenciador de janelas do Plan 9 +Comment[ro]=Un emulator al managerului de ferestre 8-1/2 din Plan 9 +Comment[ru]=Эмуляция оконного менеджера Plan 9 +Comment[rw]=Ikurura rya mugenga dirishya 8-1/2 Plan 9 +Comment[se]=Lásegieđahalli mii áddestaddá Plan 9 lásegieđahalli 8-1/2. +Comment[sk]=Emulácia správcu okien 8-1/2 systému Plan 9 +Comment[sl]=Emulacija okenskega upravitelja Plan 9 8-1/2 +Comment[sr]=Емулација Plan 9 менаџера прозора 8-1/2 +Comment[sr@Latn]=Emulacija Plan 9 menadžera prozora 8-1/2 +Comment[sv]=Emulering av Plan-9-fönsterhanteraren 8-1/2 +Comment[ta]= திட்டம் 9 சாளர மேலாளர் 8-1/2 இன் முன்மாதிரி +Comment[tg]=Эмулятори нақшаи 9-и мудири тирезаи 8-1/2 +Comment[th]=การจำลองตัวจัดการหน้าต่าง Plan 9 8-1/2 +Comment[tr]=Plan 9 pencere yöneticisi 8-1/2 için bir emülasyon +Comment[tt]=Plan 9 atlı täräzä idäräçenä axşap eşläw +Comment[uk]=Емуляція менеджера вікон Plan 9 "8-1/2" +Comment[vi]=Một bộ mô phỏng bộ quản lý cửa sổ Plan 9 8-1/2 +Comment[wa]=Ene emulåcion do manaedjeu di purneas di Plan 9 +Comment[zh_CN]=Plan 9 窗口管理器 8-1/2 的模拟 +Comment[zh_TW]=模仿 Plan 9 的視窗管理程式 8-1/2 diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am new file mode 100644 index 000000000..14577ac42 --- /dev/null +++ b/kdm/kfrontend/sessions/Makefile.am @@ -0,0 +1,49 @@ +sessionsdir = $(kde_datadir)/kdm/sessions +sessions_DATA = \ + kde.desktop gnome.desktop \ + 9wm.desktop \ + aewm++.desktop \ + aewm.desktop \ + afterstep.desktop \ + amaterus.desktop \ + amiwm.desktop \ + asclassic.desktop \ + blackbox.desktop \ + cde.desktop \ + ctwm.desktop \ + cwwm.desktop \ + enlightenment.desktop \ + evilwm.desktop \ + fluxbox.desktop \ + flwm.desktop \ + fvwm.desktop \ + fvwm95.desktop \ + golem.desktop \ + icewm.desktop \ + ion.desktop \ + larswm.desktop \ + lwm.desktop \ + matchbox.desktop \ + metacity.desktop \ + mwm.desktop \ + olvwm.desktop \ + olwm.desktop \ + openbox.desktop \ + oroborus.desktop \ + phluid.desktop \ + pwm.desktop \ + qvwm.desktop \ + ratpoison.desktop \ + sapphire.desktop \ + sawfish.desktop \ + twm.desktop \ + ude.desktop \ + vtwm.desktop \ + w9wm.desktop \ + waimea.desktop \ + wm2.desktop \ + wmaker.desktop \ + xfce.desktop \ + xfce4.desktop + +EXTRA_DIST = $(sessions_DATA) diff --git a/kdm/kfrontend/sessions/aewm++.desktop b/kdm/kfrontend/sessions/aewm++.desktop new file mode 100644 index 000000000..3eb4ee8e8 --- /dev/null +++ b/kdm/kfrontend/sessions/aewm++.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=aewm++_xsession +TryExec=aewm++_xsession +Name=AEWM++ +Name[eo]=MFA++ +Name[hi]=एईडबल्यूएम++ +Name[te]=ఎ ఈ డబ్ల్యు ఎం ++ +Comment=A minimal window manager based on AEWM, enhanced by virtual desktops and partial GNOME support +Comment[af]='n Minimale venster bestuurder wat op AEWM gebaseer is. Dit is verbeter met virtuale werkskerms en gedeeltelike GNOME ondersteuning +Comment[ar]=مدير نوافذ مصغّر مبني على AEWM، محسّن بأسطح مكتب وهمية ودعم جينوم جزئي +Comment[be]=Мінімалістычны кіраўнік вокнаў, заснаваны на AEWM, з віртуальнымі працоўнымі сталамі і частковай падтрымкай GNOME +Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার, ভার্চুয়াল ডেস্কটপ এবং আংশিক গনোম সমর্থন দ্বারা বর্ধিত +Comment[bs]=Minimalni window manager baziran na AEWM, proširen virtuelnim desktopima i djelomičnom GNOME podrškom +Comment[ca]=Un gestor de finestres minimalista basat en AEWM, orientat a escriptoris virtuals i funcionament parcial per a GNOME +Comment[cs]=Minimalizovaný správce oken založený na AEWM rozšířený o virtuální plochy a částečnou podporu GNOME +Comment[csb]=Prosti menedżer òknów na spòdlém AEWM, zbògacony o wirtualné pùltë ë dzélowé wspiarce dlô GNOME +Comment[cy]= Trefnydd ffenestri lleiafol wed'i seilio ar AEWM, wedi'i wella gan penbyrddau rhith a cynhaliaeth Gnome rhannol. +Comment[da]=En minimal vindueshåndtering baseret på AEWM, udvidet med virtuelle desktoppe og delvis GNOME-støtte +Comment[de]=Minimalistischer Fenstermanager. Beruht auf AEWM, verbessert durch virtuelle Arbeitsflächen und teilweise GNOME-Unterstützung +Comment[el]=Ένας μικρός διαχειριστής παραθύρων βασισμένος στον AEWM, εμπλουτισμένος με εικονικές επιφάνειες εργασίας και μερική υποστήριξη GNOME +Comment[eo]=Minimuma fenestroadministrilo el MFA, plibonigita per virtualaj labortabloj kaj parta helpo por Gnomikuo +Comment[es]=Un gestor de ventanas minimalista basado en AEWM, mejorado con soporte para escritorios virtailes y, parcialmente, GNOME +Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM ja mida on täiendatud virtuaalsete töölaudade ning osalise GNOME toetusega +Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimoa, mahaigain birtualen euskarriaz eta, zati batez, GNOMEz hobetua +Comment[fa]= مدیر پنجرۀ کمینه بر اساس AEWM، گسترشیافته توسط رومیزیهای مجازی و پشتیبانی جزئی GNOME +Comment[fi]=Minimaalinen AEWM:ään pohjautuva ikkunaohjelma, jota on parannettuna virtuaalityöpöydillä ja osittaisella GNOME-tuella +Comment[fr]=Un gestionnaire de fenêtres minimal fondé sur AEWM avec, en plus, la gestion des bureaux virtuels ainsi qu'un support partiel de GNOME +Comment[fy]=In minimalistyske finstersmanager basearre op AEWM, útbreide mei firtuele buroblêden en gedieltelike GNOME-stipe +Comment[gl]=Un xestor de fiestras mínimo baseado en AEWM, mellorado cos escritórios virtuais e con soporte parcial para GNOME +Comment[he]=מנהל חלונות מינימלי המבוסס על AEWM, המשופר על ידי שולחנות עבודה וירטואליים ותמיכה חלקית ב GNOME +Comment[hi]= एईडबल्यूएम आधारित अल्प विंडो प्रबंधक, आभासी डेस्कटॉप तथा आंशिक ग्नोम समर्थन से बेहतर बनाया गया +Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM, unaprijeđen virtualnim radnim površinama i djelomičnom podrškom za GNOME +Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján, virtuális munkaasztalokkal és részleges GNOME-támogatással kiegészítve +Comment[is]=Einfaldur gluggastjóri byggður á AEWM en með stuðningi fyrir sýndarskjáborð og takmörkuðum GNOME stuðningi +Comment[it]= Un window manager minimale basato su AEWM, migliorato con desktop virtuali e supporto parziale per GNOME +Comment[ja]=仮想デスクトップと部分的な GNOME サポートを強化した AEWM ベースの小さなウィンドウマネージャ +Comment[ka]=მინიმალური ფანჯრის მენეჯერი AEWM -ის ბაზაზე, имеющий частичную поддержку GNOME. +Comment[kk]=Виртуалды үстелдері және шамалы GNOME қолдауы бар AEWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចតូច ដែលផ្អែកលើ AEWM ដែលធ្វើឲ្យប្រសើរដោយផ្ទៃតុនិមិត្ត និងការគាំទ្រ GNOME +Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė paremta AEWM, išplėsta virtualių darbastalių ir daliniu GNOME palaikymu +Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM, papildināts ar virtuālajām darbvirsmām un daļēju GNOME atbalstu +Comment[mk]=Минимален менаџер на прозорци базиран на AEWM, подобрен со виртуелни површини и парцијална GNOME поддршка +Comment[ms]=Pengurus tetingkap minima berdasarkan AEWM, dipertingkatkan dengan desktop visual dan sokongan GNOME separa +Comment[mt]=Window manager żgħir ibbażat fuq AEWM, filmkien ma' desktops virtwali u sapport parzjali għal GNOME. +Comment[nb]=En minimal vindusbehandler basert på AEWM, forbedret med virtuelle skrivebord og delvis støtte for GNOME +Comment[nds]=En minimaal Finsterpleger, opbuut op AEWM, verwiedert üm virtuelle Schriefdischen un deelwies Ünnerstütten för GNOME +Comment[ne]=अवास्तविक डेस्कटप र आंशिक GNOME समर्थनद्वारा बृद्धि गरिएको AEWM मा आधारित न्यूनतम सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM, uitgebreid met virtuele bureaubladen en gedeeltelijke GNOME-ondersteuning +Comment[nn]=Ein minimal vindaugssjef basert på AEWM, forbetra med virtuelle skrivebord og delvis støtte for GNOME +Comment[pa]= AEWM ਤੇ ਅਧਾਰਿਤ ਛੋਟਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਨਾਲ ਲੈੱਸ ਤੇ ਥੋੜਾ GNOME ਸਹਾਇਕ +Comment[pl]=Prosty menedżer okien na bazie AEWM, wzbogacony o wirtualne pulpity i częściowe wsparcie dla GNOME +Comment[pt]=Um gestor de janelas simples baseado no AEWM, melhorado com os ecrãs virtuais e com um suporte parcial do GNOME +Comment[pt_BR]=Um gerenciador de janelas pequeno, baseado no AEWM, melhorado pelas áreas de trabalho virtuais e com suporte parcial ao GNOME +Comment[ro]=Un manager de ferestre minimal bazat pe AEWM, îmbunătățit cu ecrane virtuale și suport parțial pentru GNOME +Comment[ru]=Минимальный оконный менеджер на основе AEWM, имеющий частичную поддержку GNOME. +Comment[rw]=Mugenga dirishya nto ishingiye kuri AEWM, rivuguruwe n'ibiro bitagaragara n'iyifashisha GNOME rituzuye +Comment[se]=Geahpes lásegieđahalli vuođđoduvvon AEWM:as, mas leat virtuella čállinbeavddit ja doarju GNOME muhton muddui. +Comment[sk]=Minimálny správca okien založený na AEWM, rozšírrený o virtuálne plochy a čiastočnú podporu GNOME +Comment[sl]=Skromen okenski upavitelj na osnovi AEWM, izboljšan z navideznimi namizji in delno podporo GNOME +Comment[sr]=Минимални менаџер прозора заснован на AEWM-у, побољшан виртуелним радним површинама и делимичном подршком за Гном +Comment[sr@Latn]=Minimalni menadžer prozora zasnovan na AEWM-u, poboljšan virtuelnim radnim površinama i delimičnom podrškom za Gnom +Comment[sv]=Minimal fönsterhanterare baserad på AEWM, utökad med virtuella skrivbord och delvis stöd för Gnome +Comment[ta]=AEWM அடிப்படையிலான சிறிய சாளர மேலாண்மை, மெய்நிகர் மேல்மேசை மற்றும் பகுதி GNOME ஆதரவால் மேப்படுத்தப்பட்டுள்ளது +Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM дорои нопурраи интерфейси GNOME +Comment[th]=ตัวจัดการหน้าต่างขนาดเล็ก โดยใช้พื้นฐานของ AEWM แล้วเพิ่มความสามารถด้วย พื้นที่ทำงานเสมือน และสนับสนุน GNOME บางส่วน +Comment[tr]=AEWM tabanlı bir pencere yöneticisi +Comment[tt]=AEWM asılında yasalğan, xıyalí öställär belän beraz GNOME totqan ciñel täräzä-idäräçe +Comment[uk]=Мінімальний менеджер вікон, заснований на AEWM, покращений підтримкою віртуальних стільниць та частковою підтримкою GNOME +Comment[vi]=Bộ quản lý cửa sổ tối thiểu dựa trên AEWM, cải tiến với màn hình nền ảo và được hỗ trợ một phần bởi GNOME +Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM, avou sopoirt po les forveyous scribannes eyet ene miete di sopoirt po Gnome +Comment[zh_CN]=基于 AEWM 的小型窗口管理器,增强了虚拟桌面和部分 GNOME 支持 +Comment[zh_TW]=基於 AEWM 的小型視窗管理程式,增強了虛擬桌面及部分的 GNOME 支援 diff --git a/kdm/kfrontend/sessions/aewm.desktop b/kdm/kfrontend/sessions/aewm.desktop new file mode 100644 index 000000000..362fd921f --- /dev/null +++ b/kdm/kfrontend/sessions/aewm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=aewm +TryExec=aewm +Name=AEWM +Name[eo]=MFA +Name[hi]=एईडबल्यूएम +Name[te]=ఎ ఈ డబ్ల్యు ఎం +Comment=A minimalist window manager +Comment[af]='n Minimale venster bestuurder +Comment[ar]=مسيير نوافذ ذو الميزات الأقل +Comment[be]=Мінімалістычны кіраўнік вокнаў +Comment[bn]=একটি পরিমিত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalistički window manager +Comment[ca]=Un gestor de finestres minimalista +Comment[cs]=Minimalistický správce oken +Comment[csb]=Prosti menedżer òknów +Comment[cy]=Trefnydd ffenestri lleiafol +Comment[da]=En minimalistisk vindueshåndtering +Comment[de]=Minimalistischer Fenstermanager +Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων +Comment[eo]=Minimumema fenestroadministrilo +Comment[es]=Un gestor de ventanas minimalista +Comment[et]=Vähenõudlik aknahaldur +Comment[eu]=Leiho kudeatzaile minimalista +Comment[fa]=یک مدیر پنجرۀ کمینه +Comment[fi]=Minimalistinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres minimaliste +Comment[fy]=In minimalistyske finstersmanager +Comment[gl]=Un xestor de fiestras minimalista +Comment[he]=מנהל חלונות מינימליסטי +Comment[hi]=एक अल्पतम विंडो प्रबंधक +Comment[hr]=Minimalistički upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő +Comment[is]=Einfaldur gluggastjóri +Comment[it]=Un window manager minimalista +Comment[ja]=小さなウィンドウマネージャ +Comment[ka]=მინიმალისტური ფანჯრების მნეჯერი +Comment[kk]=Шағын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចលក្ខណៈពិសេសតិច +Comment[ko]=최소 지향 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė +Comment[lv]=Minimālistisks logu menedžeris +Comment[mk]=Минималистички менаџер на прозорци +Comment[mn]=Хамгийн жижиг цонхны удирдагч +Comment[mt]=Window manager żgħir +Comment[nb]=En minimalistisk vindusbehandler +Comment[nds]=En minimalistisch Finsterpleger +Comment[ne]=एक मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager +Comment[nn]=Ein minimalistisk vindaugssjef +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien +Comment[pt]=Um gestor de janelas minimalista +Comment[pt_BR]=Um gerenciador de janelas minimalista +Comment[ro]=Un manager de ferestre minimal +Comment[ru]=Минимальный оконный менеджер +Comment[rw]=Mugenga dirishya igira-bito +Comment[se]=Minimalisttalaš lásegieđahalli +Comment[sk]=Minimálny správca okien +Comment[sl]=Minimalističen okenski upravitelj +Comment[sr]=Минималистички менаџер прозора +Comment[sr@Latn]=Minimalistički menadžer prozora +Comment[sv]=Minimalistisk fönsterhanterare +Comment[ta]=ஒரு சிறிதுப்படுத்தப்பட்ட சாளர மேலாளர் +Comment[tg]=Мудири тирезаи minimalist +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก +Comment[tr]=Küçük bir pencere yöneticisi +Comment[tt]=Bik ciñel täräzä-idäräçe +Comment[uk]=Аскетичний менеджер вікон +Comment[uz]=Juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Жуда оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ đơn giản +Comment[wa]=On manaedjeu di purneas minimå +Comment[zh_CN]=最小的窗口管理器 +Comment[zh_TW]=一個最小型的視窗管理程式 diff --git a/kdm/kfrontend/sessions/afterstep.desktop b/kdm/kfrontend/sessions/afterstep.desktop new file mode 100644 index 000000000..c3f8d7329 --- /dev/null +++ b/kdm/kfrontend/sessions/afterstep.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Type=XSession +Exec=afterstep +TryExec=afterstep +Name=AfterStep +Name[bn]=আফটার-স্টেপ +Name[eo]=Postpaŝo +Name[hi]=आफ्टर-स्टेप +Name[ne]=चरण पछाडि +Name[pa]=ਪਗਬਾਅਦ +Name[rw]=NyumaIntambwe +Name[sv]=Afterstep +Name[ta]=ஆஃப்டர்ஸ்டெப் +Name[te]=ఆఫ్టర్ స్టెప్ +Comment=A window manager with the NeXTStep look and feel, based on FVWM +Comment[af]='n Venster bestuurder wat NeXTStep naboots, gebaseer of FVWM +Comment[ar]=مدير نوافذ ذو مظهر شبيه بـNeXTStep، مبني على FVWM +Comment[be]=Кіраўнік вокнаў з вонкавым выглядам NeXTStep, заснаваны на FVWM +Comment[bn]=FVWM-এর ওপর ভিত্তি করে তৈরি একটি উইণ্ডো ম্যানেজার, যা দেখতে শুনতে অনেকটানেক্সট-স্টেপ (NeXTStep)-এর মত +Comment[bs]=Window manager sa NeXTStep izgledom i osjećajem, baziran na FVWM +Comment[ca]=Un gestor de finestres amb l'aspecte i comportament de NeXTStep, basat en FVWM +Comment[cs]=Správce oken podobný NeXTStepu založený na FVWM +Comment[csb]=Menedżer òknów jidący w szlach NeXTStep, ùsôdzony na spòdlém FVWM +Comment[cy]= Trefnydd ffenestri efo golwg a theimlad CamNesaf (NeXTStep), wedi'i seilio ar FVWM +Comment[da]=En vindueshåndtering med NeXTStep udseende, baseret på FVWM +Comment[de]=Fenstermanager mit der Optik von NeXTStep, basiert auf FVWM +Comment[el]=Ένας διαχειριστής παραθύρων με την όψη και αίσθηση του NeXTStep, βασισμένος στον FVWM +Comment[eo]=Fenestroadministrilo, kiu aperas kiel Venontpaŝo, farita de FVWM +Comment[es]=Un gestor de ventanas con el aspecto de NeXTStep, basado en FVWM +Comment[et]=Aknahaldur NeXTStep välimuse ja vaimuga, aluseks FVWM +Comment[eu]=FVWMn oinarritutako, eta NeXTStep-en itxura eta portaera duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره توسط ظاهر و احساس NeXTStep، براساس FVWM +Comment[fi]=NeXTStep-tyylinen ja -tuntuinen FVWM:ään pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres similaire à NeXTStep et fondé sur FVWM +Comment[fy]=In finstersmanager mei it úterlik en gedrach fan NeXTStep; basearre op FVWM +Comment[gl]=Un xestor de fiestras de aspeito NeXTStep, baseado en FVWM +Comment[he]=מנהל חלונות עם מראה ומרגש כמו של NeXTStep המבוסס על, FVWM +Comment[hi]=एफ़वीडबल्यूएम आधारित नेक्स्टस्टेप की तरह दिखने और महसूस होने वाला विंडो प्रबंधक +Comment[hr]=Upravitelj prozora s NeXTStep izgledom i načinom rada, zasnovan na FVWM-u +Comment[hu]=Egy FVWM-alapú ablakkezelő, megjelenése a NeXTStepére hasonlít +Comment[is]=Gluggastjóri sem líkist þeim sem er í NeXTStep, byggður á FVWM +Comment[it]=Un window manager con lo stile NeXTStep, basato su FVWM +Comment[ja]=NeXTStep のルック&フィールをもった FVWM ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი FVWM -ის ბაზაზე, რომელიც NeXTStep-ს ჰგავს +Comment[kk]=FVWM-негіздеген, көрінісі NeXTStep-те сияқты, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចមានរូបរាង និងមុខងារ NeXTStep ដែលផ្អែកលើ FVWM +Comment[ko]=FVWM 기반 NeXTStep 모양 창 관리자 +Comment[lt]=Langų tvarkyklė su NeXTStep išvaizda ir jausena, paremta FVWM +Comment[lv]=Logu menedžeris ar NeXTStep izskatu un izturēšanos, bāzēts uz FVWM +Comment[mk]=Менаџер на прозорци со изгледот и чувството на NeXTStep, базиран на FVWM +Comment[mn]=NeXTStep look болон feel, based бүхий FVWM-д суурилсан цонх удирдагч +Comment[ms]=Pengurus tetingkap dengan rupa dan rasa NeXTStep berdasarkan FVWM +Comment[mt]=Window manager ibbażat fuq FVWM, jixbaħ lil NeXTStep +Comment[nb]=En vindusbehandler som ligner på NeXTStep, basert på FVWM +Comment[nds]=En Finsterpleger mit dat Utsehn vun NeXTStep, opbuut op FVWM +Comment[ne]=FVWMA आधारित एउटा सञ्झ्याल प्रबन्धक NeXTStep मा हेर्छ र थाहा पाउँछ +Comment[nl]=Een windowmanager met het uiterlijk en gedrag van NeXTStep; gebaseerd op FVWM +Comment[nn]=Ein vindaugssjef som liknar på NeXTStep, basert på FVWM +Comment[pa]=NeXTStep ਦੀ ਦਿੱਖ ਤੇ ਦਰਿਸ਼ ਵਾਲਾ FVWM ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien naśladujący NeXTStep, stworzony na podstawie FVWM +Comment[pt]=Um gestor de janelas com a aparência e comportamento do NeXTStep. Baseado no FVWM. +Comment[pt_BR]=Um gerenciador de janelas com a aparência do NeXTSep, baseado no FVWM +Comment[ro]=Un manager de ferestre cu aspect NeXTStep, bazat pe FVWM +Comment[ru]=Оконный менеджер на основе FVWM, повторяющий внешний вид NeXTStep +Comment[rw]=Mugenga dirishya ifite imboneko n'ukumva NtambweIkurikira, ishingiye kuri FVWM +Comment[se]=Lásegieđahalli mii sulastahttá NeXTStep, vuođđoduvvon FVWM:as +Comment[sk]=Správca okien podobný NeXTStep založený na FVWM +Comment[sl]=Okenski upravitelj z občutkom in izgledom NeXTStep-a, na osnovi FVWM +Comment[sr]=Менаџер прозора са NeXTStep-овим изгледом и осећајем, заснован на FVWM-у +Comment[sr@Latn]=Menadžer prozora sa NeXTStep-ovim izgledom i osećajem, zasnovan na FVWM-u +Comment[sv]=Fönsterhanterare med Nextstep-utseende och -känsla, baserad på FVWM +Comment[ta]=FVWM அடிப்படையிலான NeXTStep உடனான சாளர மேலாளர். +Comment[tg]=Мудири равзанаҳо дар асоси FVWM дорои намуди NeXTStep +Comment[th]=ระบบจัดการหน้าต่างที่มีรูปแบบและสัมผัสของระบบปฏิบัติการ NeXTStep โดยใช้พื้นฐานของ FVWM +Comment[tr]=NeXTStep görünümlü bir pencere yöneticisi +Comment[tt]=FVWM asılında qorılğan, NeXTStep küreneşe belän täräzä-idäräçe +Comment[uk]=Менеджер вікон з виглядом та поведінкою NeXTStep, заснований на FVWM +Comment[uz]=FVWM asosida yaratilgan NeXTStep'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=FVWM асосида яратилган NeXTStep'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với giao diện NeXTStep, dựa trên FVWM +Comment[wa]=On manaedjeu di purneas avou l' rivnance di NeXTStep, båzé so FVWM +Comment[zh_CN]=一个带有 NeXTStep 观感的窗口管理器,基于 FVWM +Comment[zh_TW]=一個基於 FVWM 並擁有 NeXTStep 外觀及感覺的視窗管理程式 diff --git a/kdm/kfrontend/sessions/amaterus.desktop b/kdm/kfrontend/sessions/amaterus.desktop new file mode 100644 index 000000000..3c52ee180 --- /dev/null +++ b/kdm/kfrontend/sessions/amaterus.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=XSession +Exec=amaterus +TryExec=amaterus +Name=AMATERUS +Name[hi]=एमेच्योर्स +Name[te]=అమాటెరస్ +Comment=A GTK+ based window manager with a window grouping feature +Comment[af]='n GTK+ gebaseerde venster bestuurder met 'n venster groepering funksie +Comment[ar]=مدير نوافذ مبني على GTK+ له ميزة تجميع النوافذ +Comment[be]=Кіраўнік вокнаў, заснаваны на GTK+, са здольнасцю групавання вокнаў +Comment[bn]=GTK+ ভিত্তিল উইণ্ডো ম্যানেজার, যাতে উইণ্ডো গ্রুপিং করা যায় +Comment[bs]=Window manager baziran na GTK+ sa mogućnošću grupisanja prozora +Comment[ca]=Un gestor de finestres de GTK+ amb una característica per a l'agrupament de finestres +Comment[cs]=Správce oken založený na GTK+ s funkcí seskupování okne +Comment[csb]=Menedżer òknów brëkùjący GTK+, z optacëją grëpòwaniô òknów +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar GTK+, efo nodwedd casglu ffenestri +Comment[da]=En GTK+ baseret vindueshåndtering med en vinduesgrupperingsegenskab +Comment[de]=Auf GTK+ basierender Fenstermanager mit Gruppierungsfunktion für die Fenster +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στο GTK+ με ένα χαρακτηριστικό ομαδοποίησης παραθύρων +Comment[eo]=Fenestroadministrilo kun ebleco kunigi fenestrojn, kiu uzas GTK+ +Comment[es]=Un gestor de ventanas basado en GTK+ con la posibilidad de agrupar ventanas +Comment[et]=GTK+-le tuginev aknahaldur akende grupeerimise võimalusega +Comment[eu]=GTK+-n oinarritutako leiho kudeatzailea, leihoak taldeka biltzeko gaitasuna duena +Comment[fa]=یک GTK+ بر مبنای مدیر پنجره توسط ویژگی گروهی کردن پنجرهها +Comment[fi]=GTK+-pohjainen ikkunaohjelma ikkunoiden ryhmittely -ominaisuudella +Comment[fr]=Un gestionnaire de fenêtres écrit en GTK+, avec une fonctionnalité de groupement des fenêtres +Comment[fy]=In op GTK+ basearre finstersmanager mei finsterkeppelfûnksje +Comment[gl]=Un xestor de fiestras baseado en GTK+ con agrupamento de fiestras +Comment[he]=מנהל חלונות מבוסס GTK+ עם אפשרות לקבץ חלונות +Comment[hi]=जीटीके+ आधारित विंडो प्रबंधक, विंडो समूह विशेषता सहित +Comment[hr]=Upravitelj prozora zasnovan na GTK+ s mogućnošću grupiranja prozora +Comment[hu]=Egy GTK+-alapú ablakkezelő ablakcsoportosítási lehetőséggel +Comment[is]=Gluggastjóri sem hópar saman glugga og er byggður á GTK+ +Comment[it]=Un window manager basato su GTK+ con la possibilità di raggruppare le finestre +Comment[ja]=ウィンドウのグループ化が可能な GTK+ ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი GTK+ ს ბაზაზე ფანჯრების დაჯგუფების ფუნქციით +Comment[kk]=GTK+ негіздеген, терезелерді топтастыру қасиеті бар, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចផ្អែកលើ GTK+ ដែលមានលក្ខណៈពិសេសដាក់បង្អួចជាក្រុម +Comment[ko]=창 그룹 기능을 사용하는 GTK+ 기반 창 관리자 +Comment[lt]=GTK+ paremta langų tvarkyklė su langų grupavimo galimybe +Comment[lv]=GTK+ bāzēts logu menedžeris ar logu grupēšanas iespēju +Comment[mk]=GTK+ базиран менаџер на прозорци со можност за групирање на прозорци +Comment[mn]=A GTK+ суурилсан цонх бүлэглэгчтэй цонх удирдагч +Comment[mt]=Window manager ibbażat fuq GTK+ b'faċilitajiet ta' gruppi ta' windows +Comment[nb]=En vindusbehandler basert på GTK+ med vindusgruppering +Comment[nds]=En Finsterpleger opbuut op GTK+, kann Finstern in Koppeln tosamenfaten +Comment[ne]=सञ्झ्याल समूह विशेषतासँग GTK+ मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een op GTK+ gebaseerde windowmanager met venstergroeperingfunctionaliteit +Comment[nn]=Ein GTK+-basert vindaugssjef med vindaugsgruppering +Comment[pa]=ਇੱਕ GTK+ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਥਾਂ ਸੰਭਾਲਣ ਦੀ ਸਹੂਲਤ ਨਾਲ ਲੈੱਸ ਹੈ। +Comment[pl]=Menedżer okien korzystający z GTK+, z opcją grupowania okien +Comment[pt]=Um gestor de janelas baseado em GTK+ com uma funcionalidade de agrupamento de janelas +Comment[pt_BR]=Um gerenciador de janelas baseado em GTK+, com o recurso de agrupamento de janelas +Comment[ro]=Un manager de ferestre bazat pe GTK+ și cu posibilitatea de grupare a ferestrelor +Comment[ru]=Оконный менеджер на основе GTK+ c функцией группировки окон +Comment[rw]=GTK + bishingiye mugenga dirishya ifite idirishya rihuza ibiranga +Comment[se]=GTK+-vuođđoduvvon lásegieđahalli mii sáhttá sierra lásiid bidjat seamma joavkui +Comment[sk]=Správca okien založený na GTK+ s funkciou zoskupovania okien +Comment[sl]=Okenski upravitelj na osnovi GTK+ z možnostjo združevanja oken +Comment[sr]=Менаџер прозора заснован на GTK+-у са особином груписања прозора +Comment[sr@Latn]=Menadžer prozora zasnovan na GTK+-u sa osobinom grupisanja prozora +Comment[sv]=GTK+-baserad fönsterhanterare med en funktion för fönstergruppering +Comment[ta]=சாளர குழுப்பிரித்தல் தன்மையுடனான சாளர மேலாளர் அடிப்படையிலான GTK+. +Comment[tg]=Мудири равзанаҳо дар асоси GTK+ дорои фаъолияти гурӯҳ кардан равзанаҳо +Comment[th]=ตัวจัดการหน้าต่างที่ใช้พื้นฐานจาก GTK+ พร้อมด้วยความสามารถในการจัดกลุ่มหน้าต่าง +Comment[tr]=GTK+ tabanlı bir pencere yöneticisi +Comment[tt]=GTK+ asılında qorılğan, täräzälärne törkemli ala torğan täräzä-idäräçe +Comment[uk]=Менеджер вікон заснований на GTK+ з підтримкою групування вікон +Comment[uz]=A GTK+ asosida yaratilgan, oynalarni guruhlash imkoniyatiga ega oyna boshqaruvchi +Comment[uz@cyrillic]=A GTK+ асосида яратилган, ойналарни гуруҳлаш имкониятига эга ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với khả năng tạo nhóm cửa sổ dựa trên GTK+ +Comment[wa]=On manaedjeu di purneas båzé so GTK+, avou ene fonccionålité di rgroupaedje des purneas +Comment[zh_CN]=一个基于 GTK+ 的窗口管理器,带有窗口成组特性 +Comment[zh_TW]=一個基於 GTK+ 的視窗管理程式並擁有視窗群組功能 diff --git a/kdm/kfrontend/sessions/amiwm.desktop b/kdm/kfrontend/sessions/amiwm.desktop new file mode 100644 index 000000000..ced73c346 --- /dev/null +++ b/kdm/kfrontend/sessions/amiwm.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=XSession +Exec=amiwm +TryExec=amiwm +Name=AmiWM +Name[eo]=AmiFA +Name[hi]=एमी-डबल्यूएम +Name[sv]=Ami WM +Name[te]=ఎమి డబ్ల్యు ఎం +Comment=The Amiga look-alike window manager +Comment[af]='n Amiga gebaseerde venster bestuurder +Comment[ar]=مدبِر نوافذ مشابه لِــ Amiga +Comment[be]=Кіраўнік вокнаў, падобны на Amiga +Comment[bn]=অ্যামিগার মত দেখতে উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Amigu +Comment[ca]=Un gestor de finestres que dona l'aspecte d'un Amiga +Comment[cs]=Správce oken podobný Amize +Comment[csb]=Menedżer òknów szlachùjący za Amiga +Comment[cy]=Trefnydd ffenestri sy'n edrych yn debyg i'r Amiga +Comment[da]=Amiga-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil des Amiga +Comment[el]=Ο διαχειριστής παραθύρων με όψη αλά Amiga +Comment[eo]=Fenestroadministrilo kiel tiu de Amiga +Comment[es]=Un gestor de ventanas con el aspecto de Amiga +Comment[et]=Amiga välimusega aknahaldur +Comment[eu]=Amigaren itxura duen leiho kudeatzailea +Comment[fa]=Amiga شبیه مدیر پنجره +Comment[fi]=Amigan tyylinen ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres ressemblant à Amiga +Comment[fy]=In Amiga-likens finstersmanager +Comment[gl]=Un xestor de fiestras coma o de Amiga +Comment[he]=מנהל החלונות הדומה ל־Amiga +Comment[hi]=अमीगा की तरह दिखने वाला विंडो प्रबंधक +Comment[hr]=Upravitelj prozora koji podsjeća na Amigu +Comment[hu]=Egy Amiga-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist Amiga tölvunum +Comment[it]=Un window manager in stile Amiga +Comment[ja]=Amiga に似たウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Amiga-ს სტილში +Comment[kk]=Amiga секілді терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រប់បង្អួចស្រដៀង Amiga +Comment[ko]=Amiga를 닮은 창 관리자 +Comment[lt]=Langų tvarkyklė, panaši į Amiga +Comment[lv]=Amiga izskata logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Amiga +Comment[mn]=Amiga look-alike Цонхны удирдагч +Comment[ms]=Pengurus tetingkap serupa Amiga +Comment[mt]=Window manager jixbaħ lill-Amiga +Comment[nb]=Vindusbehandler som ligner på Amiga +Comment[nds]=De Finsterpleger mit dat Utsehn vun den Amiga +Comment[ne]=अमिगा सञ्झ्याल प्रबन्धक जस्तो छ +Comment[nl]=Een Amiga-achtige windowmanager +Comment[nn]=Vindaugssjef som liknar på Amiga +Comment[pa]=ਅਮੀਗਾ ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien naśladujący Amigę +Comment[pt]=O gestor de janelas com o visual do Amiga +Comment[pt_BR]=Um gerenciador de janelas com a aparência do Amiga +Comment[ro]=Manager de ferestre cu aspect Amiga +Comment[ru]=Оконный менеджер в стиле Amiga +Comment[rw]=Amiga ijya gusa na mugenga dirishya +Comment[se]=Amiga-lágan lásegieđahalli +Comment[sk]=Správca okien podobný systému Amiga +Comment[sl]=Okenski upravitelj, podoben Amiginemu +Comment[sr]=Менаџер прозора који подсећа на Амигу +Comment[sr@Latn]=Menadžer prozora koji podseća na Amigu +Comment[sv]=Fönsterhanteraren som ser ut som Amiga +Comment[ta]=சாளர மேலாளரை ஒத்த அமிகா +Comment[tg]=Монанди мудири тирезаи Amiga look +Comment[th]=ระบบจัดการหน้าต่างที่ดูเหมือน Amiga +Comment[tr]=Amiga görünümlü bir pencere yöneticisi +Comment[tt]=Amiga küreneşendä täräzä idäräçe +Comment[uk]=Менеджер вікон на штиб Amiga +Comment[uz]=Amiga'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=Amiga'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhìn giống Amiga +Comment[wa]=On manaedjeu di purneas rishonnant l' ci di l' Amiga +Comment[zh_CN]=Amiga 外观的窗口管理器 +Comment[zh_TW]=一個看起來像 Amiga 視窗管理程式 diff --git a/kdm/kfrontend/sessions/asclassic.desktop b/kdm/kfrontend/sessions/asclassic.desktop new file mode 100644 index 000000000..e84a0977e --- /dev/null +++ b/kdm/kfrontend/sessions/asclassic.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=asclassic +TryExec=asclassic +Name=ASClassic +Name[af]= ASClassic +Name[cy]=ASClasurol +Name[eo]=KlasikaPP +Name[hi]=एएस-क्लॉसिक +Name[ne]=AS शास्त्रीय +Name[sv]=AS klassisk +Name[ta]=ASதரமான +Name[te]=ఏఎస్ క్లాసిక్ +Comment=AfterStep Classic, a window manager based on AfterStep v1.1 +Comment[af]=AfterStep Classic, 'n venster bestuurder wat op AfterStep v1.1 gebaseer is. +Comment[ar]=AfterStep كلاسيك، وهو مدير نوافذ مبني على AfterStep الإصدارة 1.1 +Comment[be]=Класічны AfterStep, кіраўнік вокнаў, заснаваны на AfterStep 1.1 +Comment[bn]=আফটার-স্টেপ ক্লাসিক: আফটার-স্টেপ ১.১ ভিত্তিক একটি উইণ্ডো ম্যানেজার +Comment[bs]=AfterStep Classic, window manager baziran na AfterStep v1.1 +Comment[ca]=El clàssic AfterStep, un gestor de finestres basat en AfterStep v1.1 +Comment[cs]=AfterStep Classic, správce oken založený na AfterStepu v1.1 +Comment[csb]=AfterStep Classic, menedżer òknów ùsôdzony na spòdlém AfterStep v1.1 +Comment[cy]=ÔlGam Clasurol, trefnydd ffenestri wedi'i seilio ar AfterStep v1.1 +Comment[da]=AfterStep Classic, en vindueshåndtering baseret på AfterStep v1.1 +Comment[de]=AfterStep Classic, ein Fenstermanager, der auf AfterStep v1.1 basiert +Comment[el]=AfterStep κλασικός, ένας διαχειριστής παραθύρων βασισμένος στον AfterStep v1.1 +Comment[eo]=Klasika Postpaŝo, fenestroadministrilo kiel Postpaŝo v1.1 +Comment[es]=AfterStep Classic, un gestor de ventanas basado en AfterStep v1.1 +Comment[et]=AfterStep Classic - aknahaldur, mille aluseks on AfterStep v1.1 +Comment[eu]=AfterStep Classic, AfterStep v1.1-en oinarrituta dagoen leiho kudeatzailea +Comment[fa]=AfterStep کلاسیک، مدیر پنجره بر اساس AfterStep نسخه ۱.۱ +Comment[fi]=AfterStep Classic, After Step v1.1:een pohjautuva ikkunaohjelma +Comment[fr]=AfterStep Classic, un gestionnaire de fenêtres fondé sur AfterStep v1.1 +Comment[fy]=AfterStep Classic, In finstersmanager basearre op AfterStep 1.1 +Comment[gl]=AfterStep Clásico, un xestor de fiestras baseado en AfterSetp v1.1 +Comment[he]=AfterStep Classic, מנהל חלונות המבוסס על AfterStep v1.1 +Comment[hi]=आफ्टरस्टेप क्लासिक, एक विंडो प्रबंधक जो आफ्टरस्टेप व.1 पर आधारित है +Comment[hr]=Klasični AfterStep, upravitelj prozora zasnovan na AfterStepu verzija 1.1 +Comment[hu]=AfterStep Classic ablakkezelő, az AfterStep v1.1 alapján +Comment[is]=Klassískur AfterStep gluggastjóri byggður á AfterStep v1.1 +Comment[it]=AfterStep Classico, un window manager basato su AfterStep v1.1 +Comment[ja]=AfterStep クラシック, AfterStep v1.1 ベースのウィンドウマネージャ +Comment[ka]=AfterStep Classic, ფანჯრის მენეჯერი AfterStep v1.1 -ის ბაზაზე +Comment[kk]=AfterStep v1.1 негіздеген AfterStep Classic терезе менеджері +Comment[km]=AfterStep បុរាណ,កម្មវិធីគ្រប់គ្រងបង្អួចដែលផ្អែកលើ AfterStep v1.1 +Comment[ko]=AfterStrp 1.1 기반 창 관리자 +Comment[lt]=AfterStep Classic, langų tvarkyklė, paremta AfterStep v1.1 +Comment[lv]=Klasiskais Afterstep, logu menedžeris bāzēts uz AfterStem v1.1 +Comment[mk]=AfterStep Classic, менаџер на прозорци базиран на AfterStep v1.1 +Comment[mn]=AfterStep Classic, AfterStep v1.1 дээр суурилсан цонх удирдагч +Comment[mt]=AfterStep klassiku, window manager ibbażat fuq AfterStep v1.1 +Comment[nb]=AfterStep Classic, en vindusbehandler basert på AfterStep v1.1 +Comment[nds]=De AfterStepClassic-Finsterpleger is opbuut op AfterStep v1.1 +Comment[ne]=AfterStep शास्त्रीय, AfterStep v१.१ मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=AfterStep Classic, een windowmanager gebaseerd op AfterStep 1.1 +Comment[nn]=AfterStep Classic, ein vindaugssjef som byggjer på AfterStep 1.1 +Comment[pa]=AfterStep ਟਕਸਾਲੀ, AfterStep v1.1 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=AfterStep Classic, menedżer okien stworzony na podstawie AfterStep v1.1 +Comment[pt]=AfterStep Classic, um gestor de janelas baseado no AfterStep v1.1 +Comment[pt_BR]=AfterSep clássico, um gerenciador de janelas baseado no AfterStep v1.1 +Comment[ro]=AfterStep Classic, un manager de ferestre bazat pe AfterStep v1.1 +Comment[ru]=AfterStep Classic, оконный менеджер на основе AfterStep v1.1 +Comment[rw]=AfterStep Classic, mugenga dirishya ishingiye kuri AfterStep v1.1 +Comment[se]=AfterStep Classic, lásegieđahalli ráhkaduvvon AfterStep 1.1 vuođul +Comment[sk]=AfterStep Classic, správca okien založený na AfterStep v1.1 +Comment[sl]=AfterStep Classic, okenski upravitelj na osnovi AfterStep različice 1.1 +Comment[sr]=Класични AfterStep, менаџер прозора заснован на AfterStep-у верзије 1.1 +Comment[sr@Latn]=Klasični AfterStep, menadžer prozora zasnovan na AfterStep-u verzije 1.1 +Comment[sv]=Afterstep klassisk, en fönsterhanterare baserad på Afterstep version 1.1 +Comment[ta]=ஆஃப்டர்ஸ்டெப் க்ளாசிக், ஆஃப்டர்ஸ்டெப் க்ளாசிக் v1.1 அடிப்படையிலான சாளர மேலாளர் +Comment[tg]=Мудири равзанаҳои AfterStep Classic дар асоси AfterStep v1.1 +Comment[th]=AfterStep Classic คือระบบจัดการหน้าต่างที่ใช้ฐานของอาฟเตอร์สเตปเวอร์ชั่น 1.1 +Comment[tr]=AfterStep Classic pencere yöneticisi +Comment[tt]=AfterStep Classic, AfterStep v1.1 asılında täräzä-idäräçe +Comment[uk]=AfterStep Classic, менеджер вікон, заснований на AfterStep v1.1 +Comment[uz]=AfterStep Classic - AfterStep v1.1 asosida yaratilgan oyna boshqaruvchi +Comment[uz@cyrillic]=AfterStep Classic - AfterStep v1.1 асосида яратилган ойна бошқарувчи +Comment[vi]=AfterStep Classic, một trình quản lý cửa sổ dựa trên AfterStep v1.1 +Comment[wa]=AfterStep Classic, on manaedjeu di purneas båzé so AfterStep v1.1 +Comment[zh_CN]=AfterStep 经典,一个基于 AfterStep v1.1 的窗口管理器 +Comment[zh_TW]=AfterStep 經典, 一個基於 AfterStep v1.1 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/blackbox.desktop b/kdm/kfrontend/sessions/blackbox.desktop new file mode 100644 index 000000000..457ec7614 --- /dev/null +++ b/kdm/kfrontend/sessions/blackbox.desktop @@ -0,0 +1,88 @@ +[Desktop Entry] +Type=XSession +Exec=blackbox +TryExec=blackbox +Name=Blackbox +Name[bn]=ব্ল্যাকবক্স +Name[cy]= Du-flwch (Blackbox) +Name[eo]=Negrujo +Name[hi]=ब्लेकबॉक्स +Name[ja]=BlackBox +Name[mn]=Хар хайрцаг +Name[ne]=कालो बाकस +Name[pa]=ਕਾਲਾਬਕਸਾ +Name[rw]=AgasandukuUmukara +Name[ta]=கறுப்புப் பெட்டி +Name[te]=నల్లడబ్బా +Name[tg]=Қуттии сиёҳ +Comment=A fast & light window manager +Comment[af]='n Vinnige, lig gewig venster bestuurder +Comment[ar]=مدير نوافذ خفيف وسريع +Comment[be]=Хуткі і лёгкі кіраўнік вокнаў +Comment[bg]=Бърз и лек мениджър на прозорци +Comment[bn]=একটি হালকা এবং দ্রুত উইণ্ডো ম্যানেজার +Comment[bs]=Brz i lagan window manager +Comment[ca]=Un gestor de finestres ràpid i clar +Comment[cs]=Rychlý a malý správce oken +Comment[csb]=Chùtczi menedżer òknów o môłëch żądaniach +Comment[cy]=Trefnydd ffenestri cyflym ac ysgafn +Comment[da]=En hurtig & let vindueshåndtering +Comment[de]=Kleiner, schneller Fenstermanager +Comment[el]=Ένας γρήγορος και ελαφρύς διαχειριστής παραθύρων +Comment[eo]=Rapida kaj malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas rápido y ligero +Comment[et]=Kiire ja vähenõudlik aknahaldur +Comment[eu]=Leiho kudeatzaile bizkor eta arina +Comment[fa]=یک مدیر پنجرۀ سبک و سریع +Comment[fi]=Kevyt ja nopea ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres rapide et léger +Comment[fy]=In flugge lichtgewicht finstersmanager +Comment[ga]=Bainisteoir fuinneoga gasta éadrom +Comment[gl]=Un xestor de fiestras lixeiro e rápido +Comment[he]=מנהל חלונות מהיר וקל +Comment[hi]=तेज और सरल विंडो प्रबंधक +Comment[hr]=Brzi i lagani upravitelj prozora +Comment[hu]=Egy gyors, egyszerű ablakkezelő +Comment[is]=Léttur og hraðvirkur gluggastjóri +Comment[it]=Un window manager veloce e leggero +Comment[ja]=軽快なウィンドウマネージャ +Comment[ka]=სწრაფი და მსუბუქი ფანჯრის მენეჯერი +Comment[kk]=Жедел және жеңіл терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចលឿន ហើយភ្លឺ +Comment[ko]=빠르고 가벼운 창 관리자 +Comment[lt]=Greita ir nedaug resursų naudojanti langų tvarkyklė +Comment[lv]=Ātrs un viegls logu menedžeris +Comment[mk]=Брз и лесен менаџер на прозорци +Comment[mn]=Хурдан & хөнгөн цонхны удирдагч +Comment[ms]=Pengurus tetingkap yang pantas & ringan +Comment[mt]=Window manager ħafif u żgħir +Comment[nb]=En rask og lett vindusbehandler +Comment[nds]=En gaue un lütte Finsterpleger +Comment[ne]=छिटो र हल्का सञ्झ्याल प्रबन्धक +Comment[nl]=Een snelle lichtgewicht windowmanager +Comment[nn]=Ein rask og lett vindaugssjef +Comment[pa]=ਇੱਕ ਤੇਜ਼ ਅਤੇ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Szybki menedżer okien o małych wymaganiach +Comment[pt]=Um gestor de janelas rápido e leve +Comment[pt_BR]=Um gerenciador de janelas rápido e leve +Comment[ro]=Un manager de ferestre mic și rapid +Comment[ru]=Быстрый и лёгкий оконный менеджер +Comment[rw]=Mugenga dirishya yihuta & yoroshye +Comment[se]=Jođánis ja geahpes lásegieđahalli +Comment[sk]=Rýchly a nenáročný správca okien +Comment[sl]=Hiter in lahek okenski uporavljalnik +Comment[sr]=Брзи и лагани менаџер прозора +Comment[sr@Latn]=Brzi i lagani menadžer prozora +Comment[sv]=Snabb och lättviktig fönsterhanterare +Comment[ta]=விரைவான மற்றும் இலகுவான KDE சாளர மேலாளர் +Comment[tg]=Суст ва мудири тирезаи равшан +Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา +Comment[tr]=Hızlı ve hafif bir pencere yöneticisi +Comment[tt]=Citez ciñel täräzä-idäräçe +Comment[uk]=Легкий та швидкий менеджер вікон +Comment[uz]=Tez va oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Тез ва оддий ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ nhẹ và nhanh +Comment[wa]=On ledjir et roed manaedjeu di purneas +Comment[zh_CN]=又快又轻巧的窗口管理器 +Comment[zh_TW]=一個快速及輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/cde.desktop b/kdm/kfrontend/sessions/cde.desktop new file mode 100644 index 000000000..1f2dee088 --- /dev/null +++ b/kdm/kfrontend/sessions/cde.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=/usr/dt/bin/Xsession +TryExec=/usr/dt/bin/Xsession +Name=CDE +Name[hi]=सीडीई +Name[mn]=КДE +Name[te]=సిడిఈ +Name[tg]=Муҳити графикии муштарак (CDE) +Name[th]=แบบ CDE +Comment=The Common Desktop Environment, a proprietary industry standard desktop environment +Comment[af]=Die 'Common Desktop Environment', 'n beskermde, industrie standaard werkskerm omgewing +Comment[ar]=محيط سطح المكتب الشائع، محيط سطح المكتب الصناعي المعايير +Comment[be]=Common Desktop Environment, прапрыетарнае стандартнае працоўнае асяроддзе +Comment[bn]=কমন ডেস্কটপ এনভায়রনমেন্ট (Common Desktop Environment), একটি মালিকানাধীন ইনডাস্ট্রি স্ট্যান্ডার্ড +Comment[bs]=Common Desktop Environment, vlasnička desktop okolina, industrijski standard +Comment[ca]=The Common Desktop Environment, l'entorn d'escriptori estàndard de la indústria propietària +Comment[csb]=Common Desktop Environment, sztandardowé industrëjné òkrãże pùltu +Comment[cy]=Yr Amgylchedd Penbwrdd Cyffredin (Common Desktop Environment), amgylchedd penbwrdd perchnogol sy'n safonol yn y diwydiant +Comment[da]=Common Desktop Environment, et privatejet industristandard desktopmiljø +Comment[de]=Das Common Desktop Environment, eine proprietäre Arbeitsumgebung und ein Industriestandard +Comment[el]=To Κοινό Περιβάλλον Επιφάνειας εργασίας, ένα βιομηχανικό πρότυπο επιφάνειας εργασίας +Comment[eo]=La Komuna Labortablo Ĉirkaŭaĵo +Comment[es]=El Common Desktop Environment, un estándar en los entornos de escritorio propietarios +Comment[et]=Üldine töölaua keskond (Common Desktop Environment) on kaubanduslik standardne töölaua keskkond +Comment[eu]=Common Desktopo Environment, mahaigain jabedun inguruneetako estandarra +Comment[fa]=محیط رومیزی مشترک، محیط رومیزی استاندارد صنعت اختصاصی +Comment[fi]=Common Desktop Environment, patentoitu työpöytäympäristöjen teollisuusstandardi +Comment[fr]=Le Common Desktop Environment, un environnement de bureau propriétaire standard dans l'industrie +Comment[fy]=The Common Desktop Environment, In kommersjele yndustrieel standerdisearre buroblêd omwrâld +Comment[gl]=O Common Desktop Environment, un entorno de escritório proprietario estándar para industria +Comment[he]=The Common Desktop Environment, סביבת עבודה מסחרית וקניינית סטנדרטית +Comment[hi]=सामूहिक डेस्कटॉप माहौल, एक स्वामित्व युक्त औद्योगिक मानक डेस्कटॉप माहौल +Comment[hr]=Opće okruženje radne površine, standardizirano industrijskim vlasništvima +Comment[hu]=The Common Desktop Environment, egy kereskedelmi, kváziszabványnak számító grafikus környezet +Comment[is]=Common Desktop Environment er lokað skjáborðsumhverfi sem var staðlað umhverfi til skamms tíma +Comment[it]=Il Common Desktop Environment, un desktop environment proprietario standard. +Comment[ja]=Common Desktop Environment,プロプライエタリな業界標準のデスクトップ環境 +Comment[ka]=Common Desktop Environment, UNIX -ის სამუშაო სფეროს სამრეწვლო სტანდარტი +Comment[kk]=Common Desktop Environment - UNIX жұмыс ортаның өнеркәсіп стандарты +Comment[km]=The Common Desktop Environment, បរិស្ថានផ្ទៃតុខ្នាតគំរូដែលមានកម្មសិទ្ធិ +Comment[lt]=Common Desktop Environment, nuosavybinių sistemų standartinė darbastalio tvarkyklė +Comment[mk]=Common Desktop Environment, сопственичка индустриски стандардна работна околина +Comment[mn]=Нийтлэг дэлгэцийн системийн орчин, үйлдвэрийн стандарт дэлгэцийн системийн орчин +Comment[ms]=Persekitaran Desktop Biasa, persekitaran desktop standard industri proprietari +Comment[mt]=Common Desktop Environment, ambjent grafiku propjetarju u standard tal-industrija +Comment[nb]=Common desktop Environment, et godseid skrivebordsmiljø som er standard i programvareindustrien +Comment[nds]=De Common Desktop Environment, de Schriefdisch-Ümgeven vun en proprieteren Industrie-Standard +Comment[ne]=साझा डेस्कटप वातावरण, श: शुल्क उद्योग मानक डेस्कटप वातावरण +Comment[nl]=The Common Desktop Environment, een commerciële industrieel gestandariseerde desktop environment +Comment[nn]=Common Desktop Environment, eit godseigd skrivebordsmiljø som er standard i programvareindustrien +Comment[pa]=ਇੱਕ ਆਮ ਵੇਹੜਾ ਵਾਤਾਵਰਣ, ਇੱਕ ਵਪਾਰਿਕ ਮਿਆਰ ਦਾ ਵੇਹੜਾ ਵਾਤਾਵਰਣ +Comment[pl]=Common Desktop Environment, standardowe przemysłowe środowisko pulpitu +Comment[pt]=O Common Desktop Environment, um ambiente de trabalho gráfico padrão e proprietário +Comment[pt_BR]=O Ambiente de Trabalho Comum (CDE), um ambiente de trabalho proprietário padrão da indústria +Comment[ro]=Common Desktop Environment, un mediu grafic proprietar și devenit standard industrial +Comment[ru]=Common Desktop Environment, промышленный стандарт рабочей среды UNIX +Comment[rw]=Ibikikije Ibiro Rusange, ibikikije ibiro bisanzwe bwite by'isosiyete +Comment[se]=Common Desktop Environment, čállinbeavdebiras mii lea standárda prográmmagálvoindustriijas +Comment[sk]=The Common Desktop Environment, proprietárne štandardné pracovné prostredie +Comment[sl]=Common Desktop Environment, lastniško standardno industrijsko namizno okolje +Comment[sr]=„Common Desktop Environment“, власничко индустријски стандардно радно окружење +Comment[sr@Latn]=„Common Desktop Environment“, vlasničko industrijski standardno radno okruženje +Comment[sv]=Common Desktop Environment, en privatägd industristandard skrivbordsmiljö +Comment[ta]=பொதுவான மேல்மேசை, தன்உரிமை உடைய நிறுவனத்தின் நிலையான மேல்மேசை சூழல் +Comment[tg]=Common Desktop Environment дар асоси UNIX +Comment[th]=Common Desktop Environment คือ สภาพแวดล้อมของพื้นที่ทำงานที่ได้มาตรฐานอุตสาหกรรม ที่ไม่ใช่ซอฟต์แวร์เสรี +Comment[tr]=Common Desktop Environment (CDE) +Comment[tt]=Common Desktop Environment, UNIX öçen citeşterü standardı +Comment[uk]=The Common Desktop Environment, закритий промисловий стандарт графічного середовища +Comment[vi]=Môi trường Màn hình nền Chung, một môi trường màn hình nền giữ bản quyền, tuân thủ chuẩn công nghiệp +Comment[wa]=Li Comon Evironmint d' Sicribanne (Common Desktop Environment), on evironmint d' sicribanne nén libe po l' industreye +Comment[zh_CN]=通用窗口环境(CDE),私有工业标准的桌面环境 +Comment[zh_TW]=The Common Desktop Environment, 一個有專利的工業標準 diff --git a/kdm/kfrontend/sessions/ctwm.desktop b/kdm/kfrontend/sessions/ctwm.desktop new file mode 100644 index 000000000..e7ee84471 --- /dev/null +++ b/kdm/kfrontend/sessions/ctwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=ctwm +TryExec=ctwm +Name=CTWM +Name[eo]=TFAC +Name[hi]=सीटीडबल्यूएम +Name[te]=సి టి డబ్ల్యు ఎం +Comment=Claude's Tab Window Manager, TWM enhanced by virtual screens, etc. +Comment[af]=Claude se Tab venster bestuurder. Dis TWM wat met virtuele skerms verbeter is +Comment[ar]=مدير نوافذ Claude's Tab، وهي TWM محسّن بشاشات وهمية، إلخ. +Comment[be]=Кіраўнік вокнаў з укладкамі ад Claude, TWM з падтрымкай віртуальных экранаў і інш. +Comment[bg]=Claude"s Tab Window Manager, TWM enhanced by virtual screens, etc. +Comment[bn]=ক্লড-এর ট্যাব উইণ্ডো ম্যানেজার +Comment[bs]=Claude's Tab Window Manager, TWM proširen virtuelnim ekranima itd. +Comment[ca]=Gestor de finestres amb pestanyes d'en Claude, millores TWM per a pantalles virtuals, etc. +Comment[csb]=Menedżer òknów Claude, TWM zbògacony ò wirtualné pùltë, ëtp. +Comment[cy]=Trefnydd Ffenestri Tab Claude, TWM wedi ei wella gan sgriniau rhith, ayyb. +Comment[da]=Claude's Tab vindueshåndtering, TWM udvidet med virtuelle skærme osv. +Comment[de]=Claudes Fenstermanager mit Karteikartenfenstern, eine verbesserte Fassung von TWM mit virtuellen Ansichten usw. +Comment[el]=Ο διαχειριστής παραθύρων Tab του Claude, ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. +Comment[eo]=Taba Fenestroadministrilo de Claude, TWM, bonigita per virtualaj ekranoj ktp +Comment[es]=Claude's Tab Window Manager, TWM mejorado con pantallas virtuales, etc. +Comment[et]=Claude kaartidega aknahaldur, aluseks TWM, mida on täiendatud virtuaaltöölaudadega jne. +Comment[eu]=Claude's Tab leiho kudeatzailea, pantaila birtual eta abarrez hobetutako TWMa +Comment[fa]=مدیر پنجرۀ تب Claude، TWM، گسترشیافته توسط پردههای مجازی و غیره. +Comment[fi]=Clauden välilehtiikkunaohjelma. TWM, johon lisätty muun muassa virtuaalityöpöydät. +Comment[fr]=Claude's Tab Window Manager, TWM avec en plus les bureaux virtuels, etc. +Comment[fy]=Claude's Tab _indow Manager, TWM útbreide mei firtuele skermen etc. +Comment[gl]=Xestor de Fiestras de Claude, TWM mellorado con pantallas virtuais, etc. +Comment[he]=Claude's Tab Window Manager, TWM המשופרת על ידי מסכים וירטואליים וכו' +Comment[hi]=क्लाउडे का टैब युक्त विंडो प्रबंधक, टीडबल्यूएम को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया. +Comment[hr]=Claudov Tab upravitelj prozora, TWM poboljšan virtualnim zaslonima, itd. +Comment[hu]=Claude lapozós ablakkezelője, lényegében a TWM, kiegészítve virtuális képernyőkkel, egyebekkel +Comment[is]=Tab gluggastjórinn eftir Claude sem hefur verið endurbættur með sýndarskjáum og fl. +Comment[it]=Window manager con linguette di Claude, TWM migliorato con schermi virtuali, ecc. +Comment[ja]=TWM に仮想デスクトップなどを強化した Claude のウィンドウマネージャ +Comment[ka]=Claude's Tab Window Manager - TWM-ის გაუმჯობესებული ვერსია +Comment[kk]=Claude's Tab Window Manager, TWM-ның жетілдірген нұсқасы. +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចជាផ្ទាំងរបស់ Claude, TWM ដែលធ្វើឲ្យប្រសើរដោយអេក្រង់និមិត្តជាដើម +Comment[lt]=Claude kortelių langų tvarkyklė, TWM praplėsta virtualių ekranų palaikymu ir t.t. +Comment[mk]=Claude's Tab Window Manager, TWM подобрен менаџер со виртуелни екрани итн. +Comment[mn]=Клаудиагийн ТАВ цонхны удирдагч, TWM виртуал дэлгэцээр өргөтгөгдсөн, гэх мэт. +Comment[mt]=Claude's Tab Window Manager, TWM flimkien ma' virtual screens, eċċ. +Comment[nb]=Claude's Tab Window Manager, TWM forbedret med virtuelle skrivebord,osv. +Comment[nds]=Claude's Tab Finsterpleger, TWM verbetert üm virtuelle Schriefdischen usw. +Comment[ne]=क्लाउडको ट्याब सञ्झ्याल प्रबन्धक, अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि +Comment[nl]=Claude's Tab Window Manager, TWM uitgebreid met virtuele schermen etc. +Comment[nn]=Claude's Tab Window Manager, TWM med virtuelle skrivebord og andre forbetringar +Comment[pa]=ਕਲਾਉਡੀ ਦਾ ਟੈਬ ਝਰੋਖਾ ਮੈਨੈਜਰ, TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਆਦਿ ਨਾਲ ਲੈੱਸ ਹੈ। +Comment[pl]=Menedżer okien Claude, TWM wzbogacony o wirtualne pulpity, itp. +Comment[pt]=O Tab Window Manager do Claude, um TWM melhorado com ecrãs virtuais, etc. +Comment[pt_BR]=O gerenciador de janelas em abas do Claude, o TWM melhorado pelas telas virtuais, etc. +Comment[ro]=Managerul de ferestre al lui Claude, o versiune îmbunătățită de TWM cu ecrane virtuale etc. +Comment[ru]=Claude's Tab Window Manager - улучшенная версия TWM +Comment[rw]=Mugenga Dirishya y'Agafishi ya Claude, TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi +Comment[se]=Claudea Tab Window Manager, TWM mas lea virtuella čállinbeavddit ja eará buorideamit. +Comment[sk]=Claude's Tab Window Manager, TWM rozšírený o virtuálne plochy, atď. +Comment[sl]=Claude's Tab Window Manager, TWM izboljšan z navideznimi zasloni ipd. +Comment[sr]=„Claude's Tab Window Manager“, TWM побољшан виртуелним екранима и сл. +Comment[sr@Latn]=„Claude's Tab Window Manager“, TWM poboljšan virtuelnim ekranima i sl. +Comment[sv]=Claudes fönsterhanterare med flikar, TWM förbättrad med virtuella skärmar, etc. +Comment[ta]= க்ளூடின் தத்தல் சாளர மேளாளர், TWM ஆல் மேம்படுத்தப்பட்ட மெய்நிகர் திரைகள்.. +Comment[tg]=Claude's Tab Window Manager - Версияи навтарини TWM +Comment[th]=ตัวจัดการแท็บหน้าต่างของ Claude คือ TWM ที่เพิ่มความสามารถด้วยหน้าจอเสมือน และอื่นๆ +Comment[tr]=Claude's Sekme Pencere Yöneticisi, sanal ekranlar ile TWM genişletilmiş, vb. +Comment[tt]=Claude's Tab Window Manager, TWM'nıñ qulaylanğan töre +Comment[uk]=Claude's Tab Window Manager, TWM з підтримкою віртуальних екранів, тощо. +Comment[vi]=Trình quản lý cửa sổ kiểu Thẻ của Claude, TWM cải tiến với màn hình ảo v.v. +Comment[wa]=Li Manaedjeu di Purneas a Linwetes di Claude (Claude's Tab Window Manager). TWM permete des forveyowès waitroûles, evnd. +Comment[zh_CN]=Claude 的标签式窗口管理器,加强了虚拟屏幕等功能的 TWM。 +Comment[zh_TW]=Claude's Tab 視窗管理程式, 基於 TWM 並加強虛擬螢幕等功能 diff --git a/kdm/kfrontend/sessions/cwwm.desktop b/kdm/kfrontend/sessions/cwwm.desktop new file mode 100644 index 000000000..51b60abd3 --- /dev/null +++ b/kdm/kfrontend/sessions/cwwm.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=cwwm +TryExec=cwwm +Name=CWWM +Name[eo]=CWFA +Name[hi]=सीडबल्यूडबल्यूएम +Name[te]=సి డబ్ల్యు డబ్ల్యు ఎం +Comment=The ChezWam Window Manager, a minimalist window manager based on EvilWM +Comment[af]=Die ChezWam venster bestuurder. Dis 'n minimalistiese venster bestuurder wat op EvilWM gebaseer is. +Comment[ar]=مدير نوافذ ChezWam، وهو مدير نوافذ مصغّر مبني على EvilWM +Comment[be]=Кіраўнік вокнаў ChezWam, мінімалістычны, заснаваны на EvilWM +Comment[bn]=ChezWam উইণ্ডো ম্যানেজার, EvilWM ভিত্তিক একটি উইণ্ডো ম্যানেজার +Comment[bs]=ChezWam Window Manager, minimalistički window manager baziran na EvilWM +Comment[ca]=El gestor de finestres ChezWam, un gestor de finestres minimalista basat en EvilWM +Comment[cs]=ChezWam, minimalistický správce oken založený na EvilWM +Comment[csb]=Menedżer òknów ChezWam, prosti menedżer òknów ùsôdzony na spòdlém EvilWM +Comment[cy]=Y Trefnydd Ffenestri ChezWam, trefnydd ffenestri lleiafol wedi'i seilio ar EvilWM +Comment[da]=ChezWam vindueshåndteringen, en minimalistisk vindueshåndtering baseret på EvilWM +Comment[de]=Deer ChezWam-Fenstermanager, eine minimalistische Lösung, die auf EvilWM basiert +Comment[el]=Ο ChezWam διαχειριστής παραθύρων, ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον EvilWM +Comment[eo]=La ChezWam Fenestroadministrilo, devenigita de MalbonaFA +Comment[es]=El gestor de ventanas ChezWam, un gestor minimalista basado en EvilWM +Comment[et]=ChezWami aknahaldur on vähenõudlik aknahaldur, mille aluseks on EvilWM +Comment[eu]=ChezWarn leiho kudeatzailea, EvilWM-en oinarritutako leiho kudeatzaile minimalista +Comment[fa]=مدیر پنجره ChezWam، مدیر پنجرۀ کمینه بر اساس EvilWM +Comment[fi]=ChezWam, minimalistinen EvilWM:ään pohjautuva ikkunaohjelma. +Comment[fr]=Le ChezWam Window Manager, un gestionnaire de fenêtres minimaliste fondé sur EvilWM +Comment[fy]=The ChezWam Window Manager, in minimalistyske finstersmanager baseare op EvilWM +Comment[gl]=O Xestor de Fiestras ChezWarm, un xestor minimalista baseado en EvilWM +Comment[he]=The ChezWam Window Manager, מנהל חלונות מינימליסטי המבוסס על EvilWM +Comment[hi]=चेकवाम विंडो प्रबंधक, एक अल्पतम विंडो प्रबंधक EvilWM पर आधारित +Comment[hr]=ChezWam, minimalistički upravitelj prozora zasnovan na EvilWM +Comment[hu]=ChezWam ablakkezelő, egy nagyon egyszerű ablakkezelő az EvilWM alapján +Comment[is]=ChezWam gluggastjórinn er lágmarks gluggastjóri sem er byggður á EvilWM +Comment[it]=Il ChezWam Window Manager, un window manager minimalista basato su EvilWM +Comment[ja]=ChezWam ウィンドウマネージャ, EvilWM ベースの小さなウィンドウマネージャ +Comment[ka]=ChezWam Window Manager - მინიმალისტური ფანჯრის მენეჯერი EvilWM -ის ბაზაზე +Comment[kk]=ChezWam Window Manager, EvilWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួច ChezWam ដែលជាកម្មវិធីគ្រប់គ្រងបង្អួចមិនសូវសម្បូរបែបហើយផ្អែកលើ EvilWM +Comment[lt]=ChezWam langų tvarkyklė, minimalistinė langų tvarkyklė, paremta EvilWM +Comment[mk]=ChezWam Window Manager, минималистички менаџер на прозорци базиран на EvilWM +Comment[mn]=ChezWam Цонхны удирдагч, EvilWM дээр суурилсан хамгийн жижиг цонхны удирдагч +Comment[mt]=ChezWam Window Manager - window manager minimu ibbażat fuq EvilWM +Comment[nb]=The ChezWam Window Manager, en minimalistisk vindusbehandler basert på EvilWM +Comment[nds]=De ChezWam Finsterpleger is minimalistisch un buut op EvilWM op +Comment[ne]=चेजवाम सञ्झ्याल प्रबन्धक, EvilWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=The ChezWam Window Manager, een minimalistische windowmanager gebaseerd op EvilWM +Comment[nn]=ChezWam Window Manager, ein minimalistisk vindaugssjef som byggjer på EvilWM +Comment[pa]=ChezWam ਝਰੋਖਾ ਮੈਨੇਜਰ, ਇੱਕ EvilWM ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ ਹੈ +Comment[pl]=Menedżer okien ChezWam, prosty menedżer okien stworzony na podstawie EvilWM +Comment[pt]=O ChezWam Window Manager, um gestor de janelas minimalista baseado no EvilWM +Comment[pt_BR]=O gerenciador de janelas de ChezWam, um gerenciador de janelas minimalista baseado no EvilWM +Comment[ro]=Managerul de ferestre ChezWam, o versiune minimalistică bazată pe EvilWM +Comment[ru]=ChezWam Window Manager - минимальный оконный менеджер на основе EvilWM +Comment[rw]=Mugenga Dirishya ChezWam, mugenga dirishya igira-nto ishingiye kuri EvilWM +Comment[se]=ChezWam Window Manager, ein minimalisttalaš lásegieđahalli, ráhkaduvvon EvilWM vuođul +Comment[sk]=The ChezWam Window Manager, minimálny správca okien založený na EvilWM +Comment[sl]=ChezWam Window Manager, skromen okenski upravitelj na osnovi EvilWM +Comment[sr]=„ChezWam Window Manager“, минималистички менаџер прозора заснован на EvilWM-у +Comment[sr@Latn]=„ChezWam Window Manager“, minimalistički menadžer prozora zasnovan na EvilWM-u +Comment[sv]=Fönsterhanteraren Chezwam, en minimalistisk fönsterhanterare baserad på Ond WM +Comment[ta]=செஸ்வாம் சாளர மேளாளர்,EvilWM ஐ அடிப்படையிலான குறைந்தபட்ச சாளர மேளாளர் +Comment[tg]=ChezWam Window Manager - Мудири равзанаҳои хурд дар асоси EvilWM +Comment[th]=ตัวจัดการหน้าต่าง ChezWarm คือ ระบบจัดการ หน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ EvilWM +Comment[tr]=ChezWam Pencere Yöneticisi +Comment[tt]=ChezWam Window Manager, EvilWM asılında ciñel täräzä-idäräçe +Comment[uk]=Мінімалістичний менеджер вікон ChezWam, заснований на EvilWM +Comment[uz]=EvilWM asosida yaratilgan juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=EvilWM асосида яратилган жуда оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ ChezWam, một trình quản lý cửa sổ đơn giản dựa trên EvilWM +Comment[wa]=Li Manaedjeu di Purneas di ChezWam (ChezWam Window Manager). On manaedjeu di purneas tot simpe, båzé so EvilWM +Comment[zh_CN]=ChezWam 窗口管理器,基于 EvilWM 的最小化窗口管理器 +Comment[zh_TW]=The ChezWam 視窗管理程式,基於 EvilWM 的小型化視窗管理程式 diff --git a/kdm/kfrontend/sessions/enlightenment.desktop b/kdm/kfrontend/sessions/enlightenment.desktop new file mode 100644 index 000000000..66dcdd574 --- /dev/null +++ b/kdm/kfrontend/sessions/enlightenment.desktop @@ -0,0 +1,86 @@ +[Desktop Entry] +Type=XSession +Exec=enlightenment_start +TryExec=enlightenment +Name=Enlightenment +Name[bn]=এনলাইটেনমেন্ট +Name[cy]=Goleuni (Enlightenment) +Name[eo]=Lumaĵo +Name[fa]=روشنفکری +Name[hi]=एनलाइटनमेंट +Name[km]=ភ្លឺ +Name[mn]=Гэгээрэл +Name[ne]=बुद्धत्व +Name[pa]=ਗਿਆਨ +Name[rw]=Imurika +Name[ta]=விளக்கிக்கூறுதல் +Name[te]=జ్ఞానొదయం +Comment=An extremely themable very feature-rich window manager +Comment[af]='n Uitbreibare, tema geaktiveerde venster bestuurder +Comment[ar]=مدير نوافذ غني بالمزايا وقابل لاستخدام السّمات بشكل كبير. +Comment[be]=Абсалютна змяняльны, багаты на здольнасці кіраўнік вокнаў +Comment[bn]=প্রচুর বৈশিষ্ট্য সম্বলিত একটি উইণ্ডো ম্যানেজার, যা বহুভাবে নিজের পছন্দমত বদলে নেওয়া যায় +Comment[bs]=Izuzetno prilagodljiv window manager bogat opcijama +Comment[ca]=Un gestor de finestres extremadament temible molt ric en característiques +Comment[cs]=Na funkce bohatý správce oken s širokou škálou témat +Comment[csb]=Bògati w fùnkcëje menedżer òknów ò wiôldżich mòżnotach zjinaczi wëzdrzatkù +Comment[cy]=Trefnydd ffenestri sy'n llawn o nodweddion, efo llawer o themau. +Comment[da]=En ekstremt tema-fleksibel egenskabsrig vindueshåndtering +Comment[de]=Sehr design- und funktionsreicher Fenstermanager +Comment[el]=Ένας εξαιρετικά παραμετροποιήσιμος και πλούσιος σε χαρακτηριστικά διαχειριστής παραθύρων +Comment[eo]=Fenestroadministrilo kun tre multaj eblecoj +Comment[es]=Un gestor de ventanas lleno de características y extremadamente personalizable +Comment[et]=Äärmiselt paljude teemade ja väga laialdaste võimalustega aknahaldur +Comment[eu]=Gaitasun ugari dituen, eta zeharo pertsonalizagarria den leiho kudeatzailea +Comment[fa]=مدیر پنجره با ویژگی زیاد و شدیداً موضوعی +Comment[fi]=Erittäin muokattavissa oleva ominaisuusrikas ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres avec beaucoup de thèmes et de fonctionnalités +Comment[fy]=In tige rike en ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras moi configurábel en apariencia e rico en características +Comment[he]=מנהל חלונות פונקציונלי המכיל אפשרויות רבות להגדרת ערכות נושא +Comment[hi]=एक विंडो प्रबंधक जो अत्यंत प्रसंग युक्त तथा विशेषता से भरपूर है +Comment[hr]=Izuzetno prilagodljiv upravitelj prozora, bogat mogućnostima +Comment[hu]=Egy nagyon sokoldalúan témázható, sok lehetőséget biztosító ablakkezelő +Comment[is]=Afskaplega öflugur gluggastjóri með góðum þemastuðningi +Comment[it]=Un window manager estremamente temabile con molte funzionalità +Comment[ja]=詳細な部分までもテーマ化が可能な非常に多機能のウィンドウマネージャ +Comment[ka]=მრავალფუნქციური ფანჯრის მენეჯერი თემების მხარდაჭერით +Comment[kk]=Қасиеттер жағынан бай, көп тақырыпты терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចមានលក្ខណៈពិសេសសម្បូរបែប ដែលអាចប្ដូររូបរាងបានតាមចិត្ត +Comment[ko]=다양한 곳을 꾸밀 수 있는 기능이 풍부한 창 관리자 +Comment[lt]=Daug temų ir savybių turinti langų tvarkyklė +Comment[lv]=Tēmām un iespējām bagāts logu menedžeris +Comment[mk]=Менаџер на прозорци богат со можности и екстремно подложен на стилизирање со теми +Comment[mn]=Маш ирээдүйтэй цонхны удирдагч +Comment[ms]=Pengurus tetingkap kaya ciri yang amat boleh tema +Comment[mt]=Window manager rikk u b'ħafna effetti viżwali. +Comment[nb]=En svært omfattende vindusbehandler som kan tilpasses med temaer +Comment[nds]=En Finsterpleger mit bannig vele Funkschonen un Mustern +Comment[ne]=अत्याधिक विषयवस्तु योग्य धेरै आकृति सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer rijke en configureerbare windowmanager +Comment[nn]=Ein svært omfattande vindaugssjef som kan tilpassast med tema +Comment[pa]=ਇੱਕ ਸਰੂਪ ਦੇ ਪੂਰੇ ਫੀਚਰਾਂ ਨਾਲ ਭਰਪੂਰ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Bogaty w funkcje menedżer okien o dużych możliwościach zmiany wyglądu +Comment[pt]=Um gestor de janelas muito rico em funcionalidades e extremamente personalizado na sua aparência +Comment[pt_BR]=Um gerenciador de janelas rico em recursos e extremamente configurável através de temas +Comment[ro]=Un manager de ferestre extrem de versatil și cu multe facilități +Comment[ru]=Многофункциональный, поддерживающий темы оконный менеджер +Comment[rw]=Mugenga Dirishya biranga-bikize cyane ngirwa-nsanganyamatsiko mu buryo burenze +Comment[se]=Lášegieđahalli mas leat erenoamáš ollu doaimmat ja maid sáhttá heivehit fáttáin +Comment[sk]=Správca okien s veľkým množstvom funkcií a extrémnou podporou tém +Comment[sl]=Okenski upravitelj, zelo prilagodljiv in poln možnosti +Comment[sr]=Изузетно прилагодљив менаџер прозора са пуно могућности +Comment[sr@Latn]=Izuzetno prilagodljiv menadžer prozora sa puno mogućnosti +Comment[sv]=En ytterst anpassningsbar mycket funktionsrik fönsterhanterare +Comment[ta]=நிறைய தன்மைகள் அடங்கிய சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳо дорои мавзӯъҳои гуногун ва дигар бисёр функсияҳо +Comment[th]=ระบบจัดการหน้าต่างที่เต็มไปด้วยความสามารถ และใช้ชุดตกแต่งมากมาย +Comment[tr]=İleri derecede temalanabilir, özellik zengini bir masaüstü yöneticisi +Comment[tt]=Küpçaralı tışlanulı täräzä-idäräçe +Comment[uk]=Менеджер вікон з потужною підтримкою тем та різноманітних функцій +Comment[uz]=Mavzu va imkoniyatlarga juda boy oyna boshqaruvchi +Comment[uz@cyrillic]=Мавзу ва имкониятларга жуда бой ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ cực kỳ dễ thay đổi sắc thái với nhiều tích năng +Comment[wa]=On manaedjeu di purneas foirt bén po-z eployî des tinmes et foirt ritche en usteyes +Comment[zh_CN]=强主题化的多功能窗口管理器 +Comment[zh_TW]=一個功能相當豐富的視窗管理程式 diff --git a/kdm/kfrontend/sessions/evilwm.desktop b/kdm/kfrontend/sessions/evilwm.desktop new file mode 100644 index 000000000..3c8c4f657 --- /dev/null +++ b/kdm/kfrontend/sessions/evilwm.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=evilwm +TryExec=evilwm +Name=EvilWM +Name[eo]=MalbonaFA +Name[hi]=एविलडबल्यूएम +Name[sv]=Ond WM +Name[te]=ఈవిల్ డబ్ల్యు ఎం +Comment=A minimalist window manager based on AEWM +Comment[af]='n Minimalistiese venster bestuurder wat op AEWM gebaseer is +Comment[ar]=مدير نوافذ مصغّر مبني على AEWM +Comment[be]=Кіраўнік вокнаў для мінімаліста, заснаваны на AEWM +Comment[bn]=AEWM ভিত্তিক একটি পরিমিত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalistički window manager baziran na AEWM +Comment[ca]=Un gestor de finestres minimalista basat en AEWM +Comment[cs]=Minimalistický správce oken založený na AEWM +Comment[csb]=Prosti menedżer òknów ùsôdzony na spòdlém AEWM +Comment[cy]=Trefnydd ffenestri lleiafol wedi'i seilio ar AEM +Comment[da]=En minimalistisk vindueshåndtering baseret på AEWM +Comment[de]=Minimalistischer Fenstermanager, der auf AEWM basiert +Comment[el]=Ένας μινιμαλιστικός διαχειριστής παραθύρων βασισμένος στον AEWM +Comment[eo]=Minimumema fenestroadministrilo +Comment[es]=Un administrado de ventanas minimalista basado en AEWM +Comment[et]=Vähenõudlik aknahaldur, mille aluseks on AEWM +Comment[eu]=AEWMn oinarritutako leiho kudeatzaile minimalista +Comment[fa]=یک مدیر پنجرۀ کمینه براساس AEWM +Comment[fi]=Minimalistinen, AEWM:ään pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur AEWM +Comment[fy]=In minimalistyske finstersmanager basearre op AEWM +Comment[gl]=Un xestor de fiestras minimalista baseado en AEWM +Comment[he]=מנהל חלונות מינימליסטי המבוסס על AEWM +Comment[hi]= एक अल्पतम विंडो प्रबंधक एईडबल्यूएम पर आधारित +Comment[hr]=Minimalistički upravitelj prozora zasnovan na AEWM-u +Comment[hu]=Egy nagyon egyszerű ablakkezelő az AEWM alapján +Comment[is]=Lágmarks gluggastjóri sem er byggður á AEWM +Comment[it]=Un window manager minimalista basato su AEWM +Comment[ja]=AEWM ベースの小さなウィンドウマネージャ +Comment[ka]=მინიმალისტური ფანჯრის მენეჯერი AEWM-ის ბაზაზე +Comment[kk]=AEWM-негіздеген шағын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចលក្ខណៈពិសេសតិច ដែលផ្អែកលើ AEWM +Comment[ko]=AEWM 기반 창 관리자 +Comment[lt]=Minimalistinė langų tvarkyklė, paremta AEWM +Comment[lv]=Minimālistisks logu menedžeris bāzēts uz AEWM +Comment[mk]=Минималистички менаџер на прозорци базиран на AEWM +Comment[mn]=AEWM дээр суурилсан цонхны удирдагч +Comment[mt]=Window manager minimu ibbażat fuq AEWM +Comment[nb]=En minimalistisk vindusbehandler basert på AEWM +Comment[nds]=En minimalistischen Finsterpleger, de op AEWM opbuut +Comment[ne]=AEWM आधारित मिनिमलिस्ट सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimalistische windowmanager gebaseerd op AEWM +Comment[nn]=Ein minimalistisk vindaugssjef som byggjer på AEWM +Comment[pa]=AEWM ਤੇ ਆਧਾਰਿਤ ਨਿਊਨਤਮ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien stworzony na podstawie AEWM +Comment[pt]=Um gestor de janelas minimalista baseado no AEWM +Comment[pt_BR]=Um gerenciador de janelas minimalista baseado no AEWM +Comment[ro]=Un manager de ferestre minimalistic bazat pe AEWM +Comment[ru]=Минимальный оконный менеджер, основанный на AEWM +Comment[rw]=Mugenga dirishya igira-nto ishingiye kuri AEWM +Comment[se]=Minimalisttalaš lásegieđahalli, ráhkaduvvon AEWM vuođul +Comment[sk]=Minimálny správca okien založený na AEWM +Comment[sl]=Minimalističen okenski upravitelj na osnovi AEWM +Comment[sr]=Минималистички менаџер прозора заснован на AEWM-у +Comment[sr@Latn]=Minimalistički menadžer prozora zasnovan na AEWM-u +Comment[sv]=Minimalistisk fönsterhanterare baserad på AEWM +Comment[ta]=AEWM அடிப்படையிலான குறைதபட்ச சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои хурд дар асоси AEWM +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก สร้างจากพื้นฐานของ AEWM +Comment[tr]=AEWM tabanlı küçük bir pencere yöneticisi +Comment[tt]=AEWM asılında ciñel täräcä-idäräçe +Comment[uk]=Мінімалістичний менеджер вікон, заснований на AEWM +Comment[uz]=AEWM asosida yaratilgan juda oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=AEWM асосида яратилган жуда оддий ойна бошқарувчи +Comment[vi]=Một trình quản lý cửa sổ đơn giản dựa trên AEWM +Comment[wa]=On manaedjeu di purneas minimå båzé so AEWM +Comment[zh_CN]=基于 AEWM 的最小化窗口管理器 +Comment[zh_TW]=一個基於 AEWM 的小型化視窗管理程式 diff --git a/kdm/kfrontend/sessions/fluxbox.desktop b/kdm/kfrontend/sessions/fluxbox.desktop new file mode 100644 index 000000000..df6a0813c --- /dev/null +++ b/kdm/kfrontend/sessions/fluxbox.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=startfluxbox +TryExec=startfluxbox +Name=Fluxbox +Name[bn]=ফ্লাক্সবক্স +Name[cy]=Llif-flwch (Fluxbox) +Name[eo]=Fluujo +Name[hi]=फ्ल्क्स-बाक्स +Name[ne]=फ्लक्सबक्स +Name[pa]=ਫਕਸਬਕਸ +Name[rw]=AgasandukuUmujyoumwe +Name[ta]=ப்ளக்ஸ் பெட்டி +Name[te]=ఫ్లక్స్ బాక్స్ +Name[tg]=Қуттии Flux +Comment=A highly configurable and low resource window manager based on Blackbox +Comment[af]='n Baie konfigureerbare en lae hulpbron intensiewe venster bestuurder, wat op Blackbox gebaseer is. +Comment[ar]=مدير نوافذ قابل للإعداد بشكل كبير ويستخدم القليل من موارد الجهاز وهو مبني Blackbox +Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з вялікімі здольнасцямі змяняцца і з нізкай патрабавальнасцю да рэсурсаў +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক একটি উইণ্ডো ম্যানেজার, যা নানাভাবে কনফিগার করা যায়, কিন্তু খুবই কম রিসোর্স ব্যবহার করে +Comment[bs]=Visoko prilagodljiv window manager sa malim zauzećem resursa baziran na Blackbox-u +Comment[ca]=Un gestor de finestres altament configurable i que necessita pocs recursos basat en Blackbox +Comment[cs]=Vysoce přizpůsobitelný a nízkoúrovňový správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów òpiarti na Blackbox ò wiôldżich mòżnotach kònfigùracëji ë nisczich żądaniach +Comment[cy]=Trefnydd ffenestri hawdd ei ffurfweddu ac ysgafn ei ddefnydd adnoddau, wedi'i seilio ar Ddu-flwch (Blackbox) +Comment[da]=En meget indstillelig vindueshåndtering med lavt ressourceforbrug baseret på Blackbox +Comment[de]=Sehr flexibler, aber ressourcenschonender Fenstermanager, der auf Blackbox basiert +Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος και με μικρή κατανάλωση πόρων διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[eo]=Fenestroadministrilo devenigita de Negrujo +Comment[es]=Un gestor de ventanas basado en Blackbox muy configurable y con poco consumo de recursos +Comment[et]=Väga hästi kohandatav ja vähenõudlik aknahaldur, mille aluseks on Blackbox +Comment[eu]=Blackbox-en oinarritutako leiho kudeatzaile zeharo konfiguragarria, eta errekurtso gutxi kontsumitzen dituena +Comment[fa]=یک مدیر پنجره با قابلیت پیکربندی بالا و منبع پایین براساس Blackbox +Comment[fi]=Blackboxiin pohjautuva erittäin muokattava ja vähäisen resurssitarpeen omaava ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très configurable et utilisant peu de ressources, fondé sur Blackbox +Comment[fy]=In tige ynstelbere lichtgewicht finstersmanager basearre op Blackbox +Comment[gl]=Un xestor de fiestras moi configurábel e lixeiro baseado en Blackbox +Comment[he]=מנהל חלונות בעל הגדרות רבות הצורך משאבים מעטים ומבוסס עלBlackbox +Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कॉन्फ़िगरेबल तथा कम साधन चाहने वाला विंडो प्रबंधक +Comment[hr]=Visoko konfigurabilan upravitelj prozora, male potrošnje resursa, zasnovan na Blackbox-u +Comment[hu]=Egy Blackbox-alapú ablakkezelő, alacsony erőforrásigénnyel, sokféle beállítási lehetőséggel +Comment[is]=Öflugur gluggastjóri sem notar lítið af auðlindum vélarinnar sem er byggður á Blackbox +Comment[it]= Un window manager molto configurabile e che utilizza poche risorse basato su Blackbox +Comment[ja]=Blackbox ベースの高度な設定が可能でリソースにやさしいウィンドウマネージャ +Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox -ის ბაზაზე +Comment[kk]=Blackbox-негіздеген, баптаулары көп, үнемді терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចដែលអាចកំណត់រចនាសម្ព័ន្ធបានខ្ពស់ និងប្រើធនធានតិច ដែលផ្អែកលើ Blackbox +Comment[ko]=Blackbox 기반의 다양하게 설정 가능하고 자원을 적게 사용하는 창 관리자 +Comment[lt]=Daug konfigūravimo parinkčių turinti ir mažai resursų naudojanti langų tvarkyklė, paremta Blackbox +Comment[lv]=Plaši konfigurējams un resursus taupošs logu menedžeris bāzēts uz Blackbox +Comment[mk]=Високо конфигурабилен менаџер на прозорци со мали побарувања на ресурси базиран на Blackbox +Comment[mn]=Хар хайрцаг дээр суурилсан маш бага нөөц хэрэглэдэг тохируулах чадвар өндөр цонхны удирдагч +Comment[mt]=Window manager ħafif u konfigurabbli ibbażat fuq BlackBox +Comment[nb]=En lite ressurskrevende og svært fleksibel vindusbehandler basert på Blackbox +Comment[nds]=En Finsterpleger, de wenig Ressourcen bruukt, man bannig vele Instellen hett. Opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित उच्च कन्फिगरयोग्य र न्यून संसाधन सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer configureerbare lichtgewicht windowmanager gebaseerd op Blackbox. +Comment[nn]=Ein lite ressurskrevjande og svært fleksibel vindaugssjef basert på Blackbox +Comment[pa]=ਇੱਕ ਬਿਲਕੁੱਲ ਹਲਕਾ ਤੇ ਜਿਆਦਾ ਸੋਧਯੋਗ ਫਾਇਲ਼ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Blackbox o dużych możliwościach konfiguracji i niskich wymaganiach +Comment[pt]=Um gestor de janelas bastante configurável e que usa poucos recursos, baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas altamente configurável e com baixo uso de recursos, baseado no Blackbox +Comment[ro]=Un manager de ferestre foarte configurabil și mic, bazat pe Blackbox +Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya mbonezwa mu buryo buhanitse kandi bikorana bike ishingiye ku Gasandukumukara +Comment[se]=Lásegieđahalli vuođđoduvvon Blackbox:as, hui heivehahtti ja geavaha unnán resurssaid +Comment[sk]=Veľmi konfigurovateľný a nenáročný správca okien založený na Blackbox +Comment[sl]=Visoko nastavljiv in učinkovit okenski upravitelj na osnovi Blackboxa +Comment[sr]=Врло подесив и незахтеван менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Vrlo podesiv i nezahtevan menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Mycket anpassningsbar fönsterhanterare med litet resursbehov baserad på Blackbox +Comment[ta]=கறுப்புபெட்டி சார்ந்த அமைக்கக்கூடிய குறைந்த வள சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои танзимшаванда дар асоси Blackbox +Comment[th]=ระบบจัดการหน้าต่างที่สามารถปรับแต่งได้อย่างละ เอียด และใช้ทรัพยากรน้อย สร้างบนพื้นฐานของ Blackbox +Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir düşük kaynaklı bir pencere yöneticisi +Comment[tt]=Blackbox asılında qorılğan, yaqşı caylana torğan täräcä-idäräçe +Comment[uk]=Дуже гнучкий та невибагливий для ресурсів менеджер вікон, заснований на Blackbox +Comment[vi]=Một trình quản lý cửa sổ rất dễ cấu hình và đòi hỏi ít tài nguyên dựa trên Blackbox +Comment[wa]=On ledjir et foirt apontiåve manaedjeu di purneas båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 可深入配置且占用资源较少的窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且高可組態及低資源的視窗管理程式 diff --git a/kdm/kfrontend/sessions/flwm.desktop b/kdm/kfrontend/sessions/flwm.desktop new file mode 100644 index 000000000..d6dc24010 --- /dev/null +++ b/kdm/kfrontend/sessions/flwm.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=flwm +TryExec=flwm +Name=FLWM +Name[eo]=RMFA +Name[hi]=एफएलडबल्यूएम +Name[te]=ఎఫ్ ఎల్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง FLWM +Comment=The Fast Light Window Manager, based primarily on WM2 +Comment[af]=Die Vinnige, ligte venster bestuurder, wat op WM2 gebaseer is +Comment[ar]=مدير النوافذ السريع الخفيف، مبني بشكل أساسي على WM2 +Comment[be]=The Fast Light Window Manager, заснаваны на WM2 +Comment[bn]=ফাস্ট লাইট উইণ্ডো ম্যানেজার, WM2 ভিত্তি করে তৈরি +Comment[bs]=Fast Light Window Manager, baziran uglavnom na WM2 +Comment[ca]=El gestor de finestres Fast Light, primerament basat en WM2 +Comment[cs]=Fast Light Window Manager založený původně na WM2 +Comment[csb]=Fast Light Window Manager, menedżer òknów ùsôdzony przédno na WM2 +Comment[cy]=Y Trefnydd Ffenestri Chwim ac Ysgafn, wedi'i seilio ar WM2 am y rhan fwyaf +Comment[da]=Fast Light vindueshåndtering, baseret først og fremmest på WM2 +Comment[de]=Der Fast Light Window Manager, der vor allem auf WM2 basiert +Comment[el]=Ο Fast Light διαχειριστής παραθύρων, βασισμένος κυρίως στον WM2 +Comment[eo]=Rapida malpeza fenestroadministrilo +Comment[es]=El Fast Light Window Manager, basado principalmente en WM2 +Comment[et]=Kiire ja vähenõudlik aknahaldur, aluseks peamiselt WM2 +Comment[eu]=Batez ere WM2-en oinarritutako leiho kudeatzaile arin eta bizkorra +Comment[fa]=مدیر پنجرۀ سریع و سبک، در اصل بر اساس WM2 +Comment[fi]=Fast Light Window Manager. Pohjautuu suurimmaksi osin WM2:een +Comment[fr]=The Fast Light Window Manager, fondé au départ sur WM2 +Comment[fy]=De Fast Light Window Manager, primêr basearre op WM2 +Comment[gl]=O Fast Light Window Manager, un xestor de fiestras lixeiro baseado en WM2 +Comment[he]=The Fast Light Window Manager, מבוסס בעיקר על WM2 +Comment[hi]=मुख्यतः डबल्यूएम2 पर आधारित तेज और हल्का विंडो प्रबंधक +Comment[hr]=Brzi i lagani upravitelj prozora (FLWM), zasnovan na WM2 +Comment[hu]=Fast Light Window Manager ablakkezelő, elsősorban a WM2 alapján +Comment[is]=Léttur og hraðvirkur gluggastjóri sem er aðallega byggður á WM2 +Comment[it]=Il Fast Light Window Manager, basato principalmente su WM2 +Comment[ja]="高速で軽い"WM2 ベースのウィンドウマネージャ +Comment[ka]=სწრაფი და მსუბუქი ფანჯრების მენეჯერი WM2 -ის ბაზაზე +Comment[kk]=WM2-негіздеген жеңіл және жедел терезе менеджері +Comment[km]=Fast Light Window Manager ផ្អែកចម្បងលើ WM2 +Comment[ko]=WM2에 기반을 둔 빠르고 가벼운 창 관리자 +Comment[lt]=Greita ir lengva langų tvarkyklė, paremta daugiausiai WM2 +Comment[lv]=Fast Light logu menedžeris, bāzēts galvenokārt uz WM2 +Comment[mk]=Fast Light Window Manager, менаџер примарно базиран на WM2 +Comment[mn]=Ерөнхийдөө WM2 дээр суурилсан хурдан хөнгөн цонхны удирдагч +Comment[mt]=Fast Light Window Manager, ibbażat fuq WM2 +Comment[nb]=En rask, lett vindusbehandler (Fast Light Window Manager), mest basert på WM2 +Comment[nds]=De "Fast Light"-Finsterpleger, to'n gröttsten Deel opbuut op WM2 +Comment[ne]=साधारणतया WM2 मा आधारित छिटो हल्का सञ्झ्याल प्रबन्धक +Comment[nl]=De Fast Light Window Manager, primair gebaseerd op WM2. +Comment[nn]=Ein rask, lett vindaugssjef (Fast Light Window Manager), mest basert på WM2 +Comment[pa]=ਇੱਕ ਹਲਕਾ ਤੇਜ਼ ਫਾਇਲ਼ ਮੈਨੇਜਰ, ਜੋ ਕਿ WM2 ਤੇ ਆਧਾਰਿਤ ਹੈ +Comment[pl]=Fast Light Window Manager, menedżer okien stworzony głownie na podstawie WM2 +Comment[pt]=O Fast Light Window Manager, baseado em primeiro lugar no WM2 +Comment[pt_BR]=Acrônimo para Fast Light Window Manager (gerenciador rápido e leve), baseado primeiramente no WM2 +Comment[ro]=Fast Light Window Manager, bazat în principal pe WM2 +Comment[ru]=Быстрый и лёгкий оконный менеджер, основанный на WM2 +Comment[rw]=Mugenga Dirishya Yihuta Yoroshye, ishingiye mbere na mbere kuri WM2 +Comment[se]=Jođánis, geahpes lásegieđahalli, ráhkaduvvon WM2 vuođul +Comment[sk]=The Fast Light Window Manager založený na WM2 +Comment[sl]=Fast Light Window Manager, v glavnem na osnovi WM2 +Comment[sr]=Брзи лаки менаџер прозора (FLWM), заснован на WM2 +Comment[sr@Latn]=Brzi laki menadžer prozora (FLWM), zasnovan na WM2 +Comment[sv]=Fönsterhanteraren Fast Light Window Manager, i huvudsak baserad på WM2 +Comment[ta]=WM2 அடிப்படையிலான வேக ஒளி வேக சாளர மேளாளர் +Comment[tg]=мудири равзанаҳои тез ва осон дар асоси WM2 +Comment[th]=ระบบจัดการหน้าต่างที่เร็วและเบา สร้างบนพื้นฐานของ WM2 +Comment[tr]=Fast Light Pencere Yöneticisi +Comment[tt]=WM2 asılında qorılğan, citez ciñel täräcä-idäräçe +Comment[uk]=Швидкий легкий менеджер вікон, заснований здебільшого на WM2 +Comment[uz]=Asosan WM2 asosida yaratilgan tez va oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Асосан WM2 асосида яратилган тез ва оддий ойна бошқарувчи +Comment[vi]=Trình Quản lý Cửa sổ Nhanh và Nhẹ, dựa chủ yếu vào WM2 +Comment[wa]=Li Roed et Ledjir Manaedjeu di Purneas (ast Light Window Manager) båzé so WM2 +Comment[zh_CN]=又快又轻巧的窗口管理器,主要基于 WM2 +Comment[zh_TW]=一個主要基於 WM2 且快速及輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm.desktop b/kdm/kfrontend/sessions/fvwm.desktop new file mode 100644 index 000000000..20ae57d4c --- /dev/null +++ b/kdm/kfrontend/sessions/fvwm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm +TryExec=fvwm +Name=FVWM +Name[hi]=एफ़वीडबल्यूएम +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం +Comment=A powerful ICCCM-compliant multiple virtual desktop window manager +Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. +Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة +Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў +Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব +Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa +Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM +Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë +Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM +Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe +Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen +Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας +Comment[eo]=Fenestroadministrilo +Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales +Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur +Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza +Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند +Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples +Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden +Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais +Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים +Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक +Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina +Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel +Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum +Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali +Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ +Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი +Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចផ្ទៃតុនិមិត្តច្រើនដ៏មានអានុភាព ដែលអនុវត្តតាម ICCCM +Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 +Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė +Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu +Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM +Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. +Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM +Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen +Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक +Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen +Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM +Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity +Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais +Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais +Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale +Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы +Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara +Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit +Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch +Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM +Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина +Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina +Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM +Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ +Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง +Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi +Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe +Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць +Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo +Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM +Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 +Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm2.desktop b/kdm/kfrontend/sessions/fvwm2.desktop new file mode 100644 index 000000000..1a25a91e4 --- /dev/null +++ b/kdm/kfrontend/sessions/fvwm2.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm2 +TryExec=fvwm2 +Name=FVWM2 +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 2 +Comment=A powerful ICCCM-compliant multiple virtual desktop window manager +Comment[af]='n Kragtige, ICCCM-aanpasbare veelvuldige virtuele werkskermvenster bestuurder. +Comment[ar]=مدير نوافذ قوي ومتوافق مع ICCCM ذي أسطح مكتب وهمية متعددة +Comment[be]=Магутны ICCCM-сумяшчальны кіраўнік вокнаў з падтрымкай віртуальных працоўных сталоў +Comment[bn]= একটি শক্তিশালী ICCCM-compliant উইণ্ডো ম্যানেজার, যাতে একাধিক ভার্চুয়াল ডেস্কটপ সম্ভব +Comment[bs]=Moćan ICCCM-sukladan window manager sa podrškom za više virtuelnih desktopa +Comment[ca]=Un poderós gestor de finestres per a múltiples escriptoris virtuals que compleix amb ICCCM +Comment[csb]=Stolemny menedżer òknów zgòdny z ICCCM òbsłëgòwujący wirtualné pùltë +Comment[cy]=Trefnydd ffenestri pwerus efo penbyrddau rhith lluosol, sy'n cydymffurfio â ICCCM +Comment[da]=En kraftig ICCCM-kompliant vindueshåndtering med flere virtuelle desktoppe +Comment[de]=Ein leistungsfähiger ICCCM-kompatibler Fenstermanager mit virtuellen Arbeitsflächen +Comment[el]=Ένας πολύ δυνατός, συμβατός με το ICCCM, διαχειριστής παραθύρων με πολλαπλές εικονικές επιφάνειες εργασίας +Comment[eo]=Fenestroadministrilo +Comment[es]=Un potente gestor de ventanas, compatible con ICCCM y que soporta varios escritorios virtuales +Comment[et]=Võimas ICCCM nõuetele vastav mitme virtuaalse töölauaga aknahaldur +Comment[eu]=ICCCM konpatiblea den, eta mahaigain birtual ugari dituen leiho kudeatzaile bortitza +Comment[fa]=یک مدیر پنجرۀ رومیزی مجازی چندگانه ICCCM-compliant نیرومند +Comment[fi]=Tehokas ICCCM-mukautuva virtuaalityöpöytiä tukeva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres puissant compatible ICCCM avec gestion de bureaux virtuels multiples +Comment[fy]=In krêftige ICCCM-compliant finstersmanager mei meardere buroblêden +Comment[gl]=Un xestor de fiestras potente acorde coa ICCCM con múltiplos escritórios virtuais +Comment[he]=מנהל חלונות עצמתי עם תאימות ל־ICCCM בעל שולחנות עבודה וירטואליים רבים +Comment[hi]=शक्तिशाली आईसीसीसीएम-कम्पलाएंट अनेक आभासी डेस्कटॉप विंडो प्रबंधक +Comment[hr]=Comment=Moćni, ICCCM kompatibilan, upravitelj prozora s više virtualnih radnih površina +Comment[hu]=Egy sokoldalú, ICCCM-kompatibilis ablakkezelő, virtuális munkaasztal-kezeléssel +Comment[is]=Öflugur ICCCM samhæfður gluggastjóri með sýndarskjáborðum +Comment[it]=Un window manager molto potente e ICCCM-compatibile che supporta i desktop virtuali +Comment[ja]=複数の仮想デスクトップをサポートした ICCCM 準拠のパワフルなウィンドウマネージャ +Comment[ka]=ძლიერი ICCCM-თავსებადი ვირტულური სამუშაო დაფების მხარდამჭერი ფანჯრის მენეჯერი +Comment[kk]=Қуатты ICCCM-үйлесімді, көп виртуалды үстел қолдайтын терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចផ្ទៃតុនិមិត្តច្រើនដ៏មានអានុភាព ដែលអនុវត្តតាម ICCCM +Comment[ko]=다중 가상 데스크톱을 사용하는 ICCCM 호환 창 관리자 +Comment[lt]=galinga, su ICCCM suderinama daugelio virtualių darbastalių langų tvarkyklė +Comment[lv]=Spēcīgs ICCCM-savietojams logu menedžeris ar vairāku darbvirsmu atbalstu +Comment[mk]=Моќен менаџер на прозорци со повеќе виртуелни површини во согласност со ICCCM +Comment[mt]=Window manager b'saħħtu, konformi ma' ICCCM, b'desktops virtwali. +Comment[nb]=En slagkraftig vindusbehandler med flere virtuelle skrivebord, som støtter ICCCM +Comment[nds]=En kraftvulle, ICCCM-kompatible Finsterpleger mit vele virtuelle Schriefdischen +Comment[ne]=शक्तिशाली ICCCM-मान्ने बहुविध अवास्तविक डेस्कटप सञ्झ्याल प्रबन्धक +Comment[nl]=Een krachtige ICCCM-compliant windowmanager met meerdere bureaubladen +Comment[nn]=Ein slagkraftig vindaugssjef med fleire virtuelle skrivebord, som støttar ICCCM +Comment[pa]=ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ICCCM-ਅਨੁਕੂਲ ਬਹੁ-ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਵਾਲਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Potężny menedżer okien zgodny z ICCCM obsługujący wirtualne pulpity +Comment[pt]=Um gestor de janelas poderoso em conformidade com o ICCCM e que suporta vários ecrãs virtuais +Comment[pt_BR]=Um poderoso gerenciador de janelas compatível com o ICCM, com suporte a múltiplas áreas de trabalho virtuais +Comment[ro]=Un manager de ferestre puternic compliant ICCCM ce suportă ecrane virtuale +Comment[ru]=Мощный ICCCM-совместимый оконный менеджер, поддерживающий виртуальные рабочие столы +Comment[rw]=igikoranisha-ICCCM nyembaraga mugenga dirishya y'ibiro bitandukanye bitagaragara +Comment[se]=Fápmolaš ICCCM-heivvolaš lásegieđahalli mas lea virtuealla čállinbeavddit +Comment[sk]=Výkonný správca okien kompatibilný s ICCCM s podporou virtuálnych plôch +Comment[sl]=Močan okenski upravitelj z večimi navideznimi namizji in popolnoma v skladu z ICCCM +Comment[sr]=Моћни, ICCCM-сагласни, менаџер прозора са више виртуелних радних површина +Comment[sr@Latn]=Moćni, ICCCM-saglasni, menadžer prozora sa više virtuelnih radnih površina +Comment[sv]=Kraftfull fönsterhanterare med flera virtuella skrivbord som följer ICCCM +Comment[ta]=ICCCM-தரத்தில் பலதரப்பட்ட மெய்நிகர் மேல் மேசை சாளர மேளாளர் +Comment[tg]=Мудири равзанаҳои бузург дар асоси ICCCM дорои мудири равзанаҳо бо мизикориҳои виртуалӣ +Comment[th]=ระบบจัดการหน้าต่างที่มีหลายพื้นที่ทำงานเสมือน สอดรับกับ ICCCM ประสิทธิภาพสูง +Comment[tr]=Güçlü ICCCM-uyumlu çoklu sanal masaüstü yöneticisi +Comment[tt]=ICCCM-ütkän, küp öställär totqan köçle täräzä-idäräçe +Comment[uk]=Потужний, сумісний з ICCCM менеджер вікон, з підтримкою віртуальних стільниць +Comment[vi]=Trình quản lý cửa sổ tương thích với ICCCM nhiều chức năng, quản lý nhiều màn hình nền ảo +Comment[wa]=On manaedjeu di purneas avou multi-forveyowès sicribannes ki rote avou ICCM +Comment[zh_CN]=强大的多虚拟桌面窗口管理器,与 ICCCM 兼容 +Comment[zh_TW]=一個強大的 ICCCM 相容的多重虛擬桌面視窗管理程式 diff --git a/kdm/kfrontend/sessions/fvwm95.desktop b/kdm/kfrontend/sessions/fvwm95.desktop new file mode 100644 index 000000000..2bbd1c403 --- /dev/null +++ b/kdm/kfrontend/sessions/fvwm95.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=fvwm95 +TryExec=fvwm95 +Name=FVWM95 +Name[hi]=एफ़वीडबल्यूएम95 +Name[te]=ఎఫ్ వి డబ్ల్యు ఎం 95 +Comment=A Windows 95 look-alike derivative of FVWM +Comment[af]='n FVWM venster bestuurder wat soos Windows 95 lyk +Comment[ar]=شبيه بـWin95 ومشتق من FVWM +Comment[be]=Вытворная ад FVWM, падобная на Windows 95 +Comment[bn]=FVWM-ভিত্তিক Windows 95-এর মত দেখতে একটি উইণ্ডো ম্যানেজার +Comment[bs]=Derivacija FVWM nalik na Windows 95 +Comment[ca]=Un semblant a Win95 derivat de FVWM +Comment[cs]=Správce oken se vzhledem Windows 95 odvozený od FVWM +Comment[csb]=Pòchòdzący z FVWM menedżer òknów ò wëzdrzatkù szlachùjącym za Windows 95 +Comment[cy]=Deilliant o FVWM sy'n edrych yn debyg i Windows95 +Comment[da]=En Windows 95-lignende vindueshåndtering afledt af FVWM +Comment[de]=Ein Abkömmling von FVWM im Stil von Windows 95 +Comment[el]=Ένας παρόμοιος με τα Windows 95 διαχειριστής παραθύρων προερχόμενος από τον FVWM +Comment[eo]=Fenestroadministrilo kiel tiu de Vindozo 95 +Comment[es]=Un derivado de FVWM de aspecto similar a Win95 +Comment[et]=FVWM derivaat, mis näeb välja nagu Windows 95 +Comment[eu]=Windows 95en itxura duen FVWMren ondorengo bat +Comment[fa]=ویندوز ۹۵ شبیه مشتق FVWM +Comment[fi]=Windows 95:lta näyttävä FVWM-johdannainen +Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95 dérivant de FVWM +Comment[fy]=In op Windows 95 lykjende fariant fan FVWM +Comment[gl]=Un xestor de fiestras coma o de Windows 95 derivado de FVWM +Comment[he]=נגזרת של FVWM הנראה כמו חלונות 95 +Comment[hi]=विंडोज़ 95 जैसा दिखने वाला एफ़वीडबल्यूएम का प्रतिरूप +Comment[hr]=Derivat FVWM-a nalik na Windows 95 +Comment[hu]=Win95-szerű FVWM-változat +Comment[is]=Útgáfa af FVWM sem líkist Windows 95 +Comment[it]=Una variante di FVWM che assomiglia a Windows 95 +Comment[ja]=Windows95 に似た外見の FVWM 派生ウィンドウマネージャ +Comment[ka]=FVWM კლონი Windows 95-ის სტილში +Comment[kk]=Windows 95 секілді FVWM-негіздеген терезе менеджері +Comment[km]=ស្រដៀង Windows 95 ដែលក្លាយមកពី FVWM +Comment[ko]=FVWM의 윈도 95를 닮은 변종 +Comment[lt]=Windows 95 išvaizdą primenanti FVWM atmaina +Comment[lv]=Windows 95 līdzīgs FVWM atvasinājums +Comment[mk]=Деривација на FVWM менаџерот со изглед на Windows 95 +Comment[mn]=FVWM -ээс уламжилсан Виндовс 95 шиг харагдалттай +Comment[ms]=Terbitan FVWM yang menyerupai Windows 95 +Comment[mt]=Derivattiv ta' FVWM jixbaħ lil Windows 95 +Comment[nb]=En variant av FVWM som ser ut som Windows 95 +Comment[nds]=Süht ut as A Windows 95 un is vun FVWM afleddt +Comment[ne]=विण्डोज ९५ FVWM को डेरिभेटिभ जस्तो छ +Comment[nl]=Een op Windows 95 lijkende variant van FVWM +Comment[nn]=Ein variant av FVWM som ser ut som Windows 95 +Comment[pa]=ਵਿੰਡੋ 95 ਵਰਗਾ FVWM ਦਾ ਇੱਕ ਰੂਪ +Comment[pl]=Wywodzący się z FVWM menedżer okien o wyglądzie podobnym do Windows 95 +Comment[pt]=Uma derivação do FVWM parecida com o Windows 95 +Comment[pt_BR]=Um derivado do FVWM com a aparência do Windows 95 +Comment[ro]=O versiune de FVWM cu aspect de Windows 95 +Comment[ru]=Клон FVWM в стиле Windows 95 +Comment[rw]=Windows 95 isa nk'ikomoka kuri FVWM +Comment[se]=FVWM-vuođđoduvvon lásegieđahalli mii lea Windows 95-lágan +Comment[sk]=Správca okien podobný Windows 95 založený na FVWM +Comment[sl]=Izpeljanka FVWM v izgledu Windows 95 +Comment[sr]=Дериват FVWM-а налик на Windows 95 +Comment[sr@Latn]=Derivat FVWM-a nalik na Windows 95 +Comment[sv]=Fönsterhanterare som liknar Windows 95 med ursprung i FVWM +Comment[ta]=FVWM லிருந்து தோன்றிய விண்டோஸ் 95 ஐப் போன்ற +Comment[tg]=Windows 95 look-монанди маҳсулии FVWM +Comment[th]=FVWM ที่ถูกทำให้ดูเหมือนวินโดวส์ 95 +Comment[tr]=Windows 95'e benzeyen bir pencere yönetimi +Comment[tt]=Windows 95 küreneşendä FVWM qabatlama +Comment[uk]=Похідний від FVWM з виглядом Windows 95 +Comment[uz]=Win95'ga oʻxshagan FVWM'ning turi +Comment[uz@cyrillic]=Win95'га ўхшаган FVWM'нинг тури +Comment[vi]=Trình quản lý cửa sổ giống Windows 95, hậu duệ của FVWM +Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 et k' est båzé so FVWM +Comment[zh_CN]=一个与 Windows 95 外观类似的 FVWM 变种 +Comment[zh_TW]=一個由 FVWM 演化出來且外觀像 Win95 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/gnome.desktop b/kdm/kfrontend/sessions/gnome.desktop new file mode 100644 index 000000000..ed89391ec --- /dev/null +++ b/kdm/kfrontend/sessions/gnome.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=gnome-session +TryExec=gnome-session +Name=GNOME +Name[bn]=গনোম +Name[eo]=Gnomikuo +Name[hi]=ग्नोम +Name[ko]=세임 그놈 +Name[mn]=ГНОМЕ +Name[ne]=जिनोम +Name[sv]=Gnome +Name[ta]=க்னோம் +Name[te]=గ్నొమ్ +Comment=The GNU Network Object Model Environment. A complete, free and easy-to-use desktop environment +Comment[af]=Die GNU 'Network Object Model Environment'. 'n Volledige, gratis en maklik om te gebruik werkskerm omgewing. +Comment[ar]=بيئة نموذج الكائن الشبكي من GNU، بيئة سطح مكتبي حرّة وسهلة الاستخدام +Comment[be]=The GNU Network Object Model Environment. Поўнае, свабоднае і простае ў выкарыстанні працоўнае асяроддзе +Comment[bn]=দি গনিউ নেটওয়ার্ক অবজেক্টমডেল এনভায়রনমেন্ট। একটি পূর্ণ, মুক্ত এবং সহজেই ব্যবহারযোগ্য ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=GNU Network Object Model Environment. Kompletna, slobodna i jednostavna za upotrebu desktop okolina +Comment[ca]=El GNU Network Object Model Environment. Un complet, lliure i fàcil d'usar entorn d'escriptori +Comment[cs]=GNOME, GNU Network Object Model Environment. Kompletní, svobodné a uživatelsky přívětivé garfické prostředí. +Comment[csb]=GNU Network Object Model Environment (GNOME). Fùlwôrtné, wòlné ë prosté w brëkòwaniô òkrãżé pùltu +Comment[cy]=Yr Amgylchedd Model Gwrthrych Rhwydwaith GNU (GNU Network Object Model Environment). Amgylchedd penbwrdd cyflawn, rhydd, a hawdd ei ddefnyddio. +Comment[da]=GNU Network Object Model Environment. Et fuldstænding, frit og nemt at bruge desktopmiljø +Comment[de]=Das GNU Network Object Model Environment. Eine vollständige, freie und leicht bedienbare Arbeitsumgebung +Comment[el]=Το GNU Network Object Model Environment. Ένα πλήρης, ελεύθερο και εύκολο στη χρήση περιβάλλον επιφάνειας εργασίας +Comment[eo]=Plena labortabla ĉirkaŭaĵo +Comment[es]=El GNU Network Object Model Environment, un entorno de escritorio completo, libre y fácil de usar +Comment[et]=GNU Network Object Model Environment on täielik, vaba ja väga hõlpsasti kasutatav töölaua keskkond +Comment[eu]=GNU Network Object Model Environment. mahaigain-ingurune oso, libre eta erabilterraza +Comment[fa]=محیط مدل شئ شبکه گنو. محیط رومیزی کامل، آزاد و آسان برای استفاده. +Comment[fi]=GNU Network Object Model Environment. Valmis, vapaa ja helppokäyttöinen työpöytäympäristö +Comment[fr]=The GNU Network Object Model Environment. Un environnement de bureau complet, gratuit et facile à utiliser +Comment[fy]=De GNU Network Object Model Environment, In komplete, frije en ienfâldige te brûken buroblêd omwrâld +Comment[gl]=O GNU Network Object Model Environment. Un entorno de escritório completo, libre e de uso doado +Comment[he]=The GNU Network Object Model Environment. סביבת עבודה מלאה, חופשית וקלה לשימוש +Comment[hi]=जीएनयू नेटवर्क ऑब्जेक्ट मॉडल एनवायरनमेंट. एक संपूर्ण, उपयोग में आसान डेस्कटॉप वातावरण +Comment[hr]=GNOME - GNU Network Object Model Environment - Cjelokupno, besplatno i jednostavno okruženje radne površine +Comment[hu]=GNU Network Object Model Environment (GNOME), egy teljes, ingyenes, könnyen kezelhető grafikus környezet +Comment[is]=GNU Network Object Model Environment er fullkomið og fjrálst skjáborðsumhverfi sem er auðvelt að nota +Comment[it]=Il GNU Network Object Model Environment. Un ambiente desktop completo, libero e facile da usare +Comment[ja]=GNU オブジェクトモデル環境, 完全にフリーで使いやすいデスクトップ環境 +Comment[ka]=GNU Network Object Model Environment - სრული, თავისუფალი და ადვილად გამოყენებადი სამუშაო გარემო +Comment[kk]=GNU Network Object Model Environment. Толық, еркін таратылатын, ыңғайлы графикалық орта +Comment[km]=GNU Network Object Model Environment ។ បរិស្ថានផ្ទៃតុពេញលេញ, ឥតគិតថ្លៃ និងងាយស្រួលប្រើ +Comment[ko]=GNU Network Object Model Environment(그놈). 완전한 자유 소프트웨어 데스크톱 환경입니다. +Comment[lt]=GNU tinklo objektų modeliavimo aplinka. Savarankiška, laisva ir lengvai naudojama darbastalio aplinka +Comment[lv]=GNU Network Object Model Environment. Pilnvērtīga bezmaksas viegli lietojama darba vide. +Comment[mk]=GNU Network Object Model Environment. Работна околина која е комплетна, слободна и едноставна за користење +Comment[mn]=GNU Network Object Model Environment. Бүрэн, үнэгүй хэрэглэхэд хялбар дэлгэцийн системийн орчин +Comment[mt]=GNU Network Object Model Environment. Ambjent grafiku komplet, ħieles u faċli tużah. +Comment[nb]=GNU Network Object Model Environment. Et skrivebordsmiljø som er komplett, fritt og lett å bruke. +Comment[nds]=De "GNU Network Object Model Environment". En komplette Schriefdisch-Ümgeven, ümsunst un eenfach to bruken +Comment[ne]=GNU सञ्जाल बस्तु नमूना वातावरण । पूर्ण, स्वतन्त्र र प्रयोग गर्न सजिलो डेस्कटप वातावरण +Comment[nl]=De GNU Network Object Model Environment, een complete, vrije en eenvoudig te gebruiken desktop environment. +Comment[nn]=GNU Network Object Model Environment. Eit skrivebordsmiljø som er komplett, fritt og lett å bruka. +Comment[pa]=GNU Network Object Model Environment, ਇੱਕ ਸੰਪੂਰਨ, ਮੁਫਤ ਅਤ ਵਰਤਣ ਵਿੱਚ ਅਤਿ ਆਸਾਨ ਵੇਹੜਾ ਵਾਤਾਵਰਣ +Comment[pl]=GNU Network Object Model Environment (GNOME). Pełne, wolne i łatwe w użyciu środowisko pulpitu +Comment[pt]=O GNU Network Object Model Environment. Um ambiente de trabalho completo, livre e fácil de usar +Comment[pt_BR]=Acrônimo para GNU Network Object Model Environment ou Ambiente de Modelo de Objetos de Rede GNU; um ambiente de trabalho completo, livre e fácil de usar +Comment[ro]=GNU Network Object Model Environment. Un mediu grafic complet, gratuit și ușor de utilizat +Comment[ru]=GNU Network Object Model Environment - полная, свободная и лёгкая в использовании графическая среда +Comment[rw]=Ibikikije Moderi Igikoresho Urusobemiyoboro GNU. Ibikikije by'ibiro byuzuye, by'ubuntu kandi byoroshye-gukoresha. +Comment[se]=GNU Netword Object Model Environment: Čállinbeavdebiras mii lea aibbas fridja ja álki geavahit. +Comment[sk]=The GNU Network Object Model Environment. Úplné, voľne šíriteľné a ľahko použiteľné pracovné prostredie +Comment[sl]=GNU Network Object Model Environment. Popolno, prosto in preposto namizno okolje +Comment[sr]=„GNU Network Object Model Environment“(Gnome, Гном). Потпуно, бесплатно и лако за коришћење радно окружење +Comment[sr@Latn]=„GNU Network Object Model Environment“(Gnome, Gnom). Potpuno, besplatno i lako za korišćenje radno okruženje +Comment[sv]=GNU Network Object Model Environment. En fullständig, fri och lättanvänd skrivbordsmiljö +Comment[ta]=GNU மாதிரி வலை பொருள் சூழல்.முழுமையான , இலவச சுலபமாக பயன்படுத்தக்கூடிய மேல்மேசை சூழல் +Comment[th]=GNU Network Object Model Environment สภาพแวดล้อมสำหรับเดสก์ทอปที่ครบถ้วน, ฟรี และใช้งานง่าย +Comment[tr]=GNU Network Object Model Environment (GNOME) +Comment[tt]=The GNU Network Object Model Environment. Qullanu öçen ciñel, buşlay, tulıçaralı östäl möxite +Comment[uk]=The GNU Network Object Model Environment. Повнофункціональне, вільне та зручне графічне середовище +Comment[uz]=GNOME (GNU Network Object Model Environment) - mukammal, erkin va foydalanish uchun juda qulay ish stoli muhiti +Comment[uz@cyrillic]=GNOME (GNU Network Object Model Environment) - мукаммал, эркин ва фойдаланиш учун жуда қулай иш столи муҳити +Comment[vi]=Môi trường Mạng Mô hình Đối tượng của GNU. Một môi trường màn hình nền đầy đủ, tự do và dễ sử dụng +Comment[wa]=L' evironmint di modele di cayets d' rantoele GNU (GNU Network Object Model Environment). On complet evironmint d' sicribanne, libe et åjhey a -z eployî. +Comment[zh_CN]=GNU 网络对象模型环境。完整、自由、易用的桌面环境 +Comment[zh_TW]=GNU 網路物件模型環境。一個完整,免費且容易使用的桌面環境 diff --git a/kdm/kfrontend/sessions/golem.desktop b/kdm/kfrontend/sessions/golem.desktop new file mode 100644 index 000000000..3ba7f2b41 --- /dev/null +++ b/kdm/kfrontend/sessions/golem.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=golem +TryExec=golem +Name=Golem +Name[bn]=গোলেম +Name[eo]=Golemo +Name[hi]=गोलेम +Name[ne]=गोलेम +Name[pa]=ਗੋਲੀਮ +Name[te]=గొలెం +Comment=A lightweight window manager +Comment[af]='n Lig gewig venster bestuurder +Comment[ar]=مدير نوافر خفيف العبء +Comment[be]=Лёгкі кіраўнік вокнаў +Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager +Comment[ca]=Un lleuger gestor de finestres KDE +Comment[cs]=Malý správce oken +Comment[csb]=Menedżer òknół ò môłëch żądaniach +Comment[cy]=Trefnydd ffenestri ysgafn +Comment[da]=En letvægtsvindueshåndtering +Comment[de]=Eine schlanker Fenstermanager +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων +Comment[eo]=Malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero +Comment[et]=Imeväike aknahaldur +Comment[eu]=Leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ سبک +Comment[fi]=Kevyt ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très léger +Comment[fy]=In lichtgewicht finstersmanager +Comment[gl]=Un xestor de fiestras lixeiro +Comment[he]=מנהל החלונות קל משקל +Comment[hi]=एक हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő +Comment[is]=Léttur gluggastjóri +Comment[it]=Un window manager leggero +Comment[ja]=軽量なウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრი მენეჯერი +Comment[kk]=Жеңіл терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសមត្ថភាពខ្សោយ +Comment[ko]=가벼운 창 관리자 +Comment[lt]=Nedaug resursų eikvojanti langų tvarkyklė +Comment[lv]=Viegls logu menedžeris +Comment[mk]=Лесен менаџер на прозорци +Comment[mn]=Хөнгөн цонхны удирдагч +Comment[ms]=Pengurus tetingkap ringan +Comment[mt]=Window manager ħafif +Comment[nb]=En lettvekts vindusbehandler +Comment[nds]=En ranke Finsterpleger +Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager +Comment[nn]=Ein lett vindaugssjef +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach +Comment[pt]=Um gestor de janelas leve +Comment[pt_BR]=Um gerenciador de janelas leve +Comment[ro]=Un manager de ferestre foarte mic +Comment[ru]=Лёгкий оконный менеджер +Comment[rw]=Mugenga dirishya yoroshye +Comment[se]=Geahpes lásegieđahalli +Comment[sk]=Nenáročný správca okien +Comment[sl]=Lahek okenski upravitelj +Comment[sr]=Лагани менаџер прозора +Comment[sr@Latn]=Lagani menadžer prozora +Comment[sv]=Lättviktig fönsterhanterare +Comment[ta]=குறைவான எடை உடைய சாளர மேலாளர் +Comment[te]=తెలికైన విండొ అభికర్త +Comment[tg]=Мудири тирезаи сабук +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา +Comment[tr]=Hızlı çalışan bir pencere yöneticisi +Comment[tt]=Ciñel täräzä-idäräçe +Comment[uk]=Швидкий менеджер вікон +Comment[uz]=Oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhẹ ký +Comment[wa]=On ledjir manaedjeu di purneas +Comment[zh_CN]=轻量级窗口管理器 +Comment[zh_TW]=一個輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/icewm.desktop b/kdm/kfrontend/sessions/icewm.desktop new file mode 100644 index 000000000..8b70361fa --- /dev/null +++ b/kdm/kfrontend/sessions/icewm.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=XSession +Exec=icewm-session +TryExec=icewm-session +Name=IceWM +Name[eo]=GlaciFA +Name[hi]=आइस-डबल्यूएम +Name[lo]=ຕົວຈັດການຫນ້າຕ່າງ IceWM +Name[sv]=Ice WM +Name[te]=ఐస్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง IceWM +Comment=A Windows 95-OS/2-Motif-like window manager +Comment[af]='n Windows 95-OS/2-Motif tipe venster bestuurder +Comment[ar]=مدير نوافذ مشابه لـ Win95-OS/2-Motif +Comment[be]=Кіраўнік вокнаў, падобны на Windows 95-OS/2-Motif +Comment[bn]=Windows 95-OS/2-Motif-এর অনুরূপ একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Windows 95-OS/2-Motif +Comment[ca]=Un gestor de finestres com els de Windows 95-OS/2-Motif +Comment[cs]=Správce oken podobný Windows 95-OS/2-Motif +Comment[csb]=Menedżer òknół szlachùjący za Windows 95-OS/2-Motif +Comment[cy]=Trefnydd ffenestri sy'n debyg i Windows95-OS/2-Motif +Comment[da]=En Windows 95-OS/2-Motif-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil von Windows 95, OS/2 und Motif +Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95-OS/2-Motif +Comment[eo]=Fenestroadministrilo kiel Vindozo 95, OS/2 kaj Motifo +Comment[es]=Un gestor de ventanas similar a Win95-OS/2-Motif +Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95-OS/2-Motif +Comment[eu]=Windows 95 OS/2 Motif-en itxura duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره شبیه Windows 95-OS/2-Motif +Comment[fi]=Windows 95:n ja OS/2-Motifin tyylinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres ressemblant à Windows 95-OS/2-Motif +Comment[fy]=In Win95-OS/2-Motif-likens finstersmanager +Comment[gl]=Un xestor de fiestras coma o de Windows 95-OS/2-Motif +Comment[he]=מנהל חלונות מבוסס Motif הדומה במראהו לחלונות 95/OS-2 +Comment[hi]=विंडोज़ 95-ओएस/2-मोटिफ जैसा विंडो प्रबंधक +Comment[hr]=Upravitelj prozora nalik na Windows 95/OS/2/Motif +Comment[hu]=Win95-OS/2-Motif-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist 95-OS/2-Motif +Comment[it]=Un window manager in stile Windows 95-OS/2-Motif +Comment[ja]=Windows95, OS/2, Motif に似たウィンドウマネージャ +Comment[ka]=ფანჯრების მენეჯერი Windows95-OS/2-Motif სტილში +Comment[kk]=Windows 95-OS/2-Motif-секілді терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចដែលដូច Windows 95-OS/2-Motif +Comment[ko]=윈도 95, OS/2, Motif를 닮은 창 관리자 +Comment[lt]=A Windows 95-OS/2-Motif-primenanti langų tvarkyklė +Comment[lv]=Windows 95 - OS/2 - Motif līdzīgs logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Windows 95, OS/2 и Motif +Comment[mn]=Виндовс 95-OS/2-Motif-шиг цонхны удирдагч +Comment[ms]=Pengurus tetingkap seperti Motif Windows 95-OS/2 +Comment[mt]=Window manager jixbaħ lill-Windows 95-OS/2-Motif +Comment[nb]=En vindusbehandler som likner Windows 95-OS/2-Motif +Comment[nds]=Finsterpleger, de utsüht as Windows 95-OS/2-Motif +Comment[ne]=विण्डोज ९५-OS/2-मोटिफ जस्तो सञ्झ्याल प्रबन्धक +Comment[nl]=Een Win95-OS/2-Motif-achtige windowmanager +Comment[nn]=Ein vindaugssjef som liknar Windows 95-OS/2-Motif +Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95-OS/2-Motif-ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien podobny do Windows 95-OS/2-Motif +Comment[pt]=Um gestor de janelas parecido com o Windows 95, o OS/2 e o Motif +Comment[pt_BR]=Um gerenciador de janelas parecido com Windows 95-OS/2-Motif +Comment[ro]=Un manager de ferestre cu aspect de Windows 95, OS/2 sau Motif +Comment[ru]=Оконный менеджер в стиле Windows95-OS/2-Motif +Comment[rw]=Windows 95-OS/2-umutako-nka mugenga dirishya +Comment[se]=Windows 95-OS/2-Motif-lágan lásegieđahalli +Comment[sk]=Správca okien podobný Windows 95-OS/2-Motif +Comment[sl]=Okenski upravitelj, podoben Windows 95, OS/2 in Motifu +Comment[sr]=Менаџер прозора налик на Windows 95/OS/2/Motif +Comment[sr@Latn]=Menadžer prozora nalik na Windows 95/OS/2/Motif +Comment[sv]=Fönsterhanterare som liknar Windows 95-OS/2-Motif +Comment[ta]=சாளரங்கள் 95-OS/2-மாடிஃப்-லைக் சாளர மேலாளர் +Comment[te]=విండొస్ 95-ఒఎస్/2 -మొటిఫ్ లాంటి విండొ అభికర్త +Comment[tg]=Windows 95-OS/2-Motif-монанди мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างของที่ดูคล้าย วินโดวส์ 95-โอเอสทู-โมทิฟ +Comment[tr]=Windows 95-OS/2-Motif benzeri bir pencere yöneticisi +Comment[tt]=Windows 95-OS/2-Motif küreneşendä täräzä-idäräçe +Comment[uk]=Менеджер вікон на кшталт Windows 95-OS/2-Motif +Comment[uz]=Win95-OS/2-Motif'ga oʻxshash oyna boshqaruvchi +Comment[uz@cyrillic]=Win95-OS/2-Motif'га ўхшаш ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ với mô típ kiểu Windows 95 +Comment[wa]=On manaedjeu di purneas rishonnant Windows95-OS/2-Motif +Comment[zh_CN]=类似 Windows-OS/2-Motif 的窗口管理器 +Comment[zh_TW]=一個像 Win95-OS/2-Motif 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/ion.desktop b/kdm/kfrontend/sessions/ion.desktop new file mode 100644 index 000000000..c4ae9ca04 --- /dev/null +++ b/kdm/kfrontend/sessions/ion.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=ion +TryExec=ion +Name=Ion +Name[bn]=আয়ন (Ion) +Name[eo]=Iono +Name[hi]=आयन +Name[ja]=ION +Name[ko]=카메룬 +Name[pa]=ਲੋਨ +Name[te]=ఐయాన్ +Name[th]=ไอออน +Comment=A keyboard-friendly window manager with tiled windows, based on PWM +Comment[af]='n Sleutelbord vriendelike venster bestuurder, met geteëlde vensters. Dis op PWM gebaseer. +Comment[ar]=مدير نوافذ سهل استخدام لوحة المفاتيح ذي نوافذ معنونة، مبني على PWM +Comment[be]=Кіраўнік вокнаў для працы з клавіятурай, заснаваны на PWM +Comment[bn]=PWM ভিত্তিক উইণ্ডো ম্যানেজার, যা কীবোর্ড দিয়ে নিয়ন্ত্রণ করা সহজ +Comment[bs]=Window manager za tastaturu sa popločanim prozorima, baziran na PWM +Comment[ca]=Un gestor de finestres amigable amb el teclat i amb finestres alicatades, basat en PWM +Comment[csb]=Menedżer òknów z dobrą òbsłëgą klawiaturë ë kachelkòwaniém òknów, ùsôdzony na spòdlém PWM +Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ddefnyddio o'r alweddell, efo ffenestri wedi'u teilio, wedi'i seilio ar PVM +Comment[da]=En tastaturvenlig vindueshåndtering med fliselagte vinduer, baseret på PWM +Comment[de]=Tastaturfreundlicher Fenstermanager mit gekachelten Fenstern, basiert auf PWM +Comment[el]=Ένας φιλικός με το πληκτρολόγιο διαχειριστής παραθύρων με υποστήριξη παραθύρων σε παράθεση, βασισμένος στον PWM +Comment[eo]=Fenestroadministrilo por la uzo klaviara +Comment[es]=Un gestor de ventanas utilizable desde el teclado con mosaico de ventanas, basado en PWM +Comment[et]=Klaviatuurisõprade aknahaldur paanitud akendega, aluseks PWM +Comment[eu]=PWMn oinarritutako leiho-mosaikoa duen leiho kudeatzailea, teklatutik erabil daitekeena +Comment[fa]=یک مدیر پنجرۀ صفحه کلید پسند با پنجرههای کاشیشده، براساس PWM +Comment[fi]=Näppäimistöystävällinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres utilisable au clavier avec des fenêtres en mosaïque, fondé sur PWM +Comment[fy]=In toetseboerdfreonlike finstersmanager mei tegele finsters. basearre op PWM +Comment[gl]=Un xestor de fiestras de manexo co teclado e fiestras en mosaico baseado en PWM +Comment[he]=מנהל חלונות ידידותי למקלדת עם חלונות פרושים המבוסס על PWM +Comment[hi]=पीडबल्यूएम आधारित चटाई विंडो युक्त विंडो प्रबंधक जो कुंजीपट फ्रेडली है +Comment[hr]=Comment=Upravitelj prozora s popločenim prozorima, namijenjen tipkovnici i zasnovan na PWM-u +Comment[hu]=Egy billentyűzetről könnyen kezelhető ablakkezelő, mozaikszerű ablakelrendezéssel, a PWM alapján +Comment[is]=Gluggastjóri sem er gott að vinna í með lyklaborðinu einu, byggður á PWM +Comment[it]=Un window manager "amico della tastiera" con finestre affiancate, basato su PWM +Comment[ja]=PWM ベースのキーボード操作に適したタイル表示式のウィンドウマネージャ +Comment[ka]=კლავიატურით მართვადი ფანჯრების მენეჯერი, PWM-ის ბაზაზე +Comment[kk]=PWM-негіздеген, пернетақтадан басқарылатын, терезелері кезектескен, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចដែលងាយប្រើជាមួយក្ដារចុច ហើយអាចរៀបបង្អួចជាក្បឿង និងផ្អែកលើ PWM +Comment[lt]=Patogi dirbti su klaviatūra langų tvarkyklė su išklotais langais, paremta PWM +Comment[lv]=Tastatūrai draudzīgs logu menedžeris ar tiled logiem, bāzēts uz PWM +Comment[mk]=Менаџер на прозорци со поплочени прозорци базиран на PWM погоден за работа со тастатура +Comment[mn]=PWM дээр суурилсан гараар ажиллахад тохиромжтой цонх удирдагч +Comment[ms]=Pengurus tetingkap mesra papan kekunci dengan tetingkap berjubin, berdasarkan PWM +Comment[mt]=Window manager ibbażat fuq PWM, b'sapport għal tastieri u windows imqassma fuiq madum +Comment[nb]=En tastaturvennlig vindusbehandler med flislagte vinduer, basert på PWM +Comment[nds]=En tastatuurfründliche Finsterpleger mit kachelte Finstern, opbuut op PWM +Comment[ne]=शीर्षक सञ्झ्यालसँग सोझो सञ्झ्याल प्रबन्धक कुञ्जीपाटी +Comment[nl]=Een toetsenbordvriendelijke windowmanager met getegelde vensters. Gebaseerd op PWM +Comment[nn]=Ein tastaturvennleg vindaugssjef med flislagde vindauge, basert på PWM +Comment[pa]=ਇੱਕ ਕੀ-ਬੋਰਡ ਸਹਾਇਕ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ PWM ਤੇ ਆਧਾਰਿਤ ਹੈ +Comment[pl]=Menedżer okien z dobrą obsługą klawiatury i kafelkowaniem okiem, stworzony na podstawie PWM +Comment[pt]=Um gestor de janelas amigável para o teclado, com janelas lado-a-lado, baseado no PWM +Comment[pt_BR]=Um gerenciador de janelas amigável com o teclado, com janelas ladrilhadas, baseado no PWM +Comment[ro]=Un manager de ferestre ușor de utilizat din tastatură, cu ferestre ce pot fi așezate în mozaic, bazat pe PWM +Comment[ru]=Управляемый с клавиатуры оконный менежер, основанный на PWM +Comment[rw]=mugenga dirishya ya mwandikisho-yoroshyeikoresha ifite amadirishya agerekeranye, ishingiye kuri PWM +Comment[se]=Boallobeavdeustitlaš lašegieđahalli, mas leat bálddalas láset, ráhkaduvvon PWM vuođul +Comment[sk]=Správca okien s podporou kláves, usporiadania okien do dlaždíc, založený na PWM +Comment[sl]=Tipkovnici prijazen okenski upravitelj z razdeljenimi okni, na osnovi PWM +Comment[sr]=Пријатељски према тастатури менаџер прозора са наслаганим прозорима, заснован на PWM-у +Comment[sr@Latn]=Prijateljski prema tastaturi menadžer prozora sa naslaganim prozorima, zasnovan na PWM-u +Comment[sv]=Tangentbordsvänlig fönsterhanterare med fönster sida vid sida, baserad på PWM +Comment[ta]=PWM அடிப்படையிலான விசைப்பலகையால் கையாளமுடிந்த சாளர மேளாளர் +Comment[th]=ระบบจัดการหน้าต่างที่เป็นมิตรกับการใช้แป้นพิมพ์ พร้อมกับหน้าต่างที่ถูกปูเรียง สร้างจาก PWM +Comment[tr]=PWM tabanlı, klavye dostu uzatılmış pencereleriyle bir pencere yönetici +Comment[tt]=Täräzä bülü belän töylek-söygän täräzä-idäräçe, PWM asılında +Comment[uk]=Менеджер вікон налаштований для легкого використання з клавіатурою, засновано на PWM +Comment[vi]=Trình quản lý cửa sổ thiết kết thân thiện với việc dùng bàn phím, có các cửa sổ xếp ngói, dựa trên PWM +Comment[wa]=On manaedjeu di purneas k' inme li taprece avou des purneas å pus grand, båzé so PWM +Comment[zh_CN]=一个基于 PWM 的窗口管理器,适合键盘操作,可平铺窗口 +Comment[zh_TW]=一個基於 PWM 且方便鍵盤使用和支援棋盤化視窗的視窗管理程式 diff --git a/kdm/kfrontend/sessions/kde.desktop.in b/kdm/kfrontend/sessions/kde.desktop.in new file mode 100644 index 000000000..b032d395a --- /dev/null +++ b/kdm/kfrontend/sessions/kde.desktop.in @@ -0,0 +1,45 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=XSession +Exec=@KDE_BINDIR@/startkde +TryExec=@KDE_BINDIR@/startkde +Name=KDE +Name[hi]=केडीई +Name[mn]=КДЭ +Name[ta]=Kஏற்றக் காவலன் +Name[xh]=iKDE +Name[xx]=xxKDExx +Comment=The K Desktop Environment. A powerful Open Source graphical desktop environment +Comment[bs]=K Desktop Environment. Moćan grafički desktop otvorenog izvornog koda +Comment[ca]=L'entorn d'escriptori K. Un poderós entorn d'escriptori gràfic de Codi Font Obert +Comment[cy]=Yr Amgylchedd Penbwrdd K. Amgylchedd penbwrdd graffegol pwerus, sy'n gôd-agored. +Comment[da]=K Skrivebordsmiljøet. Et kraftigt, åbent, grafisk skrivebordsmiljø +Comment[de]=Das K Desktop Environment. Eine mächtige, graphische Arbeitsumgebung und Open Source / Freie Software +Comment[el]=Το K Desktop Environment. Ένα πανίσχυρο ελεύθερης προέλευσης γραφικό περιβάλλον επιφάνειας εργασίας +Comment[es]=El Entorno de Escritorio K, un potente entorno de escritorio gráfico realizado de código abierto +Comment[et]=K töölaua keskkond on võimas vaba tarkvara graafiline töölaua keskkond +Comment[fi]=KDE-työpöytäympäristö (K Desktop Environment) on tehokas avoimen lähdekoodin graafinen työpöytäympäristö +Comment[fr]=The K Desktop Environment. Un environnement de bureau graphique, puissant et Open Source +Comment[he]=The K Desktop Environment. סביבת עבודה גרפית, בעלת-עוצמה בקוד פתוח +Comment[hi]=के डेस्कटॉप वातावरण. एक शक्तिशाली, ओपन सोर्स चित्रमय डेस्कटॉप वातावरण +Comment[hu]=A KDE grafikus munkakörnyezet, egy szabad forráskódú grafikus ablakkezelő környezet +Comment[it]=L'ambiente desktop KDE. Un potente ambiente desktop grafico Open Source +Comment[mn]=The K Desktop Environment. Хүчирхэг нээлттэй эх код бүхий график дэлгэцийн орчин +Comment[nb]=K Desktop Environment. Et kraftig grafisk skrivebordsmiljø med åpen kildekode. +Comment[nl]=De K Desktop Environment, een krachtige open source grafische desktop environment +Comment[nn]=K Desktop Environment. Eit kraftig grafisk skrivebordsmiljø med open kjeldekode. +Comment[pl]=Środowisko KDE. Potężne środowisko graficzne Wolnego Oprogramowania. +Comment[pt]=O K Desktop Environment. Um ambiente gráfico open source poderoso +Comment[pt_BR]=Acrônimo para K Desktop Environment (ou Ambiente de Trabalho K). Um poderoso ambiente de trabalho gráfico de código aberto +Comment[ro]=K Desktop Environment. Un mediu grafic cu surse deschise, foarte puternic +Comment[sk]=The K Desktop Environment. Výkonné, voľne šíriteľné grafické pracovné prostredie +Comment[sl]=Namizno okolje K. Zmogljivo grafično namizno okolje odprte kode +Comment[sr]=K Desktop Environment (KDE). Моћно графичко радно окружење отвореног кода +Comment[sv]=K-skrivbordsmiljön. En kraftfull grafisk skrivbordsmiljö med öppen källkod +Comment[ta]= Kமேல்மேசை சூழல். சக்திவாய்ந்த திறந்த ஆணைமூல சித்திர வகை மேல்மேசை சூழல் +Comment[tr]=KDE Masaüstü Yöneticisi. Güçlü bir grafiksel masaüstü ortamı +Comment[uk]=The K Desktop Environment. Потужне графічне середовище з відкритими текстами +Comment[uz]=KDE (K Desktop Environment) - кучли Open Source график иш столи муҳити +Comment[vi]=môi trường desktop K, môi trường desktop đồ hoạ mã nguồn mở rất mạnh +Comment[xx]=xxThe K Desktop Environment. A powerful Open Source graphical desktop environmentxx +Comment[zh_CN]=K 桌面环境。强大的开放源代码图形桌面环境 diff --git a/kdm/kfrontend/sessions/larswm.desktop b/kdm/kfrontend/sessions/larswm.desktop new file mode 100644 index 000000000..072b382c5 --- /dev/null +++ b/kdm/kfrontend/sessions/larswm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=larswm +TryExec=larswm +Name=LarsWM +Name[eo]=Lazero +Name[hi]=लार्स-डबल्यूएम +Name[ko]=라이코스 +Name[sv]=Lars WM +Name[te]=లార్స్ డబ్ల్యు ఎం +Comment=The Lars Window Manager, based on 9WM, supports tiled windows +Comment[af]=Die Lars venster bestuurder, wat op 9WM gebaseer is. Dit ondersteun geteëlde vensters. +Comment[ar]=مدير نوافذ لارس، مبني على 9WM، يدعم النوافذ المعنونة +Comment[be]=Кіраўнік вокнаў Lars Window Manager, заснаваны на 9WM +Comment[bn]=লার্স উইণ্ডো ম্যানেজার, 9WM-এর ওপর ভিত্তি করে তৈরি +Comment[bs]=Lars Window Manager, baziran 9WM, podržava popločane prozore +Comment[ca]=El gestor de finestres Lars, basat en 9WM, permet finestres alicatades +Comment[csb]=Menedżer òknów Larsa, ùsôdzony na spòdlém 9WM, wspiérô kachelkòwanié òknów +Comment[cy]=Y Trefnydd Ffenestri Lars, wedi'i seilio ar 9WM, sy'n cynnal ffenestri wedi'u teilio +Comment[da]=Lars vindueshåndteringen, baseret på 9WM, understøtter fliselagte vinduer +Comment[de]=Lars-Fenstermanager, basiert auf 9WM und unterstützt gekachelte Fenstern +Comment[el]=Ο διαχειριστής παραθύρων Lars, βασισμένος στον 9WM, υποστηρίζει παράθυρα σε παράθεση +Comment[eo]=La Laza Fenestroadministrilo, devenigita de 9FA +Comment[es]=El Lars Window Manager, basado en 9WM, soporta mosaico de ventanas +Comment[et]=Larsi aknahaldur, mille aluseks on 9WM, toetab paanitud aknaid +Comment[eu]=Lars leiho kudeatzailea, 9WM-n oinarritua, leiho-mosaikorako euskarria duena +Comment[fa]=مدیر پنجرۀ Lars، بر اساس 9WM، پنجرههای کاشیشده را پشتیبانی میکند. +Comment[fi]=Lars-ikkunaohjelma. Pohjautuu 9WM:ään ja tukee järjestettyjä ikkunoita +Comment[fr]=The Lars Window Manager, fondé sur 9WM, avec une gestion des fenêtres en mosaïque +Comment[fy]=De Lars Window Manager, basearre op 9WM. Biedt stipe foar tegele finsters +Comment[gl]=O Xestor de Fiestras Lars, baseado en 9WM, atura fiestras en mosaico +Comment[he]=The Lars Window Manager, מבוסס על 9WM, תומך בחלונות פרושים +Comment[hi]=9डबल्यूएम आधारित लार्स विंडो प्रबंधक, चटाई विडो समर्थित करता है +Comment[hr]=Lars upravitelj prozora, zasnovan na 9WMu, podržava popločene prozore +Comment[hu]=Lars ablakkezelője, a 9WM alapján, mozaikszerű ablakelrendezési lehetőséggel +Comment[is]=Lars gluggastjórinn, byggður á 9WM og styður flísaða glugga +Comment[it]=Il Window Manager di Lars, basato su 9WM, supporta le finestre affiancate +Comment[ja]=Lars ウィンドウマネージャ, 9WMベース, タイル表示をサポートするウィンドウマネージャ +Comment[kk]=9WM-негіздеген терезе менеджері +Comment[km]=Lars Window Manager ផ្អែកលើ 9WM គាំទ្របង្អួចជាក្បឿង +Comment[lt]=Lars langų tvarkyklė, paremta 9WM, turi galimybę iškloti langus +Comment[mk]=Lars Window Manager, менаџер базиран на 9WM, поддржува поплочени прозорци +Comment[mn]=The Lars Window Manager, 9WM дээр суурилсан, олон цонхтой +Comment[ms]=Pengurus Tetingkap Lars, berdasarkan 9WM, menyokong tetingkap berjubin +Comment[mt]=Lars Window Manager - ibbażat fuq 9WM u jiflaħ windows imqassma f'madum +Comment[nb]=Lars vindusbehandler, basert på 9WM, støtter flislagte vinduer +Comment[nds]=De Lars-Finsterpleger, opbuut op 9WM, ünnerstütt kachelte Finstern +Comment[ne]=9WM मा आधारित लार्स सञ्झ्याल प्रबन्धक, टायल गरिएका सञ्झ्यालहरू समर्थन गर्छ +Comment[nl]=De Lars Window Manager, gebaseerd op 9WM. Biedt ondersteuning voor getegelde vensters +Comment[nn]=Vindaugssjefen Lars, basert på 9WM, støttar flislagde vindauge +Comment[pa]=ਲਾਰਸ ਫਾਇਲ਼ ਮੈਨੇਜਰ 9WM ਤੇ ਆਧਾਰਿਤ, ਝਰੋਖਿਆਂ ਦੇ ਸਮੇਟਣ ਲਈ ਸਹਾਈ +Comment[pl]=Menedżer okien Larsa, stworzony na podstawie 9WM, obsługuje kafelkowanie okien +Comment[pt]=O Lars Window Manager, baseado no 9WM, e que suporta janelas lado-a-lado +Comment[pt_BR]=O gerenciador de janelas Lars, baseado no 9WM, com suporte a janelas ladrilhadas +Comment[ro]=Managerul de ferestre al lui Lars, bazat pe 9WM. Suportă ferestre aranjate în mozaic +Comment[ru]=Оконный менеджер на основе 9wm +Comment[rw]=Mugenga Dirishya Lars, ishingiye kuri 9WM, yemera amadirishya agerekeranye +Comment[se]=Lásegieđahalli Lars, ráhkaduvvon 9WM vuođul, doarju bálddalas lásiid. +Comment[sk]=The Lars Window Manager založený na 9WM s podporou okien usporiadaných do dlaždíc +Comment[sl]=Larsov okenski upravitelj, na osnovi 9WM, podpira porazdeljena okna +Comment[sr]=„Lars Window Manager“, заснован на 9WM-у, подржава наслагане прозоре +Comment[sr@Latn]=„Lars Window Manager“, zasnovan na 9WM-u, podržava naslagane prozore +Comment[sv]=Lars fönsterhanterare, baserad på 9WM, med stöd för fönster sida vid sida +Comment[ta]=9WM அடிபடையிலான லார்ஸ் சாளர மேலாளர் சீரமைக்கப்பட்ட சாளரங்களை ஆதரிக்கிறது +Comment[th]=ระบบจัดการหน้าต่าง Lars สร้างจาก 9WM สนับสนุนการปูเรียงหน้าต่าง +Comment[tr]=Lars Pencere Yöneticisi +Comment[tt]=Lars Window Manager, 9WM asılında, bülengän täräzä tota +Comment[uk]=The Lars Window Manager, засновано на 9WM, підтримує розташування вікон плиткою +Comment[vi]= Trình Quản lý Cửa sổ Lars, dựa vào 9WM, hỗ trợ cửa sổ xếp ngói +Comment[wa]=Li manaedjeu d' purnea d' Lasrs (Lars Window Manager), båzé so 9WM, sopoite les purneas å pus grand +Comment[zh_CN]=Lars 窗口管理器,基于 9WM,支持平铺窗口 +Comment[zh_TW]=The Lars 視窗管理程式,基於 9WM,支援棋盤化視窗 diff --git a/kdm/kfrontend/sessions/lwm.desktop b/kdm/kfrontend/sessions/lwm.desktop new file mode 100644 index 000000000..2f3e0ff00 --- /dev/null +++ b/kdm/kfrontend/sessions/lwm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=lwm +TryExec=lwm +Name=LWM +Name[eo]=MFA +Name[hi]=एलडबल्यूएम +Name[te]=ఎల్ డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง LWM +Comment=The Lightweight Window Manager. A non-configurable, bare window manager +Comment[af]=Die lig gewig venster bestuurder. +Comment[ar]=مدير النوافذ خفيف العبء، مدير نوافذ مجرّد غير قابل للإعداد +Comment[be]=The Lightweight Window Manager. Пусты кіраўнік вокнаў без падтрымкі настаўленняў +Comment[bn]=দি লাইটওয়েট উইণ্ডো ম্যানেজার +Comment[bs]=Lightweight Window Manager. Ne-podesivi, potpuno osnovni window manager +Comment[ca]=El gestor de finestres Lightweight. Un gestor de finestres no configurable i pelat +Comment[cs]=The Lightweight Window Manager. Prostý a nekonfigurovatelný správce oken +Comment[csb]=Lightweight Window Manager (Letczi menedżer òknół). Bro prosti menedżer òknów bez mòżnoté kònfigùracëji +Comment[cy]=Y Trefnydd Ffenestri Ysgafn. Trefnydd ffenestri noeth, na ellir ffurfweddu +Comment[da]=Lightweight Window Manager, en ikke-indstillelig, minimal vindueshåndtering +Comment[de]=Lightweight Window Manager -- reiner Fenstermanager ohne Einstellmöglichkeiten +Comment[el]=Ο ελαφρύς διαχειριστής παραθύρων. Ένας μη παραμετροποιήσιμος, πολύ απλός διαχειριστής παραθύρων +Comment[eo]=Malpeza Fenestroadministrilo +Comment[es]=El Lightweight Window Manager, un sencillísimo y no configurable gestor de ventanas +Comment[et]=Imeväike aknahaldur on seadistamatu, sõna otseses mõttes ainult akende haldur +Comment[eu]=Libhtweight leiho kudeatzailea. Konfiguraziorik onartzen ez duen leiho-kudeatzaile zeharo sinplea +Comment[fa]=مدیر پنجرۀ سبک، مدیر پنجرۀ غیرقابل پیکربندی و ساده +Comment[fi]=Kevyt ikkunaohjelma. Paljas, ei muokattavissa oleva ikkunaohjelma +Comment[fr]=The Lightweight Window Manager. Un gestionnaire de fenêtres non configurable et nu +Comment[fy]=De Lightweight Window Manager, in net-ynstelbere, keale finstersmanager +Comment[gl]=O Xestor de Fiestras Lixeiro. +Comment[he]=The Lightweight Window Manager. מנהל חלונות מצומצם בלי אפשרויות להגדרה. +Comment[hi]=हल्का विंडो प्रबंधक. खाली विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता +Comment[hr]=LWM - Lightweight Window Manager (Lagani upravitelj prozora) - Temeljni upravitelj prozora bez mogućnosti konfiguriranja +Comment[hu]=Lightweight Window Manager, egy könnyen konfigurálható, alapszintű ablakkezelő +Comment[is]=Hinn létti gluggastjóri. Ekki stillanlegur og hrár +Comment[it]=Il Window Manager Leggero. Un window manager essenziale e non configurabile +Comment[ja]=設定項目のない、単純なウィンドウマネージャ +Comment[ka]=მსუბუქი არაკონფიგურირებადი ფანჯრების მენეჯერი +Comment[kk]=Lightweight Window Manager. Баптауы жоқ, жай терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសមត្ថភាពខ្សោយ ។ កម្មវិធីគ្រប់គ្រងបង្អួចដែលគ្មានអ្វីបិទបាំង ហើយមិនអាចកំណត់រចនាសម្ព័ន្ធបាន +Comment[lt]=„Lengva“ langų tvarkyklė. Nekonfigūruojama, „plika“ langų tvarkyklė +Comment[lv]=Vieglais logu menedžeris. Nekonfigurējams, vienkāršs logu menedžeris +Comment[mk]=Lightweight Window Manager. Неконфигурабилен, скоро празен менаџер на прозорци +Comment[mn]=The Lightweight Window Manager. Тохируулгах боломжгүй,цонхны удирдлага +Comment[ms]=Pengurus tetingkap Ringan. Tidak boleh konfigur, pengurus tetingkap terdedah +Comment[mt]=Lightweight Window Manager. Window Manager sempliċi u mhux konfigurabbli +Comment[nb]=Lettvekts vindusbehandler- Lightweight Window Manager. En enkel vindusbehandler uten innstillinger. +Comment[nds]=De "Lightweight"-Finsterpleger. En reen Finsterpleger ahn Instellen +Comment[ne]=हल्का वजन सञ्झ्याल प्रबन्धक । कन्फिगर गर्न नसकिने, बेयर सञ्झ्याल प्रबन्धक +Comment[nl]=De Lightweight Window Manager, een niet-instelbare, kale windowmanager +Comment[nn]=Lightweight Window Manager. Ein enkel vindaugssjef utan innstillingar. +Comment[pa]=ਇੱਕ ਹਲਕਾ, ਨਾ-ਸੰਰਚਿਤਯੋਗ ਪੱਟੀ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Lightweight Window Manager (Lekki menedżer okien). Surowy menedżer okien bez możliwości konfiguracji +Comment[pt]=O Lightweight Window Manager. Um gestor de janelas não-configurável e básico +Comment[pt_BR]=Um gerenciador de janelas leve, sendo básico e não muito configurável +Comment[ro]=Lightweight Window Manager. Un manager de ferestre neconfigurabil și minimal +Comment[ru]=Облегчённый, не настраиваемый простой оконный менеджер +Comment[rw]=Mugenga Dirishya Yoroshye. Mugenga dirishya idafite ikintu, itabonezwa. +Comment[se]=Lightweight Window Manager. Oktageardánis lásegieđahalli mii ii lea heivehahtti. +Comment[sk]=The Lightweight Window Manager. Nenastaviteľný, jednoduchý správca okien +Comment[sl]=Lahek okenski upravitelj. Ni nastavljiv, osnovni okenski upravitelj +Comment[sr]=„Lightweight Window Manager“. Неподесив, голи менаџер прозора +Comment[sr@Latn]=„Lightweight Window Manager“. Nepodesiv, goli menadžer prozora +Comment[sv]=Den lättviktiga fönsterhanteraren. En enkel fönsterhanterare utan anpassningsmöjligheter +Comment[ta]=குறைந்த எடையுள்ள சாளர மேலாளர். வடிவமைக்க முடியாத +Comment[th]=Lightweight Window Manager ระบบจัดการหน้าต่างเปล่าๆ ที่ไม่สามารถปรับแต่งได้เลย +Comment[tr]=Lightweight Pencere Yöneticisi. Yapılandırılamayan, kaba pencere yönetici +Comment[tt]=Lightweight Window Manager. Caylanmí torğan, ciñel täräzä-idäräçe +Comment[uk]=Невеличкий менеджер вікон без можливості налаштування +Comment[vi]=Trình Quản lý Cửa sổ Nhẹ ký. Rất khó cấu hình +Comment[wa]=Li Ledjir Manaedjeu di Purneas (Lightweight Window Manager). On manaedjeu di purneas tot simpe, nén apontiåve +Comment[zh_CN]=轻量级窗口管理器。不可配置的裸窗口管理器 +Comment[zh_TW]=一個輕量化的視窗管理程式。不可組態、只有基礎視窗管理的視窗管理程式 +# this can't be used as a session in itself +Hidden=true diff --git a/kdm/kfrontend/sessions/matchbox.desktop b/kdm/kfrontend/sessions/matchbox.desktop new file mode 100644 index 000000000..8c6e2fd52 --- /dev/null +++ b/kdm/kfrontend/sessions/matchbox.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=matchbox +TryExec=matchbox +Name=Matchbox +Name[bn]=ম্যাচবক্স +Name[eo]=Alumetujo +Name[hi]=मैचबॉक्स +Name[ne]=मिल्ने बाकस +Name[pa]=ਮੈਚ-ਬਾਕਸ +Name[rw]=Agasandukugahura +Name[ta]=பொருத்தப்பெட்டி +Name[te]=అగ్గి పెట్టె +Name[tg]=Қуттии гӯгирд +Name[wa]=Boesse di brocales (Matchbox) +Comment=A window manager for handheld devices +Comment[af]='n Venster bestuurder vir draagbare toestelle +Comment[ar]=مدير نوافذ للأجهزة اليدوية +Comment[be]=Кіраўнік вокнаў для кішанёвых кампутараў +Comment[bn]=হ্যাণ্ডহেল্ড যন্ত্রাদির উপযোগী একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager za ručne uređaje +Comment[ca]=Un gestor de finestres per a dispositius de ma +Comment[cs]=Správce oken pro PDA +Comment[csb]=Menedżer òknów dlô palmtopów +Comment[cy]=Trefnydd ffenestri ar gyfer llawiaduron +Comment[da]=En vindueshåndtering for håndholdte enheder +Comment[de]=Fenstermanager für portable Geräte +Comment[el]=Ένας διακομιστής παραθύρων για συσκευές παλάμης +Comment[eo]=Fenestroadministrilo por manaj aparatoj +Comment[es]=Un gestor de ventanas para dispositivos de mano +Comment[et]=Aknahaldur pihuarvutitele +Comment[eu]=Eskuan erabiltzeko gailuentzako leiho kudeatzailea +Comment[fa]=یک مدیر پنجره برای دستگاههای دستی +Comment[fi]=ikkunaohjelma PDA-laitteisiin +Comment[fr]=Un gestionnaire de fenêtres pour les périphériques contrôlés à la main +Comment[fy]=In finstersmanager foar hânkompjûters +Comment[gl]=Un xestor de fiestras para dispositivos manuais +Comment[he]=מנהל חלונות למכשירים נישאים +Comment[hi]=हाथ में रखने वाले औज़ारों के लिए विंडो प्रबंधक +Comment[hr]=Upravitelj prozora za ručna računala +Comment[hu]=Ez az ablakkezelő elsősorban kéziszámítógépekhez ajánlott +Comment[is]=Gluggastjóri fyrir lófatölvur +Comment[it]=Un window manager per palmari +Comment[ja]=ハンドヘルドデバイス向けのウィンドウマネージャ +Comment[ka]=ფანჯრების მენეჯერი მობილური მოწყობილობებისთვის +Comment[kk]=Қол құрылғыларға арналған терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួច សម្រាប់ឧបករណ៍យួរដៃ +Comment[ko]=핸드헬드 장치를 위한 창 관리자 +Comment[lt]=Langų tvarkyklė įvairiems įrenginiams +Comment[lv]=Logu menedžeris priekš portatīvajām iekārtām +Comment[mk]=Менаџер на прозорци за преносни уреди +Comment[mn]=Гар төхөөрөмжид зориулсан цонхны удирдлага +Comment[ms]=Pengurus tetingkap untuk peranti telapak +Comment[mt]=Window manager għal apparat "handheld" +Comment[nb]=En vindusbehandler for håndholdte enheter +Comment[nds]=Finsterpleger för Handreekner +Comment[ne]=ह्यान्डहेल्ड यन्त्रहरूका लागि सञ्झ्याल प्रबन्धक +Comment[nl]=Een windowmanager voor handcomputers +Comment[nn]=Ein vindaugssjef for handhaldne einingar +Comment[pa]=ਹੱਥਲੇ ਜੰਤਰਾਂ ਲਈ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien dla palmtopów +Comment[pt]=Um gestor de janelas para dispositivos móveis +Comment[pt_BR]=Um gerenciador de janelas para dispositivos handheld +Comment[ro]=Un manager de ferestre pentru PDA-uri +Comment[ru]=Оконный менеджер для мобильных устройств +Comment[rw]=Mugenga dirishya y'amapareye atwarwa-ntoki +Comment[se]=Lásegieđahalli giehtaovttadagaid várás +Comment[sk]=Správca okien pre prenosné zariadenia +Comment[sl]=Okenski upravitelj za dlančne naprave +Comment[sr]=Менаџер прозора за мале преносне уређаје +Comment[sr@Latn]=Menadžer prozora za male prenosne uređaje +Comment[sv]=Fönsterhanterare för handburna enheter +Comment[ta]=கையில் உள்ள சாதனங்களுக்கான சாளர மேலாளர் +Comment[tg]=Як мудири тиреза барои дастгоҳҳои дастӣ +Comment[th]=ระบบจัดการหน้าต่างของอุปกรณ์มือถือ +Comment[tr]=El bilgisayarları için bir pencere yöneticisi +Comment[tt]=Qul cıhazı öçen täräzä-idäräçe +Comment[uk]=Менеджер вікон для портативних пристроїв +Comment[vi]=Trình quản lý cửa sổ dành cho thiết bị cầm tay +Comment[wa]=On manaedjeu di purneas po les éndjins ebarkés +Comment[zh_CN]=手持设备的窗口管理器 +Comment[zh_TW]=一個掌上型設備所使用的視窗管理程式 diff --git a/kdm/kfrontend/sessions/metacity.desktop b/kdm/kfrontend/sessions/metacity.desktop new file mode 100644 index 000000000..d2a5a5537 --- /dev/null +++ b/kdm/kfrontend/sessions/metacity.desktop @@ -0,0 +1,83 @@ +[Desktop Entry] +Type=XSession +Exec=metacity +TryExec=metacity +Name=Metacity +Name[bn]=মেটাসিটি +Name[eo]=Metaurbo +Name[hi]=मेटासिटी +Name[mn]=Метасити +Name[ne]=मेटासिटी +Name[rw]=Metacity(Mugenga-dirishya) +Name[ta]=மெடாசிட்டி +Name[te]=మెటాసిటి +Comment=A lightweight GTK2 based window manager +Comment[af]=Die lig gewig GTK2 gebaseerde venster bestuurder +Comment[ar]=مدير نوافذ خفيف العبء مبني على GTK2 +Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на GTK2 +Comment[bn]=একটি হাল্কা GTK2 ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager baziran na GTK2 +Comment[ca]=Un gestor de finestres lleuger basat en GTK2 +Comment[cs]=Malý správce oken založený na GTK2 +Comment[csb]=Menedżer òknół ò môłëch żądniach, òpiarti na GTK2 +Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar GTK2 +Comment[da]=En letvægts GTK2 baseret vindueshåndtering +Comment[de]=Schlanker Fenstermanager, der auf GTK2 basiert +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στο GTK2 +Comment[eo]=Malpeza fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero basado en GTK2 +Comment[et]=Imeväike aknahaldur, mille aluseks on GTK2 +Comment[eu]=GTK2n oinarritutako leiho kudeatzaile arin bat +Comment[fa]=GTK2 سبک بر اساس مدیر پنجره +Comment[fi]=Kevyt, GTK2-pohjainen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur GTK2 et léger +Comment[fy]=In lichtgewicht op GTK2 basearre finstersmanager +Comment[gl]=Un xestor de fiestras lixeiro baseado en GTK2 +Comment[he]=מנהל חלונות קל מבוסס GTK2 +Comment[hi]=जीटीके2 आधारित हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora zasnovan na GTK2 +Comment[hu]=Egy egyszerű, GTK2-alapú ablakkezelő +Comment[is]=Léttur gluggastjóri byggður á GTK2 +Comment[it]=Un window manager leggero basato su GTK2 +Comment[ja]=GTK2 ベースの軽量なウィンドウマネージャ +Comment[ka]=GTK2-ს ბაზაზე მსუბუქი ფანჯრის მენეჯერი +Comment[kk]=GTK2-негіздеген, жеңіл терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសមត្ថភាពខ្សោយ ដែលផ្អែកលើ GTK2 +Comment[ko]=가벼운 GTK2 기반 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta GTK2 +Comment[lv]=Viegls GTK 2 bāzēts logu menedžeris +Comment[mk]=Лесен менаџер на прозорци базиран на GTK2 +Comment[mn]=Хөнгөн GTK2 суурьт цонхны удирдагч +Comment[ms]=Pengurus tetingkap berasaskan GTK2 ringan +Comment[mt]=Window manager ħafif ibbażat fuq GTK2 +Comment[nb]=En lettvekts vindusbehandler basert på GTK2 +Comment[nds]=En ranke Finsterpleger, opbuut op GTK2 +Comment[ne]=सञ्झ्याल प्रबन्धकमा आधारित हल्का वजन GTK2 +Comment[nl]=Een lichtgewicht op GTK2 gebaseerde windowmanager +Comment[nn]=En lett vindaugssjef basert på GTK2 +Comment[pa]=ਇੱਕ ਹਲਕਾ GTK2 ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, oparty na GTK2 +Comment[pt]=Um gestor de janelas leve, baseado em GTK2 +Comment[pt_BR]=Um gerenciador de Janelas leve baseado em GTK2 +Comment[ro]=Un manager de ferestre mic bazat pe GTK2 +Comment[ru]=Лёгкий оконный менеджер на основе GTK2 +Comment[rw]=Mugenga dirishya ishingiye kuri GTK2 yoroshye +Comment[se]=Geahpes GTK2-vuođđoduvvon lásegieđahalli +Comment[sk]=Nenáročný správca okien založený na GTK2 +Comment[sl]=Lahek okenski upravitelj na osnovi GTK2 +Comment[sr]=Лагани менаџер прозора заснован на GTK2 +Comment[sr@Latn]=Lagani menadžer prozora zasnovan na GTK2 +Comment[sv]=Lättviktig GTK2-baserad fönsterhanterare +Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு குறைந்த எடை GTK2 +Comment[te]=తెలికైన జిటికె2 ఆధారిత విండొ అభికర్త +Comment[tg]=Сабуки GTK2 ба асоси мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ GTK2 +Comment[tr]=Gtk2 tabanlı hafif bir pencere yöneticisi +Comment[tt]=GTK2 asılında ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон для GTK2 +Comment[uz]=GTK2 asosida yaratilgan oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=GTK2 асосида яратилган оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên GTK2 +Comment[wa]=On ledjir manaedjeu di purneas båzé so GTK2 +Comment[zh_CN]=轻量级 GTK2 窗口管理器 +Comment[zh_TW]=一個基於 GTK2 的輕量化視窗管理程式 diff --git a/kdm/kfrontend/sessions/mwm.desktop b/kdm/kfrontend/sessions/mwm.desktop new file mode 100644 index 000000000..b1d6e2acd --- /dev/null +++ b/kdm/kfrontend/sessions/mwm.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=XSession +Exec=mwm +TryExec=mwm +Name=MWM +Name[eo]=MFA +Name[hi]=एमडबल्यूएम +Name[te]=ఎం డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง MWM +Comment=The Motif Window Manager +Comment[af]=Die Motif venster bestuurder +Comment[ar]=مسيير النوافذ Motif +Comment[be]=Кіраўнік вокнаў Motif +Comment[bn]=দি মোটিফ উইণ্ডো ম্যানেজার +Comment[bs]=Motif Window Manager +Comment[ca]=El gestor de finestres Motif +Comment[cs]=Motif Window Manager +Comment[csb]=Menedżer òknów Motif +Comment[cy]=Y Trefnydd Ffenestri Motif +Comment[da]=Motif vindueshåndtering +Comment[de]=Motif-Fenstermanager +Comment[el]=Ο διαχειριστής παραθύρων Motif +Comment[eo]=Motifa fenestroadministrilo +Comment[es]=El gestor de ventanas de Motif +Comment[et]=Motifi aknahaldur +Comment[eu]=Motif leiho kudeatzailea +Comment[fa]=مدیر پنجره موتیف +Comment[fi]=Motif-ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres Motif +Comment[fy]=De Motif Window Manager +Comment[ga]=Bainisteoir fuinneoga Motif +Comment[gl]=O Xestor de Fiestras Motif +Comment[he]=מנהל החלונות Motif +Comment[hi]=मोटिफ विंडो प्रबंधक +Comment[hr]=Motif upravitelj prozora +Comment[hu]=Motif ablakkezelő +Comment[is]=Motif gluggastjórinn +Comment[it]=Il window manager di Motif +Comment[ja]=Motif 風のウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Motif +Comment[kk]=Motif терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួច Motif +Comment[ko]=Motif 창 관리자 +Comment[lt]=Motif langų tvarkyklė +Comment[lv]=Motif logu menedžeris +Comment[mk]=Менаџерот на прозорци Motif +Comment[mn]=Motif Цонхны удирдагч +Comment[ms]=Pengurus Tertingkap Motif +Comment[mt]=Window manager tal-Motif +Comment[nb]=Motif vindusbehandler +Comment[nds]=De Motif-Finsterpleger +Comment[ne]=मोटिफ सञ्झ्याल प्रबन्धक +Comment[nl]=De Motif Window Manager +Comment[nn]=Motif-vindaugssjefen +Comment[pa]=Motif ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien Motif +Comment[pt]=O gestor de janelas do Motif +Comment[pt_BR]=O gerenciador de janelas Motif +Comment[ro]=Managerul de ferestre Motif +Comment[ru]=Оконный менеджер Motif +Comment[rw]=Mugenga Dirishya Umutako +Comment[se]=Motif lásegieđahalli +Comment[sk]=Správca okien Motif +Comment[sl]=Okenski upravitelj Motif +Comment[sv]=Motifs fönsterhanterare +Comment[ta]=மோடிஃப் சாளர மேலாளர் +Comment[te]=మొటిఫ్ విండొ అభికర్త +Comment[tg]=Мавзӯъи мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างของโมทิฟ +Comment[tr]=Motif Pencere Yöneticisi +Comment[tt]=Motif Täräzä İdäräçe +Comment[uk]=Менеджер вікон Motif +Comment[uz]=Motif oyna boshqaruvchi +Comment[uz@cyrillic]=Motif ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ Motif +Comment[wa]=Li manaedjeu di purneas di Motif +Comment[zh_CN]=Motif 窗口管理器 +Comment[zh_TW]=Motif 視窗管理程式 diff --git a/kdm/kfrontend/sessions/olvwm.desktop b/kdm/kfrontend/sessions/olvwm.desktop new file mode 100644 index 000000000..e181331bc --- /dev/null +++ b/kdm/kfrontend/sessions/olvwm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec= +TryExec= +Name=OLVWM +Name[br]=OVLWM +Name[eo]=OLVFA +Name[hi]=ओएलवीडबल्यूएम +Name[te]=ఒ ఎల్ వి డబ్యు ఎం +Comment=The OpenLook Virtual Window Manager. OLWM enhanced for handling of virtual desktops +Comment[af]=Die OpenLook virtuele venster bestuurder. OLWM wat uitgebrei is vir virtuele werkskerms +Comment[ar]=مدير النوافذ الوهمي OpenLook، محسّن للتعامل مع أسطح المكتب الوهمية +Comment[be]=The OpenLook Virtual Window Manager. OLWM дапрацаваны для падтрымкі віртуальных працоўных сталоў +Comment[bn]=দি ওপেনলুক ভার্চুয়াল উইণ্ডো ম্যানেজার। OLWM-এর বর্ধিত সংস্করণ যাতে ভার্চুয়াল ডেস্কটপ সমর্থিত +Comment[bs]=OpenLook Virtual Window Manager. OLWM proširen podrškom za virtualne desktope +Comment[ca]=El OpenLook Virtual Window Manager. OLWM millorat per a escriptoris virtuals de ma +Comment[csb]=OpenLook Virtual Window Manager. OLWM zbògacony ò wspiarce wirtualnëch pùltów +Comment[cy]=Y Trefnydd Ffenestri Rhith GolwgAgored (OpenLook). OLWM wedi'i wella i gynnal penbyrddau rhith +Comment[da]=OpenLook Virtual Window Manager. OLWM udvidet med håndtering af virtuelle desktoppe +Comment[de]=OpenLook virtueller Fenstermanager, OLWM mit verbesserter Verwaltung von virtuellen Arbeitsflächen +Comment[el]=Ο OpenLook εικονικός διαχειριστής παραθύρων. Ο OLWM εμπλουτισμένος με διαχείριση εικονικών επιφανειών εργασίας +Comment[eo]=Fenestroadministrilo por virtualaj labortabloj +Comment[es]=El OpenLook Virtual Window Manager, un versión mejorada de OLWM con soporte para escritorios virtuales +Comment[et]=OpenLook virtuaalne aknahaldur on OLWM, mida on täiendatud virtuaalsete töölaudade võimalusega +Comment[eu]=OpenLook leiho kudeatzaile birtuala. mahaigain birtualak kudeatzeko OLWM hobetua +Comment[fa]=مدیر پنجرۀ مجازی OpenLook. OLWM گسترشیافته برای گرداندن رومیزیهای مجازی +Comment[fi]=OpenLook virtuaalinen ikkunanhallinta. OLWM:n paranneltu versio,joka käsittelee virtuaalityöpöytiä paremmin +Comment[fr]=The OpenLook Virtual Window Manager. OLWM avec en plus la gestion des bureaux virtuels +Comment[fy]=De OpenLook Virtual Window Manager. OLWM útbreide mei firtuele buroblêden +Comment[gl]=O OpenLook Virtual Window Manager. OLWM mellorado para manexar escritórios virtuais +Comment[he]=The OpenLook Virtual Window Manager. OLWM משופר בשביל טיפול בשולחנות עבודה וירטואליים +Comment[hi]=ओपनलुक आभासी विंडो प्रबंधक. ओएलडबल्यूएम को आभासी डेस्कटॉप हैंडल करने के लिए बेहतर बनाया गया +Comment[hr]=OpenLook virtualni upravitelj prozora - OLWM unaprijeđen mogućnošću rukovanja s virtualnim radnim površinama +Comment[hu]=OpenLook Virtual Window Manager (OLWM), virtuális munkaasztalok kezelésére is képes +Comment[is]=OpenLook sýndargluggastjórinn. Endurbættur með OLWM til að styðja sýndarskjáborð +Comment[it]=L'OpenLook Virtual Window Manager. OLWM migliorato per gestire i desktop virtuali +Comment[ja]=OpenLook 仮想ウィンドウマネージャ, OLWM 強化仮想デスクトップ +Comment[ka]=გაუმჯობესებული ფანჯრის მენეჯერი OpenLook, რამდენიმე სამუშაო დაფის მხარდაჭერით +Comment[kk]=OpenLook Virtual Window Manager - виртуалды үстелдерді қолдайтын терезе менеджері +Comment[km]=OpenLook Virtual Window Manager ។ OLWM ដែលបានធ្វើឲ្យប្រសើរ សម្រាប់ការប្រើផ្ទៃតុនិមិត្ត ។ +Comment[lt]=OpenLook virtuali langų tvarkyklė. OLWM išplėsta su virtualių darbastalių palaikymu +Comment[mk]=OpenLook Virtual Window Manager. OLWM менаџерот со подобрено ракување на виртуелни површини +Comment[ms]=Pengurus Tetingkap Maya OpenLook. OLWM dipertingkat untuk mengendalikan desktop maya +Comment[mt]=OpenLook Virtual Window Manager - OLWM flimkien ma' desktops virtwali. +Comment[nb]=OpenLook Virtual Window Manager. OLWM utvidet med virtuelle skrivebord. +Comment[nds]=De "OpenLook Virtual Window Manager" is OLWM verwiedert üm virtuelle Schriefdischen +Comment[ne]=अवास्तविक डेस्कटपहरूको ह्यान्डलका लागि बृद्धि गरिएको OLWM खुला देखिने अवास्तविक सञ्झ्याल प्रबन्धक । +Comment[nl]=De OpenLook Virtual Window Manager. OLWM uitgebreid met virtuele bureaubladen +Comment[nn]=OpenLook Virtual Window Manager. OLWM utvida med virtuelle skrivebord. +Comment[pa]=OpenLook Virtual Window Manager. OLWM ਫਰਜ਼ੀ ਵੇਹੜਿਆਂ ਲਈ ਖਾਸ ਤੌਰ ਤੇ ਤਿਆਰ +Comment[pl]=OpenLook Virtual Window Manager. OLWM wzbogacony o obsługę wirtualnych pulpitów +Comment[pt]=O OpenLook Virtual Window Manager. Um OLWM melhorado para lidar com ecrãs virtuais +Comment[pt_BR]=Acrônimo para OpenLook Virtual Window Manager, o OLWM melhorado para a manipulação de áreas de trabalho virtuais +Comment[ro]=OpenLook Virtual Window Manager. Un OLWM îmbunătățit cu ecrane virtuale +Comment[ru]=Улучшенный оконный менеджер OpenLook, поддерживающий несколько рабочих столов +Comment[rw]=Mugenga Dirishya Itagaragara GufunguraKureba. OLWM ivuguruwe mu gufasha ibiro bitagaragara +Comment[se]=The OpenLook Virtual Window Manager. OLWM buoriduvvon nu ahte das leat virtuella čállinbeavddit +Comment[sk]=Virtuálny správca okien OpenLook. OLWM rozšírený o podporu virtuálnych plôch +Comment[sl]=Open Look Virtual Window Manager je izboljšan OLWM s podporo navideznim namizjem +Comment[sr]=„OpenLook Virtual Window Manager“. OLWM побољшан за управљање виртуелним радним површинама +Comment[sr@Latn]=„OpenLook Virtual Window Manager“. OLWM poboljšan za upravljanje virtuelnim radnim površinama +Comment[sv]=Open Look virtuell fönsterhanterare. OLWM utökad för att hantera virtuella skrivbord +Comment[ta]=ஓபன்லுக் மெய்நிகர் சாளர மேலாளர். மெய்நிகர் மேல்மேசைகளை கையாளுவதற்கு OLWM மேம்படுத்தப்பட்டது. +Comment[th]=ระบบจัดการหน้าต่างเสมือน OpenLook คือ OLWM ที่ถูกเพิ่มเติมความสามารถในการรับมือกับพื้นที่ทำงานเสมือน +Comment[tr]=OpenLook Sanal Pencere Yöneticisi. +Comment[tt]=OpenLook Virtual Window Manager. Xıyalí öställär öçen yaqşırtılğan OpenLook +Comment[uk]=OpenLook Virtual Window Manager. OLWM з підтримкою віртуальних стільниць +Comment[vi]=Trình Quản lý Cửa sổ Ảo "Cái nhìn Mở". Nó được cải tiến cho việc xử lý màn hình nền ảo +Comment[wa]=Li Manaedjeu di Forveyou Purnea OpenLook (OpenLook Virtual Window Manager). OLWM permete d' apougnî des forveyowès sicribannes +Comment[zh_CN]=OpenLook 虚拟窗口管理器。OLWM 特别增强了虚拟桌面的处理 +Comment[zh_TW]=Openlook 視窗管理程式。基於 OLWM 並強化管理虛擬桌面 diff --git a/kdm/kfrontend/sessions/olwm.desktop b/kdm/kfrontend/sessions/olwm.desktop new file mode 100644 index 000000000..e3368af74 --- /dev/null +++ b/kdm/kfrontend/sessions/olwm.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=olwm +TryExec=olwm +Name=OLWM +Name[eo]=OLFA +Name[hi]=ओएलडबल्यूएम +Name[te]=ఒ ఎల్ డబ్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง OLWM +Comment=The traditional Open Look Window Manager +Comment[af]=Die tradisionele Open Look venster bestuurder +Comment[ar]=مسيير النوافذ Open Look التقليدي +Comment[be]=Традыцыйны кіраўнік вокнаў Open Look +Comment[bn]=দি ওপেনলুক উইণ্ডো ম্যানেজার +Comment[bs]=Tradicionalni Open Look Window Manager +Comment[ca]=El tradicional gestor de finestres Open Look +Comment[cs]=Tradiční Open Look Window Manager +Comment[csb]=Tradicëjny menedżer òknów Open Look +Comment[cy]=Y Trefnydd Ffenestri GolwgAgored (OpenLook) traddodiadol +Comment[da]=Den traditionelle Open Look vindueshåndtering +Comment[de]=Der traditionelle Open-Look-Fenstermanager +Comment[el]=Ο παραδοσιακός διαχειριστής παραθύρων Open Look +Comment[eo]=La klasika OL-fenestroadministrilo +Comment[es]=El tradicional Open Look Window Manager +Comment[et]=Tavapärane OpenLooki aknahaldur +Comment[eu]=Betiko Open Look leiho kudeatzailea +Comment[fa]=مدیر پنجره Open Look سنتی +Comment[fi]=Perinteinen Open Look -ikkunaohjelma +Comment[fr]=Le gestionnaire de fenêtres traditionnel Open Look +Comment[fy]=De tradisjoneel iepen like finstersManager +Comment[gl]=O tradicional Xestor de Fiestras de Open Look +Comment[he]=Open Look Window Manager המסורתי +Comment[hi]=परम्परागत ओपन लुक विंडो प्रबंधक +Comment[hr]=Tradicionalni 'Open Look' upravitelj prozora +Comment[hu]=A hagyományos Open Look ablakkezelő +Comment[is]=Hinn hefðbundni Open Look gluggastjóri +Comment[it]=L'Open Look Window Manager tradizionale +Comment[ja]=伝統的な OpenLook ウィンドウマネージャ +Comment[ka]=OpenLook სისტემის ტრადიციული ფანჯრის მენეჯერი +Comment[kk]=Дәстүрлі Open Look терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចរូបរាងបើកចំហបុរាណ +Comment[lt]=Tradicinė Open Look langų tvarkyklė +Comment[lv]=Tradicionālais Open Look logu menedžeris +Comment[mk]=Традиционален Open Look Window Manager +Comment[mn]=Уламжилалт нээж харагч цонхны удирдагч +Comment[ms]=Pengurus Tetingkap OpenLook tradisional +Comment[mt]=Window manager tradizzjonali ta' OpenLook +Comment[nb]=Den tradisjonelle Open Look-vindusbehandleren +Comment[nds]=De traditschonelle OpenLook-Finsterpleger +Comment[ne]=खुला देखिने परम्परागत सञ्झ्याल प्रबन्धक +Comment[nl]=De traditionele Open Look Window Manager +Comment[nn]=Den tradisjonelle Open Look-vindaugssjefen +Comment[pa]=ਇੱਕ ਮੂਲ ਓਪਨ ਲੁੱਕ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Tradycyjny menedżer okien Open Look +Comment[pt]=O gestor de janelas Open Look tradicional +Comment[pt_BR]=O tradicional Open Look Window Manager +Comment[ro]=Managerul de ferestre tradițional Open Look Window Manager +Comment[ru]=Традиционный оконный менеджер системы OpenLook +Comment[rw]=Mugenga Dirishya Gufungura Kureba karande +Comment[se]=Árbevirolaš Open Look lásegieđahalli +Comment[sk]=Tradičný správca okien Open Look +Comment[sl]=Tradicionalni Open Look Window Manager +Comment[sr]=Традиционални „Open Look“ менаџер прозора +Comment[sr@Latn]=Tradicionalni „Open Look“ menadžer prozora +Comment[sv]=Den traditionella Open Look fönsterhanteraren +Comment[ta]=பழமையான சாளர மேலாளர் +Comment[te]=సాంప్రదాయ ఒపెన్ లుక్ విండొ అభికర్త +Comment[tg]=Расмшудаи Open Look-и мудири тиреза +Comment[th]=ระบบจัดการหน้าต่าง OpenLook แบบดั้งเดิม +Comment[tr]=OpenLook Pencere Yöneticisi +Comment[tt]=Open Look täräzä-idäräçeneñ töp söreme +Comment[uk]=Традиційний менеджер вікон Open Look +Comment[vi]=Trình Quản lý Cửa sổ "Cái nhìn Mở" truyền thống +Comment[wa]=Li mwaisse Manaedjeu di Purnea OpenLook (OpenLook Virtual Window Manager) +Comment[zh_CN]=传统的 OpenLook 窗口管理器 +Comment[zh_TW]=傳統的 Open Look 視窗管理程式 diff --git a/kdm/kfrontend/sessions/openbox.desktop b/kdm/kfrontend/sessions/openbox.desktop new file mode 100644 index 000000000..d0f4a06d7 --- /dev/null +++ b/kdm/kfrontend/sessions/openbox.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Type=XSession +Exec=openbox-session +TryExec=openbox +Name=Openbox +Name[bn]=ওপেনবক্স +Name[cy]=Blwchagored (Openbox) +Name[eo]=Malfermujo +Name[hi]=ओपनबाक्स +Name[ne]=खुला बाकस +Name[pa]=ਓਪਨ ਬਕਸਾ +Name[rw]=GufunguraAgasanduku +Name[ta]=திறப்பு பெட்டி +Name[te]=ఒపెన్ బాక్స్ +Name[tg]=Кушодани қуттӣ +Comment=A lightweight window manager based on Blackbox +Comment[af]='n Lig gewig venster bestuurder wat op Blackbox gebaseer is +Comment[ar]=مدير نوافذ خفيف العبء مبني على Blackbox +Comment[be]=Лёгкі кіраўнік вокнаў, заснаваны на Blackbox +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক হাল্কা উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager baziran na Blackbox-u +Comment[ca]=Un lleuger gestor de finestres basat en Blackbox +Comment[cs]=Malý správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów o môłëch żądaniach, òpairti na Blackbox +Comment[cy]=Trefnydd ffenestri ysgafn, wedi'i seilio ar Ddu-flwch +Comment[da]=En letvægts vindueshåndtering baseret på Blackbox +Comment[de]=Schlanker Fenstermanager, der auf Blackbox beruht +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[eo]=Fenestroadministrilo devenigita de Negrujo +Comment[es]=Un gestor de ventanas ligero basado en BlackBox +Comment[et]=Imeväike aknahaldur, mille aluseks on Blackbox +Comment[eu]=Blackboxen oinarritutako leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ سبک بر اساس Blackbox +Comment[fi]=Kevyt, Blackboxiin pohjautuva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres léger fondé sur Blackbox +Comment[fy]=In lichtgewicht finstersmanager, basearre op Blackbox +Comment[gl]=Un xestor de fiestras lixeiro baseado en Blackbox +Comment[he]=מנהל חלונות קל מבוסס על Blackbox +Comment[hi]=ब्लेकबाक्स आधारित हल्का विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora zasnovan na Blackboxu +Comment[hu]=Egy nagyon egyszerű ablakkezelő a Blackbox alapján +Comment[is]=Léttur gluggastjóri byggður á Blackbox +Comment[it]=Un window manager leggero basato su BlackBox +Comment[ja]=Blackbox ベースの軽量なウィンドウマネージャ +Comment[ka]=Blackbox-ის ბაზაზე ფანჯრიოს მენეჯერი +Comment[kk]=Blackbox-негіздеген жеңіл терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសមត្ថភាពខ្សោយ ដែលផ្អែកលើ Blackbox +Comment[ko]=Blackbox 기반 가벼운 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, paremta Blackbox +Comment[lv]=Viegls logu menedžeris, bāzēts uz Blackbox +Comment[mk]=Лесен менаџер на прозорци базиран на Blackbox +Comment[ms]=Pengurus tetingkap ringan berdasarkan Kotak Hitam +Comment[mt]=Window manager ħafif ibbażat fuq BlackBox +Comment[nb]=En lettvekts vindusbehandler basert på Blackbox +Comment[nds]=En ranke Finsterpleger, opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager, gebaseerd op Blackbox +Comment[nn]=Ein lett vindaugssjef basert på Blackbox +Comment[pa]=ਬਲੈਕਬਕਸੇ ਤੇ ਆਧਾਰਿਤ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, oparty na Blackbox +Comment[pt]=Um gestor de janelas leve baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas leve, baseado no Blackbox +Comment[ro]=Un manager de ferestre minimal bazat pe Blackbox +Comment[ru]=Лёгкий оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya yoroshye ishingiye ku Gasandukumukara +Comment[se]=Geahpes lásegieđahalli ráhkaduvvon Blackboxa vuođul +Comment[sk]=Nenáročný správca okien založený na Blackbox +Comment[sl]=Lahek okenski upravitelj na osnovi Blackboxa +Comment[sr]=Лагани менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Lagani menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Lättviktig fönsterhanterare baserad på Blackbox +Comment[ta]=கருப்புப் பெட்டியின் அடிப்படையிலான ஒரு குறைந்த எடை சாளர மேலாளர் +Comment[te]=బ్లాక్ బాక్స్ ఆధారిత తెలికైన విండొ అభికర్త +Comment[tg]=Мудири тирезаи сабук ба асоси қуттии сиёҳ +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา สร้างมาจาก Blackbox +Comment[tr]=Blackbox temelli küçük bir pencere yöneticisi +Comment[tt]=Blackbox asılında ciñel täräzä-idäräçe +Comment[uk]=Легкий менеджер вікон, заснований на Blackbox +Comment[uz]=Blackbox asosida yaratilgan oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=Blackbox асосида яратилган оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn dựa trên Blackbox +Comment[wa]=On ledjir manaedjeu di purneas båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 的轻量级窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且輕量化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/oroborus.desktop b/kdm/kfrontend/sessions/oroborus.desktop new file mode 100644 index 000000000..b7ea37c30 --- /dev/null +++ b/kdm/kfrontend/sessions/oroborus.desktop @@ -0,0 +1,76 @@ +[Desktop Entry] +Type=XSession +Exec=oroborus +TryExec=oroborus +Name=Oroborus +Name[eo]=Koloroj +Name[hi]=ऑरोबोरस +Name[pa]=ਓਰੂਬੋਰੁਸ +Name[te]=ఒరొబొరస్ +Comment=A lightweight themeable window manager +Comment[af]='n Lig gewig, tema venster bestuurder +Comment[ar]=مدير نوافذ خفيف العبء قابل لاستخدام السمات +Comment[be]=Лёгкі кіраўнік вокнаў з падтрымкай тэмаў +Comment[bn]=হাল্কা থীমযুক্ত উইণ্ডো ম্যানেজার +Comment[bs]=Lagani window manager sa podrškom za teme +Comment[ca]=Un gestor de finestres lleuger i configurable amb temes +Comment[cs]=Malý správce oken s tématy +Comment[csb]=Menedżer òknów ò môłëch żądanich, z mòżnotą zmianë wëzdrzatkù +Comment[cy]=Trefnydd ffenestri ysgafn sy'n defnyddio themau +Comment[da]=En letvægts vindueshåndtering med temaer +Comment[de]=Schlanker Fenstermanager mit Designs +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με υποστήριξη θεμάτων +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas ligero con temas +Comment[et]=Imeväike teemadega aknahaldur +Comment[eu]=Temak onartzen dituen leiho kudeatzaile arina +Comment[fa]=یک مدیر پنجرۀ قابل چهرهبندی سبک +Comment[fi]=Kevyt teemoitettava ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres avec gestion des thèmes +Comment[fy]=In lichtgewicht finstersmanager mei temabehear +Comment[gl]=Un xestor de fiestras lixeiro e con capacidade para temas +Comment[he]=מנהל חלונות קל ובר התאמה אישית של ערכות נושא +Comment[hi]=हल्का, प्रसंगयोग्य विंडो प्रबंधक +Comment[hr]=Lagani upravitelj prozora s temama +Comment[hu]=Kis erőforrásigényű ablakkezelő, témázási lehetőséggel +Comment[is]=Léttur þemanlegur gluggastjóri +Comment[it]=Un window manager leggero che supporta i temi +Comment[ja]=テーマ化可能な軽量のウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრის მენეჯერი თემების მხარდაჭერით +Comment[kk]=Жеңіл, нақыштары бар терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចអាចប្ដូរស្បែកបាន តែមានសមត្ថភាពខ្សោយ +Comment[ko]=가벼운 테마를 설정할 수 있는 창 관리자 +Comment[lt]=Nedaug resursų reikalaujanti temas palaikanti langų tvarkyklė +Comment[lv]=Viegls logu menedžeris ar tēmu atbalstu +Comment[mk]=Лесен менаџер на прозорци со теми +Comment[ms]=Pengurus tetingkap boleh tema ringan +Comment[mt]=Window manager ħafif u temabbli +Comment[nb]=En lettvekts vindusbehandler med temaer +Comment[nds]=En ranke Finsterpleger, kann Mustern bruken +Comment[ne]=विषयवस्तु योग्य हल्का वजन सञ्झ्याल प्रबन्धक +Comment[nl]=Een lichtgewicht windowmanager met themabeheer +Comment[nn]=Ein lett vindaugssjef med tema +Comment[pa]=ਇੱਕ ਸਰੂਪਾਂ ਨਾਲ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o małych wymaganiach, z możliwością zmiany wyglądu +Comment[pt]=Um gestor de janelas leve e com suporte para temas +Comment[pt_BR]=Um gerenciador de Janelas leve com vários temas +Comment[ro]=Un manager de ferestre mic și configurabil cu diverse tematici +Comment[ru]=Лёгкий оконный менеджер, поддерживающий темы +Comment[rw]=Mugenga dirishya ngirwa-nsanganyamatsiko yoroshye +Comment[se]=Geahpes lásegieđahalli mas leat fáttát +Comment[sk]=Nenáročný správca okien s podporou tém +Comment[sl]=Lahek okenski upravitelj s temami +Comment[sr]=Лагани менаџер прозора са темама +Comment[sr@Latn]=Lagani menadžer prozora sa temama +Comment[sv]=Lättviktig fönsterhanterare med teman +Comment[ta]=குறைந்தஎடை தலைப்புடைய சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างขนาดเบาที่ใช้ชุดตกแต่งได้ +Comment[tr]=Küçük, hafif, temalı bir pencere yöneticisi +Comment[tt]=Tışlana torğan ciñel täräzä-idäräçe +Comment[uk]=Легкий менеджер вікон з підтримкою тем +Comment[vi]=Trình quản lý cửa sổ thay đổi được sắc thái +Comment[wa]=On ledjir manaedjeu di purneas avou des tinmes +Comment[zh_CN]=轻量级窗口管理器,可定义主题 +Comment[zh_TW]=一個輕量化且有佈景功能的視窗管理程式 +# not usable as a session +Hidden=true diff --git a/kdm/kfrontend/sessions/phluid.desktop b/kdm/kfrontend/sessions/phluid.desktop new file mode 100644 index 000000000..f1cca1d66 --- /dev/null +++ b/kdm/kfrontend/sessions/phluid.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Type=XSession +Exec=phluid +TryExec=phluid +Name=Phluid +Name[eo]=Plena +Name[hi]=फ्लुइड +Name[pa]=ਫਲੁਇਡ +Name[te]=ఫ్లూయిడ్ +Comment=An Imlib2 based window manager +Comment[af]='n Imlib2 gebaseerde venster bestuurder +Comment[ar]=مدير نوافذ مبني على Imlib2 +Comment[be]=Кіраўнік вокнаў, заснаваны на Imlib2 +Comment[bn]=Imlib2 ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Window manager baziran na Imlib2 +Comment[ca]=Un gestor de finestres basta en Imlib2 +Comment[cs]=Správce oken založený na Imlib2 +Comment[csb]=Menedżer òknów òpiarti na Imlib2 +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar lmlib2 +Comment[da]=En Imlib2 baseret vindueshåndtering +Comment[de]=Imlib2-basierter Fenstermanager +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στην imlib2 +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas basado en Imlib2 +Comment[et]=Aknahaldur, mille aluseks on Imlib2 +Comment[eu]=Imlib2-n oinarritutako leiho kudeatzailea +Comment[fa]=یک Imlib2 بر اساس مدیر پنجره +Comment[fi]=Imlib2-pohjainen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres fondé sur Imlib2 +Comment[fy]=In op imlib2 basearre finstersmanager +Comment[ga]=Bainisteoir fuinneoga bunaithe ar Imlib2 +Comment[gl]=Un xestor de fiestras baseado en Imlib2 +Comment[he]=מנהל חלונות מבוסס Imlib2 +Comment[hi]=आईएमलिब2 आधारित विंडो प्रबंधक +Comment[hr]=Upravitelj prozora zasnovan na Imlib2 +Comment[hu]=Egy Imlib2-alapú ablakkezelő +Comment[is]=Gluggastjóri sem notar Imlib2 +Comment[it]=Un window manager basato su Imlib2 +Comment[ja]=Imlib2ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი imlib2 ის ბაზაზე +Comment[kk]=Imlib2-негіздеген терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចផ្អែកលើ Imlib2 +Comment[ko]=Imlib2 기반 창 관리자 +Comment[lt]=Langų tvarkyklė, paremta Imlib2 +Comment[lv]=Imlib 2 bāzēts logu menedžeris +Comment[mk]=Менаџер на прозорци базиран на Imlib2 +Comment[mn]=Imlib2 дээр суурилсан цонхны удирдагч +Comment[ms]=Pengurus tetingkap berasaskan lmlib2 +Comment[mt]=Window manager ibbażat fuq Imlib2 +Comment[nb]=En vindusbehandler basert på Imlib2 +Comment[nds]=En Finsterpleger opbuut op Imlib2 +Comment[ne]=Imlib2 मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een op imlib2 gebaseerde windowmanager +Comment[nn]=Ein vindaugssjef basert på Imlib2 +Comment[pa]=ਇੱਕ Imlib2 ਆਧਾਰਿਤ ਫਾਇਲ਼ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Imlib2 +Comment[pt]=Um gestor de janelas baseado na Imlib2 +Comment[pt_BR]=Um gerenciador de janelas baseado na lmlib2 +Comment[ro]=Un manager de ferestre bazat pe Imlib2 +Comment[ru]=Оконный менеджер на основе imlib2 +Comment[rw]=Mugenga dirishya ishingiye kuri Imlib2 +Comment[se]=Imlib2-vuođđoduvvon lásegieđahalli +Comment[sk]=Správca okien založený na imlib2 +Comment[sl]=Okenski upravitelj na osnovi lmlib2 +Comment[sr]=Менаџер прозора заснован на Imlib2 +Comment[sr@Latn]=Menadžer prozora zasnovan na Imlib2 +Comment[sv]=Imlib2-baserad fönsterhanterare +Comment[ta]=சாளர மேலாளர் அடிப்படையிலான ஒரு Imlib2 +Comment[te]=ఐఎంలిబ్2 ఆధారిత విండొ అభికర్త +Comment[tg]=Imlib2 ба асосимудири тиреза +Comment[th]=ระบบจัดการหน้าต่างที่สร้างบน Imlib2 +Comment[tr]=Imlib2 tabanlı bir pencere yöneticisi +Comment[tt]=Imlib2 asılında täräzä-idäräçe +Comment[uk]=Менеджер вікон, заснований на Imlib2 +Comment[uz]=Imlib2 asosida yaratilgan oyna boshqaruvchi +Comment[uz@cyrillic]=Imlib2 асосида яратилган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ dựa trên lmlib2 +Comment[wa]=On manaedjeu di purneas båzé so lmlib2 +Comment[zh_CN]=基于 Imlib2 的窗口管理器 +Comment[zh_TW]=一個基於 Imlib2 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/pwm.desktop b/kdm/kfrontend/sessions/pwm.desktop new file mode 100644 index 000000000..036c9bff4 --- /dev/null +++ b/kdm/kfrontend/sessions/pwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=pwm +TryExec=pwm +Name=PWM +Name[eo]=UnuFA +Name[hi]=पीडबल्यूएम +Name[te]=పి డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง PWM +Comment=A lightweight window manager able to attach multiple windows to one frame +Comment[af]='n Lig gewig venster bestuurder wat veelvuldige vensters aan een raam kan koppel +Comment[ar]=مدير نوافذ خفيف العبء قابل لربط عدة نوافذ إلى إطار واحد +Comment[be]=Лёгкі кіраўнік вокнаў, які можа далучаць некалькі вокнаў да аднаго фрэйма +Comment[bn]=একটি হাল্কা উইণ্ডো ম্যানেজার, যাতে একটি ফ্রেমে একাধিক উইণ্ডো সংযুক্ত করা সম্ভব +Comment[bs]=Lagani window manager koji može prikačiti više prozora na jedan okvir +Comment[ca]=Un lleuger gestor de finestres capaç d'aplegar múltiples finestres en un marc +Comment[csb]=Menedżer òknów ò môłëch żądaniach, rozmiejący doczepic wiele òknów do jedny ramë +Comment[cy]=Trefnydd ffenestri ysgafn sy'n gallu atodi mwy nag un ffenestr at un ffrâm +Comment[da]=En letvægts vindueshåndtering der kan knytte flere vinduer til én ramme +Comment[de]=Schlanker Fenstermanager, der mehrere Fenster an einen Rahmen andocken kann +Comment[el]=Ένας ελαφρύς διαχειριστής παραθύρων με δυνατότητα να προσαρτά πολλαπλά παράθυρα σε ένα πλαίσιο +Comment[eo]=Fenestroadministrilo, kiu faras unun fenestron el kelkaj +Comment[es]=Un gestor de ventanas ligero capaz de conectar varias ventanas a un mismo marco +Comment[et]=Imeväike aknahaldur, mis suudab mitu akent ühe raami külge haakida +Comment[eu]=Hainbat leiho marko bakarrean uztar ditzakeen leiho kudeatzaile arina +Comment[fa]=مدیر پنجرۀ سبک قادر به پیوست پنجرههای چندگانه در یک قابک +Comment[fi]=Kevyt ikkunaohjelma, joka osaa liittää useita ikkunoita yhteen kehykseen +Comment[fr]=Un gestionnaire de fenêtres léger capable d'attacher plusieurs fenêtres à un même cadre +Comment[fy]=In lichtgewicht finstersmanager, hokker meardere finsters kin ferbine mei in kader +Comment[gl]=Un xestor de fiestras lixeiro capaz de adxuntar varias fiestras nun marco +Comment[he]=מנהל חלונות קל המסוגל לחבר חלונות רבים למסגרת אחת +Comment[hi]=एक हल्का विंडो प्रबंधक जिसके एक फ़रमा में अनेक विंडो जोड़े जा सकते हैं +Comment[hr]=Lagani upravitelj prozora koji jednom okviru može pridodati više prozora +Comment[hu]=Alacsony erőforrásigényű ablakkezelő, több ablakot képes egy kerethez rendelni +Comment[is]=Léttur gluggastjóri sem getur tengt marga glugga við einn ramma +Comment[it]=Un window manager leggero in grado di attaccare più finestre ad una cornice +Comment[ja]=複数のウィンドウ枠を設定可能な軽量なウィンドウマネージャ +Comment[ka]=მსუბუქი ფანჯრის მენეჯერი, რომელსაც შეუძლია ბევრი ფანჯრის ერთ ჩარჩოში ჩასმა +Comment[kk]=Жеңіл, бір коршауда бірнеше терезелерді біріктірелетін, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសមត្ថភាពខ្សោយ អាចភ្ជាប់បង្អួចច្រើនទៅស៊ុមមួយ +Comment[lt]=Nedaug resursų reikalaujanti langų tvarkyklė, galinti prijungti daug langų prie vieno rėmo +Comment[lv]=Viegls logu menedžeris ar iespēju pievienot vairākus logus vienam kadram +Comment[mk]=Лесен менаџер на прозорци кој може да прикачи повеќе прозорци на една рамка +Comment[ms]=Pengurus tetingkap ringan yang boleh melekapkan berbilang tetingkap pada satu bingkai +Comment[mt]=Window manager ħafif li jista' jgħaqqad iżjed minn window waħda fl-istess gwarniċ +Comment[nb]=En lettvekts vindusbehandler som kan koble flere vinduer til én ramme +Comment[nds]=En ranke Finsterpleger, de mennige Finstern an een Rahmen andocken kann +Comment[ne]=एक हल्का वजन सञ्झ्याल प्रबन्धकले बहुभागिय सञ्झ्यालहरूलाई एक फ्रेममा सङ्लग्न गर्न सक्छ +Comment[nl]=Een lichtgewicht windowmanager, welke meerdere vensters kan verbinden met een frame +Comment[nn]=Ein lett vindaugssjef som kan kopla fleire vindauge til den same ramma +Comment[pa]=ਇੱਕ ਹਲਕਾ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਜੋ ਕਿ ਕਈ ਝਰੋਖਿਆਂ ਨੂੰ ਇੱਕ ਫਰੇਮ ਵਿੱਚ ਰੱਖ ਸਕਦਾ ਹੈ +Comment[pl]=Menedżer okien o małych wymaganiach, potrafiący doczepić wiele okien do jednego obramowania +Comment[pt]=Um gestor de janelas leve, com a possibilidade de anexar várias janelas a uma área +Comment[pt_BR]=Um gerenciador de janelas leve, capaz de anexar múltiplas janelas em um quadro +Comment[ro]=Un manager de ferestre minimal capabil să atașeze multe ferestre la un singur cadru +Comment[ru]=Лёгкий оконный менеджер, способный объединить несколько окон в одной рамке +Comment[rw]=Mugenga dirishya yoroshye ishobora gufatishya amadirishya menshi ku ikadiri imwe. +Comment[se]=Geahpes lásegieđahalli mii sáhttá ovttastahttit máŋga láse seamma rámmii. +Comment[sk]=Nenáročný správca okien schopný spojiť viac okien do jednoho rámca +Comment[sl]=Lahek okenski upravitelj, ki lahko pripne več oken na en okvir +Comment[sr]=Лагани менаџер прозора способан да прикачи више прозора за један оквир +Comment[sr@Latn]=Lagani menadžer prozora sposoban da prikači više prozora za jedan okvir +Comment[sv]=Lättviktig fönsterhanterare som kan ansluta flera fönster till en ram +Comment[ta]=குறைந்த கனமுள்ள பல சாளரங்களை இணைக்க முடிந்த ஒற்றை சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างขนาดเบา มีความสามารถในการปะติดหลายๆหน้าต่างลงใน 1 กรอบ +Comment[tr]=Düşük ağırlıklı bir çok pencereyi bir çerçeveye toplayabilen bir pencere yöneticisi +Comment[tt]=Ber qısa eçendä berniçä täräzä totaştırala torğan täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, що дозволяє долучати декілька вікон до однієї рамки +Comment[vi]=Trình quản lý cửa sổ nhỏ gọn, có thể gắn nhiều cửa sổ vào một khung +Comment[wa]=On ledjir manaedjeu di purneas ki pout ataetchî sacwants purneas so-z on cåde +Comment[zh_CN]=轻量级窗口管理器,可将多个窗口附加到一个框架中 +Comment[zh_TW]=一個輕量化且可以將多個視窗結合在一起的視窗管理程式 diff --git a/kdm/kfrontend/sessions/qvwm.desktop b/kdm/kfrontend/sessions/qvwm.desktop new file mode 100644 index 000000000..922e3e0bd --- /dev/null +++ b/kdm/kfrontend/sessions/qvwm.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Type=XSession +Exec=qvwm +TryExec=qvwm +Name=QVWM +Name[eo]=QVFA +Name[hi]=क्यूवीडबल्यूएम +Name[te]=క్యు వి డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง QVWM +Comment=A Windows 95 like window manager +Comment[af]='n Venster bestuurder wat soos Windows 95 lyk +Comment[ar]=مدير نوافذ شبيه بويندوز 95 +Comment[be]=Кіраўнік вокнаў, падобны на Windows 95 +Comment[bn]=Windows 95-এর অনুরূপ একটি উইণ্ডো ম্যানেজার +Comment[bs]=Window manager nalik na Windows 95 +Comment[ca]=Un gestor de finestres com el Windows 95 +Comment[cs]=Správce oken se vzhledem Windows 95 +Comment[csb]=Menedżer òknów o wëzdrzatkù szlachùjącym za Windows 95 +Comment[cy]=Trefnydd Ffenestri sy'n debyg i Windows95 +Comment[da]=En Windows 95-lignende vindueshåndtering +Comment[de]=Fenstermanager im Stil von Windows 95 +Comment[el]=Ένας διαχειριστής παραθύρων παρόμοιος με τα Windows 95 +Comment[eo]=Fenestroadministrilo kiel Vindozo 95 +Comment[es]=Un gestor de ventanas similar a Windows 95 +Comment[et]=Aknahaldur, mis näeb välja nagu Windows 95 +Comment[eu]=Windows 95en itxura duen leiho kudeatzailea +Comment[fa]=یک مدیر پنجره شبیه ویندوز ۹۵ +Comment[fi]=Windows 95:n tyylinen ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres semblable à Windows 95 +Comment[fy]=In Win95-likens finstersmanager +Comment[ga]=Bainisteoir fuinneoga cosúil le Windows 95 +Comment[gl]=Un xestor de fiestras como o de Windows 95 +Comment[he]=מנהל חלונות הדומה לחלונות 95 +Comment[hi]=विंडोज़ 95 जैसा विंडो प्रबंधक +Comment[hr]=Upravitelj prozora nalik na Windows 95 +Comment[hu]=Egy Windows 95-szerű ablakkezelő +Comment[is]=Gluggastjóri sem líkist Windows 95 +Comment[it]=Un window manager in stile Windows 95 +Comment[ja]=Windows95 風のウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი Windows 95-ს სტილში +Comment[kk]=Windows 95 секілді терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចស្រដៀង Windows 95 +Comment[ko]=윈도 95를 닮은 창 관리자 +Comment[lt]=Langų tvarkyklė, primenanti Windows 95 +Comment[lv]=Windows 95 līdzīgs logu menedžeris +Comment[mk]=Менаџер на прозорци со изглед на Windows 95 +Comment[mn]=Виндовс 95 шиг цонхны удирдагч +Comment[ms]=Pengurus tetingkap seperti Windows 95 +Comment[mt]=Window manager jixbaħ lil Windows95 +Comment[nb]=En vindusbehandler som likner Windows 95 +Comment[nds]=En Finsterpleger liek to Windows 95 +Comment[ne]=विण्डोज ९५ जस्तो सञ्झ्याल प्रबन्धक +Comment[nl]=Een Win95-achtige windowmanager +Comment[nn]=Ein vindaugssjef som liknar Windows 95 +Comment[pa]=ਇੱਕ ਵਿੰਡੋ 95 ਵਰਗਾ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien o wyglądzie podobnym do Windows 95 +Comment[pt]=Um gestor de janelas com o visual do Windows 95 +Comment[pt_BR]=Um gerenciador de janelas parecido com o Windows 95 +Comment[ro]=Un manager de ferestre cu aspect de Windows 95 +Comment[ru]=Оконный менеджер в стиле Windows 95 +Comment[rw]=Windows 95 nka mugenga dirishya +Comment[se]=Windows95-lágan lásegieđahalli +Comment[sk]=Správca okien podobný Windows 95 +Comment[sl]=Okenski upravitelj, podoben Windows 95 +Comment[sr]=Менаџер прозора налик на Windows 95 +Comment[sr@Latn]=Menadžer prozora nalik na Windows 95 +Comment[sv]=Fönsterhanterare som liknar Windows 95 +Comment[ta]=சாளர மேலாளர் போன்ற விண்டோஸ் 95 +Comment[te]=విండొస్ 95 లాంటి విండొ అభికర్త +Comment[tg]=Windows 95 монанди мудири тиреза +Comment[th]=ระบบจัดการหน้าต่างที่ดูคล้ายวินโดวส์ 95 +Comment[tr]=Windows 95 benzeri bir pencere yöneticisi +Comment[tt]=Windows 95 kebek täräzä-idäräçe +Comment[uk]=Менеджер вікон на кшталт Windows95 +Comment[uz]=Win95'ga oʻxshagan oyna boshqaruvchi +Comment[uz@cyrillic]=Win95'га ўхшаган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ giống Windows 95 +Comment[wa]=On manaedjeu di purneas rishonnant a Windows 95 +Comment[zh_CN]=类似 Windows 95 的窗口管理器 +Comment[zh_TW]=一個像 Win95 的視窗管理程式 diff --git a/kdm/kfrontend/sessions/ratpoison.desktop b/kdm/kfrontend/sessions/ratpoison.desktop new file mode 100644 index 000000000..1127db151 --- /dev/null +++ b/kdm/kfrontend/sessions/ratpoison.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=ratpoison +TryExec=ratpoison +Name=Ratpoison +Name[bn]=র্যাট-পয়সন +Name[cy]=Gwenwynllygodmawr (Ratpoison) +Name[eo]=Raticido +Name[fa]=مرگ موش +Name[hi]=रैट-पॉइज़न +Name[ne]=र्याटपोइजन +Name[pa]=ਰਾਟਪੋਈਸਾਨ +Name[rw]=UburoziImbeba +Name[sv]=Råttgift +Name[ta]=ராட் பாய்சன் +Name[te]=ఎలుకలమందు +Name[vi]=Bả chuột +Name[wa]=Pwezon po les rats (Ratpoison) +Comment=A simple keyboard-only window manager modeled after Screen +Comment[af]='n Eenvoudige venster bestuurder wat net met die sleutel bord werk en op Screen gemoduleer is. +Comment[ar]=مدير نوافذ بسيط يستخدم لوحة المفاتيح فقط صنع مشابهاً لـScreen +Comment[be]=Просты кіраўнік вокнаў, працуе толькі з клавіятурай +Comment[bn]=একটি সরল কীবোর্ড-ভিত্তিক উইণ্ডো ম্যানেজার, Screen-এর আদর্শে তৈরি +Comment[bs]=Jednostavan windows manager samo za tastaturu, modeliran po uzoru na Screen +Comment[ca]=Un gestor de finestres simple de sols teclat modelat després de Screen +Comment[csb]=Prosti menedżer òknów òbsłùgiwôny blós z klawiaturë, szlachùje za programą screen +Comment[cy]=Trefnydd ffenestri syml sy'n defnyddio'r allweddell yn unig, wedi'i arddullio ar Sgrîn (Screen) +Comment[da]=En simpel kun-tastatur vindueshåndtering modeleret efter Screen +Comment[de]=Einfacher Fenstermanager, der nur über die Tastatur bedient wird und Screen nachgebildet ist +Comment[el]=Ένας απλός, μονό για πληκτρολόγιο, διαχειριστής παραθύρων σχεδιασμένος με βάση το Screen +Comment[en_GB]=A simple keyboard-only window manager modelled after Screen +Comment[eo]=Fenestroadministrilo por klaviaro +Comment[es]=Un gestor de ventanas sólo para teclado realizado a partir de Screen +Comment[et]=Lihtne ainult klaviatuuri abil kasutatav aknahaldur, mille eeskujuks on Screen +Comment[eu]=Screen-en oinarriturik egindako leiho kudeatzailea, teklatu hutsez erabiltzekoa +Comment[fa]=یک مدیر پنجره فقط صفحه کلید سادۀ مدلیافته پس از پرده +Comment[fi]=Yksinkertainen, vain näppäimistöltä käytettävä ikkunamanageri, screen-ohjelman tyyliin +Comment[fr]=Un gestionnaire de fenêtres simple uniquement dirigeable au clavier et fondé sur Screen +Comment[fy]=In ienfâldige finstersmanager dy allinnich mei it toetseboerd te betsjinnen is, ynspiraasje troch Screen +Comment[gl]=Un xestor de fiestras de manexo co teclado modelado despois de Screen +Comment[he]=מנהל חלונות פשוט למקלדת בלבד המעוצב בסגנון Screen +Comment[hi]=आफ्टर स्क्रीन आधारित साधारण विंडो प्रबंधक जो सिर्फ कुंजीपट के लिए है +Comment[hr]=Jednostavan, samo za tipkovnicu, upravitelj prozora napravljen prema Screenu +Comment[hu]=Egyszerű, csak billentyűzetről vezérelhető ablakkezelő (a Screen alapján) +Comment[is]=Einfaldur gluggastjóri sem notar eingöngu lyklaborðið hannaður eftir Screen forritinu +Comment[it]=Un window manager semplice solo-tastiera pensato come Screen +Comment[ja]=Screen をもとに作られた、キーボードインターフェースのみのウィンドウマネージャ +Comment[ka]=მარტივი კლაიატურით მართვადი ფანჯრის მმართველი +Comment[kk]=Screen үлгідегі, тек перенетақтадан басқарылатын, қарапайым терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចសាមញ្ញប្រើតែក្ដារចុច ដែលយកគំរូតាមអេក្រង់ +Comment[lt]=Paprasta, tik klaviatūra valdoma langų tvarkyklė, panaši į Screen +Comment[lv]=Vienkāršs tikai tastatūras logu menedžeris, līdzīgs Screen +Comment[mk]=Едноставен менаџер на прозорци кој работи само со тастатура, моделиран според Screen +Comment[ms]=Pengurus tetingkap hanya papan kekunci ringkas dimodelkan seperti Skrin +Comment[mt]=Window manager għal tastieri biss immudellat fuq Screen +Comment[nb]=En enkel tastaturbasert vindusbehandler, etter forbilde av Screen +Comment[nds]=En eenfache Finsterpleger, de bloots mit de Tastatuur bruukt warrt. Screen weer dat Modell dorför +Comment[ne]=पर्दा पछाडि सञ्झ्याल प्रबन्धक मात्र नमूना बनाउने साधारण कुञ्जीपाटी +Comment[nl]=Een eenvoudige windowmanager die alleen met het toetsenbord te bedienen is, geïnspireerd door Screen +Comment[nn]=Ein enkel tastaturbasert vindaugssjef, med Screen som førebilete +Comment[pa]=ਪਰਦੇ ਮੈਡੀਊਲ ਬਾਅਦ ਸਿਰਫ ਕੀ-ਬੋਰਡ ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien obsługiwany wyłącznie za pomocą klawiatury, stworzony na podobieństwo programu screen +Comment[pt]=Um gestor de janelas simples, só para o teclado e modelado sobre o Screen +Comment[pt_BR]=Um simples gerenciador de janelas baseado somente em teclado, modelado após a tela +Comment[ro]=Un manager de ferestre manipulat din tastatură, modelat după Screen +Comment[ru]=Простой клавиатурный оконный менеджер, моделирующий Screen +Comment[rw]=Mugenga dirishya ya mwandikisho-gusa yoroheje itunganyijwe nyuma ya Mugaragaza +Comment[se]=Oktageardánis, boallobeavdestivrejuvvon lásegieđahalli, mas lea Screen ovdagovvan +Comment[sk]=Jednoduchý správca okien ovládaný iba klávesami podľa programu Screen +Comment[sl]=Preprost okenski uporavljalnik na osnovi Screen, upravlja se samo s tipkovnico +Comment[sr]=Једноставан, само за тастатуру менаџер прозора, направљен према Screen-у +Comment[sr@Latn]=Jednostavan, samo za tastaturu menadžer prozora, napravljen prema Screen-u +Comment[sv]=Enkel fönsterhanterare bara för tangentbord modellerad efter Screen +Comment[ta]=சாளரமொன்றில் நிழல் ஏறுகிறது +Comment[th]=ตัวจัดการหน้าต่างแบบเรียบง่าย ใช้แป้นพิมพ์ควบคุมได้อย่างเดียว ถูกสร้างขึ้นมาตามหลัง Screen +Comment[tr]=Screen'den sonra modellenmiş salt klavye basit pencere yöneticisi +Comment[tt]=Töylekle genä ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, розроблений на базі Screen, з підтримкою тільки клавіатури +Comment[vi]=Trình quản lý cửa sổ chỉ dùng bàn phím, dựa theo Screen +Comment[wa]=On simpe manaedjeu di purneas eployant fok li taprece, båzé so ls idêyes da «Screen» +Comment[zh_CN]=Screen 后又一只支持键盘的窗口管理器 +Comment[zh_TW]=一個簡易、只支援鍵盤的視窗管理程式 diff --git a/kdm/kfrontend/sessions/sapphire.desktop b/kdm/kfrontend/sessions/sapphire.desktop new file mode 100644 index 000000000..5cdd998d7 --- /dev/null +++ b/kdm/kfrontend/sessions/sapphire.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Type=XSession +Exec=sapphire +TryExec=sapphire +Name=Sapphire +Name[bn]=স্যাফায়ার +Name[eo]=Safiro +Name[fa]=ياقوت كبود +Name[hi]=सेफायर +Name[ka]=საფირონი +Name[ne]=नीलमणि +Name[pa]=ਸਾਪਰਫੀਰੀ +Name[ru]=Сапфир +Name[ta]=சபையர் +Name[te]=ఇంద్రనీలం +Name[tg]=Ёқути кабуд +Comment=A minimal but configurable window manager +Comment[af]='n Minimalistiese venster bestuurder, wat nogsteeds opstel funksionaliteit bevat. +Comment[ar]=مدير نوافذ مصغّر ولكن قابل للإعداد +Comment[be]=Мінімалістычны кіраўнік вокнаў з магчымасцю настаўлення +Comment[bn]=পরিমিত কিন্তু থীমযুক্ত উইণ্ডো ম্যানেজার +Comment[bs]=Minimalan ali podesiv window manager +Comment[ca]=Un minimalista però configurable gestor de finestres +Comment[cs]=Minimalistický, ale přizpůsobitelný správce oken +Comment[csb]=Prosti menedżer òknów, równak z mòżnotą kònfigùracëji +Comment[cy]=Trefnydd ffenestri lleiafol a ffurfweddir +Comment[da]=En minimal men indstillelig vindueshåndtering +Comment[de]=Minimalistischer, aber anpassbarer Fenstermanager +Comment[el]=Ένας μικρός αλλά παραμετροποιήσιμος διαχειριστής παραθύρων +Comment[eo]=Fenestroadministrilo +Comment[es]=Un gestor de ventanas minimalista pero configurable +Comment[et]=Väga väike, kuid seadistatav aknahaldur +Comment[eu]=Leiho kudeatzaile minimal baina konfiguragarria +Comment[fa]=یک مدیر پنجرۀ کمینه، اما قابل پیکربندی +Comment[fi]=Minimaalinen, mutta muokattavissa oleva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres minimaliste mais configurable +Comment[fy]=In minimale mar ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras mínimo pero configurábel +Comment[he]=מנהל חלונות מינימלי אך ניתן להגדרה +Comment[hi]=एक अल्पतम परंतु कॉन्फ़िगर योग्य विंडो प्रबंधक +Comment[hr]=Minimalan, ali podesiv upravitelj prozora +Comment[hu]=Egyszerű, de jól konfigurálható ablakkezelő +Comment[is]=Einfaldur en stillanlegur gluggastjóri +Comment[it]=Un window manager minimale ma configurabile +Comment[ja]=各種設定が可能な小さなウィンドウマネージャ +Comment[ka]=მინიმალური მაგრამ კონფიგურირებადი ფანჯრის მენეჯერი +Comment[kk]=Шағын, баптауы бар, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចតូច តែអាចកំណត់រចនាសម្ព័ន្ធបាន +Comment[ko]=설정 가능한 최소한의 창 관리자 +Comment[lt]=Minimalistinė tačiau konfigūruojama langų tvarkyklė +Comment[lv]=Minimālistisks, bet konfigurējams logu menedžeris +Comment[mk]=Минимален но конфигурабилен менаџер на прозорци +Comment[mn]=Маш жижиг тохируулах боломжгүй цонх удирдагч +Comment[ms]=Pengurus tetingkap minimum tetapi boleh konfigur +Comment[mt]=Window manager minimu imma konfigurabbli +Comment[nb]=En minimal vindusbehandler, men med innstillinger +Comment[nds]=En minimaal, man instellbor Finsterpleger +Comment[ne]=सानो तर कन्फिगर गर्न सकिने सञ्झ्याल प्रबन्धक +Comment[nl]=Een minimale maar instelbare windowmanager +Comment[nn]=Ein minimal vindaugssjef, men med innstillingar +Comment[pa]=ਇੱਕ ਨਿਊਨਤਮ, ਪਰ ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Prosty menedżer okien, ale z możliwością konfiguracji +Comment[pt]=Um gestor de janelas configurável mas mínimo +Comment[pt_BR]=Um gerenciador de janelas mínimo, mas configurável +Comment[ro]=Un manager de ferestre minimal, dar configurabil +Comment[ru]=Минимальный, но настраиваемый оконный менеджер +Comment[rw]=Ntoya ariko mugenga dirishya ibonezwa +Comment[se]=Unna, muhto heivehahtti lásegieđahalli +Comment[sk]=Minimálny, ale nastaviteľný správca okien +Comment[sl]=Skromen, a nastavljiv okenski upravitelj +Comment[sr]=Минимални, али подесиви менаџер прозора +Comment[sr@Latn]=Minimalni, ali podesivi menadžer prozora +Comment[sv]=Minimal men anpassningsbar fönsterhanterare +Comment[ta]=சாளர மேலாளரின் மேம்பட்ட திறன்களை வடிவமைக்கலாம் +Comment[th]=ระบบจัดการหน้าต่างขนาดเล็ก แต่สามารถปรับแต่งได้ +Comment[tr]=Küçük, ancak kolayca özelleştirilebilir bir pencere yöneticisi +Comment[tt]=Ciñel bulsa da, köylänä torğan täräzä-idäräçe +Comment[uk]=Мінімальний менеджер вікон з можливістю налаштування +Comment[uz]=Oddiy, ammo moslab boʻladigan oyna boshqaruvchi +Comment[uz@cyrillic]=Оддий, аммо мослаб бўладиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ tối thiểu, nhưng có thể cấu hình được +Comment[wa]=On ptit, nén apontiåve, manaedjeu di purnea +Comment[zh_CN]=很小却可配置的窗口管理器 +Comment[zh_TW]=一個小但可組態的視窗管理程式 diff --git a/kdm/kfrontend/sessions/sawfish.desktop b/kdm/kfrontend/sessions/sawfish.desktop new file mode 100644 index 000000000..668620fff --- /dev/null +++ b/kdm/kfrontend/sessions/sawfish.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=sawfish +TryExec=sawfish +Name=Sawfish +Name[bn]=স-ফিশ +Name[eo]=Segfiŝo +Name[fa]=ارهماهی +Name[hi]=सा-फिश +Name[ne]=सफीस +Name[pa]=ਸ਼ਾਅਫਿਸ਼ +Name[te]=సాఫిష్ +Comment=An extensible window manager scriptable with an Emacs Lisp-like language +Comment[af]='n Uitbreibare venster bestuurder met 'n ingeboude skrip taal wat soos Emacs List lyk. +Comment[ar]=مدير نوافذ قابل للتوسعة يمكن بشفيره بلغة إيماكس ليسب +Comment[be]=Кіраўнік вокнаў з магчымасцю пашырэння сцэнарамі на мове, падобнай на Emacs Lisp +Comment[bs]=Proširiv window manager sa podškom za skriptiranje u jeziku sličnom Emacs Lisp-u +Comment[ca]=Un extensible gestor de finestres mitjançant scripts amb una aparença com el Lisp de Emacs +Comment[cs]=Rožšiřitelný správce oken skriptovatelný jazykem podobným jazyku Emacs Lisp +Comment[csb]=Menedżer òknów, jaczi je mòżno rozbùdowac dzãka skriptom w jãzëkù szlachùjącym za Emacs Lisp +Comment[cy]=Trefnydd ffenestri estynadwy a all ei sgriptio efo iaith sy'n debyg i Emacs Lisp +Comment[da]=En udvidelig vindueshåndtering der kan scriptes med et Emacs Lisp-lignende sprog +Comment[de]=Erweiterbarer Fenstermanager, der über Skripts ähnlich Emacs-Lisp gesteuert werden kann +Comment[el]=Ένας επεκτάσιμος διαχειριστής παραθύρων παραμετροποιήσιμος με μια γλώσσα παρόμοια με την Emacs Lisp +Comment[eo]=Fenestroadministrilo, kiu uzas Lispon por esti programata +Comment[es]=Un gestor de ventanas extensible con guiones escritos en un lenguaje similar a Lisp de Emacs +Comment[et]=Laiendatav aknahaldur, mis kasutab Emacs Lispi keele moodi skripte +Comment[eu]=Emacs Lisp bezalako hizkuntza batez idatziriko scripten bidez heda daitekeen leiho kudeatzailea +Comment[fa]=مدیر پنجرۀ توسعهپذیر دستنوشتهای با یک زبان شبیه Emacs Lisp +Comment[fi]=Laajennettavissa oleva ikkunaohjelma, johon voi luoda komentosarjoja Emacs lispin tyylisellä kielellä +Comment[fr]=Un gestionnaire de fenêtres extensible, à l'aide scripts dans un langage semblable au Lisp d'Emacs +Comment[fy]=In útbreidbere finstersmanager, skriptber fia in Emacs Lisp-likene taal +Comment[gl]=Un xestor de fiestras extensíbel e configurábel con scripts en linguaxe Emacs Lisp +Comment[he]=מנהל חלונות מקיף הניתן לתכנות עם שפה דמוית Emacs Lisp +Comment[hi]=ई-मेक्स लिस्प जैसे भाषा में स्क्रिप्ट किया जा सकने लायक विंडो प्रबंधक जिसे विस्तार दिया जा सकता है +Comment[hr]=Proširivi upravitelj prozora pisan u skripti nalik na jezik Emacs Lisp +Comment[hu]=Egy könnyen tovább bővíthető ablakkezelő, egy Emacs Lisp-szerű nyelvvel szkriptelhető +Comment[is]=Viðbætanlegur gluggastjóri sem er skriftanlegur á Emacs Lisp líku máli +Comment[it]=Un window manager estensibile per cui è possibile fare script in un linguaggio simile all'Emacs lisp +Comment[ja]=Emacs Lisp 言語スクリプトで機能拡張可能なウィンドウマネージャ +Comment[ka]=Lisp სკრიპტებით გაფათოვებადი Emacs ის მაგვარი ფანჯრის მენეჯერი +Comment[kk]=Emacs Lisp-секілді тілдегі скриптті қолданып, кеңейтілетін терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចដែលអាចពង្រីកបាន ហើយអាចសរសេរស្គ្រីបជាមួយភាសាដែលដូច Emacs Lisp +Comment[lt]=Langų tvarkyklė, kurią galima išplėsti Emacs Lisp primenančia programavimo kalba +Comment[lv]=Paplašināms logu menedžeris ar Emacs Lisp līdzīgas valodas atbalstu +Comment[mk]=Екстензивен менаџер на прозорци кој може да се скриптира со јазик како Emacs Lisp +Comment[ms]=Pengurus tetingkap boleh kembang dan boleh diskrip dengan bahasa seperti Emacs Lisp +Comment[mt]=Window manager li jista' jiġi estiż, b'lingwa tixbaħ lil Emacs Lisp +Comment[nb]=En utvidbar vindusbehandler som kan skriptes med et språk som likner Emacs Lisp. +Comment[nds]=En verwiederbor Finsterpleger, de över en Skriptspraak liek to Emacs-Lisp stüert warrn kann +Comment[ne]=इमाक्स लिस्प जस्तो भाषसँग स्क्रिप्ट गर्न सकिने एउटा विस्तारयोग्य सञ्झ्याल प्रबन्धक +Comment[nl]=Een uitbreidbare windowmanager, scriptbaar via een Emacs Lisp-achtige taal +Comment[nn]=Ein utvidbar vindaugssjef som kan skriptast med eit språk som liknar Emacs Lisp +Comment[pa]= Emacs Lisp-ਵਰਗੀ ਭਾਸ਼ਾ ਸਕ੍ਰਿਪਟਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien, który można rozszerzać za pomocą skrytów w języku podobnym do Emacs Lisp +Comment[pt]=Um gestor de janelas extensível e programável com uma linguagem semelhante ao Emacs Lisp +Comment[pt_BR]=um gerenciador de janelas extensível, baseado em scripts, com uma linguagem parecida com o Lisp do Emacs +Comment[ro]=Un manager de ferestre extensibil scriptabil cu un limbaj similar cu Emacs Lisp +Comment[ru]=Расширяемый скриптами Lisp наподобие Emacs оконный менеджер +Comment[rw]=Mugenga dirishya yagurwa yandikwaho hakoreshejwe Emacs Kudedemanga-nka ururimi +Comment[sk]=Rozšíriteľný správca okien, ktorého je možné ovládať programovacím jazykom podobným Emacs Lispu +Comment[sl]=Razširljiv okenski upravitelj, ki se lahko upravlja s skripti v jeziku podobnem Emacs Lisp +Comment[sr]=Проширив менаџер прозора који се може скриптовати помоћу језика налик на Emacs-ов Lisp +Comment[sr@Latn]=Proširiv menadžer prozora koji se može skriptovati pomoću jezika nalik na Emacs-ov Lisp +Comment[sv]=Utökningsbar fönsterhanterare som kan styras med ett Emacs Lisp-liknande skriptspråk +Comment[ta]=Emacs Lisp-like மொழியுடனான விரிவாக்ககூடிய சாளர மேலாளர் எழுத்தாக்கம் +Comment[th]=ระบบจัดการหน้าต่างที่สามารถเพิ่มขยายได้ และควบคุมด้วยการเขียนสคริปต์โดยใช้ภาษาแบบ Emacs Lisp +Comment[tr]=Eklenti destekli Emacs Lisp benzeri bir kodlama dili kullanan kodlanabilir bir pencere yöneticisi +Comment[tt]=Emacs Lisp-kebek tel belän kiñäylelgän täräzä-idäräçe +Comment[uk]=Менеджер вікон, що можна розширювати мовою скриптів на кшталт Emacs Lisp +Comment[vi]=Trình quản lý cửa sổ có thể viết kịch bản được với ngôn ngữ giống Emacs Lisp +Comment[wa]=On manaedjeu d' purnea k' on pout radjouter des rawetes, apontiåve e scripes dins on lingaedje do stîle Emacs Lisp +Comment[zh_CN]=可用类似 Emacs Lisp 的语法进行编程的窗口管理器 +Comment[zh_TW]=一個可用類似 Emacs Lisp 語言延伸的視窗管理程式 diff --git a/kdm/kfrontend/sessions/twm.desktop b/kdm/kfrontend/sessions/twm.desktop new file mode 100644 index 000000000..894371ae9 --- /dev/null +++ b/kdm/kfrontend/sessions/twm.desktop @@ -0,0 +1,71 @@ +[Desktop Entry] +Type=XSession +Exec=twm +TryExec=twm +Name=TWM +Name[eo]=TFA +Name[hi]=टीडबल्यूएम +Name[te]=టి డబ్ల్యు ఎం +Comment=The Tab Window Manager +Comment[af]=Die Tab venster bestuurder +Comment[ar]=مدير النوافذ Tab +Comment[be]=Кіраўнік вокнаў з укладкамі Tab Window Manager +Comment[bn]=দি ট্যাব উইণ্ডো ম্যানেজার +Comment[bs]=Tab Window Manager +Comment[ca]=El gestor de finestres Tab +Comment[csb]=Tab Window Manager +Comment[cy]=Y Trefnydd Ffenestri Tab +Comment[da]=Tab-vindueshåndtering +Comment[de]=Der Tab-Fenstermanager +Comment[el]=Ο διαχειριστής παραθύρων Tab +Comment[eo]=Taba fenestroadministrilo +Comment[es]=El Tab Window Manager +Comment[et]=Kaartidega aknahaldur +Comment[eu]=Tab leiho kudeatzailea +Comment[fa]=مدیر پنجرۀ تب +Comment[fi]=Välilehtiä tukeva ikkunaohjelma +Comment[fy]=De Ljepper Finster Behearder +Comment[gl]=O Xestor de Fiestras Tab +Comment[hi]=टैब विंडो प्रबंधक +Comment[hr]=Tab upravitelj prozora +Comment[hu]=Tab Window Manager ablakkezelő +Comment[is]=Tab gluggastjórinn +Comment[it]=Il Tab Window Manager +Comment[ja]=Tab 化ウィンドウマネージャ +Comment[ka]=X11 სისტემის ტრადიციული ფანჯრის მენეჯერი +Comment[kk]=Tab терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចជាផ្ទាំង +Comment[ko]=탭 창 관리자 +Comment[lt]=Kortelių langų tvarkyklė +Comment[lv]=Tabu logu menedžeris +Comment[mk]=Tab Window Manager +Comment[mn]=Tab Цонхны удирдагч +Comment[ms]=Pengurus Tetingkap Tab +Comment[mt]=Tab Window Manager +Comment[nb]=Tab Vindusbehandler +Comment[nds]=De Tab-Finsterpleger +Comment[ne]=ट्याब सञ्झ्याल प्रबन्धक +Comment[nl]=De Tab Window Manager +Comment[nn]=Tab Window Manager +Comment[pa]=ਟੈਬ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Tab Window Manager +Comment[pt]=O Tab Window Manager +Comment[pt_BR]=O Gerenciador de Janelas de Abas +Comment[ro]=Tab Window Manager +Comment[ru]=Традиционный оконный менеджер системы X11 +Comment[rw]=Mugenga Dirishya Agafishi +Comment[se]=Tab-láse lásegieđahalli +Comment[sk]=Správca okien s kartami +Comment[sl]=Tab Window Manager, okenski upravitelj z zavihki +Comment[sv]=Flikfönsterhanteraren +Comment[ta]=டாப் சாளர மேலாளர் +Comment[te]=టాబ్ విండొ అభికర్త +Comment[tg]=Tab-и мудири тиреза +Comment[th]=Tab Window Manager +Comment[tr]=Tab Pencere Yöneticisi +Comment[tt]=X11 sistemendäge kebek tabaqlı täräzä-idäräçe +Comment[uk]=Tab Window Manager +Comment[vi]=Trình Quản lý Cửa sổ Thẻ +Comment[wa]=Li manaedjeu di purneas avou Linwetes (Tab Window Manager) +Comment[zh_CN]=标签式窗口管理器 +Comment[zh_TW]=Tab 視窗管理程式 diff --git a/kdm/kfrontend/sessions/ude.desktop b/kdm/kfrontend/sessions/ude.desktop new file mode 100644 index 000000000..fb451da1a --- /dev/null +++ b/kdm/kfrontend/sessions/ude.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Type=XSession +Exec=ude +TryExec=ude +Name=UDE +Name[eo]=ULĈ +Name[hi]=यूडीई +Name[te]=యుడిఈ +Comment=The UNIX Desktop Environment +Comment[af]=Die 'Unix Desktop Environment' +Comment[ar]=بيئة سطح مكتب يونكس +Comment[be]=Працоўнае асяроддзе UNIX +Comment[bn]=দি ইউনিক্স ডেস্কটপ এনভায়রনমেন্ট +Comment[br]=An endro burev UNIX +Comment[bs]=UNIX Desktop Environment +Comment[ca]=L'entorn d'escriptori de Unix +Comment[csb]=Òkrãże pùltu Uniksa +Comment[cy]=Yr Amgylchedd Penbwrdd UNIX +Comment[da]=UNIX desktopmiljø +Comment[de]=Das UNIX Desktop Environment +Comment[el]=Το περιβάλλον επιφάνειας εργασίας του UNIX +Comment[eo]=La Uniksa Labortablo Ĉirkauaĵo +Comment[es]=El UNIX Desktop Environment +Comment[et]=UNIXi töölaua keskkond +Comment[eu]=UNIX mahaigain ingurunea +Comment[fa]=محیط رومیزی یونیکس +Comment[fi]=UNIX-työpöytäympäristö +Comment[fy]=De Unix Desktop Environment +Comment[ga]=Timpeallacht Deisce UNIX (UDE) +Comment[gl]=O Entorno de Escritório de UNIX +Comment[hi]=यूनिक्स डेस्कटॉप माहौल +Comment[hr]=UNIX radno okruženje +Comment[hu]=UNIX Desktop Environment ablakkezelő +Comment[is]=UNIX skjáborðsumhverfið +Comment[it]=Lo Unix Desktop Environment +Comment[ja]=UNIX デスクトップ環境 +Comment[ka]=UNIX-ის სამუშაო გარემო +Comment[kk]=UNIX Desktop Environment +Comment[km]=UNIX Desktop Environment +Comment[ko]=UNIX 데스크톱 환경 +Comment[lt]=UNIX darbastalio aplinka +Comment[lv]= UNIX Darba virsmas vide +Comment[mk]=UNIX Desktop Environment +Comment[mn]=ЮНИКС ажлын тавцангийн орчин +Comment[ms]=Persekitaran Desktop UNIX +Comment[mt]=UNIX Desktop Environment +Comment[nb]=UNIX Desktop Environment +Comment[nds]=De UNIX-Schriefdisch-Ümgeven +Comment[ne]=युनिक्स डेस्कटप वातावरण +Comment[nl]=De Unix Desktop Environment +Comment[nn]=UNIX Desktop Environment +Comment[pa]=UNIX Desktop Environment +Comment[pl]=Środowisko pulpitu Uniksa +Comment[pt]=O Unix Desktop Environment +Comment[pt_BR]=Ambiente de Trabalho do UNIX +Comment[ro]=Mediul grafic UNIX +Comment[ru]=UNIX Desktop Environment +Comment[rw]=Ibikikije Ibiro UNIX +Comment[se]=UNIX Desktop Environment +Comment[sl]=Namizno okolje UNIX +Comment[sr]=Unix радно окружење +Comment[sr@Latn]=Unix radno okruženje +Comment[sv]=Unix-skrivbordsmiljön +Comment[ta]=யுனிக்ஸ் மேல்மேசை சூழல் +Comment[te]=యూనిక్స్ రంగస్థల పర్యావరణం +Comment[tg]=Атрофи мизи кории UNIX +Comment[th]=สภาพแวดล้อมเดสก์ทอป UNIX +Comment[tr]=Unix Masaüstü Ortamı +Comment[tt]=UNIX Desktop Environment +Comment[uz]=Unix ish stoli muhiti (Unix Desktop Environment) +Comment[uz@cyrillic]=Unix иш столи муҳити (Unix Desktop Environment) +Comment[vi]=Môi trường Màn hình nền UNIX +Comment[wa]=L' evironmint di scribanne Unix UDE +Comment[zh_CN]=UNIX 桌面环境 +Comment[zh_TW]=Unix 桌面環境 diff --git a/kdm/kfrontend/sessions/vtwm.desktop b/kdm/kfrontend/sessions/vtwm.desktop new file mode 100644 index 000000000..50af40a63 --- /dev/null +++ b/kdm/kfrontend/sessions/vtwm.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=vtwm +TryExec=vtwm +Name=VTWM +Name[eo]=VTFA +Name[hi]=वीटीडबल्यूएम +Name[te]= వి టి డబ్ల్యు ఎం +Comment=The Virtual Tab Window Manager. TWM enhanced by virtual screens, etc. +Comment[af]=Die virtuele tab venster bestuurder. TWM wat met virtuele skerms uitgebreik is. +Comment[ar]=مدير نوافذ Tab الوهمي، مدير نوافذ TWM محسّن بأسطح المكتب الوهمية، إلخ. +Comment[be]=Віртуальны кіраўнік вокнаў з укладкамі Virtual Tab Window Manager. TWM, з дадатковай падтрымкай віртуальных экранаў і інш. +Comment[bn]=ভার্চুয়াল ট্যাব উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ ইত্যাদি দ্বারা বর্ধিত +Comment[bs]=Virtual Tab Window Manager. TWM proširen virtuelnim ekranima itd. +Comment[ca]=El Virtual Tab Window Manager. TWM millorat per a pantalles virtuals, etc. +Comment[cs]=The Virtual Tab Window Manager. TWM vylepšené o virtuální obrazovky aj. +Comment[csb]=Virtual Tab Window Manager. TWM zbògacony ò wirtualné pùltë ëtp. +Comment[cy]=Y Trefnydd Ffenestri Tab Rhith. TWM wedi'i wella gan sgriniau rhith, ayyb. +Comment[da]=Virtual Tab Window Manager. TWM udvidet med virtuelle skærme osv. +Comment[de]=Der Virtual-Tab-Fenstermanager, eine Erweiterung von TWM mit virtuellen Arbeitsflächen usw. +Comment[el]=Ο εικονικός Tab διαχειριστής παραθύρων. Ο TWM εμπλουτισμένος με εικονικές οθόνες, κτλ. +Comment[eo]=La Virtuala Taba Fenestroadministrilo, TFA plibonigita per virtualaj ekranoj +Comment[es]=El Virtual Tab Window Manager, TWM mejorado con pantallas virtuales, etc. +Comment[et]=Virtuaalsete kaartidega aknahaldur ehk TWM, mida on täiendatud virtuaalsete ekraanidega jne. +Comment[eu]=Virtual Tab leiho kudeatzailea. Pantaila birtual eta abarrez hobetutako TWM-a +Comment[fa]=یک مدیر پنجرۀ تب مجازی.TWM گسترشیافته توسط پردههای مجازی و غیره. +Comment[fi]=Välilehtiä ja virtuaalityöpöytiä tukeva ikkunaohjelma, pohjautuu TWM:ään +Comment[fr]=The Virtual Tab Window Manager. TWM avec en plus la gestion des bureaux multiples +Comment[fy]=De firtuele Ljepper Window Manager. TWM útbreid mei firtuele buroblêden, ensfh. +Comment[gl]=O Virtual Tab Window Manager. TWM mellorado con pantallas virtuais, etc. +Comment[he]=The Virtual Tab Window Manager. TWM המשופר בשולחנות עבודה וירטואליים וכו' +Comment[hi]=आभासी टैब विंडो प्रबंधक. TWM को आभासी स्क्रीन इत्यादि से बेहतर बनाया गया +Comment[hr]=Comment=Virtual Tab Window Manager. TWM poboljšan virtualnim zaslonima itd. +Comment[hu]=Virtual Tab Window Manager, egy TWM-változat, támogatja a virtuális képernyőkezelést +Comment[is]=Tab gluggastjórinn endurbættur með sýndarskjám og fleiru. +Comment[it]=Il Virtual Tab Window Manager. TWM migliorato con schermi virtuali ecc. +Comment[ja]=仮想スクリーンなどの機能を拡張した TWM ベースの仮想タブウィンドウマネージャ +Comment[ka]=ვირტუალური ეკრანებით აღჭურვილი TWM-ის ვარიანტი +Comment[kk]=Virtual Tab Window Manager. TWM-негіздеген, виртуалды экрандары және т.б.с.с бар терезе менеджері. +Comment[km]=Virtual Tab Window Manager ។ TWM ដែលបានធ្វើឲ្យប្រសើរដោយអេក្រង់និមិត្ត ជាដើម ។ +Comment[lt]=Virtualių kortelių darbastalio aplinka. TWM išplėsta virtualiais darbastaliais ir pan. +Comment[lv]=Virtuālo tabu logu menedžeris. TWM papildināts ar virtuālajiem ekrāniem utml. +Comment[mk]=Virtual Tab Window Manager. TWM подобрен со виртуелни површини итн. +Comment[ms]=Pengurus Tetingkap Tab Maya. TWM dipertingkat dengan skrin maya, dsb. +Comment[mt]=Virtual Tab Window Manager. TWM flimkien ma' desktops virtwali eċċ +Comment[nb]=Virtual Tab vindusbehandler. TWM utvidet med virtuelle skjermer, osv. +Comment[nds]=De "Virtual Tab Window Manager". Dat is TWM verwiedert üm virtuelle Schirmen etc. +Comment[ne]=अवास्तविक ट्याब सञ्झ्याल प्रबन्धक । अवास्तविक पर्दाद्वारा बृद्धि गरिएको TWM, आदि +Comment[nl]=De Virtual Tab Window Manager. TWM uitgebreid met virtuele bureaubladen, etc. +Comment[nn]=Virtual Tab Window Manager. TWM utvida med virtuelle skjermar og anna. +Comment[pa]=Virtual Tab Window Manager. TWM ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਨਾਲ ਲੈੱਸ +Comment[pl]=Virtual Tab Window Manager. TWM wzbogacony o wirtualne pulpity itp. +Comment[pt]=O Virtual Tab Window Manager. Um TWM melhorado com ecrãs virtuais, etc. +Comment[pt_BR]=O gerenciador de janelas de abas virtuais. TWM melhorado pelas telas virtuais. +Comment[ro]=Virtual Tab Window Manager. TWM îmbunătățit cu ecrane virtuale etc. +Comment[ru]=Вариант TWM, имеющий виртуальные экраны и т.д. +Comment[rw]=Mugenga Dirishya y'Agafishi Itaboneka.TWM ivuguruwe na mugaragaza zitagaragara, n'ibindi. +Comment[se]=The Virtual Tab Window Manager. TWM buoriduvvon virtuella čállinbevddiin, jna. +Comment[sk]=The Virtual Tab Window Manager. TWM rozšírený o virtuálne obrazovky atď. +Comment[sl]=Virtual Tab Window Manager. TWM, izboljšan z navideznimi zasloni ipd. +Comment[sr]=„The Virtual Tab Window Manager“. TWM побољшан виртуелним екранима и сл. +Comment[sr@Latn]=„The Virtual Tab Window Manager“. TWM poboljšan virtuelnim ekranima i sl. +Comment[sv]=Virtuell flikfönsterhanterare. TWM utökad med virtuella skärmar, etc. +Comment[ta]=மெய்நிகர் தத்தல் சாளர மேலாளர். TWM மெய்நிகர் திரைகளால் மேம்படுத்தப்பட்டது. +Comment[th]=The Virtual Tab Window Manager คือ TWM ที่เพิ่มความสามารถโดยหน้าจอเสมือน และอื่นๆ +Comment[tr]=Virtual Tab Masaüstü Yöneticisi. +Comment[tt]=Virtual Tab Window Manager. Öställär östälengän TWM kebek. +Comment[uk]=Virtual Tab Window Manager. TWM з підтримкою віртуальних екранів. +Comment[vi]=Trình Quản lý Cửa sổ Thẻ Ảo. TWM cải tiến với màn hình ảo, ... +Comment[wa]=Li Forveyou Manaedjeu di Purneas avou Linwetes (Virtual Tab Window Manager). TWM a sacwants forveyowès waitroûles, evnd. +Comment[zh_CN]=虚拟标签式窗口管理器。用虚拟屏幕等功能增强的 TWM。 +Comment[zh_TW]=虛擬 Tab 視窗管理程式。基於 TWM 並加強虛擬螢幕等等。 diff --git a/kdm/kfrontend/sessions/w9wm.desktop b/kdm/kfrontend/sessions/w9wm.desktop new file mode 100644 index 000000000..92633bcf7 --- /dev/null +++ b/kdm/kfrontend/sessions/w9wm.desktop @@ -0,0 +1,74 @@ +[Desktop Entry] +Type=XSession +Exec=w9wm +TryExec=w9wm +Name=W9WM +Name[eo]=F9FA +Name[hi]=डबल्यू9डबल्यूएम +Name[ta]=IceWM +Name[te]=డబ్ల్యు 9 డబ్ల్యు ఎం +Name[th]=ตัวจัดการหน้าต่าง W9WM +Comment=A window manager based on 9WM, enhanced by virtual screens and keyboard bindings +Comment[af]='n Venster bestuurder wat op 9WM gebaseer is, uitgebrei met virtuele skerms en sleutelbord bindinge +Comment[ar]=مدير نوافذ مبني على 9WM، محسّن الشاشات الوهمية والمفاتيح المرتبطة +Comment[be]=Кіраўнік вокнаў, заснаваны на 9WM, з дадатковай падтрымкай віртуальных экранаў і клавішных скаротаў +Comment[bn]=9WM ভিত্তিক উইণ্ডো ম্যানেজার, ভার্চুয়াল স্ক্রীণ এবং কীবোর্ড বাইন্ডিং দ্বারা বর্ধিত +Comment[bs]=Window manager baziran na 9WM, proširen virtuelnim ekranima i prečicama tastature +Comment[ca]=Un gestor de finestres basat en 9WM, millorat per a pantalles virtuals i amb dreceres de teclat +Comment[cs]=Správce oken založený na 9WM rozšířený o virtuální plochy a klávesové zkratky +Comment[csb]=Menedżer òknów òpiarty na 9WM, zbògacony ò wirtualné ekranë ë kònfigùracëjã klawiszowëch skrodzënów +Comment[cy]=Trefnydd ffenestri wedi'i seilio ar 9WM, wedi'i wella gan sgriniau rhith a rhwymiadau bysyll. +Comment[da]=En vindueshåndtering baseret på 9WM, udvidet med virtuelle skærme og tastaturbindinger +Comment[de]=Fenstermanager auf der Basis von 9WM, erweitert durch virtuelle Arbeitsflächen und Tastaturzuordnungen +Comment[el]=Ένας διαχειριστής παραθύρων βασισμένος στον 9WM, εμπλουτισμένος με εικονικές οθόνες και συνδυασμούς πλήκτρων +Comment[eo]=Fenestroadministrilo devenigita de 9FA, plibonigita per virtualaj ekranoj kaj klaviara uzo +Comment[es]=Un gestor de ventanas basado en 9WM, mejorado con ventanas virtuales y accesos rápidos de teclado +Comment[et]=Aknahaldur, mille aluseks on 9WM ja mida on täiendatud virtuaalsete ekraanide ja kiirklahvide võimalusega +Comment[eu]=9WM-n oinarritutako leiho kudeatzailea, pantaila birtual eta laster-teklez hobetua +Comment[fa]=یک مدیر پنجره بر اساس 9WM، گسترشیافته توسط پردههای مجازی و مقیدسازیهای صفحه کلید +Comment[fi]=9WM:ään pohjautuva ikkunaohjelma, jossa tuki virtuaalityöpöydille ja näppäimistöyhdistelmille +Comment[fr]=Un gestionnaire de fenêtres fondé sur 9WM, avec en plus la gestion des bureaux virtuels et des raccourcis clavier +Comment[fy]=In finstersmanager basearrre op 9WM. útbreid mei firtuele buroblêden en fluchtoetsen +Comment[gl]=Un xestor de fiestras baseado en 9WM, mellorado polas pantallas virtuais e atallos de teclado +Comment[he]=מנהל חלונות המבוסס על 9WM, המשופר בשולחנות עבודה וירטואליים ומיפוי מקשים +Comment[hi]= 9डबल्यूएम आधारित विंडो प्रबंधक, आभासी स्क्रीन तथा की-बोर्ड बाइंडिंग से बेहतर बनाया गया +Comment[hr]=Upravitelj prozora zasnovan na 9WM, unaprijeđen virtualnim zaslonima i prečacima tipkovnice +Comment[hu]=Egy 9WM-alapú ablakkezelő, virtuális képernyőkezeléssel, konfigurálható billentyűparancsokkal +Comment[is]=Gluggastjóri byggður á 9WM en endurbættur með sýndarskjám og lyklaborðsvörpunum +Comment[it]=Un window manager basato su 9WM, migliorato con schermi virtuali e scorciatoie per la tastiera. +Comment[ja]=仮想スクリーンとキーボードショートカット機能を強化した 9WM ベースのウィンドウマネージャ +Comment[ka]=ფანჯრის მენეჯერი 9wm-ს ბაზაზე, ვირტუალური ეკრანებით და კლავიატურის შესაბამისობებით +Comment[kk]=9WM-негіздеген, виртуалды экрандары, пернетақта тіркесімдері бар терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចផ្អែកលើ 9WM ដែលត្រូវបានធ្វើឲ្យប្រសើរដោយអេក្រង់និមិត្ត និងការចងគ្រាប់ចុច +Comment[ko]=부분적 그놈 지원과 가상 데스크톱 지원을 사용하는 AEWM 기반 창 관리자 +Comment[lt]=Langų tvarkyklė, paremta 9WM, išplėsta virtualių ekranų ir klaviatūros greitųjų klavišų palaikymu +Comment[lv]=Logu menedžeris bāzēts uz 9WM, papildināts ar virtuālajiem ekrāniem un tastatūras saīsnēm +Comment[mk]=Менаџер на прозорци базиран на 9WM, подобрен со виртуелни површини и поврзувања за тастатурата +Comment[ms]=Pengurus tetingkap berdasarkan 9WM, dipertingkat dengan skrin maya dan ikatan papan kekunci +Comment[mt]=Window manager ibbażat fuq 9WM, flimkien ma desktops virtwali u hotkeys +Comment[nb]=En vindusbehandler basert på 9WM, forbedret med virtuelle skjermer og hurtigtaster +Comment[nds]=En Finsterpleger opbuut op 9WM, verwiedert üm virtuelle Schirmen un Tastkombinatschonen +Comment[ne]=कुञ्जीपाटी बाइन्डिङ र अवास्तविक पर्दाहरूद्वारा बृद्धि गरिएको 9WM मा आधारित सञ्झ्याल प्रबन्धक +Comment[nl]=Een windowmanager gebaseerd op 9WM. Uitgebreid met virtuele bureaubladen en sneltoetsen +Comment[nn]=Ein vindaugssjef basert på 9WM, forbetra med virtuelle skjermar og snøggtastar +Comment[pa]=9WM ਤੇ ਆਧਾਰਿਤ ਝਰੋਖਾ ਮੈਨੇਜਰ, ਫਰਜ਼ੀ ਪਰਦਿਆਂ ਤੇ ਕੀ-ਬੋਰਡ ਬਾਈਡਿੰਗ ਨਾਲ ਲੈੱਸ +Comment[pl]=Menedżer okien oparty na 9WM, wzbogacony o wirtualne ekrany i konfigurowanie skrótów klawiszowych +Comment[pt]=Um gestor de janelas baseado no 9WM, melhorado com ecrãs virtuais e atalhos de teclado +Comment[pt_BR]=Um gerenciador de janelas baseado no 9Wm, melhorado pelas telas virtuais e atalhos de teclado +Comment[ro]=Un manager de ferestre bazat pe 9WM, îmbunătățir cu ecrane virtuale și acceleratori de tastatură +Comment[ru]=Оконный менеджер на основе 9wm, имеющий виртуальные экраны и привязку клавиш +Comment[rw]=Mugenga Dirishya ishingiye kuri 9WM, ivuguruwe hakoreshejwe mugaragaza itaboneka n'amahuza mwandikisho +Comment[sk]=Správca okien založený na 9WM, rozšírený o virtuálne obrazovkya klávesové skratky +Comment[sl]=Okenski upravitelj na osnovi 9WM, izboljšan z navideznimi zasloni in tipkovnimi vezmi +Comment[sr]=Менаџер прозора заснован на 9WM-у, побољшан виртуелним екранима и повезивањем тастатуре +Comment[sr@Latn]=Menadžer prozora zasnovan na 9WM-u, poboljšan virtuelnim ekranima i povezivanjem tastature +Comment[sv]=Fönsterhanterare baserad på 9WM, utökad med virtuella skärmar och tangentbindingar +Comment[ta]=9WM அடிப்படையிலான மெய்நிகர் திரை மற்றும் விசைப்பலகை சேர்ப்புகளால் மேம்படுத்தப்பட்ட சாளர மேலாளார், +Comment[th]=ระบบจัดการหน้าต่างที่สร้างมาจาก 9WM และเพิ่มความสามารถด้วยหน้าจอเสมือนและแป้นพิมพ์ลัด +Comment[tr]=9WM tabanlı, sanal ekranları ve klavye kısayolları ile geliştirilmiş bir masaüstü yöneticisi +Comment[tt]=Xıyalí öställär belän töylekne totqan täräzä-idäräçe. 9WM asılında +Comment[uk]=Менеджер вікон, заснований на 9WM, додано віртуальні екрани та прив'язки клавіш +Comment[vi]=Trình quản lý cửa sổ dựa vào 9WM, cải tiến với màn hình ảo, tổ hợp phím +Comment[wa]=On manaedjeu di purneas båzé so 9WM, avou sopoirt po les forveyous scribannes eyet les rascourtis di taprece. +Comment[zh_CN]=基于 9WM 的窗口管理器,用虚拟屏幕和键盘绑定等功能增强了 +Comment[zh_TW]=一個基於 9WM 並加強虛擬螢幕及鍵盤組合鍵功能 diff --git a/kdm/kfrontend/sessions/waimea.desktop b/kdm/kfrontend/sessions/waimea.desktop new file mode 100644 index 000000000..8981b5af6 --- /dev/null +++ b/kdm/kfrontend/sessions/waimea.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=waimea +TryExec=waimea +Name=Waimea +Name[eo]=Vaimeo +Name[hi]=वाईमिया +Name[ne]=विमेआ +Name[pa]=ਵਾਈਮਿਆ +Name[te]=వైమెయా +Comment=A highly customizable window manager based on Blackbox +Comment[af]='n Hoë opstelbare venster bestuurder wat op Blackbox gebaseer is +Comment[ar]=مدير نوافذ قابل جداً للتخصيص مبني على Blackbox +Comment[be]=Кіраўнік вокнаў, заснаваны на Blackbox, з магчымасцю настаўлення +Comment[bn]=ব্ল্যাকবক্স ভিত্তিক উইণ্ডো ম্যানেজার +Comment[bs]=Visoko prilagodljiv window manager baziran na Blackbox +Comment[ca]=Un gestor de finestres altament configurable basat en Blackbox +Comment[cs]=Vysoce přizpůsobitelný správce oken založený na Blackboxu +Comment[csb]=Menedżer òknów òpiartëch na Blackbox z wiôldżima mòżnotama dopasowaniô +Comment[cy]=Trefnydd ffenestri sy'n hawdd ei ffurfweddu, wedi'i seilio ar Ddu-flwch +Comment[da]=En meget indstillelig vindueshåndtering baseret på Blackbox +Comment[de]=Vielfältig anpassbarer Fenstermanager, der auf Blackbox basiert +Comment[el]=Ένας ιδιαίτερα παραμετροποιήσιμος διαχειριστής παραθύρων βασισμένος στον Blackbox +Comment[en_GB]=A highly customisable window manager based on Blackbox +Comment[eo]=Tre agordebla fenestroadministrilo, devenigita de Negrujo +Comment[es]=Un gestor de ventanas muy personalizable basado en Blackbox +Comment[et]=Väga hästi kohandatav aknahaldur, aluseks Blackbox +Comment[eu]=Blackboxen oinarritutako leiho-kudeatzaile zeharo pertsonalizagarria +Comment[fa]=یک مدیر پنجره با قابلیت سفارشیسازی بالا بر اساس Blackbox +Comment[fi]=Blackboxiin perustuva paljon muokattavissa oleva ikkunaohjelma +Comment[fr]=Un gestionnaire de fenêtres très configurable fondé sur Blackbox +Comment[fy]=In tige ynstelbere finstersmanager, basearre op Blackbox +Comment[gl]=Un xestor de fiestras moi personalizábel baseado en Blackbox +Comment[he]=מנהל חלונות המאפשר התאמה אישית גבוהה והמבוסס על Blackbox +Comment[hi]=ब्लेक-बाक्स आधारित, अत्यंत कस्टमाइजेबल विंडो प्रबंधक +Comment[hr]=Vrlo prilagodljiv upravitelj prozora zasnovan na Blackboxu +Comment[hu]=Egy sokféle beállítási lehetőséggel rendelkező ablakkezelő a Blackbox alapján +Comment[is]=Afar stillanlegur gluggastjóri byggður á Blackbox +Comment[it]=Un window manager molto personalizzabile basato su BlackBox +Comment[ja]=Blackbox ベースの高度なカスタマイズが可能なウィンドウマネージャ +Comment[ka]=კონფიგურირებადი ფანჯრის მენეჯერი Blackbox-ს ბაზაზე +Comment[kk]=Blackbox-негіздеген, баптау жағынан бай, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចដែលអាចប្ដូរតាមបំណងកម្រិតខ្ពស់ ដោយផ្អែកលើ Blackbox +Comment[ko]=Blackbox 기반의 사용자 정의가 가능한 관리자 +Comment[lt]=Daug konfigūravimo parinkčių turinti langų tvarkyklė, paremta Blackbox +Comment[lv]=Plaši konfigurējams logu menedžeris bāzēts uz Blackbox +Comment[mk]=Менаџер на прозорци базиран на Blackbox со голем број опции +Comment[ms]=Pengurus tetingkap boleh suai berdasarkan Kotak Hitam +Comment[mt]=Window manager konfigurabbli ibbażat fuq BlackBox +Comment[nb]=En vindusbehandler med mange tilpasninger, basert på Blackbox +Comment[nds]=En Finsterpleger mit mennige Instellen, opbuut op Blackbox +Comment[ne]=कालो बाकसमा आधारित उच्च अनुकूल योग्य एक सञ्झ्याल प्रबन्धक +Comment[nl]=Een zeer instelbare windowmanager, gebaseerd op Blackbox +Comment[nn]=Ein vindaugssjef med mange tilpassingar, basert på Blackbox +Comment[pa]=ਬਲੈਕਬਕਸੇ 'ਤੇ ਆਧਾਰਿਤ ਅਤਿ ਸੋਧਯਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Menedżer okien oparty na Blackbox z dużymi możliwościami dostosowania +Comment[pt]=Um gestor de janelas altamente configurável, baseado no Blackbox +Comment[pt_BR]=Um gerenciador de janelas altamente personalizável, baseado no Blackbox +Comment[ro]=Un manager de ferestre foarte configurabil bazat pe Blackbox +Comment[ru]=Настраиваемый оконный менеджер, основанный на Blackbox +Comment[rw]=Mugenga dirishya ihabwa imiterere yifuzwa mu buryo hejuru ishingiye ku Gasandukumukara +Comment[sk]=Veľmi prispôsobiteľný správca okien založený na Blackbox +Comment[sl]=Visoko nastavljiv okenski upravitelj na osnovi Blackboxa +Comment[sr]=Врло прилагодљив менаџер прозора заснован на Blackbox-у +Comment[sr@Latn]=Vrlo prilagodljiv menadžer prozora zasnovan na Blackbox-u +Comment[sv]=Ytterst anpassningsbar fönsterhanterare baserad på Blackbox +Comment[ta]=தனதாக்க வல்ல கருப்புப்பெட்டி சார்ந்த சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าต่างที่ปรับแต่งได้อย่างละเอียด สร้างมาจาก Blackbox +Comment[tr]=Blackbox temelli, kolayca özelleştirilebilir bir pencere yöneticisi +Comment[tt]=Yaqşı köylänüçän täräzä-idäräçe. Blackbox asılında +Comment[uk]=Надгнучкий менеджер вікон, заснований на Blackbox +Comment[uz]=Blackbox asosida yaratilgan, moslab boʻladigan oyna boshqaruvchi +Comment[uz@cyrillic]=Blackbox асосида яратилган, мослаб бўладиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ rất dễ cá nhân hoá dựa trên Blackbox +Comment[wa]=On manaedjeu di purneas k' vos ploz pår mete da vosse båzé so Blackbox +Comment[zh_CN]=基于 BlackBox 可高度自定义的窗口管理器 +Comment[zh_TW]=一個基於 Blackbox 且高度可客製化的視窗管理程式 diff --git a/kdm/kfrontend/sessions/wm2.desktop b/kdm/kfrontend/sessions/wm2.desktop new file mode 100644 index 000000000..618c10bcc --- /dev/null +++ b/kdm/kfrontend/sessions/wm2.desktop @@ -0,0 +1,77 @@ +[Desktop Entry] +Type=XSession +Exec=wm2 +TryExec=wm2 +Name=WM2 +Name[eo]=Fa2 +Name[hi]=डबल्यूएम2 +Name[te]=డబ్ల్యు ఎం 2 +Name[th]=ตัวจัดการหน้าต่าง WM2 +Comment=A small, non-configurable window manager +Comment[af]='n Klein, nie opstelbare venster bestuurder +Comment[ar]=مدير نوافذ صغير غير قابل للإعداد +Comment[be]=Маленькі кіраўнік вокнаў, без магчымасці настаўленняў +Comment[bn]=একটি ছোটো উইণ্ডো ম্যানেজার +Comment[bs]=Mali, ne-konfigurabilni window manager +Comment[ca]=Un petit i no configurable gestor de finestres +Comment[cs]=Malý nepřizpůsobitelný správce oken +Comment[csb]=Môłi menedżer òknów bez mòżnotë kònfigùracëji +Comment[cy]=Trefnydd ffenestri bach na ellir ffurfweddu +Comment[da]=En lille, ikke-indstillelig vindueshåndtering +Comment[de]=Kleiner, nicht einstellbarer Fenstermanager +Comment[el]=Ένας μικρός, μη παραμετροποιήσιμος διαχειριστής παραθύρων +Comment[eo]=Malgranda, ne agordebla fenestroadministrilo +Comment[es]=Un gestor de ventanas pequeño y no configurable +Comment[et]=Väike ja seadistamatu aknahaldur +Comment[eu]=Leiho-kudeatzaile txikia, konfiguratu ezin dena +Comment[fa]=یک مدیر پنجرۀ کوچک و غیرقابل پیکربندی +Comment[fi]=Pieni ikkunaohjelma, jossa ei ole asetuksia +Comment[fr]=Un gestionnaire de fenêtres petit et non configurable +Comment[fy]=In lytse, net-ynstelbere finstersmanager +Comment[gl]=Un xestor de fiestras pequeno non configurábel +Comment[he]=מנהל חלונות קטן ולא ניתן להגדרה +Comment[hi]=एक छोटा विंडो प्रबंधक जो कॉन्फ़िगर नहीं हो सकता +Comment[hr]=Malen, nepodesiv upravitelj prozora +Comment[hu]=Egy nagyon egyszerű ablakkezelő, beállítási lehetőségek nélkül +Comment[is]=Lítill, einfaldur gluggastjóri sem er ekki hægt að stilla +Comment[it]=Un window manager piccolo e non configurabile +Comment[ja]=小さくて設定項目のないウィンドウマネージャ +Comment[ka]=პატარა და არაკონფიგურირებადი ფანჯრის მენეჯერი +Comment[kk]=Шағын, баптауы жоқ, терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចតូច ហើយមិនអាចកំណត់រចនាសម្ព័ន្ធបាន +Comment[ko]=설정할 수 없는 작은 창 관리자 +Comment[lt]=Maža, nekonfigūruojama langų tvarkyklė +Comment[lv]=Mazs, nekonfigurējams logu menedžeris +Comment[mk]=Мал и неконфигурабилен менаџер на прозорци +Comment[mn]=Жижиг тохируулах боломжгүй цонх удирдагч +Comment[ms]=Pengurus tetingkap yang kecil dan tidak boleh konfigur +Comment[mt]=Window manager żgħir u mhux konfigurabbli +Comment[nb]=En liten vindusbehandler uten tilpasninger +Comment[nds]=En lütte Finsterpleger ahn Instellen +Comment[ne]=सानो, कन्फिगर गर्न नसकिने सञ्झ्याल प्रबन्धक +Comment[nl]=Een kleine, niet-instelbare windowmanager +Comment[nn]=Ein liten vindaugssjef utan tilpassingar +Comment[pa]=ਇੱਕ ਹਲਕਾ ਨਾ-ਸੋਧਯੋਗ ਝਰੋਖਾ ਮੈਨੇਜਰ +Comment[pl]=Mały menedżer okien nie podlegający konfiguracji +Comment[pt]=Um gestor de janelas pequeno e não-configurável +Comment[pt_BR]=Um pequeno e não-configurável gerenciador de janelas +Comment[ro]=Un manager de ferestre mic, neconfigurabil +Comment[ru]=Маленький, не настраиваемый оконный менеджер +Comment[rw]=Mugenga Dirishya itabonezwa, ntoya +Comment[se]=Unna, ii heivehahtti lásegieđahalli +Comment[sk]=Malý, nenastaviteľný správca okien +Comment[sl]=Majhen, nenastavljiv okenski upravitelj +Comment[sr]=Мали, неподесиви менаџер прозора +Comment[sr@Latn]=Mali, nepodesivi menadžer prozora +Comment[sv]=Liten fönsterhanterare utan anpassningsmöjligheter +Comment[ta]=சிறிய, வடிவமைக்க முடியாத சாளர மேலாளர் +Comment[th]=ระบบจัดการหน้าที่ขนาดเล็ก ที่ไม่สามารถปรับแต่งอะไรได้ +Comment[tr]=Küçük ve yapılandırılamayan bir pencere yöneticisi +Comment[tt]=Caylanmí torğan keçkenä täräzä-idäräçe +Comment[uk]=Невеличкий менеджер вікон без можливості налаштування +Comment[uz]=Kichik, moslab boʻlmaydigan oyna boshqaruvchi +Comment[uz@cyrillic]=Кичик, мослаб бўлмайдиган ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ nhỏ, không cấu hình được +Comment[wa]=On ptit, nén apontiåve, manaedjeu di purneas +Comment[zh_CN]=小巧的不可配置的窗口管理器 +Comment[zh_TW]=一個小型且不可組態的視窗管理者 diff --git a/kdm/kfrontend/sessions/wmaker.desktop b/kdm/kfrontend/sessions/wmaker.desktop new file mode 100644 index 000000000..fada3d3b5 --- /dev/null +++ b/kdm/kfrontend/sessions/wmaker.desktop @@ -0,0 +1,82 @@ +[Desktop Entry] +Type=XSession +Exec=wmaker +TryExec=wmaker +Name=WindowMaker +Name[bn]=উইণ্ডো-মেকার +Name[cy]=GwneuthuryddFfenestri (WindowMaker) +Name[eo]=Fenestroadministrilo +Name[hi]=विंडोमेकर +Name[ne]=सञ्झ्याल निर्माता +Name[pa]=ਝਰੋਖਾ-ਨਿਰਮਾਤਾ +Name[rw]=MukoraDirishya +Name[sv]=Windowmaker +Name[ta]=விண்டோஸ்மேக்கர் +Name[te]=విండొమెకర్ +Name[tg]=Созандаи тиреза +Comment=A simple window manager that resembles the NeXTStep look very closely +Comment[af]='n Eenvoudige venster bestuurder wat soos NeXTStep lyk +Comment[ar]=مدير نوافذ بسيط يمثّل مظهر NeXTStep بشكل قريب جداً +Comment[be]=Просты кіраўнік вокнаў, які вельмі дакладна паўтарае вонкавы выгляд NeXTStep +Comment[bn]=একটি উইণ্ডো ম্যানেজার যা ভীষণরকম NeXTStep-এর মত দেখতে +Comment[bs]=Jednostavan window manager koji vrlo dosljedno imitira NeXTStep izgled +Comment[ca]=Un gestor de finestres simple que s'assembla molt a l'aspecte de NeXTStep +Comment[cs]=Jendoduchý správce oken, který se velmi podobá NeXTStep +Comment[csb]=Prosti menedżer òknów szlachùjący za NeXTStep +Comment[cy]=Trefnydd ffenestri syml sy'n debyg iawn i'r golwg CamNesaf +Comment[da]=En simpel vindueshåndtering der ligner NeXTStep's udseende meget +Comment[de]=Einfacher Fenstermanager mit starker Ähnlichkeit zu NeXTStep +Comment[el]=Ένας απλός διαχειριστής παραθύρων που προσομοιώνει πολύ καλά το στυλ του NeXTStep +Comment[eo]=Simpla fenestroadministrilo +Comment[es]=Un gestor de ventanas sencillo cuyo aspecto se parece mucho al de NeXTStep +Comment[et]=Lihtne aknahaldur, mis meenutab väga tugevasti NeXTStepi +Comment[eu]=Leiho kudeatzaile sinplea, NeXTStep-en antz handia duena +Comment[fa]=یک مدیر پنجرۀ ساده که خیلی شبیه گام بعدی است +Comment[fi]=Yksinkertainen ikkunaohjelma, joka muistuttaa erittäin paljon NeXTStepiltä +Comment[fr]=Un gestionnaire de fenêtres simple qui ressemble assez précisement à NeXTStep +Comment[fy]=In ienfâldige finstersmanager dy it úterlik fan NeXTStep saer tichtby benaderd +Comment[gl]=Un xestor de fiestras sinxelo que se achega moito á apariencia de NeXTStep +Comment[he]=מנהל חלונות פשוט הדומה מאוד במראה שלו ל־NeXTStep +Comment[hi]=नेक्स्टस्टेप की तरह दिखने वाला सादा विंडो प्रबंधक +Comment[hr]=Jednostavan upravitelj prozora koji odražava vrlo blisko izgled NeXTStepa +Comment[hu]=Egy egyszerű ablakkezelő, megjelenése nagyon hasonlít a NeXTStephez +Comment[is]=Einfaldur gluggastjóri sem líkir vel eftir NeXTStep umhverfinu +Comment[it]=Un semplice window manager che assomiglia molto a NeXTStep. +Comment[ja]=NextStep にとてもよく似たシンプルなウィンドウマネージャ +Comment[ka]=NeXTStep -ის მაგვარი მარტივი ფანჯრის მენეჯერი +Comment[kk]=Қарапайым, NeXTStep-ке үқсас терезе менеджері +Comment[km]=កម្មវិធីគ្រប់គ្រងបង្អួចធម្មតាមួយ ដែលប្រហាក់ប្រហែលនឹងរូបរាង NeXTStep បំផុត +Comment[lt]=Paprasta langų tvarkyklė, išvaizda labai primenanti NeXTStep +Comment[lv]=Vienkāršs logu menedžeris, kas ir ļoti līdzīgs NeXTStep +Comment[mk]=Едноставен менаџер на прозорци кој е многу сличен на изгледот на NeXTStep +Comment[ms]=Pengurus tetingkap ringkas yang memasang NeXTStep dan menjadikannya tampak sangat hampir +Comment[mt]=Window manager li jixbaħ ħafna lil NextStep +Comment[nb]=En enkel vindusbehandler som ligner mye på NeXTStep +Comment[nds]=En eenfache Finsterpleger, de meist utsüht as NeXTStep +Comment[ne]=NeXTStep जस्तो देखिने साधारण सञ्झ्याल प्रबन्धक +Comment[nl]=Een eenvoudige windowmanager die het uiterlijk van NeXTStep zeer dicht benaderd +Comment[nn]=Ein enkel vindaugssjef som liknar mykje på NeXTStep +Comment[pa]=ਇੱਕ ਸਧਾਰਨ ਜੋ ਕਿ NeXTStep ਵਰਗਾ ਜਾਪਦਾ ਹੈ +Comment[pl]=Prosty menedżer okien przypominający bardzo wyglądem NeXTStep +Comment[pt]=Um gestor de janelas simples que faz lembrar bastante o visual do NeXTStep +Comment[pt_BR]=Um gerenciador de janelas simples, que lembra a aparência do NeXTStep +Comment[ro]=Un manager de ferestre simplu, care amintește foarte bine de aspectul NeXTStep +Comment[ru]=Простой оконный менеджер, воспроизводящий интерфейс NeXTStep +Comment[rw]=Mugenga Dirishya yoroheje ihuriza hamwe imboneko IntambweIkurikira byegeranye cyane +Comment[se]=Oktageardánis lásegieđahalli mii sulástahttá NeXTStep hui ollu +Comment[sk]=Jednoduchý správca okien, ktorý veľmi pripojíma NeXTStep +Comment[sl]=Preprost okenski upravitelj, ki zelo spominja na izgled NeXTStep +Comment[sr]=Једноставан менаџер прозора који одражава врло блиско изглед NeXTStep-а +Comment[sr@Latn]=Jednostavan menadžer prozora koji odražava vrlo blisko izgled NeXTStep-a +Comment[sv]=Enkel fönsterhanterare som mycket nära efterliknar Nextstep-utseendet +Comment[ta]=NeXTStep ஐ ஒத்த எளிய சாளர மேலாளார். +Comment[th]=ระบบจัดการหน้าต่างแบบเรียบง่าย ที่ดูคล้ายระบบ NeXTStep มากๆ +Comment[tr]=NeXTStep'e aşırı benzeyen basit bir masaüstü yöneticisi +Comment[tt]=NeXTStep küreneşendä ciñel täräzä-idäräçe +Comment[uk]=Простий менеджер вікон, що дуже нагадує NeXTStep +Comment[uz]=NeXTStep'ga juda oʻxshash oddiy oyna boshqaruvchi +Comment[uz@cyrillic]=NeXTStep'га жуда ўхшаш оддий ойна бошқарувчи +Comment[vi]=Trình quản lý cửa sổ giống với NeXTStep +Comment[wa]=On simpe manaedjeu di purneas avou l' foite rivnance di NeXTStep +Comment[zh_CN]=非常接近 NeXTStep 外观的简单窗口管理器 +Comment[zh_TW]=一個小型且與 NeXTStep 外觀很接近的視窗管理程式 diff --git a/kdm/kfrontend/sessions/xfce.desktop b/kdm/kfrontend/sessions/xfce.desktop new file mode 100644 index 000000000..6b199228b --- /dev/null +++ b/kdm/kfrontend/sessions/xfce.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=XSession +Exec=xfwm +TryExec=xfwm +Name=XFce +Name[eo]=Facoj +Name[hi]=एक्सएफसीई +Name[sv]=Xfce +Name[te]=ఎక్స్ ఎఫ్ సి ఈ +Comment=The Cholesterol Free Desktop Environment. A desktop environment reminiscent of CDE +Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing. 'n Werkskerm omgewing wat op CDE gebaseer is +Comment[ar]=بيئة سطح المكتب الخالي من الكوليسترول، بيئة سطح مكتب مليئة بذكريات CDE +Comment[be]=XFCE - Cholesterol Free Desktop Environment. Працоўнае асяроддзе, падобнае на CDE +Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE +Comment[ca]=El Cholesterol Free Desktop Environment. Un entorn d'escriptori amb reminiscències de CDE +Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol. Prostředí připomínající CDE +Comment[csb]=Òkrãże pùltu szlachùjące za CDE +Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol. Amgylchedd penbwrdd sy'n atgoffaol o CDE +Comment[da]=Det kolesterolfrie desktopmiljø. Et desktopmiljø der minder om CDE +Comment[de]=Cholesterol Free Desktop Environment. Graphische Arbeitsumgebung, die an CDE erinnert +Comment[el]=Το Cholesterol Free Desktop Environment. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE +Comment[eo]=La libera labortablo ĉirkaŭajo +Comment[es]=El Cholesterol Free Desktop Environment, un entorno de escritorio que recuerda a CDE +Comment[et]=Kolesteroolivaba töölaua keskkond, mis meenutab mitmeti CDE-d +Comment[eu]=Kolesterolik gabeko mahaigain ingurunea. CDE gogorarazten duen mahaigaina +Comment[fa]=محیط رومیزی آزاد Cholesterol. یادآور محیط رومیزی CDE +Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. +Comment[fr]=The Cholesterol Free Desktop Environment. Un environnement de bureau rappelant CDE +Comment[fy]=The Cholesterol Free Desktop Environment. In buroblêd omwrâld die tinken dat oan CDE +Comment[gl]=O Cholesterol Free Desktop Environment. Un entorno de escritório reminiscente de CDE +Comment[he]=The Cholesterol Free Desktop Environment. סביבת עבודה המזכירה את CDE +Comment[hi]=कॉलेस्ट्रॉल रहित डेस्कटॉप माहौल. एक डेस्कटॉप माहौल जो सीडीई जैसा है +Comment[hr]=Cholesterol Free Desktop Environment - Okruženje radne površine koje podsjeća na CDE +Comment[hu]=Cholesterol Free Desktop Environment, egy a CDE-re emlékeztető ablakkezelő +Comment[is]=Kólesterol-lausa skjáborðsumhverfið. Skjáborð sem líkist CDE +Comment[it]=Il Cholesterol Free Desktop Environment. Un desktop environment che ricorda CDE +Comment[ja]=Cholesterol Free Desktop Environment, CDE を思わせる、むだのないデスクトップ環境 +Comment[ka]=CDE-ს მაგვარი სამუშაო დაფა ქოლესტერინის გარეშე +Comment[kk]=Cholesterol Free Desktop Environment. CDE-ге үқсас графикалық орта +Comment[km]=Cholesterol Free Desktop Environment ។ បរិស្ថានផ្ទៃតុដែលសម្អាងលើ CDE +Comment[lt]=Darbatalio aplinka „Be cholesterolio“. CDE primenanti darbastalio aplinka +Comment[lv]=Darbvirsmas vide bez holesterīna. Darba virsmas vide, kas atgādina CDE +Comment[mk]=Cholesterol Free Desktop Environment. Работна околина која потсетува на CDE +Comment[ms]=Persekitaran Desktop Bebas Kolesterol. Mengenang kembali persekitaran desktop CDE +Comment[mt]=Cholesterol Free Desktop Environment. Ambjent grafiku li jixbaħ lis-CDE +Comment[nb]=Det kolesterolfrie skrivebordsmiljø. Et skrivebordsmiljø som minner om CDE +Comment[nds]=De "Cholesterol Free Desktop Environment". En Schriefdisch-Ümgeven, de wat liek is to CDE +Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश । CDE को स्मरणशील डेस्कटप परिवेश +Comment[nl]=The Cholesterol Free Desktop Environment. Een desktop environment die herinnert aan CDE +Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE +Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ +Comment[pl]=Środowisko pulpitu przypominające CDE +Comment[pt]=O Cholesterol Free Desktop Environment. Um ambiente de trabalho com vestígios do CDE +Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), um ambiente de trabalho remanescente do CDE +Comment[ro]=Cholesterol Free Desktop Environment. Un mediu grafic cu reminescente din CDE +Comment[ru]="Не содержащая холестерина" рабочая среда, напоминающая CDE +Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole. Ibikikije ibiro nkumburwa bya CDE +Comment[se]=The Cholesterol Free Desktop Environment. Čállinbeavdebiras mii muittuha CDE +Comment[sk]=The Cholesterol Free Desktop Environment. Pracovné prostredie pripomínajúce CDE +Comment[sl]=Cholesterol Free Desktop Environment. Namizno okolje, podobno okolju CDE +Comment[sr]=„The Cholesterol Free Desktop Environment“. Радно окружење које подсећа на CDE +Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“. Radno okruženje koje podseća na CDE +Comment[sv]=Den kolesterolfria skrivbordsmiljön. En skrivbordsmiljö som påminner om CDE +Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். CDE பொருள்பொதிந்த மேல்மேசை சூழல் +Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปไร้คอเลสเตอรอล เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE +Comment[tr]=Cholesterol Masaüstü Ortamı +Comment[tt]=Holesterol Bulmağan Östäl Möxite. CDE küreneşendä +Comment[uk]=The Cholesterol Free Desktop Environment. Графічне середовище, що нагадує CDE +Comment[vi]=Môi trường Màn hình nền Không có Cholesterol. Một môi trường màn hình nền gợi nhớ lại CDE +Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment). On evironmint d' sicribanne ki nos vént d' CDE +Comment[zh_CN]=胆固醇自由桌面环境。CDE 桌面环境的追随者 +Comment[zh_TW]=Cholesterol 免費桌面環境。一個另人懷念的 CDE 桌面環境 diff --git a/kdm/kfrontend/sessions/xfce4.desktop b/kdm/kfrontend/sessions/xfce4.desktop new file mode 100644 index 000000000..11b4097a6 --- /dev/null +++ b/kdm/kfrontend/sessions/xfce4.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=XSession +Exec=startxfce4 +TryExec=startxfce4 +Name=XFce 4 +Name[eo]=Facoj 4 +Name[hi]=एक्सएफसीई4 +Name[sv]=Xfce 4 +Name[te]=ఎక్స్ ఎఫ్ సి ఈ 4 +Comment=The Cholesterol Free Desktop Environment, version 4. A desktop environment reminiscent of CDE +Comment[af]=Die Cholesterol Gratis Werkskerm Omgewing, weergawe 4. 'n Werkskerm omgewing wat op CDE gebaseer is +Comment[be]=XFCE4 - Cholesterol Free Desktop Environment, version 4. Працоўнае асяроддзе, падобнае на CDE +Comment[bn]=দি কলেস্টরল ফ্রী ডেস্কটপ এনভায়রনমেন্ট, ৪র্থ সংস্করণ। CDE-র কথা মনে করিয়ে দেয় এমন একটি ডেস্কটপ এনভায়রনমেন্ট +Comment[bs]=Cholesterol Free Desktop Environment. Desktop okolina nalik na CDE +Comment[ca]=L'entorn d'escriptori sense colesterol, versió 4. Un entorn d'escriptori que recorda a CDE +Comment[cs]=Svobodné grafické prostředí neobsahující cholesterol verze 4. Prostředí připomínající CDE +Comment[csb]=Cholesterol Free Desktop Environment, wersëjô 4 - graficzné òkrãże szlachùjące za CDE +Comment[cy]=Yr Amgylchedd Penbwrdd Di-Golesterol, fersiwn 4. Amgylchedd penbwrdd sy'n atgoffaol o CDE +Comment[da]=Det kolesterolfrie desktopmiljø, version 4. Et desktopmiljø der minder om CDE +Comment[de]=Cholesterol Free Desktop Environment, Version 4. Benutzerumgebung in der Art von CDE +Comment[el]=Το Cholesterol Free Desktop Environment, έκδοση 4. Ένα περιβάλλον επιφάνειας εργασίας βασισμένο στο CDE +Comment[eo]=La libera labortablo ĉirkaŭajo 4 +Comment[es]=El Cholesterol Free Desktop Environment, versión 4. Un entorno de escritorio que recuerda a CDE +Comment[et]=Kolesteroolivaba töölaua keskkond (versioon 4), mis meenutab mitmeti CDE-d +Comment[eu]=Kolesterolik gabeko mahaigain ingurunea, 4 bertsioa. CDE gogorarazten duen mahaigaina +Comment[fa]=محیط رومیزی آزاد Cholesterol، نسخه ۴. یادآور محیط رومیزی CDE +Comment[fi]=Cholesterol Free -työpöytäympäristö. CDE:tä muistuttavatyöpöytäympäristö. +Comment[fr]=The Cholesterol Free Desktop Environment, version 4. Un environnement de bureau rappelant CDE +Comment[fy]=De Cholesterol Free Desktop Environment, ferzje 4. In buroblêd omwrâld die tinken dat oan CDE +Comment[gl]=O Cholesterol Free Desktop Environment, versión 4. Un entorno de escritório reminiscencia de CDE +Comment[he]=The Cholesterol Free Desktop Environment. גרסה 4, סביבת עבודה המזכירה את CDE +Comment[hi]=कोलेस्ट्रॉल मुक्त डेस्कटॉप वातावरण, संस्करण 4. सीडीई की याद दिलाता एक डेस्कटॉप वातावरण +Comment[hr]=Cholesterol Free Desktop Environment verzija 4 - Okruženje radne površine koje podsjeća na CDE +Comment[hu]=The Cholesterol Free Desktop Environment, 4-es verzió. Egy CDE-szerű ablakkezelő +Comment[is]=Kólesterol-lausa skjáborðsumhverfið, útgáfa 4. Skjáborð sem líkist CDE +Comment[it]=Il Cholesterol Free Desktop Environment, versione 4. Un desktop environment che ricorda CDE +Comment[ja]=Cholesterol Free Desktop Environment, version 4, CDE を思わせる、むだのないデスクトップ環境 +Comment[ka]=CDE-ს მაგვარი უქოლესტერინო სამუშაო დაფა xfce 4 +Comment[kk]=Cholesterol Free Desktop Environment, 4-нұсқа. CDE-ге ұқсас графикалық орта +Comment[km]=Cholesterol Free Desktop Environment កំណែ 4 ។ បរិស្ថានផ្ទៃតុដែលសម្អាងលើ CDE +Comment[lt]=Darbatalio aplinka „Be cholesterolio“ , 4 versija. CDE primenanti darbastalio aplinka +Comment[lv]=Darbvirsmas vide bez holesterīna, versija 4. Darbavirsmas vide, kas atgādina CDE +Comment[mk]=Cholesterol Free Desktop Environment, верзија 4. Работна околина која потсетува на CDE +Comment[ms]=Persekitaran Desktop Bebas Kolesterol, versi 4. Mengingatkan kembali persekitaran desktop CDE +Comment[mt]=Cholesterol Free Desktop Environment (v4). Ambjent grafiku li jixbaħ lis-CDE +Comment[nb]=Det kolesterolfrie skrivebordet, versjon 4. Et skrivebordsmiljø som minner om CDE +Comment[nds]=De "Cholesterol Free Desktop Environment", Verschoon 4. En Schriefdisch-Ümgeven, de wat liek is to CDE +Comment[ne]=कोलेस्ट्रोल रहित डेस्कटप परिवेश, संस्करण ४ । CDE को स्मरणशील डेस्कटप परिवेश +Comment[nl]=De Cholesterol Free Desktop Environment, versie 4. Een desktop environment die herinnert aan CDE +Comment[nn]=Cholesterol Free Desktop Environment. Eit skrivebordsmiljø som minner om CDE +Comment[pa]=ਚੋਲੀਸਟੀਰੋਲ ਮੁਫਤ ਵਾਤਾਵਰਣ, ਵਰਜਨ 4 ਇੱਕ CDE ਵਰਗਾ ਵਾਤਾਵਰਣ +Comment[pl]=Cholesterol Free Desktop Environment, wersja 4 - środowisko graficzne podobne do CDE. +Comment[pt]=O Cholesterol Free Desktop Environment, versão 4. Um ambiente de trabalho com vestígios do CDE +Comment[pt_BR]=Acrônimo para Cholesterol Free Desktop Environment (ou ambiente livre de colesterol), versão 4; um ambiente de trabalho remanescente do CDE +Comment[ro]=Cholesterol Free Desktop Environment, versiunea 4. Un mediu grafic cu reminescente din CDE +Comment[ru]="Не содержащая холестерина" рабочая среда xfce версии 4, напоминающая CDE +Comment[rw]=Ibikikije Ibiro Ubuntu Kolesiterole, verisiyo 4. Ibikikije ibiro nkumburwa bya CDE +Comment[se]=The Cholesterol Free Desktop Environment, version 4. Čállinbeavdebiras mii muittuha CDE +Comment[sk]=The Cholesterol Free Desktop Environment verzia 4. Pracovné prostredie pripomínajúce CDE +Comment[sl]=Cholesterol Free Desktop Environment, različica 4. Namizno okolje, podobno okolju CDE +Comment[sr]=„The Cholesterol Free Desktop Environment“ 4. издање. Радно окружење које подсећа на CDE +Comment[sr@Latn]=„The Cholesterol Free Desktop Environment“ 4. izdanje. Radno okruženje koje podseća na CDE +Comment[sv]=Den kolesterolfria skrivbordsmiljön, version 4. En skrivbordsmiljö som påminner om CDE +Comment[ta]=கொலஸ்ட்ரால் இல்லாத மேல்மேசை சூழல். பதிப்பு 4. CDE பொருள்பொதிந்த மேல்மேசை சூழல் +Comment[th]=สภาพแวดล้อมสำหรับเดสก์ทอปแบบไร้คอเลสเตอรอล เวอร์ชั่น 4 เป็นสภาพแวดล้อมสำหรับเดสก์ทอปที่เหลือมาจาก CDE +Comment[tr]=Cholesterol Ücretsiz Masaüstü Ortamı, sürüm 4. CDE'nin benzeri olan masaüstü ortamı +Comment[tt]=Holesterol Bulmağan Östäl Möxiteneñ 4. söreme. CDE küreneşendä +Comment[uk]=The Cholesterol Free Desktop Environment, версія 4. Графічне середовище, що нагадує CDE +Comment[vi]=Môi trường Màn hình nền Không có Cholesterol, phiên bản 4. Một môi trường màn hình nền gợi nhớ lại CDE +Comment[wa]=Li Libe Evironmint di Scribanne Colesterole (Cholesterol Free Desktop Environment), modêye 4. On evironmint d' sicribanne ki nos vént d' CDE +Comment[zh_CN]=胆固醇自由桌面环境,版本 4。CDE 桌面环境的追随者 +Comment[zh_TW]=Cholesterol 免費桌面環境,第 4 版。一個另人懷念的 CDE 桌面環境 diff --git a/kdm/kfrontend/themer/Makefile.am b/kdm/kfrontend/themer/Makefile.am new file mode 100644 index 000000000..7f6eb5701 --- /dev/null +++ b/kdm/kfrontend/themer/Makefile.am @@ -0,0 +1,16 @@ +AM_CPPFLAGS = -I$(srcdir)/../../backend -I$(srcdir)/.. -I../.. \ + -I$(top_srcdir)/kdmlib \ + $(all_includes) + +noinst_LIBRARIES = libkdmthemer.a +libkdmthemer_a_SOURCES = \ + kdmthemer.cpp \ + kdmitem.cpp \ + kdmpixmap.cpp \ + kdmrect.cpp \ + kdmlabel.cpp \ + kdmlayout.cpp + +METASOURCES = AUTO + +libkdmthemer_a_COMPILE_FIRST = ../../config.ci diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp new file mode 100644 index 000000000..48c0d1faf --- /dev/null +++ b/kdm/kfrontend/themer/kdmitem.cpp @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Generic Kdm Item + */ + +//#define DRAW_OUTLINE 1 // for debugging only + +#include "kdmitem.h" +#include "kdmlayout.h" + +#include <kglobal.h> +#include <kdebug.h> + +#include <qframe.h> +#include <qwidget.h> +#include <qlayout.h> +#include <qimage.h> +#ifdef DRAW_OUTLINE +# include <qpainter.h> +#endif + +KdmItem::KdmItem( KdmItem *parent, const QDomNode &node, const char *name ) + : QObject( parent, name ) + , boxManager( 0 ) + , fixedManager( 0 ) + , image( 0 ) + , myWidget( 0 ) + , myLayoutItem( 0 ) + , buttonParent( 0 ) +{ + // Set default layout for every item + currentManager = MNone; + pos.x = pos.y = 0; + pos.width = pos.height = 1; + pos.xType = pos.yType = pos.wType = pos.hType = DTnone; + pos.anchor = "nw"; + + isShown = InitialHidden; + + // Set defaults for derived item's properties + properties.incrementalPaint = false; + state = Snormal; + + // The "toplevel" node (the screen) is really just like a fixed node + if (!parent || !parent->inherits( "KdmItem" )) { + setFixedLayout(); + return; + } + // Read the mandatory Pos tag. Other tags such as normal, prelighted, + // etc.. are read under specific implementations. + QDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + QDomNode child = childList.item( nod ); + QDomElement el = child.toElement(); + QString tagName = el.tagName(), attr; + + if (tagName == "pos") { + parseAttribute( el.attribute( "x", QString::null ), pos.x, pos.xType ); + parseAttribute( el.attribute( "y", QString::null ), pos.y, pos.yType ); + parseAttribute( el.attribute( "width", QString::null ), pos.width, pos.wType ); + parseAttribute( el.attribute( "height", QString::null ), pos.height, pos.hType ); + pos.anchor = el.attribute( "anchor", "nw" ); + } + } + + QDomNode tnode = node; + id = tnode.toElement().attribute( "id", QString::number( (ulong)this, 16 ) ); + + // Tell 'parent' to add 'me' to its children + KdmItem *parentItem = static_cast<KdmItem *>( parent ); + parentItem->addChildItem( this ); +} + +KdmItem::~KdmItem() +{ + delete boxManager; + delete fixedManager; + delete image; +} + +void +KdmItem::update() +{ +} + +void +KdmItem::needUpdate() +{ + emit needUpdate( area.x(), area.y(), area.width(), area.height() ); +} + +void +KdmItem::show( bool force ) +{ + if (isShown != InitialHidden && !force) + return; + + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->show(); + + isShown = Shown; + + if (myWidget) + myWidget->show(); + // XXX showing of layouts not implemented, prolly pointless anyway + + needUpdate(); +} + +void +KdmItem::hide( bool force ) +{ + if (isShown == ExplicitlyHidden) + return; + + if (isShown == InitialHidden && force) { + isShown = ExplicitlyHidden; + return; // no need for further action + } + + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->hide(); + + isShown = force ? ExplicitlyHidden : InitialHidden; + + if (myWidget) + myWidget->hide(); + // XXX hiding of layouts not implemented, prolly pointless anyway + + needUpdate(); +} + +void +KdmItem::inheritFromButton( KdmItem *button ) +{ + if (button) + buttonParent = button; + + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->inheritFromButton( button ); +} + +KdmItem * +KdmItem::findNode( const QString &_id ) const +{ + if (id == _id) + return const_cast<KdmItem *>( this ); + + QValueList<KdmItem *>::ConstIterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) { + KdmItem *t = (*it)->findNode( _id ); + if (t) + return t; + } + + return 0; +} + +void +KdmItem::setWidget( QWidget *widget ) +{ +// delete myWidget; -- themer->widget() owns the widgets + + myWidget = widget; + if (isHidden()) + myWidget->hide(); + else + myWidget->show(); + + // Remove borders so that it blends nicely with the theme background + QFrame* frame = ::qt_cast<QFrame *>( widget ); + if (frame) + frame->setFrameStyle( QFrame::NoFrame ); + + myWidget->setGeometry(area); + + connect( myWidget, SIGNAL(destroyed()), SLOT(widgetGone()) ); +} + +void +KdmItem::widgetGone() +{ + myWidget = 0; +} + +void +KdmItem::setLayoutItem( QLayoutItem *item ) +{ + myLayoutItem = item; + // XXX hiding not supported - it think it's pointless here + if (myLayoutItem->widget()) + connect( myLayoutItem->widget(), SIGNAL(destroyed()), + SLOT(layoutItemGone()) ); + else if (myLayoutItem->layout()) + connect( myLayoutItem->layout(), SIGNAL(destroyed()), + SLOT(layoutItemGone()) ); +} + +void +KdmItem::layoutItemGone() +{ + myLayoutItem = 0; +} + +/* This is called as a result of KdmLayout::update, and directly on the root */ +void +KdmItem::setGeometry( const QRect &newGeometry, bool force ) +{ + kdDebug() << " KdmItem::setGeometry " << id << newGeometry << endl; + // check if already 'in place' + if (!force && area == newGeometry) + return; + + area = newGeometry; + + if (myWidget) + myWidget->setGeometry( newGeometry ); + if (myLayoutItem) + myLayoutItem->setGeometry( newGeometry ); + + // recurr to all boxed children + if (boxManager && !boxManager->isEmpty()) + boxManager->update( newGeometry, force ); + + // recurr to all fixed children + if (fixedManager && !fixedManager->isEmpty()) + fixedManager->update( newGeometry, force ); + + // TODO send *selective* repaint signal +} + +void +KdmItem::paint( QPainter *p, const QRect &rect ) +{ + if (isHidden()) + return; + + if (myWidget || (myLayoutItem && myLayoutItem->widget())) + return; + + if (area.intersects( rect )) { + QRect contentsRect = area.intersect( rect ); + contentsRect.moveBy( QMIN( 0, -area.x() ), QMIN( 0, -area.y() ) ); + drawContents( p, contentsRect ); + } + +#ifdef DRAW_OUTLINE + // Draw bounding rect for this item + p->setPen( Qt::white ); + p->drawRect( area ); +#endif + + if (myLayoutItem) + return; + + // Dispatch paint events to children + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->paint( p, rect ); +} + +KdmItem *KdmItem::currentActive = 0; + +void +KdmItem::mouseEvent( int x, int y, bool pressed, bool released ) +{ + if (buttonParent && buttonParent != this) { + buttonParent->mouseEvent( x, y, pressed, released ); + return; + } + + ItemState oldState = state; + if (area.contains( x, y )) { + if (released && oldState == Sactive) { + if (buttonParent) + emit activated( id ); + state = Sprelight; + currentActive = 0; + } else if (pressed || currentActive == this) { + state = Sactive; + currentActive = this; + } else if (!currentActive) + state = Sprelight; + else + state = Snormal; + } else { + if (released) + currentActive = 0; + if (currentActive == this) + state = Sprelight; + else + state = Snormal; + } + + if (!buttonParent) { + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) + (*it)->mouseEvent( x, y, pressed, released ); + } + + if (oldState != state) + statusChanged(); +} + +void +KdmItem::statusChanged() +{ + if (buttonParent == this) { + QValueList<KdmItem *>::Iterator it; + for (it = m_children.begin(); it != m_children.end(); ++it) { + (*it)->state = state; + (*it)->statusChanged(); + } + } +} + +// BEGIN protected inheritable + +QSize +KdmItem::sizeHint() +{ + if (myWidget) + return myWidget->size(); + if (myLayoutItem) + return myLayoutItem->sizeHint(); + int w = pos.wType == DTpixel ? kAbs( pos.width ) : -1, + h = pos.hType == DTpixel ? kAbs( pos.height ) : -1; + return QSize( w, h ); +} + +QRect +KdmItem::placementHint( const QRect &parentRect ) +{ + QSize hintedSize = sizeHint(); + QSize boxHint; + + int x = parentRect.left(), + y = parentRect.top(), + w = parentRect.width(), + h = parentRect.height(); + + kdDebug() << "KdmItem::placementHint parentRect=" << id << parentRect << " hintedSize=" << hintedSize << endl; + // check if width or height are set to "box" + if (pos.wType == DTbox || pos.hType == DTbox) { + if (myLayoutItem || myWidget) + boxHint = hintedSize; + else { + if (!boxManager) + return parentRect; + boxHint = boxManager->sizeHint(); + } + kdDebug() << " => boxHint " << boxHint << endl; + } + + if (pos.xType == DTpixel) + x += pos.x; + else if (pos.xType == DTnpixel) + x = parentRect.right() - pos.x; + else if (pos.xType == DTpercent) + x += int( parentRect.width() / 100.0 * pos.x ); + + if (pos.yType == DTpixel) + y += pos.y; + else if (pos.yType == DTnpixel) + y = parentRect.bottom() - pos.y; + else if (pos.yType == DTpercent) + y += int( parentRect.height() / 100.0 * pos.y ); + + if (pos.wType == DTpixel) + w = pos.width; + else if (pos.wType == DTnpixel) + w -= pos.width; + else if (pos.wType == DTpercent) + w = int( parentRect.width() / 100.0 * pos.width ); + else if (pos.wType == DTbox) + w = boxHint.width(); + else if (hintedSize.width() > 0) + w = hintedSize.width(); + else + w = 0; + + if (pos.hType == DTpixel) + h = pos.height; + else if (pos.hType == DTnpixel) + h -= pos.height; + else if (pos.hType == DTpercent) + h = int( parentRect.height() / 100.0 * pos.height ); + else if (pos.hType == DTbox) + h = boxHint.height(); + else if (hintedSize.height() > 0) + h = hintedSize.height(); + else + h = 0; + + // defaults to center + int dx = -w / 2, dy = -h / 2; + + // anchor the rect to an edge / corner + if (pos.anchor.length() > 0 && pos.anchor.length() < 3) { + if (pos.anchor.find( 'n' ) >= 0) + dy = 0; + if (pos.anchor.find( 's' ) >= 0) + dy = -h; + if (pos.anchor.find( 'w' ) >= 0) + dx = 0; + if (pos.anchor.find( 'e' ) >= 0) + dx = -w; + } + // KdmItem *p = static_cast<KdmItem*>( parent() ); + kdDebug() << "KdmItem::placementHint " << id << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl; + y += dy; + x += dx; + + // Note: no clipping to parent because this broke many themes! + return QRect( x, y, w, h ); +} + +// END protected inheritable + + +void +KdmItem::addChildItem( KdmItem *item ) +{ + m_children.append( item ); + switch (currentManager) { + case MNone: // fallback to the 'fixed' case + setFixedLayout(); + case MFixed: + fixedManager->addItem( item ); + break; + case MBox: + boxManager->addItem( item ); + break; + } + + // signal bounce from child to parent + connect( item, SIGNAL(needUpdate( int, int, int, int )), SIGNAL(needUpdate( int, int, int, int )) ); + connect( item, SIGNAL(activated( const QString & )), SIGNAL(activated( const QString & )) ); +} + +void +KdmItem::parseAttribute( const QString &s, int &val, enum DataType &dType ) +{ + if (s.isEmpty()) + return; + + int p; + if (s == "box") { // box value + dType = DTbox; + val = 0; + } else if ((p = s.find( '%' )) >= 0) { // percent value + dType = DTpercent; + QString sCopy = s; + sCopy.remove( p, 1 ); + sCopy.replace( ',', '.' ); + val = (int)sCopy.toDouble(); + } else { // int value + dType = DTpixel; + QString sCopy = s; + if (sCopy.at( 0 ) == '-') { + sCopy.remove( 0, 1 ); + dType = DTnpixel; + } + sCopy.replace( ',', '.' ); + val = (int)sCopy.toDouble(); + } +} + +void +KdmItem::parseFont( const QString &s, QFont &font ) +{ + int splitAt = s.findRev( ' ' ); + if (splitAt < 1) + return; + font.setFamily( s.left( splitAt ) ); + int fontSize = s.mid( splitAt + 1 ).toInt(); + if (fontSize > 1) + font.setPointSize( fontSize ); +} + +void +KdmItem::parseColor( const QString &s, QColor &color ) +{ + if (s.at( 0 ) != '#') + return; + bool ok; + QString sCopy = s; + int hexColor = sCopy.remove( 0, 1 ).toInt( &ok, 16 ); + if (ok) + color.setRgb( hexColor ); +} + +void +KdmItem::setBoxLayout( const QDomNode &node ) +{ + if (!boxManager) + boxManager = new KdmLayoutBox( node ); + currentManager = MBox; +} + +void +KdmItem::setFixedLayout( const QDomNode &node ) +{ + if (!fixedManager) + fixedManager = new KdmLayoutFixed( node ); + currentManager = MFixed; +} + +#include "kdmitem.moc" diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h new file mode 100644 index 000000000..66feedd02 --- /dev/null +++ b/kdm/kfrontend/themer/kdmitem.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDMITEM_H +#define KDMITEM_H + +#include <qobject.h> +#include <qvaluelist.h> +#include <qrect.h> +#include <qdom.h> + +class KdmItem; +class KdmLayoutBox; +class KdmLayoutFixed; + +class QPainter; +class QLayoutItem; + +/** class KdmItem + * @short Base class for every kdmthemes' element. + * + * This class provides methods for arranging it and its children to the + * screen (see note below), painting the whole area or a sub-region using + * an opened painter, handling mouse events or events in general dispatching + * them to children and sending some signals to the root (for example on + * mouse click). + * + * KdmItem sits in a hierarchical top to bottom tree with signals that + * traverse the tree back from leafs (or inner nodes) to the root. + * + * To implement a KdmItem only a few virtual protected methods must be + * reimplemented, other virtual functions are there for convenience only - + * the default implementation should satisfy your needs. + */ + +/** + * A note on layouting - how does it work? + * - setgeometry is called by parent (passing the new geometry) + * - item changes its geometry + * - if item embeds a widget, reposition it too + * - call children's box manager. box->update( my geom ) + * - sum up the whole space taken by children (via *hint calls) if + * needed for box width / height computation. note that the computed + * geometry should be equal or similar to parent's geometry. + * - pad the rectangle bounding box' contents + * - for every child + * - if vertical + * ( use a top-to-bottom insertion, spacing insertion lines by + * children's individual height ) + * - set up a zero height Parent (placed at the insertion line's + * position) and get Geom = child->placementHint( p ) + * - set up child's Size using Parent's width and Geom's height. + * - call to child->setGeometry( Parent.topLeft, Size ) + * - if horizontal + * - flows like the vertical one but uses a left-to-right insertion + * and insertion entry points are vertical lines + * - call to children's fix manager. fixed->update( my geom ) + * - for every child + * - S = get child's geometry hint (and we'll give item the whole + * space it needs, without constraints) + * - call to child->setGeometry( S ) + * - TODO: send a selective redraw signal also merging children's areas + */ + +class KdmItem : public QObject { + Q_OBJECT + + friend class KdmThemer; + +public: + /** + * Item constructor and destructor + */ + KdmItem( KdmItem *parent, const QDomNode &node = QDomNode(), const char *name = 0 ); + virtual ~KdmItem(); + + /** + * Fixup the geometry of an item and its children (even if fixed + * or boxed ones). Note that this will generate repaint signals + * when needed. The default implementation should fit all needs. + */ + virtual void setGeometry( const QRect &newGeometry, bool force ); + + /** + * Paint the item and its children using the given painter. + * This is the compositing core function. It buffers paint operations + * to speed up rendering of dynamic objects. + */ + void paint( QPainter *painter, const QRect &boundaries ); + + /** + * Update representation of contents and repaint. + */ + virtual void update(); + + /** + * Handle mouse motion and dispatch events to children. This + * leads to items prelighting, activation() on click and more.. + */ + void mouseEvent( int x, int y, bool pressed = false, bool released = false ); + + /** + * Similar to sizeHint(..), this returns the area of the item + * given the @p parentGeometry. The default implementation + * takes into account geometric constraints and layoutings. + * @param parentGeometry the geometry of the caller item or a + * null rect if the geometry of the parent is not yet defined. + */ + virtual QRect placementHint( const QRect &parentGeometry ); + + /** + * Create the box layout manager; next children will be + * managed by the box layouter + */ + void setBoxLayout( const QDomNode &node = QDomNode() ); + + /** + * Create the fixed layout manager; next children will be + * in fixed position relative to this item + */ + void setFixedLayout( const QDomNode &node = QDomNode() ); + + QString type() const { return itemType; } + void setType( const QString &t ) { itemType = t; } + void setBaseDir( const QString &bd ) { basedir = bd; } + + QString baseDir() const + { + if (basedir.isEmpty() && parent()) + return static_cast<KdmItem *>( parent()->qt_cast( "KdmItem" ) )->baseDir(); + return basedir; + } + + KdmItem *findNode( const QString &id ) const; + virtual void setWidget( QWidget *widget ); + virtual void setLayoutItem( QLayoutItem *item ); + + virtual void hide( bool force = false ); + virtual void show( bool force = false ); + + bool isHidden() const { return isShown != Shown; } + bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; } + QRect rect() const { return area; } + +signals: + void needUpdate( int x, int y, int w, int h ); + void activated( const QString &id ); + +protected slots: + void widgetGone(); + void layoutItemGone(); + +protected: + /** + * Returns the optimal/minimal size for this item. + * This should be reimplemented in items like label and pixmap. + * @return (-1,-1) if no size can be determined (so it should + * default to parent's size). + */ + virtual QSize sizeHint(); + + /** + * Low level graphical function to paint the item. + * All items must reimplement this function to draw themeselves + * (or a part of) into the @p image keeping inside the @p rect . + * Try to do this as fast as possible. + * @param painter the painter to draw the item with + * @param region the part of the the image to render + */ + virtual void drawContents( QPainter *painter, const QRect ®ion ) = 0; + + /** + * Called when item changes its 'state' variable. This must + * handle item's repaint. + */ + virtual void statusChanged(); + + /** + * emits needUpdate( int, int, int, int ) with the full widget area. + */ + void needUpdate(); + + // This enum identifies in which state the item is + enum ItemState { Snormal, Sactive, Sprelight } state; + + static KdmItem *currentActive; + + // This struct can be filled in by derived items + struct { + bool incrementalPaint; + } properties; + + // This is the placement of the item + QRect area; + + // This struct is filled in by KdmItem base class + enum DataType { DTnone, DTpixel, DTnpixel, DTpercent, DTbox }; + struct { + enum DataType xType, yType, wType, hType; + int x; + int y; + int width; + int height; + QString anchor; + } pos; + + /* For internal use ONLY + * Add a child item. This function is called automatically + * when constructing an @p item with this as the parent. + */ + void addChildItem( KdmItem *item ); + + /* For internal use ONLY + * Parse type and value of an attribute (pos tag), a font or a + * color. + */ + void parseAttribute( const QString &, int &, enum DataType & ); + void parseFont( const QString &, QFont & ); + void parseColor( const QString &, QColor & ); + + void inheritFromButton( KdmItem *button ); + + QString itemType, id; + QValueList<KdmItem *> m_children; + + // Layouting related variables + enum { MNone = 0, MFixed = 1, MBox = 2 } currentManager; + KdmLayoutBox *boxManager; + KdmLayoutFixed *fixedManager; + + // Compositing related variables + QImage *image; + + // defines the directory the theme is in (may be present in the parent) + QString basedir; + + QWidget *myWidget; + QLayoutItem *myLayoutItem; + + enum { InitialHidden, ExplicitlyHidden, Shown } isShown; + + KdmItem *buttonParent; +}; + +#endif diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp new file mode 100644 index 000000000..41d7e4254 --- /dev/null +++ b/kdm/kfrontend/themer/kdmlabel.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdmlabel.h" +#include <kgreeter.h> + +#include <kglobal.h> +#include <klocale.h> +#include <kmacroexpander.h> +#include <kdebug.h> + +#include <qdatetime.h> +#include <qpainter.h> +#include <qfontmetrics.h> +#include <qtimer.h> + +#include <unistd.h> +#include <sys/utsname.h> +#if !defined(HAVE_GETDOMAINNAME) && defined(HAVE_SYSINFO) +# include <sys/systeminfo.h> +#endif + +KdmLabel::KdmLabel( KdmItem *parent, const QDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + itemType = "label"; + + // Set default values for label (note: strings are already Null) + label.active.color.setRgb( 0xFFFFFF ); + label.active.present = false; + label.prelight.present = false; + label.maximumWidth = -1; + + const QString locale = KGlobal::locale()->language(); + + // Read LABEL ID + QDomNode n = node; + QDomElement elLab = n.toElement(); + // ID types: clock, pam-error, pam-message, pam-prompt, + // pam-warning, timed-label + label.id = elLab.attribute( "id", "" ); + label.hasId = !(label.id).isEmpty(); + + // Read LABEL TAGS + QDomNodeList childList = node.childNodes(); + bool stockUsed = false; + for (uint nod = 0; nod < childList.count(); nod++) { + QDomNode child = childList.item( nod ); + QDomElement el = child.toElement(); + QString tagName = el.tagName(); + + if (tagName == "pos") + label.maximumWidth = el.attribute( "max-width", "-1" ).toInt(); + else if (tagName == "normal") { + parseColor( el.attribute( "color", "#ffffff" ), label.normal.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.normal.font ); + } else if (tagName == "active") { + label.active.present = true; + parseColor( el.attribute( "color", "#ffffff" ), label.active.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.active.font ); + } else if (tagName == "prelight") { + label.prelight.present = true; + parseColor( el.attribute( "color", "#ffffff" ), label.prelight.color ); + parseFont( el.attribute( "font", "Sans 14" ), label.prelight.font ); + } else if (tagName == "text" && el.attributes().count() == 0 && !stockUsed) { + label.text = el.text(); + } else if (tagName == "text" && !stockUsed) { + QString lang = el.attribute( "xml:lang", "" ); + if (lang == locale) + label.text = el.text(); + } else if (tagName == "stock") { + label.text = lookupStock( el.attribute( "type", "" ) ); + stockUsed = true; + } + } + + // Check if this is a timer label + label.isTimer = label.text.find( "%c" ) >= 0; + if (label.isTimer) { + timer = new QTimer( this ); + timer->start( 1000 ); + connect( timer, SIGNAL(timeout()), SLOT(update()) ); + } + cText = lookupText( label.text ); +} + +void +KdmLabel::setText( const QString &txt ) +{ + label.text = txt; + update(); +} + +QSize +KdmLabel::sizeHint() +{ + // choose the correct label class + struct LabelStruct::LabelClass *l = &label.normal; + if (state == Sactive && label.active.present) + l = &label.active; + else if (state == Sprelight && label.prelight.present) + l = &label.prelight; + // get the hint from font metrics + QSize hint = QFontMetrics( l->font ).size( AlignLeft | SingleLine, cText ); + // clip the result using the max-width label(pos) parameter + if (label.maximumWidth > 0 && hint.width() > label.maximumWidth) + hint.setWidth( label.maximumWidth ); + return hint; +} + +void +KdmLabel::drawContents( QPainter *p, const QRect &/*r*/ ) +{ + // choose the correct label class + struct LabelStruct::LabelClass *l = &label.normal; + if (state == Sactive && label.active.present) + l = &label.active; + else if (state == Sprelight && label.prelight.present) + l = &label.prelight; + // draw the label + p->setFont( l->font ); + p->setPen( l->color ); + //TODO paint clipped (tested but not working..) + p->drawText( area, AlignLeft | SingleLine, cText ); +} + +void +KdmLabel::statusChanged() +{ + KdmItem::statusChanged(); + if (!label.active.present && !label.prelight.present) + return; + if ((state == Sprelight && !label.prelight.present) || + (state == Sactive && !label.active.present)) + return; + needUpdate(); +} + +void +KdmLabel::update() +{ + QString text = lookupText( label.text ); + if (text != cText) { + cText = text; + needUpdate(); + } +} + +static const struct { + const char *type, *text; +} stocks[] = { + { "language", I18N_NOOP("Language") }, + { "session", I18N_NOOP("Session Type") }, + { "system", I18N_NOOP("Menu") }, // i18n("Actions"); + { "disconnect", I18N_NOOP("Disconnect") }, + { "quit", I18N_NOOP("Quit") }, + { "halt", I18N_NOOP("Power off") }, + { "suspend", I18N_NOOP("Suspend") }, + { "reboot", I18N_NOOP("Reboot") }, + { "chooser", I18N_NOOP("XDMCP Chooser") }, + { "config", I18N_NOOP("Configure") }, + { "caps-lock-warning", I18N_NOOP("You have got caps lock on.") }, + { "timed-label", I18N_NOOP("User %s will login in %d seconds") }, + { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString + { "username-label", I18N_NOOP("Username:") }, + { "password-label", I18N_NOOP("Password:") }, + { "login", I18N_NOOP("Login") } +}; + +QString +KdmLabel::lookupStock( const QString &stock ) +{ + //FIXME add key accels! + QString type( stock.lower() ); + + for (uint i = 0; i < sizeof(stocks)/sizeof(stocks[0]); i++) + if (type == stocks[i].type) + return i18n(stocks[i].text); + + kdDebug() << "Invalid <stock> element. Check your theme!" << endl; + return stock; +} + +QString +KdmLabel::lookupText( const QString &t ) +{ + QString text = t; + + text.replace( '_', '&' ); +// text.remove( '_' ); // FIXME add key accels, remove underscores for now + + QMap<QChar,QString> m; + struct utsname uts; + uname( &uts ); + m['n'] = QString::fromLocal8Bit( uts.nodename ); + char buf[256]; + buf[sizeof(buf) - 1] = '\0'; + m['h'] = gethostname( buf, sizeof(buf) - 1 ) ? "localhost" : QString::fromLocal8Bit( buf ); +#ifdef HAVE_GETDOMAINNAME + m['o'] = getdomainname( buf, sizeof(buf) - 1 ) ? "localdomain" : QString::fromLocal8Bit( buf ); +#elif defined(HAVE_SYSINFO) + m['o'] = (unsigned)sysinfo( SI_SRPC_DOMAIN, buf, sizeof(buf) ) > sizeof(buf) ? "localdomain" : QString::fromLocal8Bit( buf ); +#endif + m['d'] = QString::number( KThemedGreeter::timedDelay ); + m['s'] = KThemedGreeter::timedUser; + // xgettext:no-c-format + KGlobal::locale()->setDateFormat( i18n("date format", "%a %d %B") ); + m['c'] = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(), false, false ); + + return KMacroExpander::expandMacros( text, m ); +} + +#include "kdmlabel.moc" diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h new file mode 100644 index 000000000..b80d0189a --- /dev/null +++ b/kdm/kfrontend/themer/kdmlabel.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDELABEL_H +#define KDELABEL_H + +#include "kdmitem.h" + +#include <qcolor.h> +#include <qfont.h> + +class QTimer; + +/* + * KdmLabel. A label element + */ + +class KdmLabel : public KdmItem { + Q_OBJECT + +public: + KdmLabel( KdmItem *parent, const QDomNode &node, const char *name = 0 ); + void setText( const QString &txt ); + +protected: + // reimplemented; returns the minimum size of rendered text + virtual QSize sizeHint(); + + // draw the label + virtual void drawContents( QPainter *p, const QRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + + struct LabelStruct { + QString text; + bool isTimer; + bool hasId; + QString id; + struct LabelClass { + QColor color; + QFont font; + bool present; + } normal, active, prelight; + int maximumWidth; + } label; + + QTimer *timer; + +public slots: + void update(); + +private: + /* Method to lookup the caption associated with an item */ + QString lookupStock( const QString &stock ); + + /* Lookup variables in the text */ + QString lookupText( const QString &t ); + + QString cText; +}; + +#endif diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp new file mode 100644 index 000000000..ed93be264 --- /dev/null +++ b/kdm/kfrontend/themer/kdmlayout.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdmlayout.h" +#include "kdmitem.h" + +#include <kdebug.h> + +#include <qdom.h> +#include <qrect.h> + +KdmLayoutFixed::KdmLayoutFixed( const QDomNode &/*node*/ ) +{ + //Parsing FIXED parameters on 'node' [NONE!] +} + +void +KdmLayoutFixed::update( const QRect &parentGeometry, bool force ) +{ + kdDebug() << "KdmLayoutFixed::update " << parentGeometry << endl; + + // I can't layout children if the parent rectangle is not valid + if (parentGeometry.width() < 0 || parentGeometry.height() < 0) { + kdDebug() << "invalid\n"; + return; + } + // For each child in list I ask their hinted size and set it! + for (QValueList<KdmItem *>::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) + (*it)->setGeometry( (*it)->placementHint( parentGeometry ), force ); +} + +KdmLayoutBox::KdmLayoutBox( const QDomNode &node ) +{ + //Parsing BOX parameters + QDomNode n = node; + QDomElement el = n.toElement(); + box.isVertical = el.attribute( "orientation", "vertical" ) != "horizontal"; + box.xpadding = el.attribute( "xpadding", "0" ).toInt(); + box.ypadding = el.attribute( "ypadding", "0" ).toInt(); + box.spacing = el.attribute( "spacing", "0" ).toInt(); + box.minwidth = el.attribute( "min-width", "0" ).toInt(); + box.minheight = el.attribute( "min-height", "0" ).toInt(); + box.homogeneous = el.attribute( "homogeneous", "false" ) == "true"; +} + +void +KdmLayoutBox::update( const QRect &parentGeometry, bool force ) +{ + kdDebug() << this << " update " << parentGeometry << endl; + + // I can't layout children if the parent rectangle is not valid + if (!parentGeometry.isValid() || parentGeometry.isEmpty()) + return; + + // Check if box size was computed. If not compute it + // TODO check if this prevents updating changing items +// if (!hintedSize.isValid()) +// sizeHint(); + +// kdDebug() << this << " hintedSize " << hintedSize << endl; + + //XXX why was this asymmetric? it broke things big time. + QRect childrenRect = /*box.isVertical ? QRect( parentGeometry.topLeft(), hintedSize ) :*/ parentGeometry; + // Begin cutting the parent rectangle to attach children on the right place + childrenRect.addCoords( box.xpadding, box.ypadding, -box.xpadding, -box.ypadding ); + + kdDebug() << this << " childrenRect " << childrenRect << endl; + + // For each child in list ... + if (box.homogeneous) { + int ccnt = 0; + for (QValueList<KdmItem *>::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) + if (!(*it)->isExplicitlyHidden()) + ccnt++; + int height = (childrenRect.height() - (ccnt - 1) * box.spacing) / ccnt; + int width = (childrenRect.width() - (ccnt - 1) * box.spacing) / ccnt; + + for (QValueList<KdmItem *>::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + if ((*it)->isExplicitlyHidden()) + continue; + if (box.isVertical) { + QRect temp( childrenRect.left(), childrenRect.top(), childrenRect.width(), height ); + (*it)->setGeometry( temp, force ); + childrenRect.setTop( childrenRect.top() + height + box.spacing ); + } else { + QRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() ); + kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl; + temp = (*it)->placementHint( temp ); + (*it)->setGeometry( temp, force ); + childrenRect.setLeft( childrenRect.left() + width + box.spacing ); + } + } + } else { + for (QValueList<KdmItem *>::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + if ((*it)->isExplicitlyHidden()) + continue; + + QRect temp = childrenRect, itemRect; + if (box.isVertical) { + temp.setHeight( 0 ); + itemRect = (*it)->placementHint( temp ); + temp.setHeight( itemRect.height() ); + childrenRect.setTop( childrenRect.top() + itemRect.size().height() + box.spacing ); + } else { + temp.setWidth( 0 ); + itemRect = (*it)->placementHint( temp ); + kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl; + temp.setWidth( itemRect.width() ); + childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing ); + kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl; + } + itemRect = (*it)->placementHint( temp ); + kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl; + (*it)->setGeometry( itemRect, force ); + } + } +} + +//FIXME truly experimental (is so close to greeter_geometry.c) +QSize +KdmLayoutBox::sizeHint() +{ + // Sum up area taken by children + int w = 0, h = 0; + for (QValueList<KdmItem *>::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { + QSize s = (*it)->placementHint( QRect() ).size(); + if (box.isVertical) { + if (s.width() > w) + w = s.width(); + h += s.height(); + } else { + if (s.height() > h) + h = s.height(); + w += s.width(); + } + } + + // Add padding and items spacing + w += 2 * box.xpadding; + h += 2 * box.ypadding; + if (box.isVertical) + h += box.spacing * (m_children.count() - 1); + else + w += box.spacing * (m_children.count() - 1); + + // Make hint at least equal to minimum size (if set) + return QSize( w < box.minwidth ? box.minwidth : w, + h < box.minheight ? box.minheight : h ); +} diff --git a/kdm/kfrontend/themer/kdmlayout.h b/kdm/kfrontend/themer/kdmlayout.h new file mode 100644 index 000000000..2e00675fb --- /dev/null +++ b/kdm/kfrontend/themer/kdmlayout.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDMLAYOUT_H +#define KDMLAYOUT_H + +/** + * this is a container for a lot of other stuff + * but can be treated like a usual widget + */ + +#include <qvaluelist.h> +#include <qsize.h> + +class KdmItem; + +class QDomNode; +class QRect; + +class KdmLayout { + +public: +// virtual ~KdmLayout() {}; + + // Adds an item that will be managed + void addItem( KdmItem *item ) { m_children.append( item ); } + + // Return false if any item are managed by this layouter + bool isEmpty() { return m_children.isEmpty(); } + + // Updates the layout of all items knowing that the parent + // has the @p parentGeometry geometry +// virtual void update( const QRect &parentGeometry ) = 0; + +protected: + QValueList<KdmItem *> m_children; +}; + +class KdmLayoutFixed : public KdmLayout { + +public: + KdmLayoutFixed( const QDomNode &node ); + + // Updates the layout of all boxed items knowing that the parent + // has the @p parentGeometry geometry + void update( const QRect &parentGeometry, bool force ); +}; + +/** + * this is a container for a lot of other stuff + * but can be treated like a usual widget + */ + +class KdmLayoutBox : public KdmLayout { + +public: + KdmLayoutBox( const QDomNode &node ); + + // Updates the layout of all boxed items knowing that they + // should fit into @p parentGeometry container + void update( const QRect &parentGeometry, bool force ); + + // Computes the size hint of the box, telling which is the + // smallest size inside which boxed items will fit + QSize sizeHint(); + +private: + struct { + bool isVertical; + int spacing; + int xpadding; + int ypadding; + int minwidth; + int minheight; + bool homogeneous; + } box; +// QSize hintedSize; +}; + +#endif diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp new file mode 100644 index 000000000..337c19ced --- /dev/null +++ b/kdm/kfrontend/themer/kdmpixmap.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include "kdmpixmap.h" + +#include <kimageeffect.h> +#ifdef HAVE_LIBART +#include <ksvgiconengine.h> +#endif + +#include <kdebug.h> + +#include <qpainter.h> +#include <qpixmap.h> +#include <qimage.h> + +KdmPixmap::KdmPixmap( KdmItem *parent, const QDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + itemType = "pixmap"; + + // Set default values for pixmap (note: strings are already Null) + pixmap.normal.tint.setRgb( 0xFFFFFF ); + pixmap.normal.alpha = 1.0; + pixmap.active.present = false; + pixmap.prelight.present = false; + + // Read PIXMAP ID + // it rarely happens that a pixmap can be a button too! + QDomNode n = node; + QDomElement elPix = n.toElement(); + + // Read PIXMAP TAGS + QDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + QDomNode child = childList.item( nod ); + QDomElement el = child.toElement(); + QString tagName = el.tagName(); + + if (tagName == "normal") { + loadPixmap( el.attribute( "file", "" ), pixmap.normal.pixmap, pixmap.normal.fullpath ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint ); + pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + } else if (tagName == "active") { + pixmap.active.present = true; + loadPixmap( el.attribute( "file", "" ), pixmap.active.pixmap, pixmap.active.fullpath ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint ); + pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + } else if (tagName == "prelight") { + pixmap.prelight.present = true; + loadPixmap( el.attribute( "file", "" ), pixmap.prelight.pixmap, pixmap.prelight.fullpath ); + parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint ); + pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + } + } +} + +QSize +KdmPixmap::sizeHint() +{ + // choose the correct pixmap class + PixmapStruct::PixmapClass * pClass = &pixmap.normal; + if (state == Sactive && pixmap.active.present) + pClass = &pixmap.active; + if (state == Sprelight && pixmap.prelight.present) + pClass = &pixmap.prelight; + // use the pixmap size as the size hint + if (!pClass->pixmap.isNull()) + return pClass->pixmap.size(); + return KdmItem::sizeHint(); +} + +void +KdmPixmap::setGeometry( const QRect &newGeometry, bool force ) +{ + KdmItem::setGeometry( newGeometry, force ); + pixmap.active.readyPixmap.resize( 0, 0 ); + pixmap.prelight.readyPixmap.resize( 0, 0 ); + pixmap.normal.readyPixmap.resize( 0, 0 ); +} + + +void +KdmPixmap::loadPixmap( const QString &fileName, QPixmap &map, QString &fullName ) +{ + if (fileName.isEmpty()) + return; + + fullName = fileName; + if (fullName.at( 0 ) != '/') + fullName = baseDir() + "/" + fileName; + + if (!fullName.endsWith( ".svg" )) // we delay it for svgs + if (!map.load( fullName )) + fullName = QString::null; +} + +void +KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const QRect &area ) +{ +#ifdef HAVE_LIBART + // Special stuff for SVG icons + KSVGIconEngine *svgEngine = new KSVGIconEngine(); + + if (svgEngine->load( area.width(), area.height(), pClass->fullpath )) { + QImage *t = svgEngine->image(); + pClass->pixmap = *t; + pClass->readyPixmap.resize( 0, 0 ); + delete t; + } else { + kdWarning() << "failed to load " << pClass->fullpath << endl; + pClass->fullpath = QString::null; + } + + delete svgEngine; +#else + Q_UNUSED(pClass); + Q_UNUSED(area); +#endif +} + +void +KdmPixmap::drawContents( QPainter *p, const QRect &r ) +{ + // choose the correct pixmap class + PixmapStruct::PixmapClass *pClass = &pixmap.normal; + if (state == Sactive && pixmap.active.present) + pClass = &pixmap.active; + if (state == Sprelight && pixmap.prelight.present) + pClass = &pixmap.prelight; + + if (pClass->pixmap.isNull()) { + if (pClass->fullpath.isEmpty()) // if neither is set, we're empty + return; + + kdDebug() << "renderSVG\n"; + renderSvg( pClass, area ); + } + + int px = area.left() + r.left(); + int py = area.top() + r.top(); + int sx = r.x(); + int sy = r.y(); + int sw = r.width(); + int sh = r.height(); + if (px < 0) { + px *= -1; + sx += px; + px = 0; + } + if (py < 0) { + py *= -1; + sy += py; + py = 0; + } + + + if (pClass->readyPixmap.isNull()) { + QImage scaledImage; + + // use the loaded pixmap or a scaled version if needed + + if (area.size() != pClass->pixmap.size()) { + if (pClass->fullpath.endsWith( ".svg" )) { + kdDebug() << "renderSVG\n"; + renderSvg( pClass, area ); + scaledImage = pClass->pixmap.convertToImage(); + } else { + kdDebug() << "convertFromImage\n"; + QImage tempImage = pClass->pixmap.convertToImage(); + scaledImage = tempImage.smoothScale( area.width(), area.height() ); + } + } else + scaledImage = pClass->pixmap.convertToImage(); + + bool haveTint = pClass->tint.rgb() != 0xFFFFFF; + bool haveAlpha = pClass->alpha < 1.0; + + if (haveTint || haveAlpha) { + // blend image(pix) with the given tint + + scaledImage = scaledImage.convertDepth( 32 ); + int w = scaledImage.width(); + int h = scaledImage.height(); + float tint_red = float( pClass->tint.red() ) / 255; + float tint_green = float( pClass->tint.green() ) / 255; + float tint_blue = float( pClass->tint.blue() ) / 255; + float tint_alpha = pClass->alpha; + + for (int y = 0; y < h; ++y) { + QRgb *ls = (QRgb *)scaledImage.scanLine( y ); + for (int x = 0; x < w; ++x) { + QRgb l = ls[x]; + int r = int( qRed( l ) * tint_red ); + int g = int( qGreen( l ) * tint_green ); + int b = int( qBlue( l ) * tint_blue ); + int a = int( qAlpha( l ) * tint_alpha ); + ls[x] = qRgba( r, g, b, a ); + } + } + + } + + pClass->readyPixmap.convertFromImage( scaledImage ); + } + // kdDebug() << "Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl; + p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh ); +} + +void +KdmPixmap::statusChanged() +{ + KdmItem::statusChanged(); + if (!pixmap.active.present && !pixmap.prelight.present) + return; + if ((state == Sprelight && !pixmap.prelight.present) || + (state == Sactive && !pixmap.active.present)) + return; + needUpdate(); +} + +#include "kdmpixmap.moc" diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h new file mode 100644 index 000000000..eb621a0a5 --- /dev/null +++ b/kdm/kfrontend/themer/kdmpixmap.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDMPIXMAP_H +#define KDMPIXMAP_H + +#include "kdmitem.h" + +//#include <qrect.h> +#include <qpixmap.h> + +/* + * KdmPixmap. A pixmap element + */ + +class KdmPixmap : public KdmItem { + Q_OBJECT + +public: + KdmPixmap( KdmItem *parent, const QDomNode &node, const char *name = 0 ); + +protected: + // reimplemented; returns the size of loaded pixmap + virtual QSize sizeHint(); + + // draw the pixmap + virtual void drawContents( QPainter *p, const QRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + + virtual void setGeometry( const QRect &newGeometry, bool force ); + + struct PixmapStruct { + struct PixmapClass { + QString fullpath; + QPixmap pixmap; + QPixmap readyPixmap; + QColor tint; + float alpha; //TODO added: not in greeter.dtd + bool present; + } normal, active, prelight; + } pixmap; + +private: + // Method to load the pixmap given by the theme + void loadPixmap( const QString &fileName, QPixmap &p, QString &path ); + void renderSvg( PixmapStruct::PixmapClass *pClass, const QRect &area ); +}; + +#endif diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp new file mode 100644 index 000000000..478c5c8b3 --- /dev/null +++ b/kdm/kfrontend/themer/kdmrect.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdmrect.h" +#include "kdmthemer.h" + +#include <kimageeffect.h> +#include <kdebug.h> + +#include <qimage.h> +#include <qpainter.h> +#include <qwidget.h> +#include <qlayout.h> + +KdmRect::KdmRect( KdmItem *parent, const QDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + itemType = "rect"; + + // Set default values for rect (note: strings are already Null) + rect.normal.alpha = 1; + rect.active.present = false; + rect.prelight.present = false; + rect.hasBorder = false; + + // A rect can have no properties (defaults to parent ones) + if (node.isNull()) + return; + + // Read RECT ID + QDomNode n = node; + QDomElement elRect = n.toElement(); + + // Read RECT TAGS + QDomNodeList childList = node.childNodes(); + for (uint nod = 0; nod < childList.count(); nod++) { + QDomNode child = childList.item( nod ); + QDomElement el = child.toElement(); + QString tagName = el.tagName(); + + if (tagName == "normal") { + parseColor( el.attribute( "color", QString::null ), rect.normal.color ); + rect.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.normal.font ); + } else if (tagName == "active") { + rect.active.present = true; + parseColor( el.attribute( "color", QString::null ), rect.active.color ); + rect.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.active.font ); + } else if (tagName == "prelight") { + rect.prelight.present = true; + parseColor( el.attribute( "color", QString::null ), rect.prelight.color ); + rect.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); + parseFont( el.attribute( "font", "Sans 14" ), rect.prelight.font ); + } else if (tagName == "border") + rect.hasBorder = true; + } +} + +void +KdmRect::drawContents( QPainter *p, const QRect &r ) +{ + // choose the correct rect class + RectStruct::RectClass *rClass = &rect.normal; + if (state == Sactive && rect.active.present) + rClass = &rect.active; + if (state == Sprelight && rect.prelight.present) + rClass = &rect.prelight; + + if (rClass->alpha <= 0 || !rClass->color.isValid()) + return; + + if (rClass->alpha == 1) + p->fillRect( area, QBrush( rClass->color ) ); + else { + QRect backRect = r; + backRect.moveBy( area.x(), area.y() ); + QPixmap backPixmap( backRect.size() ); + bitBlt( &backPixmap, QPoint( 0, 0 ), p->device(), backRect ); + QImage backImage = backPixmap.convertToImage(); + KImageEffect::blend( rClass->color, backImage, rClass->alpha ); + p->drawImage( backRect.x(), backRect.y(), backImage ); + // area.moveBy(1,1); + } +} + +void +KdmRect::statusChanged() +{ + KdmItem::statusChanged(); + if (!rect.active.present && !rect.prelight.present) + return; + if ((state == Sprelight && !rect.prelight.present) || + (state == Sactive && !rect.active.present)) + return; + needUpdate(); +} + +/* +void +KdmRect::setAttribs( QWidget *widget ) +{ + widget->setFont( rect.normal.font ); +} + +void +KdmRect::recursiveSetAttribs( QLayoutItem *li ) +{ + QWidget *w; + QLayout *l; + + if ((w = li->widget())) + setAttribs( w ); + else if ((l = li->layout())) { + QLayoutIterator it = l->iterator(); + for (QLayoutItem *itm = it.current(); itm; itm = ++it) + recursiveSetAttribs( itm ); + } +} + +void +KdmRect::setWidget( QWidget *widget ) +{ + KdmItem::setWidget( widget ); + setAttribs( widget ); +} + +void +KdmRect::setLayoutItem( QLayoutItem *item ) +{ + KdmItem::setLayoutItem( item ); + recursiveSetAttribs( item ); +} +*/ + +#include "kdmrect.moc" diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h new file mode 100644 index 000000000..2e89a6a52 --- /dev/null +++ b/kdm/kfrontend/themer/kdmrect.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDMRECT_H +#define KDMRECT_H + +#include "kdmitem.h" + +#include <qcolor.h> +#include <qfont.h> + +/* + * KdmRect: A themed rectangular element + */ + +class KdmRect : public KdmItem { + Q_OBJECT + +public: + KdmRect( KdmItem *parent, const QDomNode &node, const char *name = 0 ); + +protected: + // draw the rect + virtual void drawContents( QPainter *p, const QRect &r ); + + // handle switching between normal / active / prelight configurations + virtual void statusChanged(); + + struct RectStruct { + struct RectClass { + float alpha; + QColor color; + bool present; + QFont font; + } normal, active, prelight; + bool hasBorder; + } rect; + +// virtual void setWidget( QWidget *widget ); +// virtual void setLayoutItem( QLayoutItem *item ); + +private: + void setAttribs( QWidget *widget ); + void recursiveSetAttribs( QLayoutItem *item ); +}; + +#endif diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp new file mode 100644 index 000000000..65eebabf4 --- /dev/null +++ b/kdm/kfrontend/themer/kdmthemer.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kdmthemer.h" +#include "kdmitem.h" +#include "kdmpixmap.h" +#include "kdmrect.h" +#include "kdmlabel.h" + +#include <kdmconfig.h> +#include <kfdialog.h> + +#include <kiconloader.h> +#include <kimageeffect.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kdebug.h> + +#include <qfile.h> +#include <qfileinfo.h> +//#include <qtimer.h> // animation timer - TODO +#include <qobjectlist.h> +#include <qpainter.h> +#include <qwidget.h> +#include <qregion.h> + +#include <unistd.h> + +/* + * KdmThemer. The main theming interface + */ +KdmThemer::KdmThemer( const QString &_filename, const QString &mode, QWidget *parent ) + : QObject( parent ) + , rootItem( 0 ) + , backBuffer( 0 ) +{ + // Set the mode we're working in + m_currentMode = mode; + + // read the XML file and create DOM tree + QString filename = _filename; + if (!::access( QFile::encodeName( filename + "/GdmGreeterTheme.desktop" ), R_OK )) { + KSimpleConfig cfg( filename + "/GdmGreeterTheme.desktop" ); + cfg.setGroup( "GdmGreeterTheme" ); + filename += '/' + cfg.readEntry( "Greeter" ); + } + QFile opmlFile( filename ); + if (!opmlFile.open( IO_ReadOnly )) { + FDialog::box( widget(), errorbox, i18n( "Cannot open theme file %1" ).arg(filename) ); + return; + } + if (!domTree.setContent( &opmlFile )) { + FDialog::box( widget(), errorbox, i18n( "Cannot parse theme file %1" ).arg(filename) ); + return; + } + // Set the root (screen) item + rootItem = new KdmRect( 0, QDomNode(), "kdm root" ); + connect( rootItem, SIGNAL(needUpdate( int, int, int, int )), + widget(), SLOT(update( int, int, int, int )) ); + + rootItem->setBaseDir( QFileInfo( filename ).dirPath( true ) ); + + // generate all the items defined in the theme + generateItems( rootItem ); + + connect( rootItem, SIGNAL(activated( const QString & )), SIGNAL(activated( const QString & )) ); + +/* *TODO* + // Animation timer + QTimer *time = new QTimer( this ); + time->start( 500 ); + connect( time, SIGNAL(timeout()), SLOT(update()) ) +*/ +} + +KdmThemer::~KdmThemer() +{ + delete rootItem; + delete backBuffer; +} + +inline QWidget * +KdmThemer::widget() +{ + return static_cast<QWidget *>(parent()); +} + +KdmItem * +KdmThemer::findNode( const QString &item ) const +{ + return rootItem->findNode( item ); +} + +void +KdmThemer::updateGeometry( bool force ) +{ + rootItem->setGeometry( QRect( QPoint(), widget()->size() ), force ); +} + +// BEGIN other functions + +void +KdmThemer::widgetEvent( QEvent *e ) +{ + if (!rootItem) + return; + switch (e->type()) { + case QEvent::MouseMove: + { + QMouseEvent *me = static_cast<QMouseEvent *>(e); + rootItem->mouseEvent( me->x(), me->y() ); + } + break; + case QEvent::MouseButtonPress: + { + QMouseEvent *me = static_cast<QMouseEvent *>(e); + rootItem->mouseEvent( me->x(), me->y(), true ); + } + break; + case QEvent::MouseButtonRelease: + { + QMouseEvent *me = static_cast<QMouseEvent *>(e); + rootItem->mouseEvent( me->x(), me->y(), false, true ); + } + break; + case QEvent::Show: + rootItem->show(); + break; + case QEvent::Resize: + updateGeometry( false ); + showStructure( rootItem ); + break; + case QEvent::Paint: + { + QRect paintRect = static_cast<QPaintEvent *>(e)->rect(); + kdDebug() << "paint on: " << paintRect << endl; + + if (!backBuffer) + backBuffer = new QPixmap( widget()->size() ); + if (backBuffer->size() != widget()->size()) + backBuffer->resize( widget()->size() ); + + QPainter p; + p.begin( backBuffer ); + rootItem->paint( &p, paintRect ); + p.end(); + + bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); + } + break; + default: + break; + } +} + +/* +void +KdmThemer::pixmap( const QRect &r, QPixmap *px ) +{ + bitBlt( px, QPoint( 0, 0 ), widget(), r ); +} +*/ + +void +KdmThemer::generateItems( KdmItem *parent, const QDomNode &node ) +{ + if (!parent) + return; + + QDomNodeList subnodeList; //List of subnodes of this node + + /* + * Get the child nodes + */ + if (node.isNull()) { // It's the first node, get its child nodes + QDomElement theme = domTree.documentElement(); + + // Get its tag, and check it's correct ("greeter") + if (theme.tagName() != "greeter") { + kdDebug() << "This does not seem to be a correct theme file." << endl; + return; + } + // Get the list of child nodes + subnodeList = theme.childNodes(); + } else + subnodeList = node.childNodes(); + + /* + * Go through each of the child nodes + */ + for (uint nod = 0; nod < subnodeList.count(); nod++) { + QDomNode subnode = subnodeList.item( nod ); + QDomElement el = subnode.toElement(); + QString tagName = el.tagName(); + + if (tagName == "item") { + if (!willDisplay( subnode )) + continue; + // It's a new item. Draw it + QString type = el.attribute( "type" ); + + KdmItem *newItem = 0; + + if (type == "label") + newItem = new KdmLabel( parent, subnode ); + else if (type == "pixmap") + newItem = new KdmPixmap( parent, subnode ); + else if (type == "rect") + newItem = new KdmRect( parent, subnode ); + else if (type == "entry") { + newItem = new KdmRect( parent, subnode ); + newItem->setType( type ); + } + // newItem = new KdmEntry( parent, subnode ); + //else if (type=="list") + // newItem = new KdmList( parent, subnode ); + else if (type == "svg") + newItem = new KdmPixmap( parent, subnode ); + if (newItem) { + generateItems( newItem, subnode ); + if (el.attribute( "button", "false" ) == "true") + newItem->inheritFromButton( newItem ); + } + } else if (tagName == "box") { + if (!willDisplay( subnode )) + continue; + // It's a new box. Draw it + parent->setBoxLayout( subnode ); + generateItems( parent, subnode ); + } else if (tagName == "fixed") { + if (!willDisplay( subnode )) + continue; + // It's a new box. Draw it + parent->setFixedLayout( subnode ); + generateItems( parent, subnode ); + } + } +} + +bool KdmThemer::willDisplay( const QDomNode &node ) +{ + QDomNode showNode = node.namedItem( "show" ); + + // No "show" node means this item can be displayed at all times + if (showNode.isNull()) + return true; + + QDomElement el = showNode.toElement(); + + QString modes = el.attribute( "modes" ); + if (!modes.isNull()) { + QStringList modeList = QStringList::split( ",", modes ); + + // If current mode isn't in this list, do not display item + if (modeList.find( m_currentMode ) == modeList.end()) + return false; + } + + QString type = el.attribute( "type" ); + if (type == "config" || type == "suspend") + return false; // not implemented (yet) + if (type == "timed") + return _autoLoginDelay != 0; + if (type == "chooser") +#ifdef XDMCP + return _loginMode != LOGIN_LOCAL_ONLY; +#else + return false; +#endif + if (type == "halt" || type == "reboot") + return _allowShutdown != SHUT_NONE; +// if (type == "system") +// return true; + + // All tests passed, item will be displayed + return true; +} + +void +KdmThemer::showStructure( QObject *obj ) +{ + + const QObjectList *wlist = obj->children(); + static int counter = 0; + if (counter == 0) + kdDebug() << "\n\n<======= Widget tree =================" << endl; + if (wlist) { + counter++; + QObjectListIterator it( *wlist ); + QObject *object; + + while ((object = it.current()) != 0) { + ++it; + QString node; + for (int i = 1; i < counter; i++) + node += "-"; + + if (object->inherits( "KdmItem" )) { + KdmItem *widget = (KdmItem *)object; + kdDebug() << node << "|" << widget->type() << " me=" << widget->id << " " << widget->area << endl; + } + + showStructure( object ); + } + counter--; + } + if (counter == 0) + kdDebug() << "\n\n<======= Widget tree =================\n\n" << endl; +} + +#include "kdmthemer.moc" diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h new file mode 100644 index 000000000..34baffbb7 --- /dev/null +++ b/kdm/kfrontend/themer/kdmthemer.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2003 by Unai Garro <ugarro@users.sourceforge.net> + * Copyright (C) 2004 by Enrico Ros <rosenric@dei.unipd.it> + * Copyright (C) 2004 by Stephan Kulow <coolo@kde.org> + * Copyright (C) 2004 by Oswald Buddenhagen <ossi@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KDMTHEMER_H +#define KDMTHEMER_H + +#include <qobject.h> +#include <qdom.h> + +class KdmThemer; +class KdmItem; +class KdmPixmap; +class KdmRect; +class KdmBox; + +class QRect; +class QWidget; +class QEvent; + +/** +* @author Unai Garro +*/ + + + +/* +* The themer widget. Whatever drawn here is just themed +* according to a XML file set by the user. +*/ + + +class KdmThemer : public QObject { + Q_OBJECT + +public: + /* + * Construct and destruct the interface + */ + + KdmThemer( const QString &path, const QString &mode, QWidget *parent ); + ~KdmThemer(); + + bool isOK() { return rootItem != 0; } + /* + * Gives a sizeHint to the widget (parent size) + */ + //QSize sizeHint() const{ return parentWidget()->size(); } + + /* + * Takes a shot of the current widget + */ +// void pixmap( const QRect &r, QPixmap *px ); + + virtual // just to put the reference in the vmt + KdmItem *findNode( const QString & ) const; + + void updateGeometry( bool force ); // force = true for external calls + + // must be called by parent widget + void widgetEvent( QEvent *e ); + +signals: + void activated( const QString &id ); + +private: + /* + * Our display mode (e.g. console, remote, ...) + */ + QString m_currentMode; + + /* + * The config file being used + */ + QDomDocument domTree; + + /* + * Stores the root of the theme + */ + KdmItem *rootItem; + + /* + * The backbuffer + */ + QPixmap *backBuffer; + + // methods + + /* + * Test whether item needs to be displayed + */ + bool willDisplay( const QDomNode &node ); + + /* + * Parses the XML file looking for the + * item list and adds those to the themer + */ + void generateItems( KdmItem *parent = 0, const QDomNode &node = QDomNode() ); + + void showStructure( QObject *obj ); + + QWidget *widget(); +}; + + +#endif diff --git a/kdm/kfrontend/themes/Makefile.am b/kdm/kfrontend/themes/Makefile.am new file mode 100644 index 000000000..bad3ea323 --- /dev/null +++ b/kdm/kfrontend/themes/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = circles diff --git a/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop b/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop new file mode 100644 index 000000000..72be02f41 --- /dev/null +++ b/kdm/kfrontend/themes/circles/GdmGreeterTheme.desktop @@ -0,0 +1,135 @@ +# This is not really a .desktop file like the rest, but it's useful to treat +# it as such + +[GdmGreeterTheme] +Greeter=circles.xml +Name=Circles +Name[ar]=الدوائر +Name[bn]=সার্কল্স +Name[br]=Kelc'hioù +Name[bs]=Krugovi +Name[ca]=Cercles +Name[cs]=Kruhy +Name[csb]=Kółka +Name[cy]=Cylchoedd +Name[da]=Cirkler +Name[de]=Kreise +Name[el]=Κύκλοι +Name[eo]=cirkloj +Name[es]=Círculos +Name[et]=Ringid +Name[fa]=دایرهها +Name[fi]=Ympyrät +Name[fy]=Cirkels +Name[ga]=Ciorcail +Name[he]=מעגלים +Name[hi]=वृत्त +Name[hr]=Krugovi +Name[hu]=Körök +Name[is]=Hringir +Name[it]=Cerchi +Name[ja]=サークル +Name[ka]=წრეები +Name[kk]=Дөңгелектер +Name[km]=រង្វង់ +Name[ko]=원 +Name[lt]=Skrituliai +Name[mk]=Кругови +Name[ms]=Bulatan +Name[nb]=Sirkler +Name[nds]=Krinken +Name[ne]=वृत्त +Name[nl]=Cirkels +Name[nn]=Sirklar +Name[pa]=ਚੱਕਰ +Name[pl]=Kółka +Name[pt]=Círculos +Name[pt_BR]=Círculos +Name[ro]=Cercuri +Name[ru]=Круги +Name[rw]=Inziga +Name[se]=Gearddut +Name[sk]=Kruhy +Name[sl]=Krogi +Name[sr]=Кругови +Name[sr@Latn]=Krugovi +Name[sv]=Cirklar +Name[ta]=வட்டங்கள் +Name[te]=వృత్తాలు +Name[tg]=Доираҳо +Name[tr]=Çemberler +Name[uk]=Кола +Name[uz]=Aylanalar +Name[uz@cyrillic]=Айланалар +Name[vi]=Vòng tròn +Name[wa]=Cekes +Name[zh_CN]=圆环 +Description=Theme with blue circles +Description[af]=Tema met blou sirkels +Description[ar]=سمة بلدوائر الزرقاء +Description[be]=Тэма з блакітнымі коламі +Description[bn]=নীল বৃত্ত সম্বলিত থীম +Description[bs]=Tema sa plavim krugovima +Description[ca]=Tema amb cercles blaus +Description[cs]=Motiv s modrými kruhy +Description[csb]=Téma z mòdrima kółkama +Description[da]=Tema med blå cirkler +Description[de]=Thema mit blauen Kreisen +Description[el]=Θέμα με μπλε κύκλους +Description[eo]=Etoso kun bluaj cirkloj +Description[es]=Tema con círculos azules +Description[et]=Siniste ringidega teema +Description[eu]=Biribil urdindun gaia +Description[fa]=چهره با دایرههای آبی +Description[fi]=Teema sinisillä ympyröillä +Description[fr]=Thème avec des cercles bleus +Description[fy]=Tema mei blauwe sirkels +Description[gl]=Tema con círculos azuis +Description[he]=ערכת נושא עם מעגלים כחולים +Description[hi]=नीले वृत्तों के साथ प्रसंग +Description[hr]=Tema s plavim krugovima +Description[hu]=Téma kék körökkel +Description[is]=Þema með bláum hringjum +Description[it]=Tema con cerchi blu +Description[ja]=青い丸のテーマ +Description[ka]=ლურჯ წრეებიანი თემა +Description[kk]=Көк дөңгелекті нақыш +Description[km]=ស្បែកមានរង្វង់ពណ៌ខៀវ +Description[ko]=파란 원이 있는 테마 +Description[lt]=Tema su melsvais skrituliais +Description[lv]=Tēma ar ziliem riņķiem +Description[mk]=Тема со сини кругови +Description[ms]=Tema dengan bulatan biru +Description[nb]=Tema med blå sirkler +Description[nds]=Muster mit blage Krinken +Description[ne]=निलो वृत्तसँग विषयवस्तु +Description[nl]=Thema met blauwe cirkels +Description[nn]=Tema med blåe sirklar +Description[pa]=ਨੀਲੇ ਚੱਕਰਾਂ ਵਾਲਾ ਸਰੂਪ +Description[pl]=Motyw z niebieskimi kółkami +Description[pt]=Tema com círculos azuis +Description[pt_BR]=Tema com círculos azuis +Description[ro]=Temă cu cercuri albastre +Description[ru]=Тема с синими кругами +Description[rw]=Insanganyamatsiko ifite inziga z'ubururu +Description[se]=Fáddá mas lea alit gearddut +Description[sk]=Téma s modrými kruhmi +Description[sl]=Tema z modrimi krogi +Description[sr]=Тема са плавим круговима +Description[sr@Latn]=Tema sa plavim krugovima +Description[sv]=Tema med blåa cirklar +Description[ta]=நீல வட்டங்களுடன் தலைப்பு +Description[tg]=Мавзӯъ бо доираҳои кабуд +Description[th]=ชุดตกแต่งมาพร้อมวงกลมสีน้ำเงิน +Description[tr]=Mavi çemberli tema +Description[tt]=Zäñgär tügäräklär belän tışlaw +Description[uk]=Тема з синіми колами +Description[uz]=Koʻk aylanalarli mavzu +Description[uz@cyrillic]=Кўк айланаларли мавзу +Description[vi]=Sắc thái với các vòng tròn xanh lam +Description[wa]=Tinme avou des bleus cekes +Description[zh_CN]=带蓝环的主题 +Description[zh_TW]=有藍色圓圈的佈景主題 +Author=Bond, James Bond +Copyright=(c) 2002 Bond, James Bond +Screenshot=screenshot.png diff --git a/kdm/kfrontend/themes/circles/Makefile.am b/kdm/kfrontend/themes/circles/Makefile.am new file mode 100644 index 000000000..97ad04b6a --- /dev/null +++ b/kdm/kfrontend/themes/circles/Makefile.am @@ -0,0 +1,11 @@ +circlesdir = $(kde_datadir)/kdm/themes/circles +circles_DATA = \ + GdmGreeterTheme.desktop \ + circles.xml \ + background.svg \ + flower.png \ + help.png \ + options.png \ + screenshot.png + +EXTRA_DIST = $(circles_DATA) diff --git a/kdm/kfrontend/themes/circles/background.svg b/kdm/kfrontend/themes/circles/background.svg new file mode 100644 index 000000000..11abc4f43 --- /dev/null +++ b/kdm/kfrontend/themes/circles/background.svg @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN" "http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd" [
+ <!ENTITY st0 "fill:url(#aigrd1);stroke:none;">
+ <!ENTITY st1 "fill:url(#aigrd3);stroke:none;">
+ <!ENTITY st2 "fill:url(#aigrd2);stroke:none;">
+ <!ENTITY st3 "fill-rule:nonzero;clip-rule:nonzero;fill:#2A569D;stroke:#000000;stroke-miterlimit:4;">
+ <!ENTITY st4 "stroke:none;">
+]>
+<svg width="508.104pt" height="383.717pt" viewBox="0 0 508.104 383.717" xml:space="preserve">
+ <g id="Layer_x0020_1" style="&st3;">
+ <g id="middle">
+ <linearGradient id="aigrd1" gradientUnits="userSpaceOnUse" x1="237.2617" y1="24.7095" x2="237.2617" y2="371.207">
+ <stop offset="0" style="stop-color:#4E77B9"/>
+ <stop offset="1" style="stop-color:#6E8CBE"/>
+ </linearGradient>
+ <path style="&st0;" d="M59.227,357.212c27.481,9.066,56.985,13.994,87.696,13.994c148.221,0,268.375-114.698,268.375-256.189c0-31.789-6.073-62.221-17.16-90.308C249.869,104.206,131.168,219.909,59.227,357.212z"/>
+ </g>
+ <linearGradient id="aigrd2" gradientUnits="userSpaceOnUse" x1="277.0767" y1="0" x2="277.0766" y2="383.7178">
+ <stop offset="0" style="stop-color:#335EA2"/>
+ <stop offset="1" style="stop-color:#6D8BBD"/>
+ </linearGradient>
+ <path id="lower_x0020_right" style="&st2;" d="M447.704,0c-16.859,7.792-33.389,16.037-49.566,24.709c11.087,28.087,17.16,58.52,17.16,90.308c0,141.491-120.154,256.189-268.375,256.189c-30.71,0-60.214-4.928-87.696-13.994
+ c-4.584,8.749-8.979,17.585-13.178,26.505h462.056V0h-60.4z"/>
+ <g id="upper_x0020_left">
+ <linearGradient id="aigrd3" gradientUnits="userSpaceOnUse" x1="199.0684" y1="0" x2="199.0683" y2="357.2129">
+ <stop offset="0" style="stop-color:#436FB6"/>
+ <stop offset="1" style="stop-color:#305CA3"/>
+ </linearGradient>
+ <path style="&st1;" d="M398.137,24.709C394.798,16.252,391.011,8.005,386.791,0H0v329.44c18.309,11.454,38.174,20.827,59.227,27.772c71.942-137.304,190.642-253.007,338.911-332.503z"/>
+ </g>
+ <g id="bottom_x0020_small">
+ <path style="&st4;" d="M0,329.44v54.277h46.048c4.2-8.92,8.594-17.756,13.178-26.505C38.174,350.267,18.309,340.894,0,329.44z"/>
+ </g>
+ <g id="top_x0020_small">
+ <path style="&st4;" d="M447.704,0h-60.913c4.221,8.005,8.008,16.252,11.347,24.709C414.315,16.037,430.844,7.792,447.704,0z"/>
+ </g>
+ </g>
+</svg>
diff --git a/kdm/kfrontend/themes/circles/circles.xml b/kdm/kfrontend/themes/circles/circles.xml new file mode 100644 index 000000000..0596e0ee7 --- /dev/null +++ b/kdm/kfrontend/themes/circles/circles.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE greeter SYSTEM "greeter.dtd"> +<greeter> + <item type="svg"> + <normal file="background.svg"/> + <pos x="0" y="0" width="100%" height="-75"/> + </item> + <item type="rect"> + <normal color="#000000"/> + <pos x="0" y="-75" width="100%" height="75"/> + <fixed> + <item type="rect"> + <normal color="#ffffff"/> + <pos x="0" y="4" width="100%" height="100%"/> + <box orientation="horizontal" spacing="10" xpadding="10"> + <item type="rect" id="language_button" button="true"> + <normal color="#ffffff"/> + <pos y="50%" anchor="w" width="box" height="box"/> + <box orientation="horizontal" spacing="10" xpadding="10"> + <item type="pixmap"> + <normal file="options.png" tint="#dddddd"/> + <prelight file="options.png"/> + <active file="options.png" tint="#ff0000"/> + <pos y="50%" anchor="w"/> + </item> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <prelight color="#666666" font="Sans 12"/> + <active color="#ff0000" font="Sans 12"/> + <pos y="50%" anchor="w"/> + <!-- Stock label for: _Language --> + <stock type="language"/> + </item> + </box> + </item> + <item type="rect" id="session_button" button="true"> + <normal color="#ffffff"/> + <pos y="50%" anchor="w" width="box" height="box"/> + <box orientation="horizontal" spacing="10" xpadding="10"> + <item type="pixmap"> + <normal file="help.png" tint="#dddddd"/> + <prelight file="help.png"/> + <active file="help.png" tint="#ff0000"/> + <pos y="50%" anchor="w"/> + </item> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <prelight color="#666666" font="Sans 12"/> + <active color="#ff0000" font="Sans 12"/> + <pos y="50%" anchor="w"/> + <!-- Stock label for: _Session --> + <stock type="session"/> + </item> + </box> + </item> + <item type="rect" id="system_button" button="true"> + <normal color="#ffffff"/> + <show modes="console" type="system"/> + <pos y="50%" anchor="w" width="box" height="box"/> + <box orientation="horizontal" spacing="10" xpadding="10"> + <item type="pixmap"> + <normal file="options.png" tint="#dddddd"/> + <prelight file="options.png"/> + <active file="options.png" tint="#ff0000"/> + <pos y="50%" anchor="w"/> + </item> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <prelight color="#666666" font="Sans 12"/> + <active color="#ff0000" font="Sans 12"/> + <pos y="50%" anchor="w"/> + <!-- Stock label for: _Actions --> + <stock type="system"/> + </item> + </box> + </item> + <item type="rect" id="disconnect_button" button="true"> + <normal color="#ffffff"/> + <show modes="flexi,remote"/> + <pos y="50%" anchor="w" width="box" height="box"/> + <box orientation="horizontal" spacing="10" xpadding="10"> + <item type="pixmap"> + <normal file="options.png" tint="#dddddd"/> + <prelight file="options.png"/> + <active file="options.png" tint="#ff0000"/> + <pos y="50%" anchor="w"/> + </item> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <prelight color="#666666" font="Sans 12"/> + <active color="#ff0000" font="Sans 12"/> + <pos y="50%" anchor="w"/> + <!-- Stock label for: D_isconnect --> + <stock type="disconnect"/> + <show modes="remote"/> + </item> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <prelight color="#666666" font="Sans 12"/> + <active color="#ff0000" font="Sans 12"/> + <pos y="50%" anchor="w"/> + <!-- Stock label for: _Quit --> + <stock type="quit"/> + <show modes="flexi"/> + </item> + </box> + </item> + </box> + </item> + </fixed> + </item> + <item type="pixmap"> + <normal file="flower.png"/> + <pos x="100%" y="100%" anchor="se"/> + </item> + <item type="label" id="clock"> + <normal color="#000000" font="Sans 12"/> + <pos x="-20" y="-37" anchor="e"/> + <text>%c</text> + </item> + + <item type="rect" id="caps-lock-warning"> + <normal color="#FFFFFF" alpha="0.5"/> + <pos anchor="c" x="50%" y="75%" width="box" height="box"/> + <box orientation="vertical" min-width="400" xpadding="10" ypadding="5" spacing="0"> + <item type="label"> + <normal color="#000000" font="Sans 12"/> + <pos x="50%" anchor="n"/> + <!-- Stock label for: You've got capslock on! --> + <stock type="caps-lock-warning"/> + </item> + </box> + </item> + + <item type="rect"> + <show type="timed"/> + <normal color="#FFFFFF" alpha="0.5"/> + <pos anchor="c" x="50%" y="25%" width="box" height="box"/> + <box orientation="vertical" min-width="400" xpadding="10" ypadding="5" spacing="0"> + <item type="label" id="timed-label"> + <normal color="#000000" font="Sans 12"/> + <pos x="50%" anchor="n"/> + <!-- Stock label for: User %s will login in %d seconds --> + <stock type="timed-label"/> + </item> + </box> + </item> + + <item type="rect"> + <normal color="#FFFFFF" alpha="0.5"/> + <pos anchor="c" x="50%" y="50%" width="box" height="box"/> + <box orientation="vertical" min-width="340" xpadding="30" ypadding="30" spacing="10"> + <item type="label"> + <pos anchor="n" x="50%"/> + <normal color="#000000" font="Sans 14"/> + <!-- Stock label for: Welcome to %h --> + <stock type="welcome-label"/> + </item> + <item type="rect" id="talker"> + <normal color="#0" alpha="0"/> + <pos anchor="n" x="50%" width="box" height="box"/> + <!-- box orientation="vertical" xpadding="0" ypadding="0" spacing="10" --> + <box orientation="horizontal" xpadding="0" ypadding="0" spacing="0"> + <item type="rect"> + <normal color="#FF8080" alpha="0.0"/> + <pos anchor="w" y="50%" width="box" height="box"/> + <box orientation="vertical" xpadding="0" ypadding="0" spacing="14"> + <item type="label"> + <pos anchor="ne" x="100%"/> + <normal color="#000000" font="Sans 12"/> + <!-- Stock label for: Username: --> + <stock type="username-label"/> + </item> + <item type="label"> + <pos anchor="ne" x="100%"/> + <normal color="#000000" font="Sans 12"/> + <!-- Stock label for: Password: --> + <stock type="password-label"/> + </item> + </box> + </item> + <item type="rect"> + <normal color="#FF80FF" alpha="0.0"/> + <pos anchor="w" y="50%" width="box" height="box"/> + <box orientation="vertical" xpadding="0" ypadding="0" spacing="10"> + <item type="entry" id="user-entry"> + <pos anchor="n" x="50%" height="24" width="150"/> + </item> + <item type="entry" id="pw-entry"> + <pos anchor="n" x="50%" height="24" width="150"/> + </item> + </box> + </item> + </box> + </item> + </box> + <fixed> + <item type="label" id="pam-error"> + <pos anchor="n" x="50%" y="110%"/> + <normal color="#000000" font="Sans 12"/> + <text></text> + </item> + </fixed> + </item> +</greeter> + + diff --git a/kdm/kfrontend/themes/circles/flower.png b/kdm/kfrontend/themes/circles/flower.png Binary files differnew file mode 100644 index 000000000..92d25f32d --- /dev/null +++ b/kdm/kfrontend/themes/circles/flower.png diff --git a/kdm/kfrontend/themes/circles/help.png b/kdm/kfrontend/themes/circles/help.png Binary files differnew file mode 100644 index 000000000..b38b48a6d --- /dev/null +++ b/kdm/kfrontend/themes/circles/help.png diff --git a/kdm/kfrontend/themes/circles/options.png b/kdm/kfrontend/themes/circles/options.png Binary files differnew file mode 100644 index 000000000..3c08e02d4 --- /dev/null +++ b/kdm/kfrontend/themes/circles/options.png diff --git a/kdm/kfrontend/themes/circles/screenshot.png b/kdm/kfrontend/themes/circles/screenshot.png Binary files differnew file mode 100644 index 000000000..7120b03d5 --- /dev/null +++ b/kdm/kfrontend/themes/circles/screenshot.png |