dslinux/user/pixil/packages/flash/flash/Kflash/saver_common Makefile kscreensave.C kscreensave.h kscreensaver.pam main.C main.h mode.h passwd.C saver.C saver.h xautolock.C xautolock.h xlock.C xlock.h xlockmore.h xs_colors.c xs_colors.h xs_hsv.c xs_hsv.h xs_utils.h xs_visual.c xs_visual.h xs_yarandom.h

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:10 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/packages/flash/flash/Kflash/saver_common
In directory antilope:/tmp/cvs-serv11916/packages/flash/flash/Kflash/saver_common

Added Files:
	Makefile kscreensave.C kscreensave.h kscreensaver.pam main.C 
	main.h mode.h passwd.C saver.C saver.h xautolock.C xautolock.h 
	xlock.C xlock.h xlockmore.h xs_colors.c xs_colors.h xs_hsv.c 
	xs_hsv.h xs_utils.h xs_visual.c xs_visual.h xs_yarandom.h 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: xs_visual.c ---
/* xscreensaver, Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
 *  by Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

/* This file contains some code for intelligently picking the best visual
   (where "best" is biased in the direction of either: high color counts;
   or: having writable color cells...)
 */

#include "xs_utils.h"

#include "xs_visual.h"

#include <X11/Xutil.h>

/* extern char *progname; */


#ifndef isupper
# define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
#endif
#ifndef _tolower
# define _tolower(c)  ((c) - 'A' + 'a')
#endif


static Visual *pick_best_visual (Screen *, Bool, Bool);
static Visual *pick_mono_visual (Screen *);
static Visual *pick_best_visual_of_class (Screen *, int);
static Visual *id_to_visual (Screen *, int);
static Visual *id_to_visual (Screen *screen, int id);


#define DEFAULT_VISUAL	-1
#define BEST_VISUAL	-2
#define MONO_VISUAL	-3
#define GRAY_VISUAL	-4
#define COLOR_VISUAL	-5
#define SPECIFIC_VISUAL	-6

Visual *
get_visual (Screen *screen, const char *string, Bool prefer_writable_cells,
	    Bool verbose_p)
{
  char *v = (string ? strdup(string) : 0);
  char c, *tmp;
  int vclass;
  unsigned long id;
  Visual *result = 0;

  if (v)
    for (tmp = v; *tmp; tmp++)
      if (isupper (*tmp)) *tmp = _tolower (*tmp);

  if (!v)					  vclass = BEST_VISUAL;
  else if (!strcmp (v, "default"))		  vclass = DEFAULT_VISUAL;
  else if (!strcmp (v, "best")) 		  vclass = BEST_VISUAL;
  else if (!strcmp (v, "mono")) 		  vclass = MONO_VISUAL;
  else if (!strcmp (v, "monochrome")) 		  vclass = MONO_VISUAL;
  else if (!strcmp (v, "gray")) 		  vclass = GRAY_VISUAL;
  else if (!strcmp (v, "grey")) 		  vclass = GRAY_VISUAL;
  else if (!strcmp (v, "color")) 		  vclass = COLOR_VISUAL;
  else if (!strcmp (v, "staticgray"))	 	  vclass = StaticGray;
  else if (!strcmp (v, "staticcolor"))		  vclass = StaticColor;
  else if (!strcmp (v, "truecolor"))		  vclass = TrueColor;
  else if (!strcmp (v, "grayscale"))		  vclass = GrayScale;
  else if (!strcmp (v, "greyscale"))		  vclass = GrayScale;
  else if (!strcmp (v, "pseudocolor"))		  vclass = PseudoColor;
  else if (!strcmp (v, "directcolor"))		  vclass = DirectColor;
  else if (1 == sscanf (v, " %ld %c", &id, &c))	  vclass = SPECIFIC_VISUAL;
  else if (1 == sscanf (v, " 0x%lx %c", &id, &c)) vclass = SPECIFIC_VISUAL;
  else
    {
      fprintf (stderr, "%s: unrecognized visual \"%s\".\n", "kscreensaver", v);
      vclass = DEFAULT_VISUAL;
    }

  if (vclass == DEFAULT_VISUAL)
    result = DefaultVisualOfScreen (screen);
  else if (vclass == BEST_VISUAL)
    result = pick_best_visual (screen, prefer_writable_cells, False);
  else if (vclass == MONO_VISUAL)
    {
      result = pick_mono_visual (screen);
      if (!result && verbose_p)
	fprintf (stderr, "%s: no monochrome visuals.\n", "kscreensaver");
    }
  else if (vclass == GRAY_VISUAL)
    {
      if (prefer_writable_cells)
	result = pick_best_visual_of_class (screen, GrayScale);
      if (!result)
	result = pick_best_visual_of_class (screen, StaticGray);
      if (!result)
	result = pick_best_visual_of_class (screen, GrayScale);
      if (!result && verbose_p)
	fprintf (stderr, "%s: no GrayScale or StaticGray visuals.\n",
		 "kscreensaver");
    }
  else if (vclass == COLOR_VISUAL)
    {
      int class;
      /* First see if the default visual will do. */
      result = DefaultVisualOfScreen (screen);
      class = visual_class(screen, result);
      if (class != TrueColor &&
	  class != PseudoColor &&
	  class != DirectColor &&
	  class != StaticColor)
	result = 0;
      if (result && visual_depth(screen, result) <= 1)
	result = 0;

      /* Else, find the best non-default color visual */
      if (!result)
	result = pick_best_visual (screen, prefer_writable_cells, True);

      if (!result && verbose_p)
	fprintf (stderr, "%s: no color visuals.\n", "kscreensaver");
    }
  else if (vclass == SPECIFIC_VISUAL)
    {
      result = id_to_visual (screen, id);
      if (!result && verbose_p)
	fprintf (stderr, "%s: no visual with id 0x%x.\n", "kscreensaver",
		 (unsigned int) id);
    }
  else
    {
      Visual *visual = pick_best_visual_of_class (screen, vclass);
      if (visual)
	result = visual;
      else if (verbose_p)
	fprintf (stderr, "%s: no visual of class %s.\n", "kscreensaver", v);
    }

  if (v) free (v);
  return result;
}

Visual *
get_visual_resource (Screen *screen, char *name, char *class,
		     Bool prefer_writable_cells)
{
/*
  char *string = get_string_resource (name, class);
  Visual *v = get_visual (screen, string, prefer_writable_cells, True);
  if (string)
    free(string);
  if (v)
    return v;
  else
*/
    return DefaultVisualOfScreen (screen);
}


static Visual *
pick_best_visual (Screen *screen, Bool prefer_writable_cells, Bool color_only)
{
  Visual *visual;

  if (!prefer_writable_cells)
    {
      /* If we don't prefer writable cells, then the "best" visual is the one
	 on which we can allocate the largest range and number of colors.

	 Therefore, a TrueColor visual which is at least 16 bits deep is best.
	 (The assumption here being that a TrueColor of less than 16 bits is
	 really just a PseudoColor visual with a pre-allocated color cube.)

	 The next best thing is a PseudoColor visual of any type.  After that
	 come the non-colormappable visuals, and non-color visuals.
       */
      if ((visual = pick_best_visual_of_class (screen, TrueColor)) &&
	  visual_depth (screen, visual) >= 16)
	return visual;
    }

#define TRY_CLASS(CLASS) \
  if ((visual = pick_best_visual_of_class (screen, CLASS)) && \
      (!color_only || visual_depth(screen, visual) > 1)) \
    return visual
  TRY_CLASS(PseudoColor);
  TRY_CLASS(TrueColor);
  TRY_CLASS(DirectColor);
  TRY_CLASS(StaticColor);
  if (!color_only)
    {
      TRY_CLASS(GrayScale);
      TRY_CLASS(StaticGray);
    }
#undef TRY_CLASS

  visual = DefaultVisualOfScreen (screen);
  if (!color_only || visual_depth(screen, visual) > 1)
    return visual;
  else
    return 0;
}

static Visual *
pick_mono_visual (Screen *screen)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count;

  vi_in.depth = 1;
  vi_in.screen = screen_number (screen);
  vi_out = XGetVisualInfo (dpy, (VisualDepthMask | VisualScreenMask),
			   &vi_in, &out_count);
  if (vi_out)
    {
      Visual *v = (out_count > 0 ? vi_out [0].visual : 0);
      if (v && vi_out[0].depth != 1)
	v = 0;
      XFree ((char *) vi_out);
      return v;
    }
  else
    return 0;
}


static Visual *
pick_best_visual_of_class (Screen *screen, int visual_class)
{
  /* The best visual of a class is the one which on which we can allocate
     the largest range and number of colors, which means the one with the
     greatest depth and number of cells.

     (But actually, for XDaliClock, all visuals of the same class are
     probably equivalent - either we have writable cells or we don't.)
   */
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count;

  vi_in.class = visual_class;
  vi_in.screen = screen_number (screen);
  vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask),
			   &vi_in, &out_count);
  if (vi_out)
    {
      /* choose the 'best' one, if multiple */
      int i, best;
      Visual *visual;
      for (i = 0, best = 0; i < out_count; i++)
	/* It's better if it's deeper, or if it's the same depth with
	   more cells (does that ever happen?  Well, it could...) */
	if ((vi_out [i].depth > vi_out [best].depth) ||
	    ((vi_out [i].depth == vi_out [best].depth) &&
	     (vi_out [i].colormap_size > vi_out [best].colormap_size)))
	  best = i;
      visual = (best < out_count ? vi_out [best].visual : 0);
      XFree ((char *) vi_out);
      return visual;
    }
  else
    return 0;
}

static Visual *
id_to_visual (Screen *screen, int id)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = id;
  vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
			   &vi_in, &out_count);
  if (vi_out)
    {
      Visual *v = vi_out[0].visual;
      XFree ((char *) vi_out);
      return v;
    }
  return 0;
}

int
visual_depth (Screen *screen, Visual *visual)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count, d;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
			   &vi_in, &out_count);
  if (! vi_out) abort ();
  d = vi_out [0].depth;
  XFree ((char *) vi_out);
  return d;
}


#if 0
/* You very probably don't want to be using this.
   Pixmap depth doesn't refer to the depths of pixmaps, but rather, to
   the depth of protocol-level on-the-wire pixmap data, that is, XImages.
   To get this info, you should be looking at XImage->bits_per_pixel
   instead.  (And allocating the data for your XImage structures by
   multiplying ximage->bytes_per_line by ximage->height.)
 */
int
visual_pixmap_depth (Screen *screen, Visual *visual)
{
  Display *dpy = DisplayOfScreen (screen);
  int vdepth = visual_depth (screen, visual);
  int pdepth = vdepth;
  int i, pfvc = 0;
  XPixmapFormatValues *pfv = XListPixmapFormats (dpy, &pfvc);

  /* Return the first matching depth in the pixmap formats.  If there are no
     matching pixmap formats (which shouldn't be able to happen at all) then
     return the visual depth instead. */
  for (i = 0; i < pfvc; i++)
    if (pfv[i].depth == vdepth)
      {
	pdepth = pfv[i].bits_per_pixel;
	break;
      }
  if (pfv)
    XFree (pfv);
  return pdepth;
}
#endif /* 0 */


int
visual_class (Screen *screen, Visual *visual)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count, c;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
			   &vi_in, &out_count);
  if (! vi_out) abort ();
  c = vi_out [0].class;
  XFree ((char *) vi_out);
  return c;
}

Bool
has_writable_cells (Screen *screen, Visual *visual)
{
  switch (visual_class (screen, visual))
    {
    case GrayScale:	/* Mappable grays. */
    case PseudoColor:	/* Mappable colors. */
      return True;
    case StaticGray:	/* Fixed grays. */
    case TrueColor:	/* Fixed colors. */
    case StaticColor:	/* (What's the difference again?) */
    case DirectColor:	/* DirectColor visuals are like TrueColor, but have
			   three colormaps - one for each component of RGB.
			   Screw it. */
      return False;
    default:
      abort();
    }
}

void
describe_visual (FILE *f, Screen *screen, Visual *visual, Bool private_cmap_p)
{
  char n[10];
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
			   &vi_in, &out_count);
  if (! vi_out) abort ();
  if (private_cmap_p)
    sprintf(n, "%3d", vi_out->colormap_size);
  else
    strcpy(n, "default");

  fprintf (f, "0x%02x (%s depth: %2d, cmap: %s)\n",
	   (unsigned int) vi_out->visualid,
	   (vi_out->class == StaticGray  ? "StaticGray, " :
	    vi_out->class == StaticColor ? "StaticColor," :
	    vi_out->class == TrueColor   ? "TrueColor,  " :
	    vi_out->class == GrayScale   ? "GrayScale,  " :
	    vi_out->class == PseudoColor ? "PseudoColor," :
	    vi_out->class == DirectColor ? "DirectColor," :
					   "UNKNOWN:    "),
	   vi_out->depth, n);
  XFree ((char *) vi_out);
}

int
screen_number (Screen *screen)
{
  Display *dpy = DisplayOfScreen (screen);
  int i;
  for (i = 0; i < ScreenCount (dpy); i++)
    if (ScreenOfDisplay (dpy, i) == screen)
      return i;
  abort ();
}

int
visual_cells (Screen *screen, Visual *visual)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  int out_count, c;
  vi_in.screen = screen_number (screen);
  vi_in.visualid = XVisualIDFromVisual (visual);
  vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask,
			   &vi_in, &out_count);
  if (! vi_out) abort ();
  c = vi_out [0].colormap_size;
  XFree ((char *) vi_out);
  return c;
}

Visual *
find_similar_visual(Screen *screen, Visual *old_visual)
{
  Display *dpy = DisplayOfScreen (screen);
  XVisualInfo vi_in, *vi_out;
  Visual *result = 0;
  int out_count;

  vi_in.screen = screen_number (screen);
  vi_in.class  = visual_class (screen, old_visual);
  vi_in.depth  = visual_depth (screen, old_visual);

  /* Look for a visual of the same class and depth.
   */
  vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualClassMask |
				 VisualDepthMask),
			   &vi_in, &out_count);
  if (vi_out && out_count > 0)
    result = vi_out[0].visual;
  if (vi_out) XFree (vi_out);
  vi_out = 0;

  /* Failing that, look for a visual of the same class.
   */
  if (!result)
    {
      vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualClassMask),
			       &vi_in, &out_count);
      if (vi_out && out_count > 0)
	result = vi_out[0].visual;
      if (vi_out) XFree (vi_out);
      vi_out = 0;
    }

  /* Failing that, return the default visual. */
  if (!result)
    result = DefaultVisualOfScreen (screen);

  return result;
}

--- NEW FILE: xautolock.h ---

typedef enum { IGNORE, FORCE_SAVE, FORCE_LOCK } CornerAction;

void setCorners( const char * );
void forceTimeout();
void initAutoLock();
void cleanupAutoLock();
int  waitTimeout( int );


--- NEW FILE: xlock.h ---
#ifndef __XLOCK_H__
#define __XLOCK_H__

/*-
 * @(#)xlock.h	3.3 95/09/24 xlockmore 
 *
 * xlock.h - external interfaces for new modes and SYSV OS defines.
 *
 * Copyright (c) 1991 by Patrick J. Naughton.
 *
 * See xlock.c for copying information.
 *
 * Revision History:
 *
 * Changes of David Bagley <bagleyd at source.asset.com>
 * 12-May-95: Added defines for SunOS's Adjunct password file
 *            Dale A. Harris <rodmur at ecst.csuchico.edu>
 * 18-Nov-94: Modified for QNX 4.2 w/ Metrolink X server from Brian Campbell
 *            <brianc at qnx.com>.
 * 11-Jul-94: added Bool flag: inwindow, which tells xlock to run in a
 *            window from Greg Bowering <greg at cs.adelaide.edu.au>
 * 11-Jul-94: patch for Solaris SYR4 from Chris P. Ross <cross at eng.umd.edu>
 * 28-Jun-94: Reorganized shadow stuff
 * 24-Jun-94: Reorganized
 * 22-Jun-94: Modified for VMS
 *            <Anthony.D.Clarke at Support.Hatfield.Raytheon.bae.eurokom.ie>
 * 17-Jun-94: patched shadow passwords and bcopy and bzero for SYSV from
 *            <reggers at julian.uwo.ca>
 * 21-Mar-94: patched the patch for AIXV3 and HP from
 *            <R.K.Lloyd at csc.liv.ac.uk>.
 * 01-Dec-93: added patch for AIXV3 from
 *            (Tom McConnell, tmcconne at sedona.intel.com) also added a patch
 *            for HP-UX 8.0.
 *
 */

#include <qapp.h> // hack for qt-1.2
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xresource.h>

// added for kscreensave
void initXLock( GC gc );


#define MAXSCREENS        1
#define NUMCOLORS         64
#ifndef KERBEROS
#define PASSLENGTH        64
#else
#define PASSLENGTH        120
#endif
#define FALLBACK_FONTNAME "fixed"
#ifndef DEF_MFONT
#define DEF_MFONT "-*-times-*-*-*-*-18-*-*-*-*-*-*-*"
#endif
#ifndef DEF_PROGRAM  /* Try the -o option ;) */
#define DEF_PROGRAM "fortune -s"
#endif

#define ICONW             64
#define ICONH             64

#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif

#if defined VMS || defined __QNX__
#ifdef VMS
/*#define VMS_PLAY*/
#include <unixlib.h>
#endif
#endif

#include <math.h>

#ifndef M_E
#define M_E    2.7182818284590452354
#endif
#ifndef M_PI
#define M_PI   3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif

#if !defined (news1800) && !defined (sun386)
#include <stdlib.h>
#if !defined (apollo) && !defined (VMS)
#include <unistd.h>
#include <memory.h>
#endif
#endif
#include <stdio.h>
#include <string.h>
 
typedef struct {
  GC            gc;                /* graphics context for animation */
  int           npixels;           /* number of valid entries in pixels */
  Colormap      cmap;              /* current colormap */
  unsigned long pixels[NUMCOLORS]; /* pixel values in the colormap */
  unsigned long bgcol, fgcol;      /* background and foreground pixel values */
} perscreen;

/* This stuff moved here from resource.c for the mode-specific options. */
#define t_String        0
#define t_Float         1
#define t_Int           2
#define t_Bool          3

typedef struct {
    caddr_t    *var;
    char       *name;
    char       *arg_class;
    char       *def;
    int         type;
} argtype;

typedef struct {
    char       *opt;
    char       *desc;
} OptionStruct;

typedef struct {
    int              numopts;
    XrmOptionDescRec *opts;
    argtype          *vars;
    OptionStruct     *desc;
} ModeSpecOpt;
/* End moved from resource.c */

extern perscreen Scr[MAXSCREENS];
extern Display *dsp;
extern int  screen;

extern char  *ProgramName;
extern char  *fontname;
extern char  *background;
extern char  *foreground;
extern char  *text_name;
extern char  *text_pass;
extern char  *text_info;
extern char  *text_valid;
extern char  *text_invalid;
extern char  *geometry;
extern float saturation;
extern int   nicelevel;
extern int   delay;
extern int   batchcount;
extern int   cycles;
extern int   timeout;
extern int   lockdelay;
#if defined(HAS_RPLAY) || defined(VMS_PLAY)
extern char  *locksound;
extern char  *infosound;
extern char  *validsound;
/*extern char  *invalidsound;*/
#endif
#ifdef AUTO_LOGOUT
extern int   forceLogout;
#endif
#ifdef LOGOUT_BUTTON
extern int   enable_button;
extern char  *logoutButtonLabel;
extern char  *logoutButtonHelp;
extern char  *logoutFailedString;
#endif
extern Bool  usefirst;
extern Bool  mono;
extern Bool  nolock;
extern Bool  allowroot;
extern Bool  enablesaver;
extern Bool  allowaccess;
extern Bool  grabmouse;
extern Bool  echokeys;
extern Bool  verbose;
extern Bool  inwindow;
extern Bool  inroot;
extern Bool  timeelapsed;
extern Bool  install;
extern int   onepause;

/* For modes with text, marquee & nose */
extern char *program;
extern char *messagesfile;
extern char *messagefile;
extern char *message;
extern char *mfont;

extern void  (*callback) ();
extern void  (*init) ();

extern void GetResources();
extern void set_colormap();
extern void fix_colormap();
#ifdef __STDC__
extern void error(char *, ...);
#else
extern void error();
#endif
extern void alarm_ctl();
extern long seconds();

/* For modes with text, marquee & nose */
extern XFontStruct *get_font();
extern char *get_words();
extern void init_words();
extern int is_ribbon();

#ifdef LESS_THAN_AIX3_2
#undef NULL
#define NULL 0
#endif /* LESS_THAN_AIX3_2 */

#ifdef VMS
#define OLD_EVENT_LOOP
#endif

#if defined(__STDC__) && (defined(__hpux) && defined(_PA_RISC1_1))
#define MATHF
#endif
#ifdef MATHF
#define SINF(n) sinf(n)
#define COSF(n) cosf(n)
#define FABSF(n) fabsf(n)
#else
#define SINF(n) ((float)sin((double)(n)))
#define COSF(n) ((float)cos((double)(n)))
#define FABSF(n) ((float)fabs((double)(n)))
#endif

/*** random number generator ***/
/* We can always use random and srandom.
   They are provided by fakes.cpp if they're not present */
#define SRAND srandom
#define LRAND random
#ifndef MAXRAND
#define MAXRAND (2147483648.0)
#endif

#define NRAND(X) ((int)(LRAND()%(X)))

#endif /* __XLOCK_H__ */

--- NEW FILE: passwd.C ---

#if !defined( lint ) && !defined( SABER )
static const char sccsid[] = "@(#)passwd.c	4.02 97/04/01 xlockmore";

#endif

/*-
 * passwd.cpp, part of the KDE kscreensaver
 *
 * changes: 06-Jun-98: updated for PAM support.
 * Code is taken essentially verbatim from xlockmore 4.09. 
 * PAM support in xlockmore is attributed as:
 * 24-Jan-98: Updated PAM support and made it configure-able.
 *            Marc Ewing <marc at redhat.com>  Original PAM support from
 *            25-Jul-96 Michael K. Johnson <johnsonm at redhat.com>
 *---------------------------------------------------------
 * passwd.c - passwd stuff.
 *
 * Copyright (c) 1988-91 by Patrick J. Naughton.
[...1433 lines suppressed...]
#ifdef        BSD_AUTH
                struct passwd *pwd = getpwnam(user);
 
                lc = login_getclass(pwd->pw_class);
                if (allowroot && (pwd = getpwnam(ROOT)) != NULL)
                        rlc = login_getclass(pwd->pw_class);
#else /* !BSD_AUTH */
                getCryptedUserPasswd();
                if (allowroot)
		    getCryptedRootPasswd();
#endif /* !BSD_AUTH */
        }
#endif /* !ultrix && !DCE_PASSWD && !USE_PAM*/
#ifdef DCE_PASSWD
        initDCE();
#endif

}



--- NEW FILE: Makefile ---
CXXSOURCES = \
	main.C \
	xautolock.C \
	saver.C \
	passwd.C \
	xlock.C \

CSOURCES = \
	xs_colors.c \
	xs_hsv.c \
	xs_visual.c

TARGET = libsvrcmn.a

OBJECTS = $(CSOURCES:.c=.o) $(CXXSOURCES:.C=.o)
CFG = -DHAVE_SETEUID -DHAVE_UNISTD_H -DHAVE_SYSLOG_H -DHAVE_CRYPT_H -DHAVE_PAM -DKDE_PAM_SERVICE -DHAVE_SHADOW -DHAVE_XPM

CXXFLAGS = $(CFG) -I/usr/include/qt
RANLIB = ranlib

# ok, all variables should be exported from top-level makefile

all: $(TARGET)

$(TARGET): $(OBJECTS)
	-rm -f $(TARGET)
	$(AR) rc $(TARGET) $(OBJECTS)
	$(RANLIB) $(TARGET)

clean:
	-rm -f core $(OBJECTS) *.moc
	-rm -f $(TARGET)

%.o: %.c
	$(CC) $(FLAGS) $(CFLAGS) $(INCS) -c $<

%.o: %.C
	$(CXX) $(FLAGS) $(CXXFLAGS) $(INCS) -c $<

MOC = moc

%.moc: %.h
	$(MOC) $*.h -o $*.moc

# dependencies
main.moc: main.h
main.o: main.moc main.h
saver.moc: saver.h
saver.o: saver.moc saver.h

xautolock.o: xautolock.h
xlock.o: xlock.h
passwd.o: xlockmore.h
xlockmore.h: mode.h
xs_colors.o: xs_colors.h
xs_hsv.o: xs_hsv.h
xs_visual.o: xs_visual.h

--- NEW FILE: xs_visual.h ---
/* xscreensaver, Copyright (c) 1993-1998 by Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

#ifndef __VISUAL_H__
#define __VISUAL_H__

extern Visual *get_visual (Screen *, const char *name, Bool, Bool);
extern Visual *get_visual_resource (Screen *, char *, char *, Bool);
extern int visual_depth (Screen *, Visual *);
/* extern int visual_pixmap_depth (Screen *, Visual *); */
extern int visual_class (Screen *, Visual *);
extern int visual_cells (Screen *, Visual *);
extern int screen_number (Screen *);
extern Visual *find_similar_visual (Screen *, Visual *old);
extern void describe_visual (FILE *f, Screen *, Visual *, Bool private_cmap_p);
extern Visual *get_overlay_visual (Screen *, unsigned long *pixel_return);
extern Bool has_writable_cells (Screen *screen, Visual *visual);

#endif /* __VISUAL_H__ */

--- NEW FILE: kscreensave.C ---
//-----------------------------------------------------------------------------
// $Id: kscreensave.C,v 1.1 2006-10-03 11:26:06 dslinux_amadeus Exp $
// KDE screen saver
//-----------------------------------------------------------------------------

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <kapp.h>

#include "kscreensave.h"

int sendSignal()
{
	QString buffer(getenv("HOME"));

	buffer.append("/.kss-install.pid.");
        char ksshostname[200];
        gethostname(ksshostname, 200);
        buffer.append(ksshostname);
	int r = -1;
	FILE *fp;

	if ( (fp = fopen( buffer, "r" ) ) != NULL )
	{
		// a screen saver is running - just tell it to lock
		int pid;

		fscanf( fp, "%d", &pid );
		fclose( fp );

                // But only kill it if the pid isn't -1!
                if (pid > 0) {
                  if( kill( pid, SIGUSR1 ) == 0 )
			  r = 0;
		}
	}

	return r;
}

void kForceLocker()
{
	if( sendSignal() != 0 )
	{
		KConfig *kdisplayConfig = new KConfig( kapp->kde_configdir() + "/kdisplayrc",
		                                       kapp->localconfigdir() + "/kdisplayrc" );
		kdisplayConfig->setGroup("ScreenSaver");
		bool allowRoot = kdisplayConfig->readBoolEntry( "allowRoot", false );
		delete kdisplayConfig;
		char *root = "-allow-root";
		if( !allowRoot )
			root = 0;

		// either no saver is running or an old pidFile was not removed
		QString buffer = QString(KApplication::kde_bindir().data());
		buffer.append("/kblankscrn.kss");
	    
		if ( fork() == 0 )
		{
			execlp( buffer, buffer, "-install", "-delay", "0", "-lock", root, 0 );

			// if we make it here then try again using default path
			execlp("kblankscrn.kss","kblankscrn.kss", "-install", "-delay", "0", "-lock", root, 0);
		    
			// uh oh - failed
			fprintf( stderr, "Could not invoke kblankscrn.kss in $PATH or"
			         " %s/bin\n" , KApplication::kde_bindir().data());
			exit (1);
		}
	}
}

--- NEW FILE: saver.C ---
#include <pwd.h>
#include <unistd.h>
#include <qapp.h>
#include <X11/Xlib.h>
#include <qbitmap.h>
#include "main.h"  // ssApp
#include <kapp.h>  // for kde_bindir()
#include <kcharsets.h>
#include <kprocess.h>
#include <qpushbt.h>
#include <qlined.h>
#include <qframe.h>
#include <qkeycode.h>
//#include "config.h"
#include "saver.h"

#include "saver.moc"

#define MAX_PASSWORD_LENGTH	20

extern KLocale *glocale;
extern ssApp *globalKapp;

int checkPasswd(char *);


kScreenSaver::kScreenSaver( Drawable drawable ) : QObject()
{
	Window root;
	int ai;
	unsigned int au;

	d = drawable;
	gc = XCreateGC( qt_xdisplay(), d, 0, 0);
	XGetGeometry( qt_xdisplay(), drawable, &root, &ai, &ai,
		&width, &height, &au, &au ); 
}

kScreenSaver::~kScreenSaver()
{
	XFreeGC( qt_xdisplay(), gc );
}

void kScreenSaver::expose( int x, int y, int width, int height )
{
    XSetForeground(qt_xdisplay(), gc, BlackPixel(qt_xdisplay(), qt_xscreen()));
    XFillRectangle(qt_xdisplay(), d, gc, x, y, width, height);                  
}

//-----------------------------------------------------------------------------

KPasswordDlg::KPasswordDlg( QWidget *parent, bool s ) : QWidget( parent )
{
	setCursor( arrowCursor );

	stars = s;
	password = "";

	QFrame *frame = new QFrame( this );
	frame->setFrameStyle( QFrame::Panel | QFrame::Raised );
	frame->setLineWidth( 2 );
	frame->setGeometry( 0, 0, 200, 100 );

	QFont font( "helvetica", 18 );
	KApplication::getKApplication()->getCharsets()->setQFont(font);
	label = new QLabel( glocale->translate("Enter Password"), frame );
	label->setGeometry( 20, 20, 160, 30 );
	label->setAlignment( AlignCenter );
	label->setFont( font );
	
	font.setPointSize( 16 );
	KApplication::getKApplication()->getCharsets()->setQFont(font);
	entry = new QLabel( "", frame );
	entry->setGeometry( 20, 60, 160, 30 );
	entry->setFont( font );	

	resize( 200, 100 );

	connect( &timer, SIGNAL( timeout() ), SLOT( timeout() ) );

	timerMode = 0;
	timer.start( 10000, TRUE );
	
	if( stars )
	{
		blinkTimer = new QTimer( this, "blink" );
		connect( blinkTimer, SIGNAL( timeout() ), SLOT( blinkTimeout() ) );
		blinkTimer->start( 300 );
		blink = false;
	}
}

void KPasswordDlg::showStars()
{
	QString s;
	
	s.fill( '*', password.length() );
	if( blink )
		s += "_";
		
	entry->setText( s );	
}

void KPasswordDlg::keyPressed( QKeyEvent *e )
{
  static bool waitForAuthentication = false;
  if (!waitForAuthentication) {
	switch ( e->key() )
	{
		case Key_Backspace:
			{
				int len = password.length();
				if ( len ) {
					password.truncate( len - 1 );
					if( stars )
						showStars();
				}
			}
			break;

		case Key_Return:
			waitForAuthentication = true;
			if ( tryPassword() )
				emit passOk();
			else
			{
				label->setText( glocale->translate("Failed") );
				password = "";
				timerMode = 1;
				timer.start( 1500, TRUE );
			}
			waitForAuthentication = false;
			break;

		case Key_Escape:
			emit passCancel();
			break;

		default:
			if ( password.length() < MAX_PASSWORD_LENGTH )
			{
				password += (char)e->ascii();
				if( stars )
					showStars();
				timer.changeInterval( 10000 );
			}
	}
  }
}


int KPasswordDlg::tryPassword()
{
#if defined HAVE_ETCPASSWD || defined HAVE_SHADOW || defined HAVE_PAM
	if( stars )
	  blinkTimer->stop();
	KProcess chkpass;
	QString kcp_binName = "";
	kcp_binName += KApplication::kde_bindir();
	kcp_binName += "/kcheckpass";
	chkpass.clearArguments();
	chkpass << kcp_binName;
	bool ret = chkpass.start(KProcess::DontCare, KProcess::Stdin);
	if (ret == false) {
	  if( stars )
	    blinkTimer->start( 300 );
	  return 2;
	}
        chkpass.writeStdin(password.data(),password.length()); // write Password to stdin
	chkpass.closeStdin();                // eof

	int timeout = 1000;
	while ( timeout != 0 ) {
	  if (! chkpass.isRunning() )
	    break;
	  else {
	    globalKapp->processEvents();
	    timeout--;
	    usleep(10000);
	  }
	}
	
	int rc = ( chkpass.normalExit() && (chkpass.exitStatus() == 0) );
	if( stars )
	  blinkTimer->start( 300 ); 
	return rc;
#else
	int e = checkPasswd(password.data());
	return e;
#endif
}

void KPasswordDlg::timeout()
{
	if ( timerMode )
	{
		label->setText( glocale->translate("Enter Password") );
		if( stars )
			showStars();
		timerMode = 0;
		timer.start( 5000, TRUE );
	}
	else
		emit passCancel();
}

void KPasswordDlg::blinkTimeout()
{
	blink = !blink;
	showStars();
}


--- NEW FILE: xlockmore.h ---
#ifndef __XLOCK_XLOCK_H__
#define __XLOCK_XLOCK_H__

/*-
 * @(#)xlock.h	4.00 97/01/01 xlockmore 
 *
 * xlock.h - external interfaces for new modes and SYSV OS defines.
 *
 * Copyright (c) 1991 by Patrick J. Naughton.
 *
 * See xlock.c for copying information.
 *
 * Revision History:
 *
 * Changes of David Bagley <bagleyd at bigfoot.com>
 * 12-May-95: Added defines for SunOS's Adjunct password file
 *            Dale A. Harris <rodmur at ecst.csuchico.edu>
 * 18-Nov-94: Modified for QNX 4.2 w/ Metrolink X server from Brian Campbell
 *            <brianc at qnx.com>.
 * 11-Jul-94: added Bool flag: inwindow, which tells xlock to run in a
 *            window from Greg Bowering <greg at cs.adelaide.edu.au>
 * 11-Jul-94: patch for Solaris SYR4 from Chris P. Ross <cross at eng.umd.edu>
 * 28-Jun-94: Reorganized shadow stuff
 * 24-Jun-94: Reorganized
 * 22-Jun-94: Modified for VMS
 *            <Anthony.D.Clarke at Support.Hatfield.Raytheon.bae.eurokom.ie>
 * 17-Jun-94: patched shadow passwords and bcopy and bzero for SYSV from
 *            <reggers at julian.uwo.ca>
 * 21-Mar-94: patched the patch for AIXV3 and HP from
 *            <R.K.Lloyd at csc.liv.ac.uk>.
 * 01-Dec-93: added patch for AIXV3 from
 *            (Tom McConnell, tmcconne at sedona.intel.com) also added a patch
 *            for HP-UX 8.0.
 *
 */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xresource.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* out of main.cpp */
#define MODE_NONE               0
#define MODE_INSTALL    1
#define MODE_SETUP              2
#define MODE_PREVIEW    3
#define MODE_TEST               4


#ifndef MAXSCREENS
#define MAXSCREENS        3
#endif
#ifndef NUMCOLORS
#define NUMCOLORS         64
#endif
#ifndef MESSAGELINES
#define MESSAGELINES      40
#endif
#define PASSLENGTH        120
#define FALLBACK_FONTNAME "fixed"
#ifndef DEF_MFONT
#define DEF_MFONT "-*-times-*-*-*-*-18-*-*-*-*-*-*-*"
#endif
#ifndef DEF_PROGRAM		/* Try the -o option ;) */
#define DEF_PROGRAM "fortune -s"
#endif

#ifndef DEF_NONE3D
#define DEF_NONE3D "Black"
#endif
#ifndef DEF_RIGHT3D
#define DEF_RIGHT3D "Red"
#endif
#ifndef DEF_LEFT3D
#define DEF_LEFT3D "Blue"
#endif
#ifndef DEF_BOTH3D
#define DEF_BOTH3D "Magenta"
#endif

#ifndef DEF_ICONW
#define DEF_ICONW         64	/* Age old default */
#endif
#ifndef DEF_ICONH
#define DEF_ICONH         64
#endif

#define MINICONW          1	/* Will not see much */
#define MINICONH          1

#ifndef MAXICONW
#define MAXICONW          256	/* Want users to know the screen is locked */
#endif
#ifndef MAXICONH
#define MAXICONH          256	/* by a particular user */
#endif

#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif

#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif

#ifndef ABS
#define ABS(a)  ((a<0)?(-(a)):(a))
#endif

#include <math.h>
#ifndef M_E
#define M_E    2.7182818284590452354
#endif
#ifndef M_PI
#define M_PI   3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#if VMS
#include <unixlib.h>
#endif
#include <sys/types.h>
#if 0
#ifndef uid_t
#define uid_t int
#endif
#ifndef gid_t
#define gid_t int
#endif
#ifndef pid_t
#define pid_t int
#endif
#ifndef size_t
#define size_t unsigned
#endif
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_MEMORY_H
#include <memory.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if HAVE_DIRENT_H
#ifdef USE_XVMSUTILS
#if 0
#include "../xvmsutils/unix_types.h"
#include "../xvmsutils/dirent.h"
#else
#include <X11/unix_types.h>
#include <X11/dirent.h>
#endif
#else /* !USE_XVMSUTILS */
#include <dirent.h>
#endif /* !USE_XVMSUTILS */
#else
#define dirent direct
#define NAMELEN(dirent) (dirent)->d_namelen
#if HAVE_SYS_NDIR_H
#include <sys/ndir.h>
#endif
#if HAVE_SYS_DIR_H
#include <sys/dir.h>
#endif
#if HAVE_NDIR_H
#include <ndir.h>
#endif
#endif
#ifndef MAXNAMLEN
#define MAXNAMLEN       256	/* maximum filename length */
#endif
#ifndef DIRBUF
#define DIRBUF          512	/* buffer size for fs-indep. dirs */
#endif

typedef struct {
	GC          gc;		/* graphics context for animation */
	int         npixels;	/* number of valid entries in pixels */
	Colormap    cmap;	/* current colormap */
	unsigned long pixels[NUMCOLORS];	/* pixel values in the colormap */
	unsigned long bgcol, fgcol;	/* background and foreground pixel values */
	unsigned long rightcol, leftcol;	/* 3D color pixel values */
	unsigned long nonecol, bothcol;
} perscreen;

#define t_String        0
#define t_Float         1
#define t_Int           2
#define t_Bool          3

typedef struct {
	caddr_t    *var;
	char       *name;
	char       *classname;
	char       *def;
	int         type;
} argtype;

typedef struct {
	char       *opt;
	char       *desc;
} OptionStruct;

typedef struct {
	int         numopts;
	XrmOptionDescRec *opts;
	int         numvarsdesc;
	argtype    *vars;
	OptionStruct *desc;
} ModeSpecOpt;

/* this must follow definition of ModeSpecOpt */
#include "mode.h"

#define IS_XBMDONE 1		/* Only need one mono image */
#define IS_XBM 2
#define IS_XBMFILE 3
#define IS_XPM 4
#define IS_XPMFILE 5
#define IS_RASTERFILE 6

extern void getResources(int argc, char **argv);
extern unsigned long allocPixel(Display * display, Colormap cmap,
				char *name, char *def);
extern void setColormap(Display * display, Window window, Colormap map,
			Bool inwindow);
extern void reserveColors(ModeInfo * mi, Colormap cmap,
			  unsigned long *blackpix, unsigned long *whitepix);
extern void fixColormap(Display * display, Window window,
			int screen, float saturation,
	  Bool mono, Bool install, Bool inroot, Bool inwindow, Bool verbose);
extern int  visualClassFromName(char *name);
extern void showVisualInfo(XVisualInfo * wantVis);
#ifdef USE_GL
extern int getVisual(ModeInfo * mi, XVisualInfo * wantVis, int mono);
#endif

extern unsigned long seconds(void);
extern void finish(void);
extern void error(char *s1,...);
extern void warning(char *s1,...);

#ifndef HAVE_STRDUP 
extern char *strdup(char *);
#endif

#ifdef MATHF
#define SINF(n) sinf(n)
#define COSF(n) cosf(n)
#define FABSF(n) fabsf(n)
#else
#define SINF(n) ((float)sin((double)(n)))
#define COSF(n) ((float)cos((double)(n)))
#define FABSF(n) ((float)fabs((double)(n)))
#endif

#endif /* __XLOCK_XLOCK_H__ */

--- NEW FILE: xs_hsv.c ---
/* xscreensaver, Copyright (c) 1992, 1997 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

/* This file contains some utility routines for randomly picking the colors
   to hack the screen with.
 */

/* #include "utils.h" */
#include "xs_hsv.h"

void
hsv_to_rgb (int h, double s, double v,
	    unsigned short *r, unsigned short *g, unsigned short *b)
{
  double H, S, V, R, G, B;
  double p1, p2, p3;
  double f;
  int i;

  if (s < 0) s = 0;
  if (v < 0) v = 0;
  if (s > 1) s = 1;
  if (v > 1) v = 1;

  S = s; V = v;
  H = (h % 360) / 60.0;
  i = H;
  f = H - i;
  p1 = V * (1 - S);
  p2 = V * (1 - (S * f));
  p3 = V * (1 - (S * (1 - f)));
  if	  (i == 0) { R = V;  G = p3; B = p1; }
  else if (i == 1) { R = p2; G = V;  B = p1; }
  else if (i == 2) { R = p1; G = V;  B = p3; }
  else if (i == 3) { R = p1; G = p2; B = V;  }
  else if (i == 4) { R = p3; G = p1; B = V;  }
  else		   { R = V;  G = p1; B = p2; }
  *r = R * 65535;
  *g = G * 65535;
  *b = B * 65535;
}

void
rgb_to_hsv (unsigned short r, unsigned short g, unsigned short b,
	    int *h, double *s, double *v)
{
  double R, G, B, H, S, V;
  double cmax, cmin;
  double cmm;
  int imax;
  R = ((double) r) / 65535.0;
  G = ((double) g) / 65535.0;
  B = ((double) b) / 65535.0;
  cmax = R; cmin = G; imax = 1;
  if  ( cmax < G ) { cmax = G; cmin = R; imax = 2; }
  if  ( cmax < B ) { cmax = B; imax = 3; }
  if  ( cmin > B ) { cmin = B; }
  cmm = cmax - cmin;
  V = cmax;
  if (cmm == 0)
    S = H = 0;
  else
    {
      S = cmm / cmax;
      if       (imax == 1)    H =       (G - B) / cmm;
      else  if (imax == 2)    H = 2.0 + (B - R) / cmm;
      else /*if (imax == 3)*/ H = 4.0 + (R - G) / cmm;
      if (H < 0) H += 6.0;
    }
  *h = (H * 60.0);
  *s = S;
  *v = V;
}

--- NEW FILE: xs_yarandom.h ---
/* xscreensaver, Copyright (c) 1997 by Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

#ifndef __YARANDOM_H__
#define __YARANDOM_H__

#undef random
#undef rand
#undef drand48
#undef srandom
#undef srand
#undef srand48
#undef frand

#ifdef VMS
# include "vms-gtod.h"
#endif

/* #define random()   ya_random()
 #define srandom(i) ya_rand_init(0) */

extern unsigned int ya_random (void);
extern void ya_rand_init (unsigned int);


#if defined (__GNUC__) && (__GNUC__ >= 2)
 /* Implement frand using GCC's statement-expression extension. */

# define frand(f)							\
  ({ double tmp = (((double) random()) /				\
		   (((double) ((unsigned int)~0)) / ((double) (f))));	\
     tmp < 0 ? (-tmp) : tmp; })

#else /* not GCC2 - implement frand using a global variable.*/

static double _frand_tmp_;
# define frand(f)							\
  (_frand_tmp_ = (((double) random()) / 				\
		  (((double) ((unsigned int)~0)) / ((double) (f)))),	\
   _frand_tmp_ < 0 ? (-_frand_tmp_) : _frand_tmp_)

#endif /* not GCC2 */

#endif /* __YARANDOM_H__ */

--- NEW FILE: main.h ---

#ifndef __MAIN_H__
#define __MAIN_H__

#include <kapp.h>
#define MODE_NONE		0
#define MODE_INSTALL	1
#define MODE_SETUP		2
#define MODE_PREVIEW	3
#define MODE_TEST		4

class ssApp : public KApplication
{
	Q_OBJECT
public:
	ssApp( int &argc, char **argv );

protected:
	virtual bool x11EventFilter( XEvent * );

private:
	bool stars;

public slots:
	void slotPassOk();
	void slotPassCancel();
};

#endif


--- NEW FILE: mode.h ---

#ifndef __XLOCK_MODE_H__
#define __XLOCK_MODE_H__

/*-
 * @(#)mode.h	4.00 97/01/01 xlockmore
 *
 * mode.h - mode management for xlock, the X Window System lockscreen.
 *
 * Copyright (c) 1991 by Patrick J. Naughton.
 *
 * See xlock.c for copying information.
 *
 * Revision History:
 *
 * Changes of David Bagley (bagleyd at bigfoot.com)
 * 18-Mar-96: Ron Hitchens <ron at idiom.com>
 *		Extensive revision to define new data types for
 *		the new mode calling scheme.
 * 02-Jun-95: Extracted out of resource.c.
 *
 */

/* 
 * Declare external interface routines for supported screen savers.
 */

/* -------------------------------------------------------------------- */

struct LockStruct_s;
struct ModeInfo_s;

typedef void (ModeHook) (struct ModeInfo_s *);
typedef void (HookProc) (struct LockStruct_s *, struct ModeInfo_s *);

typedef struct LockStruct_s {
	char       *cmdline_arg;	/* mode name */
	ModeHook   *init_hook;	/* func to init a mode */
	ModeHook   *callback_hook;	/* func to run (tick) a mode */
	ModeHook   *release_hook;	/* func to shutdown a mode */
	ModeHook   *refresh_hook;	/* tells mode to repaint */
	ModeHook   *change_hook;	/* user wants mode to change */
	ModeHook   *unused_hook;	/* for future expansion */
	ModeSpecOpt *msopt;	/* this mode's def resources */
	int         def_delay;	/* default delay for mode */
	int         def_batchcount;
	int         def_cycles;
	int         def_size;
	float       def_saturation;
	char       *desc;	/* text description of mode */
	unsigned int flags;	/* state flags for this mode */
	void       *userdata;	/* for use by the mode */
} LockStruct;

#define LS_FLAG_INITED		1

typedef struct {
	Display    *display;	/* handle to X display */
	Screen     *screenptr;	/* ptr to screen info */
	int         screen;	/* number of current screen */
	int         real_screen;	/* for debugging */
	int         num_screens;	/* number screens locked */
	int         max_screens;	/* max # active screens */
	Window      window;	/* handle to current window */
	int         win_width;	/* width of current window */
	int         win_height;	/* height of current window */
	int         win_depth;	/* depth of current window */
	Visual     *visual;	/* visual of current window */
	Colormap    colormap;	/* default colormap of current window */
	unsigned long black_pixel;	/* pixel value for black */
	unsigned long white_pixel;	/* pixel value for white */
	unsigned int flags;	/* xlock window flags */
	float       delta3d;
} WindowInfo;

#define WI_FLAG_INFO_INITTED	0x001	/* private state flag */
#define WI_FLAG_ICONIC		0x002
#define WI_FLAG_MONO		0x004
#define WI_FLAG_INWINDOW	0x008
#define WI_FLAG_INROOT		0x010
#define WI_FLAG_NOLOCK	0x020
#define WI_FLAG_INSTALL		0x040
#define WI_FLAG_DEBUG		0x080
#define WI_FLAG_USE3D		0x100
#define WI_FLAG_VERBOSE		0x200
#define WI_FLAG_FULLRANDOM		0x400
#define WI_FLAG_WIREFRAME		0x800
#define WI_FLAG_JUST_INITTED	0x1000	/* private state flag */

typedef struct {
	long        pause;	/* output, set by mode */
	long        delay;	/* inputs, current settings */
	long        batchcount;
	long        cycles;
	long        size;
	float       saturation;
} RunInfo;

typedef struct ModeInfo_s {
	WindowInfo  windowinfo;
	perscreen  *screeninfo;
	RunInfo     runinfo;
	struct LockStruct_s *lockstruct;
} ModeInfo;

/* -------------------------------------------------------------------- */

/* 
 * These are the public interfaces that a mode should use to obtain
 * information about the display and other environmental parameters.
 * Everything hangs off a ModeInfo pointer.  A mode should NOT cache
 * a ModeInfo pointer, the struct it points to is volatile.  The mode
 * can safely make a copy of the data it points to, however.  But it
 * is recommended the mode make use of the passed-in pointer and pass
 * it along to functions it calls.
 * Use these macros, don't look at the fields directly.  The insides
 * of the ModeInfo struct are certain to change in the future.
 */

#define MODE_IS_INITED(ls)	((ls)->flags & LS_FLAG_INITED)
#define MODE_NOT_INITED(ls)	( ! MODE_IS_INITED(ls))

#define MI_DISPLAY(mi)		((mi)->windowinfo.display)
#define MI_SCREEN(mi)		((mi)->windowinfo.screen)
#define MI_SCREENPTR(mi)      ((mi)->windowinfo.screenptr)
#define MI_REAL_SCREEN(mi)	((mi)->windowinfo.real_screen)
#define MI_NUM_SCREENS(mi)	((mi)->windowinfo.num_screens)
#define MI_MAX_SCREENS(mi)	((mi)->windowinfo.max_screens)
#define MI_WINDOW(mi)		((mi)->windowinfo.window)
#define MI_WIN_WIDTH(mi)	((mi)->windowinfo.win_width)
#define MI_WIN_HEIGHT(mi)	((mi)->windowinfo.win_height)
#define MI_WIN_DEPTH(mi)	((mi)->windowinfo.win_depth)
#define MI_VISUAL(mi)	((mi)->windowinfo.visual)
#define MI_COLORMAP(mi)	((mi)->windowinfo.colormap)
#define MI_WIN_BLACK_PIXEL(mi)	((mi)->windowinfo.black_pixel)
#define MI_WIN_WHITE_PIXEL(mi)	((mi)->windowinfo.white_pixel)
#define MI_DELTA3D(mi)	((mi)->windowinfo.delta3d)
#define MI_WIN_FLAGS(mi)	((mi)->windowinfo.flags)
#define MI_WIN_SET_FLAG_STATE(mi,f,bool) ((mi)->windowinfo.flags = \
					(bool) ? (mi)->windowinfo.flags | f \
					: (mi)->windowinfo.flags & ~(f))
#define MI_WIN_FLAG_IS_SET(mi,f) ((mi)->windowinfo.flags & f)
#define MI_WIN_FLAG_NOT_SET(mi,f) ( ! MI_WIN_FLAG_IS_SET(mi,f))
#define MI_WIN_IS_ICONIC(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_ICONIC))
#define MI_WIN_IS_MONO(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_MONO))
#define MI_WIN_IS_INWINDOW(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_INWINDOW))
#define MI_WIN_IS_INROOT(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_INROOT))
#define MI_WIN_IS_NOLOCK(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_NOLOCK))
#define MI_WIN_IS_INSTALL(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_INSTALL))
#define MI_WIN_IS_DEBUG(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_DEBUG))
#define MI_WIN_IS_USE3D(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_USE3D))
#define MI_WIN_IS_VERBOSE(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_VERBOSE))
#define MI_WIN_IS_FULLRANDOM(mi) (MI_WIN_FLAG_IS_SET (mi, WI_FLAG_FULLRANDOM))
#define MI_WIN_IS_WIREFRAME(mi)	(MI_WIN_FLAG_IS_SET (mi, WI_FLAG_WIREFRAME))

#define MI_PERSCREEN(mi)	((mi)->screeninfo)
#define MI_GC(mi)		((mi)->screeninfo->gc)
#define MI_NPIXELS(mi)		((mi)->screeninfo->npixels)
#define MI_CMAP(mi)		((mi)->screeninfo->cmap)
#define MI_PIXELS(mi)		((mi)->screeninfo->pixels)
#define MI_PIXEL(mi,n)		((mi)->screeninfo->pixels[n])

/* are these of interest to modes? */
#define MI_BG_COLOR(mi)		((mi)->screeninfo->bgcol)
#define MI_FG_COLOR(mi)		((mi)->screeninfo->fgcol)
#define MI_NONE_COLOR(mi)	((mi)->screeninfo->nonecol)	/* -install */
#define MI_RIGHT_COLOR(mi)	((mi)->screeninfo->rightcol)
#define MI_LEFT_COLOR(mi)	((mi)->screeninfo->leftcol)

#define MI_PAUSE(mi)		((mi)->runinfo.pause)
#define MI_DELAY(mi)		((mi)->runinfo.delay)
#define MI_BATCHCOUNT(mi)	((mi)->runinfo.batchcount)
#define MI_CYCLES(mi)		((mi)->runinfo.cycles)
#define MI_SIZE(mi)		((mi)->runinfo.size)
#define MI_SATURATION(mi)	((mi)->runinfo.saturation)

#define MI_LOCKSTRUCT(mi)	((mi)->lockstruct)
#define MI_DEFDELAY(mi)		((mi)->lockstruct->def_delay)
#define MI_DEFBATCHCOUNT(mi)	((mi)->lockstruct->def_batchcount)
#define MI_DEFCYCLES(mi)	((mi)->lockstruct->def_cycles)
#define MI_DEFSIZE(mi)	((mi)->lockstruct->def_size)
#define MI_DEFSATURATION(mi)	((mi)->lockstruct->def_saturation)

#define MI_NAME(mi)		((mi)->lockstruct->cmdline_arg)
#define MI_DESC(mi)		((mi)->lockstruct->desc)
#define MI_USERDATA(mi)		((mi)->lockstruct->userdata)

/* -------------------------------------------------------------------- */

extern HookProc call_init_hook;
extern HookProc call_callback_hook;
extern HookProc call_release_hook;
extern HookProc call_refresh_hook;
extern HookProc call_change_hook;

extern void set_default_mode(LockStruct *);
extern void release_last_mode(ModeInfo *);

/* -------------------------------------------------------------------- */

extern ModeHook init_ant;
extern ModeHook draw_ant;
extern ModeHook release_ant;
extern ModeHook refresh_ant;
extern ModeSpecOpt ant_opts;

extern ModeHook init_ball;
extern ModeHook draw_ball;
extern ModeHook release_ball;
extern ModeHook refresh_ball;
extern ModeSpecOpt ball_opts;

extern ModeHook init_bat;
extern ModeHook draw_bat;
extern ModeHook release_bat;
extern ModeHook refresh_bat;
extern ModeSpecOpt bat_opts;

extern ModeHook init_blot;
extern ModeHook draw_blot;
extern ModeHook release_blot;
extern ModeHook refresh_blot;
extern ModeSpecOpt blot_opts;

extern ModeHook init_bouboule;
extern ModeHook draw_bouboule;
extern ModeHook release_bouboule;
extern ModeHook refresh_bouboule;
extern ModeSpecOpt bouboule_opts;

extern ModeHook init_bounce;
extern ModeHook draw_bounce;
extern ModeHook release_bounce;
extern ModeHook refresh_bounce;
extern ModeSpecOpt bounce_opts;

extern ModeHook init_braid;
extern ModeHook draw_braid;
extern ModeHook release_braid;
extern ModeHook refresh_braid;
extern ModeSpecOpt braid_opts;

extern ModeHook init_bug;
extern ModeHook draw_bug;
extern ModeHook release_bug;
extern ModeHook refresh_bug;
extern ModeSpecOpt bug_opts;

extern ModeHook init_clock;
extern ModeHook draw_clock;
extern ModeHook release_clock;
extern ModeHook refresh_clock;
extern ModeSpecOpt clock_opts;

extern ModeHook init_daisy;
extern ModeHook draw_daisy;
extern ModeHook release_daisy;
extern ModeHook refresh_daisy;
extern ModeSpecOpt daisy_opts;

extern ModeHook init_dclock;
extern ModeHook draw_dclock;
extern ModeHook release_dclock;
extern ModeHook refresh_dclock;
extern ModeSpecOpt dclock_opts;

extern ModeHook init_demon;
extern ModeHook draw_demon;
extern ModeHook release_demon;
extern ModeHook refresh_demon;
extern ModeSpecOpt demon_opts;

extern ModeHook init_drift;
extern ModeHook draw_drift;
extern ModeHook release_drift;
extern ModeHook refresh_drift;
extern ModeSpecOpt drift_opts;

extern ModeHook init_eyes;
extern ModeHook draw_eyes;
extern ModeHook release_eyes;
extern ModeHook refresh_eyes;
extern ModeSpecOpt eyes_opts;

extern ModeHook init_flag;
extern ModeHook draw_flag;
extern ModeHook release_flag;
extern ModeHook refresh_flag;
extern ModeSpecOpt flag_opts;

extern ModeHook init_flame;
extern ModeHook draw_flame;
extern ModeHook release_flame;
extern ModeHook refresh_flame;
extern ModeSpecOpt flame_opts;

extern ModeHook init_forest;
extern ModeHook draw_forest;
extern ModeHook release_forest;
extern ModeHook refresh_forest;
extern ModeHook refresh_forest;
extern ModeSpecOpt forest_opts;

extern ModeHook init_fract;
extern ModeHook draw_fract;
extern ModeHook release_fract;
extern ModeHook refresh_fract;
extern ModeSpecOpt fract_opts;

extern ModeHook init_galaxy;
extern ModeHook draw_galaxy;
extern ModeHook release_galaxy;
extern ModeHook refresh_galaxy;
extern ModeSpecOpt galaxy_opts;

extern ModeHook init_geometry;
extern ModeHook draw_geometry;
extern ModeHook release_geometry;
extern ModeHook refresh_geometry;
extern ModeSpecOpt geometry_opts;

extern ModeHook init_grav;
extern ModeHook draw_grav;
extern ModeHook release_grav;
extern ModeHook refresh_grav;
extern ModeSpecOpt grav_opts;

extern ModeHook init_helix;
extern ModeHook draw_helix;
extern ModeHook release_helix;
extern ModeHook refresh_helix;
extern ModeSpecOpt helix_opts;

extern ModeHook init_hop;
extern ModeHook draw_hop;
extern ModeHook release_hop;
extern ModeHook refresh_hop;
extern ModeSpecOpt hop_opts;

extern ModeHook init_hyper;
extern ModeHook draw_hyper;
extern ModeHook release_hyper;
extern ModeHook refresh_hyper;
extern ModeSpecOpt hyper_opts;

extern ModeHook init_ico;
extern ModeHook draw_ico;
extern ModeHook release_ico;
extern ModeHook refresh_ico;
extern ModeHook change_ico;
extern ModeSpecOpt ico_opts;

extern ModeHook init_ifs;
extern ModeHook draw_ifs;
extern ModeHook release_ifs;
extern ModeSpecOpt ifs_opts;

extern ModeHook init_image;
extern ModeHook draw_image;
extern ModeHook release_image;
extern ModeHook refresh_image;
extern ModeSpecOpt image_opts;

extern ModeHook init_julia;
extern ModeHook draw_julia;
extern ModeHook release_julia;
extern ModeHook refresh_julia;
extern ModeSpecOpt julia_opts;

extern ModeHook init_kaleid;
extern ModeHook draw_kaleid;
extern ModeHook release_kaleid;
extern ModeHook refresh_kaleid;
extern ModeSpecOpt kaleid_opts;

extern ModeHook init_laser;
extern ModeHook draw_laser;
extern ModeHook release_laser;
extern ModeHook refresh_laser;
extern ModeSpecOpt laser_opts;

extern ModeHook init_life;
extern ModeHook draw_life;
extern ModeHook release_life;
extern ModeHook refresh_life;
extern ModeHook change_life;
extern ModeSpecOpt life_opts;

extern ModeHook init_life1d;
extern ModeHook draw_life1d;
extern ModeHook release_life1d;
extern ModeHook refresh_life1d;
extern ModeSpecOpt life1d_opts;

extern ModeHook init_life3d;
extern ModeHook draw_life3d;
extern ModeHook release_life3d;
extern ModeHook refresh_life3d;
extern ModeHook change_life3d;
extern ModeSpecOpt life3d_opts;

extern ModeHook init_lightning;
extern ModeHook draw_lightning;
extern ModeHook release_lightning;
extern ModeHook refresh_lightning;
extern ModeSpecOpt lightning_opts;

extern ModeHook init_lisa;
extern ModeHook draw_lisa;
extern ModeHook release_lisa;
extern ModeHook refresh_lisa;
extern ModeHook change_lisa;
extern ModeSpecOpt lisa_opts;

extern ModeHook init_lissie;
extern ModeHook draw_lissie;
extern ModeHook release_lissie;
extern ModeHook refresh_lissie;
extern ModeSpecOpt lissie_opts;

extern ModeHook init_loop;
extern ModeHook draw_loop;
extern ModeHook release_loop;
extern ModeHook refresh_loop;
extern ModeSpecOpt loop_opts;

extern ModeHook init_marquee;
extern ModeHook draw_marquee;
extern ModeHook release_marquee;
extern ModeHook refresh_marquee;
extern ModeSpecOpt marquee_opts;

extern ModeHook init_maze;
extern ModeHook draw_maze;
extern ModeHook release_maze;
extern ModeHook refresh_maze;
extern ModeSpecOpt maze_opts;

extern ModeHook init_mountain;
extern ModeHook draw_mountain;
extern ModeHook release_mountain;
extern ModeHook refresh_mountain;
extern ModeSpecOpt mountain_opts;

extern ModeHook init_nose;
extern ModeHook draw_nose;
extern ModeHook release_nose;
extern ModeHook refresh_nose;
extern ModeSpecOpt nose_opts;

extern ModeHook init_pacman;
extern ModeHook draw_pacman;
extern ModeHook release_pacman;
extern ModeHook refresh_pacman;
extern ModeSpecOpt pacman_opts;

extern ModeHook init_penrose;
extern ModeHook draw_penrose;
extern ModeHook release_penrose;

#if 0
extern ModeHook refresh_penrose;	/* Needed */

#endif
extern ModeSpecOpt penrose_opts;

extern ModeHook init_petal;
extern ModeHook draw_petal;
extern ModeHook release_petal;
extern ModeHook refresh_petal;
extern ModeSpecOpt petal_opts;

extern ModeHook init_puzzle;
extern ModeHook draw_puzzle;
extern ModeHook release_puzzle;

#if 0
extern ModeHook refresh_puzzle;	/* Needed */

#endif
extern ModeSpecOpt puzzle_opts;

extern ModeHook init_pyro;
extern ModeHook draw_pyro;
extern ModeHook release_pyro;
extern ModeHook refresh_pyro;
extern ModeSpecOpt pyro_opts;

extern ModeHook init_qix;
extern ModeHook draw_qix;
extern ModeHook release_qix;
extern ModeHook refresh_qix;
extern ModeSpecOpt qix_opts;

extern ModeHook init_roll;
extern ModeHook draw_roll;
extern ModeHook release_roll;
extern ModeHook refresh_roll;
extern ModeSpecOpt roll_opts;

extern ModeHook init_rotor;
extern ModeHook draw_rotor;
extern ModeHook release_rotor;
extern ModeHook refresh_rotor;
extern ModeSpecOpt rotor_opts;

extern ModeHook init_shape;
extern ModeHook draw_shape;
extern ModeHook release_shape;
extern ModeHook refresh_shape;
extern ModeSpecOpt shape_opts;

extern ModeHook init_slip;
extern ModeHook draw_slip;
extern ModeHook release_slip;

#if 0
extern ModeHook refresh_slip;	/* Probably not practical */

#endif
extern ModeSpecOpt slip_opts;

extern ModeHook init_sphere;
extern ModeHook draw_sphere;
extern ModeHook release_sphere;
extern ModeHook refresh_sphere;
extern ModeSpecOpt sphere_opts;

extern ModeHook init_spiral;
extern ModeHook draw_spiral;
extern ModeHook release_spiral;
extern ModeHook refresh_spiral;
extern ModeSpecOpt spiral_opts;

extern ModeHook init_spline;
extern ModeHook draw_spline;
extern ModeHook release_spline;
extern ModeHook refresh_spline;
extern ModeSpecOpt spline_opts;

extern ModeHook init_star;
extern ModeHook draw_star;
extern ModeHook release_star;
extern ModeHook refresh_star;
extern ModeSpecOpt star_opts;

extern ModeHook init_strange;
extern ModeHook draw_strange;
extern ModeHook release_strange;
extern ModeSpecOpt strange_opts;

extern ModeHook init_swarm;
extern ModeHook draw_swarm;
extern ModeHook release_swarm;
extern ModeHook refresh_swarm;
extern ModeSpecOpt swarm_opts;

extern ModeHook init_swirl;
extern ModeHook draw_swirl;
extern ModeHook release_swirl;
extern ModeHook refresh_swirl;
extern ModeSpecOpt swirl_opts;

extern ModeHook init_tri;
extern ModeHook draw_tri;
extern ModeHook release_tri;
extern ModeHook refresh_tri;
extern ModeSpecOpt tri_opts;

extern ModeHook init_triangle;
extern ModeHook draw_triangle;
extern ModeHook release_triangle;
extern ModeHook refresh_triangle;
extern ModeSpecOpt triangle_opts;

extern ModeHook init_tube;
extern ModeHook draw_tube;
extern ModeHook release_tube;
extern ModeHook refresh_tube;
extern ModeSpecOpt tube_opts;

extern ModeHook init_turtle;
extern ModeHook draw_turtle;
extern ModeHook release_turtle;
extern ModeHook refresh_turtle;
extern ModeSpecOpt turtle_opts;

extern ModeHook init_wator;
extern ModeHook draw_wator;
extern ModeHook release_wator;
extern ModeHook refresh_wator;
extern ModeSpecOpt wator_opts;

extern ModeHook init_wire;
extern ModeHook draw_wire;
extern ModeHook release_wire;
extern ModeHook refresh_wire;
extern ModeSpecOpt wire_opts;

extern ModeHook init_world;
extern ModeHook draw_world;
extern ModeHook release_world;
extern ModeHook refresh_world;
extern ModeSpecOpt world_opts;

extern ModeHook init_worm;
extern ModeHook draw_worm;
extern ModeHook release_worm;
extern ModeHook refresh_worm;
extern ModeSpecOpt worm_opts;

#if defined( USE_XPM ) || defined( USE_XPMINC )
extern ModeHook init_cartoon;
extern ModeHook draw_cartoon;
extern ModeHook release_cartoon;
extern ModeSpecOpt cartoon_opts;

#endif

#ifdef USE_GL
extern ModeHook init_gears;
extern ModeHook draw_gears;
extern ModeHook release_gears;
extern ModeSpecOpt gears_opts;

extern ModeHook init_morph3d;
extern ModeHook draw_morph3d;
extern ModeHook release_morph3d;
extern ModeHook change_morph3d;
extern ModeSpecOpt morph3d_opts;

extern ModeHook init_pipes;
extern ModeHook draw_pipes;
extern ModeHook release_pipes;
extern ModeHook refresh_pipes;
extern ModeHook change_pipes;
extern ModeSpecOpt pipes_opts;

extern ModeHook init_superquadrics;
extern ModeHook draw_superquadrics;
extern ModeHook release_superquadrics;
extern ModeHook refresh_superquadrics;
extern ModeSpecOpt superquadrics_opts;

#ifdef USE_SPROINGIES
extern ModeHook init_sproingies;
extern ModeHook draw_sproingies;
extern ModeHook release_sproingies;
extern ModeHook refresh_sproingies;
extern ModeSpecOpt sproingies_opts;

#endif
#endif

#ifdef USE_HACKERS
extern ModeHook init_fadeplot;
extern ModeHook draw_fadeplot;
extern ModeHook release_fadeplot;
extern ModeHook refresh_fadeplot;
extern ModeSpecOpt fadeplot_opts;

#endif

extern ModeHook init_blank;
extern ModeHook draw_blank;
extern ModeHook release_blank;
extern ModeHook refresh_blank;
extern ModeSpecOpt blank_opts;

#ifdef USE_BOMB
extern ModeHook init_bomb;
extern ModeHook draw_bomb;
extern ModeHook release_bomb;
extern ModeHook refresh_bomb;
extern ModeHook change_bomb;
extern ModeSpecOpt bomb_opts;

#endif

extern ModeHook init_random;
extern ModeHook draw_random;
extern ModeHook release_random;
extern ModeHook refresh_random;
extern ModeHook change_random;
extern ModeSpecOpt random_opts;

extern LockStruct LockProcs[];
extern int  numprocs;

/* -------------------------------------------------------------------- */

#endif /* __XLOCK_MODE_H__ */

--- NEW FILE: xs_hsv.h ---
/* xscreensaver, Copyright (c) 1992, 1997 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

#ifndef __HSV_H__
#define __HSV_H__

/* Converts between RGB and HSV color spaces.
   R, G, and B are in the range 0 - 65535;
   H is in the range 0 - 360;
   S and V are in the range 0.0 - 1.0.
 */
extern void hsv_to_rgb (int h, double s, double v,
			unsigned short *r,
			unsigned short *g,
			unsigned short *b);
extern void rgb_to_hsv (unsigned short r, unsigned short g, unsigned short b,
			int *h, double *s, double *v);

#endif /* __HSV_H__ */

--- NEW FILE: saver.h ---
#ifndef __SAVER_H__
#define __SAVER_H__ "$Id"

#include <qwidget.h>
#include <qlabel.h>
#include <qtimer.h>
#include <kapp.h>
#include <X11/Xlib.h>

extern "C" {
  void startScreenSaver( Drawable d );
  void stopScreenSaver();
  int setupScreenSaver();
  const char *getScreenSaverName();
  void exposeScreenSaver(int x, int y, int width, int height);
}

class kScreenSaver : public QObject
{
	Q_OBJECT
public:
	kScreenSaver( Drawable drawable );
	virtual ~kScreenSaver();

	virtual void expose( int x, int y, int width, int height );

protected:
	Drawable d;
	GC gc;
	unsigned width;
	unsigned height;
};

//-----------------------------------------------------------------------------

class KPasswordDlg : public QWidget
{
	Q_OBJECT
public:
	KPasswordDlg( QWidget *parent, bool s = true );

	void showStars();
	int tryPassword();
	void keyPressed( QKeyEvent * );

    void blank();

signals:
	void passOk();
	void passCancel();

protected slots:
	void timeout();
	void blinkTimeout();
	
private:
	QTimer timer, *blinkTimer;
	QLabel *label, *entry;
	QString password;
	int timerMode;
	bool stars;
	bool blink;
};

#endif


--- NEW FILE: kscreensave.h ---
//-----------------------------------------------------------------------------
//
// KDE screen saver
//

// call this to lock the screen at any time
void kForceLocker();


--- NEW FILE: xs_utils.h ---
/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xos.h>

--- NEW FILE: xautolock.C ---
//----------------------------------------------------------------------------
//
// KDE screensavers
//
// This module is a heavily modified xautolock.
// The orignal copyright notice follows
//

/*****************************************************************************
 *
 * xautolock
 * =========
 *
 * Authors   :  S. De Troch (SDT) + M. Eyckmans (MCE)
 *
 * Date      :  22/07/90
 *
 * ---------------------------------------------------------------------------
 *
 * Copyright 1990, 1992-1995 by S. De Troch and MCE.
 *
 * Permission to use, copy, modify and distribute this software and the
 * supporting documentation without fee is hereby granted, provided that
 *
 *  1 : Both the above copyright notice and this permission notice
 *      appear in all copies of both the software and the supporting
 *      documentation.
 *  2 : No financial profit is made out of it.
 *
 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
 * EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 *****************************************************************************/



/*
 *  Have a guess what this does...
 *  ==============================
 *
 *  Warning for swm & tvtwm users : xautolock should *not* be compiled
 *  with vroot.h, because it needs to know the real root window.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#if defined(hpux) || defined (__hpux)
#ifndef _HPUX_SOURCE
#define _HPUX_SOURCE
#endif /* _HPUX_SOURCE */
#endif /* hpux || __hpux */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#ifdef VMS
#include <ssdef.h>    
#include <processes.h>  /* really needed? */
#endif /* VMS */

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>

#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>

#ifdef HAVE_SYS_M_WAIT_H
#include <sys/m_wait.h>
#endif 

#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#undef TrueColor

#include <qapp.h>
#include "xautolock.h"

/*
 *  Usefull macros and customization stuff
 *  ======================================
 */
#define PP(x)                      x

#ifdef VMS
#define ALL_OK                     1       /* for use by exit ()           */
#define PROBLEMS                   SS$_ABORT 
                                           /* for use by exit ()           */
#else /* VMS */
#define ALL_OK                     0       /* for use by exit ()           */
#define PROBLEMS                   1       /* for use by exit ()           */
#endif /* VMS */

#define FALSE                      0       /* as it says                   */
#define TRUE                       1       /* as it says                   */
#define MINUTES                    10      /* default ...                  */
#define CREATION_DELAY             30      /* should be > 10 and
                                              < min (45,(MIN_MINUTES*30))  */
#define CORNER_SIZE                10      /* size in pixels of the
                                              force-lock areas             */
#define CORNER_DELAY               5       /* number of seconds to wait
                                              before forcing a lock        */
#define TIME_CHANGE_LIMIT         120      /* if the time changes by more
                                              than x secs then we will
                                              assume someone has changed
                                              date or machine has suspended */


#ifndef HasVFork
#define vfork                      fork
#endif /* HasVFork */

#define Error0(str)                fprintf (stderr, str)
#define SetTrigger(delta)          trigger = time ((time_t*) NULL) + delta

static caddr_t                     ch_ptr;  /* this is dirty */
#define Skeleton(t,s)              (ch_ptr = (Caddrt) malloc ((Unsigned) s), \
                                      (ch_ptr == (Caddrt) NULL)              \
                                    ? (Error0 ("Out of memory.\n"),          \
                                       exit (PROBLEMS),                      \
                                       /*NOTREACHED*/ (t*) NULL              \
                                      )                                      \
                                    : (t*) ch_ptr                            \
                                   )                                         \

#define New(tp)                    Skeleton (tp, sizeof (tp))



/*
 *  New types
 *  =========
 */
#if defined (apollo) || defined (news1800) 
typedef int                        (*XErrorHandler) PP((Display*,
                                                        XErrorEvent*));
#endif /* apollo || news1800 */

#if defined (news1800) || defined (sun386) 
typedef int                        pid_t;
#endif /* news1800  || sun386*/

#ifdef VMS
typedef long                       pid_t;
#endif /* VMS */

#define Void                       void     /* no typedef because of VAX */
typedef int                        Int;
typedef char                       Char;
typedef char*                      String;
typedef int                        Boolean;
typedef caddr_t                    Caddrt;
typedef unsigned int               Unsigned;
typedef unsigned long              Huge;

typedef struct QueueItem_
        {
          Window                   window;        /* as it says          */
          time_t                   creationtime;  /* as it says          */
          struct QueueItem_*       next;          /* as it says          */
          struct QueueItem_*       prev;          /* as it says          */
        } aQueueItem, *QueueItem;

typedef struct Queue_
        {
          struct QueueItem_*       head;          /* as it says          */
          struct QueueItem_*       tail;          /* as it says          */
        } aQueue, *Queue;


/*
 *  Function declarations
 *  =====================
 */
#if defined(news1800) 
extern Void*    malloc                PP((Unsigned));
#endif /* news1800 */
 
static int      EvaluateCounter       PP((Display*));
static int      QueryPointer          PP((Display*));
static Void     ProcessEvents         PP((Display*, Queue));
static Queue    NewQueue              PP((Void));
static Void     AddToQueue            PP((Queue, Window));
static Void     ProcessQueue          PP((Queue, Display*, time_t));
static Void     SelectEvents          PP((Display*, Window, Boolean));


/*
 *  Global variables
 *  ================
 */
static time_t        trigger = 0;            /* as it says                 */
static time_t        time_limit = MINUTES;   /* as it says                 */
static Int           corner_size = CORNER_SIZE; /* as it says              */
static time_t        corner_delay = CORNER_DELAY; /* as it says            */
static CornerAction  corners[4] = { IGNORE, IGNORE, IGNORE, IGNORE };
                                             /* default CornerActions      */

/*
 *  Functions related to the window queue
 *  =====================================
 *
 *  Function for creating a new queue
 *  ---------------------------------
 */
static Queue  NewQueue ()

{
  Queue  queue;  /* return value */

  queue = New (aQueue);
  queue->tail = New (aQueueItem);
  queue->head = New (aQueueItem);

  queue->tail->next = queue->head;
  queue->head->prev = queue->tail;
  queue->tail->prev = queue->head->next = (QueueItem) NULL;

  return queue;
}


/*
 *  Function for adding an item to a queue
 *  --------------------------------------
 */
static Void  AddToQueue (Queue queue, Window window)
{
  QueueItem  newq;  /* new item */

  newq = New (aQueueItem);

  newq->window = window;
  newq->creationtime = time ((time_t*) NULL);
  newq->next = queue->tail->next;
  newq->prev = queue->tail;
  queue->tail->next->prev = newq;
  queue->tail->next = newq;
}

/*
 *  Function for processing those entries that are old enough
 *  ---------------------------------------------------------
 */
static Void  ProcessQueue (Queue queue, Display *d, time_t age)
{
  QueueItem  current;  /* as it says */
  time_t     now;      /* as it says */

  time (&now);
  current = queue->head->prev;

  while ( current->prev && current->creationtime + age < now )
  {
    SelectEvents (d, current->window, False);
    current = current->prev;
    free (current->next);
  }

  current->next = queue->head;
  queue->head->prev = current;
}


static Void  FreeQueue( Queue queue )
{
  QueueItem  current;  /* as it says */

  current = queue->head->prev;

  while ( current->prev )
  {
	  current = current->prev;
	  free(current->next);
  }

  free(current);
  free(queue);
}


/*
 *  Functions related to (the lack of) user activity
 *  ================================================
 *
 *  Function for processing the event queue
 *  ---------------------------------------
 */
static Void  ProcessEvents (Display *d, Queue queue)
{
  XEvent  event;  /* as it says */

 /*
  *  Read whatever is available for reading.
  */
  while (XPending (d))
  {
    if (XCheckMaskEvent (d, SubstructureNotifyMask, &event))
    {
      if (event.type == CreateNotify)
      {
        AddToQueue (queue, event.xcreatewindow.window);
      }
    }
    else
    {
      XNextEvent (d, &event);
    }


   /*
    *  Reset the counter if and only if the event is a KeyPress
    *  event *and* was not generated by XSendEvent ().
    */
    if ( event.type == KeyPress && !event.xany.send_event )
    {
      SetTrigger (time_limit);
    }
  }


 /*
  *  Check the window queue for entries that are older than
  *  CREATION_DELAY seconds.
  */
  ProcessQueue (queue, d, (time_t) CREATION_DELAY);
}


/*
 *  Function for monitoring pointer movements
 *  -----------------------------------------
 */
static int  QueryPointer (Display *d)
{
  Window           dummy_w;            /* as it says                    */
  Int              dummy_c;            /* as it says                    */
  Unsigned         mask;               /* modifier mask                 */
  Int              root_x;             /* as it says                    */
  Int              root_y;             /* as it says                    */
  time_t           now;                /* as it says                    */
  Int              i;                  /* loop counter                  */
  static Window    root;               /* root window the pointer is on */
  static Screen*   screen;             /* screen the pointer is on      */
  static Unsigned  prev_mask = 0;      /* as it says                    */
  static Int       prev_root_x = -1;   /* as it says                    */
  static Int       prev_root_y = -1;   /* as it says                    */
  static Boolean   first_call = TRUE;  /* as it says                    */


 /*
  *  Have a guess...
  */
  if (first_call)
  {
    first_call = FALSE;
    root = DefaultRootWindow (d);
    screen = ScreenOfDisplay (d, DefaultScreen (d));
  }


 /*
  *  Find out whether the pointer has moved. Using XQueryPointer for this
  *  is gross, but it also is the only way never to mess up propagation
  *  of pointer events.
  *
  *  Remark : Unlike XNextEvent(), XPending () doesn't notice if the
  *           connection to the server is lost. For this reason, earlier
  *           versions of xautolock periodically called XNoOp (). But
  *           why not let XQueryPointer () do the job for us, since
  *           we now call that periodically anyway?
  */
  if (!XQueryPointer (d, root, &root, &dummy_w, &root_x, &root_y,
                      &dummy_c, &dummy_c, &mask))
  {
   /*
    *  Pointer has moved to another screen, so let's find out which one.
    */
    for (i = -1; ++i < ScreenCount (d); ) 
    {
      if (root == RootWindow (d, i)) 
      {
        screen = ScreenOfDisplay (d, i);
        break;
      }
    }
  }

  if (   root_x == prev_root_x
      && root_y == prev_root_y
      && mask == prev_mask
     )
  {
    time (&now);
    if ( now >= ( trigger - time_limit ) + corner_delay )
    {
     /*
      *  If the pointer has not moved since the previous call and 
      *  is inside one of the 4 corners, we act according to the
      *  contents of the "corners" array.
      *
      *  If root_x and root_y are less than zero, don't lock even if
      *  FORCE_LOCK is set in the upper-left corner. Why? 'cause
      *  on initial server startup, IF the pointer is never moved,
      *  XQueryPointer returns values less than zero (only some
      *  servers, Openwindows 2.0 and 3.0 in particular).
      */
      if ( root_x <= corner_size && root_x >= 0
              && root_y <= corner_size && root_y >= 0)
      {
          return corners[0];
      }
      else if ( root_x >= WidthOfScreen  (screen) - corner_size - 1
              && root_y <= corner_size)
      {
          return corners[1];
      }
      else if ( root_x <= corner_size
              && root_y >= HeightOfScreen (screen) - corner_size - 1 )
      {
          return corners[2];
      }
      else if ( root_x >= WidthOfScreen  (screen) - corner_size - 1
              && root_y >= HeightOfScreen (screen) - corner_size - 1 )
      {
  		return corners[3];
      }
    }
  }
  else
  {
    prev_root_x = root_x;
    prev_root_y = root_y;
    prev_mask = mask;
    SetTrigger (time_limit);
  }

  return 0;
}


/*
 *  Function for deciding whether to lock
 *  -------------------------------------
 */
static int  EvaluateCounter (Display *)
{
  time_t         now = 0;                /* as it says  */

 /*
  *  Now trigger the notifier if required. 
  */
  time (&now);

 /*
  *  Finally fire up the locker if time has come. 
  */
  if (now >= trigger)
  {
      SetTrigger (time_limit);
	  return TRUE;
  }

  return FALSE;
}

/*
 *  Function for selecting events on a tree of windows
 *  --------------------------------------------------
 */
static Void  SelectEvents (Display *d, Window window, Boolean substructure_only)
{
  Window             root;              /* root window of this window */
  Window             parent;            /* parent of this window      */
  Window*            children;          /* children of this window    */
  Unsigned           nof_children = 0;  /* number of children         */
  Unsigned           i;                 /* loop counter               */
  XWindowAttributes  attribs;           /* attributes of the window   */


 /*
  *  Start by querying the server about parent and child windows.
  */
  if (!XQueryTree (d, window, &root, &parent, &children, &nof_children))
  {
    return;
  }


 /*
  *  Build the appropriate event mask. The basic idea is that we don't
  *  want to interfere with the normal event propagation mechanism if
  *  we don't have to.
  */
  if (substructure_only)
  {
    XSelectInput (d, window, SubstructureNotifyMask);
  }
  else
  {
    if (parent == None)  /* the *real* rootwindow */
    {
      attribs.all_event_masks = 
        attribs.do_not_propagate_mask = KeyPressMask;
    }
    else if (XGetWindowAttributes (d, window, &attribs) == 0)
    {
      return;
    }

    XSelectInput (d, window,   SubstructureNotifyMask
                             | (  (  attribs.all_event_masks
                                   | attribs.do_not_propagate_mask)
                                & KeyPressMask));
  }


 /*
  *  Now do the same thing for all children.
  */
  for (i = 0; i < nof_children; ++i)
  {
    SelectEvents (d, children[i], substructure_only);
  }

  if (nof_children) XFree ((Char*) children);
}


int catchFalseAlarms( Display *, XErrorEvent * )
{
	return 0;
}

void setCorners( const char *cstring )
{
	char p;

	for ( int i = 0; i < 4; i++ )
	{
		p = cstring[i];
		if ( p == 0 )
			break;

		switch ( p )
		{
			case 'l':
				corners[i] = FORCE_LOCK;
				break;

			case 's':
				corners[i] = FORCE_SAVE;
				break;

			default:
				corners[i] = IGNORE;
		}
	}
}

volatile int timeoutNow = FALSE;

void forceTimeout()
{
	timeoutNow = TRUE;
}

Queue  windowQueue;
Window hiddenWin;        /* hidden window    */

void initAutoLock()
{
  Display*              d;          /* display pointer  */
  Window                r;          /* root window      */
  Int                   s;          /* screen index     */
  XSetWindowAttributes  attribs;    /* for dummy window */
  int (*oldHandler)(Display *, XErrorEvent *);

  d = qt_xdisplay();

  oldHandler = XSetErrorHandler( catchFalseAlarms );
  XSync (d, 0);

  windowQueue = NewQueue ();

  for (s = -1; ++s < ScreenCount (d); )
  {
    AddToQueue (windowQueue, r = RootWindowOfScreen (ScreenOfDisplay (d, s)));
    SelectEvents (d, r, True);
  }

 /*
  *  Get ourselves a dummy window in order to allow display and/or
  *  session managers etc. to use XKillClient() on us (e.g. xdm when
  *  not using XDMCP).
  * 
  *  I'm not sure whether the window needs to be mapped for xdm, but
  *  the default set up Sun uses for OpenWindows and olwm definitely
  *  requires it to be mapped.
  */
  attribs.override_redirect = True;
  hiddenWin = XCreateWindow (d, DefaultRootWindow (d), -100, -100, 1, 1, 0,
                CopyFromParent, InputOnly, CopyFromParent, CWOverrideRedirect,
				&attribs);

  XMapWindow (d, hiddenWin );

  XSetErrorHandler( oldHandler );
}

void cleanupAutoLock()
{
  int (*oldHandler)(Display *, XErrorEvent *);
  oldHandler = XSetErrorHandler( catchFalseAlarms );

  FreeQueue( windowQueue );
  XDestroyWindow( qt_xdisplay(), hiddenWin );
  XSetErrorHandler( oldHandler );
}


/*
 *  Main function
 *  -------------
 */
int waitTimeout( int timeout )
{
  Display*              d;          /* display pointer  */
  int rv;
  int (*oldHandler)(Display *, XErrorEvent *);
  time_t now, prev;

  time_limit = timeout;

  d = qt_xdisplay();

  oldHandler = XSetErrorHandler( catchFalseAlarms );

  SetTrigger (time_limit);

  time(&prev);

 /*
  *  Main event loop.
  */
  while ( 1 )
  {
    if ( timeoutNow )
	{
	    // this happens, when you send the screensaver a SIGUSR1
	    // this emits, that you want to lock the screen!
	     rv = FORCE_LOCK;
		timeoutNow = FALSE;
		break;
	}
    ProcessEvents (d, windowQueue);
    rv = QueryPointer (d);
	if ( rv != IGNORE )
		break;

    time(&now);

    if ((now > prev && now - prev > TIME_CHANGE_LIMIT) ||
        (prev > now && prev - now > TIME_CHANGE_LIMIT+1))
    {
      /* the time has changed in one large jump.  This could be because the
         date was changed, or the machine was suspended.  We'll just
         reset the triger. */
      SetTrigger (time_limit);
    }

    prev = now;
      
    if ( EvaluateCounter (d) )
	{
		rv = IGNORE;
		break;
	}

   /*
    *  It seems that, on some operating systems (VMS to name just one),
    *  sleep () can be vastly inaccurate: sometimes 60 calls to sleep (1)
    *  add up to only 30 seconds or even less of sleeping. Therefore,
    *  as of patchlevel 9 we no longer rely on it for keeping track of
    *  time. The only reason why we still call it, is to make  xautolock
    *  (which after all uses a busy-form-of-waiting algorithm), less
    *  processor hungry.
    */
    sleep (1);
  }

  XSetErrorHandler( oldHandler );

  return rv;
}


--- NEW FILE: xlock.C ---
//----------------------------------------------------------------------------
// This module contains code to interface original xlock savers to
// kscreensave
//

#include <qapp.h>
#include "xlock.h"


int screen;
Display *dsp;
perscreen Scr[MAXSCREENS];
int batchcount = 100;
int cycles = 100;
Bool mono = 0;
Bool allowroot = 0;
char *ProgramName;
/*
Dr. Park's algorithm published in the Oct. '88 ACM
"Random Number Generators: Good Ones Are Hard To Find"
His version available at ftp://cs.wm.edu/pub/rngs.tar
Present form by many authors.
*/

static int Seed = 1;       /* This is required to be 32 bits long */

/*
 *      Given an integer, this routine initializes the RNG seed.
 */
void SetRNG(long s)
{
	Seed = (int) s;
}

/*
 *      Returns an integer between 0 and 2147483647, inclusive.
 */
long LongRNG()
{
	if ((Seed = Seed % 44488 * 48271 - Seed / 44488 * 3399) < 0)
		Seed += 2147483647;
	return (long) (Seed - 1);
}

unsigned long
allocpixel(Colormap cmap, char *name, char *def)
{
	XColor      col;
	XColor      tmp;
	XParseColor(dsp, cmap, name, &col);
	if (!XAllocColor(dsp, cmap, &col))
	{
		fprintf(stderr, "couldn't allocate: %s, using %s instead\n", name, def);
		XAllocNamedColor(dsp, cmap, def, &col, &tmp);
	}

	return col.pixel;
}

void initXLock( GC gc )
{
	SetRNG( time(NULL) );

	dsp = qt_xdisplay();
	screen = qt_xscreen();

	Screen *scr = ScreenOfDisplay(dsp, screen);

	Scr[0].gc = gc;
	Scr[0].npixels = NUMCOLORS;
	Scr[0].cmap = None;

	Colormap    cmap = DefaultColormapOfScreen(scr);
	Scr[0].bgcol = allocpixel(cmap, "background", "White");
	Scr[0].bgcol = allocpixel(cmap, "foreground", "Black");

	QColor color;

	for ( int i = 0; i < NUMCOLORS; i++ )
	{
		color.setHsv( i * 360 / NUMCOLORS, 255, 255 );
		Scr[0].pixels[i] = color.alloc();
	}
}


--- NEW FILE: xs_colors.c ---
/* xscreensaver, Copyright (c) 1997 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

/* This file contains some utility routines for randomly picking the colors
   to hack the screen with.
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xresource.h>

#include "xs_visual.h"
#include "xs_yarandom.h"
#include "xs_hsv.h"
#include "xs_colors.h"

/* extern char *progname; */

void
free_colors(Display *dpy, Colormap cmap, XColor *colors, int ncolors)
{
  int i;
  if (ncolors > 0)
    {
      unsigned long *pixels = (unsigned long *)
	malloc(sizeof(*pixels) * ncolors);
      for (i = 0; i < ncolors; i++)
	pixels[i] = colors[i].pixel;
      XFreeColors (dpy, cmap, pixels, ncolors, 0L);
      free(pixels);
    }
}


void
allocate_writable_colors (Display *dpy, Colormap cmap,
			  unsigned long *pixels, int *ncolorsP)
{
  int desired = *ncolorsP;
  int got = 0;
  int requested = desired;
  unsigned long *new_pixels = pixels;

  *ncolorsP = 0;
  while (got < desired
	 && requested > 0)
    {
      if (desired - got < requested)
	requested = desired - got;

      if (XAllocColorCells (dpy, cmap, False, 0, 0, new_pixels, requested))
	{
	  /* Got all the pixels we asked for. */
	  new_pixels += requested;
	  got += requested;
	}
      else
	{
	  /* We didn't get all/any of the pixels we asked for.  This time, ask
	     for half as many.  (If we do get all that we ask for, we ask for
	     the same number again next time, so we only do O(log(n)) server
	     roundtrips.)
	  */
	  requested = requested / 2;
	}
    }
  *ncolorsP += got;
}



void
make_color_ramp (Display *dpy, Colormap cmap,
		 int h1, double s1, double v1,   /* 0-360, 0-1.0, 0-1.0 */
		 int h2, double s2, double v2,   /* 0-360, 0-1.0, 0-1.0 */
		 XColor *colors, int *ncolorsP,
		 Bool closed_p,
		 Bool allocate_p,
		 Bool writable_p)
{
  int i;
  int ncolors = *ncolorsP;
  double dh, ds, dv;		/* deltas */

 AGAIN:

  memset (colors, 0, (*ncolorsP) * sizeof(*colors));

  if (closed_p)
    ncolors = (ncolors / 2) + 1;

  /* Note: unlike other routines in this module, this function assumes that
     if h1 and h2 are more than 180 degrees apart, then the desired direction
     is always from h1 to h2 (rather than the shorter path.)  make_uniform
     depends on this.
   */
  dh = ((double)h2 - (double)h1) / ncolors;
  ds = (s2 - s1) / ncolors;
  dv = (v2 - v1) / ncolors;

  for (i = 0; i < ncolors; i++)
    {
      colors[i].flags = DoRed|DoGreen|DoBlue;
      hsv_to_rgb ((int) (h1 + (i*dh)), (s1 + (i*ds)), (v1 + (i*dv)),
		  &colors[i].red, &colors[i].green, &colors[i].blue);
    }

  if (closed_p)
    for (i = ncolors; i < *ncolorsP; i++)
      colors[i] = colors[(*ncolorsP)-i];

  if (!allocate_p)
    return;

  if (writable_p)
    {
      unsigned long *pixels = (unsigned long *)
	malloc(sizeof(*pixels) * ((*ncolorsP) + 1));

      /* allocate_writable_colors() won't do here, because we need exactly this
	 number of cells, or the color sequence we've chosen won't fit. */
      if (! XAllocColorCells(dpy, cmap, False, 0, 0, pixels, *ncolorsP))
	{
	  free(pixels);
	  goto FAIL;
	}

      for (i = 0; i < *ncolorsP; i++)
	colors[i].pixel = pixels[i];
      free (pixels);

      XStoreColors (dpy, cmap, colors, *ncolorsP);
    }
  else
    {
      for (i = 0; i < *ncolorsP; i++)
	{
	  XColor color;
	  color = colors[i];
	  if (XAllocColor (dpy, cmap, &color))
	    {
	      colors[i].pixel = color.pixel;
	    }
	  else
	    {
	      free_colors (dpy, cmap, colors, i);
	      goto FAIL;
	    }
	}
    }

  return;

 FAIL:
  /* we weren't able to allocate all the colors we wanted;
     decrease the requested number and try again.
   */
  ncolors = (ncolors > 170 ? ncolors - 20 :
	     ncolors > 100 ? ncolors - 10 :
	     ncolors >  75 ? ncolors -  5 :
	     ncolors >  25 ? ncolors -  3 :
	     ncolors >  10 ? ncolors -  2 :
	     ncolors >   2 ? ncolors -  1 :
	     0);
  *ncolorsP = ncolors;
  if (ncolors > 0)
    goto AGAIN;
}


#define MAXPOINTS 50	/* yeah, so I'm lazy */


static void
make_color_path (Display *dpy, Colormap cmap,
		 int npoints, int *h, double *s, double *v,
		 XColor *colors, int *ncolorsP,
		 Bool allocate_p,
		 Bool writable_p)
{
  int i, j, k;
  int total_ncolors = *ncolorsP;

  int ncolors[MAXPOINTS];  /* number of pixels per edge */
  double dh[MAXPOINTS];    /* distance between pixels, per edge (0 - 360.0) */
  double ds[MAXPOINTS];    /* distance between pixels, per edge (0 - 1.0) */
  double dv[MAXPOINTS];    /* distance between pixels, per edge (0 - 1.0) */

  if (npoints == 0)
    {
      *ncolorsP = 0;
      return;
    }
  else if (npoints == 2)	/* using make_color_ramp() will be faster */
    {
      make_color_ramp (dpy, cmap,
		       h[0], s[0], v[0], h[1], s[1], v[1],
		       colors, ncolorsP,
		       True,  /* closed_p */
		       allocate_p, writable_p);
      return;
    }
  else if (npoints >= MAXPOINTS)
    {
      npoints = MAXPOINTS-1;
    }

 AGAIN:

  {
    double DH[MAXPOINTS];	/* Distance between H values in the shortest
				   direction around the circle, that is, the
				   distance between 10 and 350 is 20.
				   (Range is 0 - 360.0.)
				*/
    double edge[MAXPOINTS];	/* lengths of edges in unit HSV space. */
    double ratio[MAXPOINTS];	/* proportions of the edges (total 1.0) */
    double circum = 0;
    double one_point_oh = 0;	/* (debug) */

    for (i = 0; i < npoints; i++)
      {
	int j = (i+1) % npoints;
	double d = ((double) (h[i] - h[j])) / 360;
	if (d < 0) d = -d;
	if (d > 0.5) d = 0.5 - (d - 0.5);
	DH[i] = d;
      }

    for (i = 0; i < npoints; i++)
      {
	int j = (i+1) % npoints;
	edge[i] = sqrt((DH[i] * DH[j]) +
		       ((s[j] - s[i]) * (s[j] - s[i])) +
		       ((v[j] - v[i]) * (v[j] - v[i])));
	circum += edge[i];
      }

#ifdef DEBUG
    fprintf(stderr, "\ncolors:");
    for (i=0; i < npoints; i++)
      fprintf(stderr, " (%d, %.3f, %.3f)", h[i], s[i], v[i]);
    fprintf(stderr, "\nlengths:");
    for (i=0; i < npoints; i++)
      fprintf(stderr, " %.3f", edge[i]);
#endif /* DEBUG */

    if (circum < 0.0001)
      goto FAIL;

    for (i = 0; i < npoints; i++)
      {
	ratio[i] = edge[i] / circum;
	one_point_oh += ratio[i];
      }

#ifdef DEBUG
    fprintf(stderr, "\nratios:");
    for (i=0; i < npoints; i++)
      fprintf(stderr, " %.3f", ratio[i]);
#endif /* DEBUG */

    if (one_point_oh < 0.99999 || one_point_oh > 1.00001)
      abort();

    /* space the colors evenly along the circumference -- that means that the
       number of pixels on a edge is proportional to the length of that edge
       (relative to the lengths of the other edges.)
     */
    for (i = 0; i < npoints; i++)
      ncolors[i] = total_ncolors * ratio[i];


#ifdef DEBUG
    fprintf(stderr, "\npixels:");
    for (i=0; i < npoints; i++)
      fprintf(stderr, " %d", ncolors[i]);
    fprintf(stderr, "  (%d)\n", total_ncolors);
#endif /* DEBUG */

    for (i = 0; i < npoints; i++)
      {
	int j = (i+1) % npoints;

	if (ncolors[i] > 0)
	  {
	    dh[i] = 360 * (DH[i] / ncolors[i]);
	    ds[i] = (s[j] - s[i]) / ncolors[i];
	    dv[i] = (v[j] - v[i]) / ncolors[i];
	  }
      }
  }

  memset (colors, 0, (*ncolorsP) * sizeof(*colors));

  k = 0;
  for (i = 0; i < npoints; i++)
    {
      int distance, direction;
      distance = h[(i+1) % npoints] - h[i];
      direction = (distance >= 0 ? -1 : 1);

      if (distance > 180)
	distance = 180 - (distance - 180);
      else if (distance < -180)
	distance = -(180 - ((-distance) - 180));
      else
	direction = -direction;

#ifdef DEBUG
      fprintf (stderr, "point %d: %3d %.2f %.2f\n",
	       i, h[i], s[i], v[i]);
      fprintf(stderr, "  h[i]=%d  dh[i]=%.2f  ncolors[i]=%d\n",
	      h[i], dh[i], ncolors[i]);
#endif /* DEBUG */
      for (j = 0; j < ncolors[i]; j++, k++)
	{
	  double hh = (h[i] + (j * dh[i] * direction));
	  if (hh < 0) hh += 360;
	  else if (hh > 360) hh -= 0;
	  colors[k].flags = DoRed|DoGreen|DoBlue;
	  hsv_to_rgb ((int)
		      hh,
		      (s[i] + (j * ds[i])),
		      (v[i] + (j * dv[i])),
		      &colors[k].red, &colors[k].green, &colors[k].blue);
#ifdef DEBUG
	  fprintf (stderr, "point %d+%d: %.2f %.2f %.2f  %04X %04X %04X\n",
		   i, j,
		   hh,
		   (s[i] + (j * ds[i])),
		   (v[i] + (j * dv[i])),
		   colors[k].red, colors[k].green, colors[k].blue);
#endif /* DEBUG */
	}
    }

  /* Floating-point round-off can make us decide to use fewer colors. */
  if (k < *ncolorsP)
    {
      *ncolorsP = k;
      if (k <= 0)
	return;
    }

  if (!allocate_p)
    return;

  if (writable_p)
    {
      unsigned long *pixels = (unsigned long *)
	malloc(sizeof(*pixels) * ((*ncolorsP) + 1));

      /* allocate_writable_colors() won't do here, because we need exactly this
	 number of cells, or the color sequence we've chosen won't fit. */
      if (! XAllocColorCells(dpy, cmap, False, 0, 0, pixels, *ncolorsP))
	{
	  free(pixels);
	  goto FAIL;
	}

      for (i = 0; i < *ncolorsP; i++)
	colors[i].pixel = pixels[i];
      free (pixels);

      XStoreColors (dpy, cmap, colors, *ncolorsP);
    }
  else
    {
      for (i = 0; i < *ncolorsP; i++)
	{
	  XColor color;
	  color = colors[i];
	  if (XAllocColor (dpy, cmap, &color))
	    {
	      colors[i].pixel = color.pixel;
	    }
	  else
	    {
	      free_colors (dpy, cmap, colors, i);
	      goto FAIL;
	    }
	}
    }

  return;

 FAIL:
  /* we weren't able to allocate all the colors we wanted;
     decrease the requested number and try again.
   */
  total_ncolors = (total_ncolors > 170 ? total_ncolors - 20 :
		   total_ncolors > 100 ? total_ncolors - 10 :
		   total_ncolors >  75 ? total_ncolors -  5 :
		   total_ncolors >  25 ? total_ncolors -  3 :
		   total_ncolors >  10 ? total_ncolors -  2 :
		   total_ncolors >   2 ? total_ncolors -  1 :
		   0);
  *ncolorsP = total_ncolors;
  if (total_ncolors > 0)
    goto AGAIN;
}


void
make_color_loop (Display *dpy, Colormap cmap,
		 int h0, double s0, double v0,   /* 0-360, 0-1.0, 0-1.0 */
		 int h1, double s1, double v1,   /* 0-360, 0-1.0, 0-1.0 */
		 int h2, double s2, double v2,   /* 0-360, 0-1.0, 0-1.0 */
		 XColor *colors, int *ncolorsP,
		 Bool allocate_p,
		 Bool writable_p)
{
  int h[3];
  double s[3], v[3];
  h[0] = h0; h[1] = h1; h[2] = h2;
  s[0] = s0; s[1] = s1; s[2] = s2;
  v[0] = v0; v[1] = v1; v[2] = v2;
  make_color_path(dpy, cmap,
		  3, h, s, v,
		  colors, ncolorsP,
		  allocate_p, writable_p);
}


static void
complain (int wanted_colors, int got_colors,
	  Bool wanted_writable, Bool got_writable)
{
  if (wanted_writable && !got_writable)
    fprintf(stderr,
	    "%s: wanted %d writable colors; got %d read-only colors.\n",
	    "colors (kscreensaver)", wanted_colors, got_colors);

  else if (wanted_colors > (got_colors + 10))
    /* don't bother complaining if we're within ten pixels. */
    fprintf(stderr, "%s: wanted %d%s colors; got %d.\n",
	    "colors (kscreensaver)", wanted_colors, (got_writable ? " writable" : ""),
	    got_colors);
}


void
make_smooth_colormap (Display *dpy, Visual *visual, Colormap cmap,
		      XColor *colors, int *ncolorsP,
		      Bool allocate_p,
		      Bool *writable_pP,
		      Bool verbose_p)
{
  int npoints;
  int ncolors = *ncolorsP;
  Bool wanted_writable = (allocate_p && writable_pP && *writable_pP);
  int i;
  int h[MAXPOINTS];
  double s[MAXPOINTS];
  double v[MAXPOINTS];
  double total_s = 0;
  double total_v = 0;
  Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */

  if (*ncolorsP <= 0) return;

  {
    int n = random() % 20;
    if      (n <= 5)  npoints = 2;	/* 30% of the time */
    else if (n <= 15) npoints = 3;	/* 50% of the time */
    else if (n <= 18) npoints = 4;	/* 15% of the time */
    else             npoints = 5;	/*  5% of the time */
  }

 REPICK_ALL_COLORS:
  for (i = 0; i < npoints; i++)
    {
    REPICK_THIS_COLOR:
      h[i] = random() % 360;
      s[i] = frand(1.0);
      v[i] = frand(0.8) + 0.2;

      /* Make sure that no two adjascent colors are *too* close together.
	 If they are, try again.
       */
      if (i > 0)
	{
	  int j = (i+1 == npoints) ? 0 : (i-1);
	  double hi = ((double) h[i]) / 360;
	  double hj = ((double) h[j]) / 360;
	  double dh = hj - hi;
	  double distance;
	  if (dh < 0) dh = -dh;
	  if (dh > 0.5) dh = 0.5 - (dh - 0.5);
	  distance = sqrt ((dh * dh) +
			   ((s[j] - s[i]) * (s[j] - s[i])) +
			   ((v[j] - v[i]) * (v[j] - v[i])));
	  if (distance < 0.2)
	    goto REPICK_THIS_COLOR;
	}
      total_s += s[i];
      total_v += v[i];
    }

  /* If the average saturation or intensity are too low, repick the colors,
     so that we don't end up with a black-and-white or too-dark map.
   */
  if (total_s / npoints < 0.2)
    goto REPICK_ALL_COLORS;
  if (total_v / npoints < 0.3)
    goto REPICK_ALL_COLORS;

  /* If this visual doesn't support writable cells, don't bother trying.
   */
  if (wanted_writable && !has_writable_cells(screen, visual))
    *writable_pP = False;

 RETRY_NON_WRITABLE:
  make_color_path (dpy, cmap, npoints, h, s, v, colors, &ncolors,
		   allocate_p, (writable_pP && *writable_pP));

  /* If we tried for writable cells and got none, try for non-writable. */
  if (allocate_p && *ncolorsP == 0 && *writable_pP)
    {
      *writable_pP = False;
      goto RETRY_NON_WRITABLE;
    }

  if (verbose_p)
    complain(*ncolorsP, ncolors, wanted_writable,
	     wanted_writable && *writable_pP);

  *ncolorsP = ncolors;
}


void
make_uniform_colormap (Display *dpy, Visual *visual, Colormap cmap,
		       XColor *colors, int *ncolorsP,
		       Bool allocate_p,
		       Bool *writable_pP,
		       Bool verbose_p)
{
  int ncolors = *ncolorsP;
  Bool wanted_writable = (allocate_p && writable_pP && *writable_pP);
  Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */

  double S = ((double) (random() % 34) + 66) / 100.0;	/* range 66%-100% */
  double V = ((double) (random() % 34) + 66) / 100.0;	/* range 66%-100% */

  if (*ncolorsP <= 0) return;

  /* If this visual doesn't support writable cells, don't bother trying. */
  if (wanted_writable && !has_writable_cells(screen, visual))
    *writable_pP = False;

 RETRY_NON_WRITABLE:
  make_color_ramp(dpy, cmap,
		  0,   S, V,
		  359, S, V,
		  colors, &ncolors,
		  False, True, wanted_writable);

  /* If we tried for writable cells and got none, try for non-writable. */
  if (allocate_p && *ncolorsP == 0 && writable_pP && *writable_pP)
    {
      ncolors = *ncolorsP;
      *writable_pP = False;
      goto RETRY_NON_WRITABLE;
    }

  if (verbose_p)
    complain(*ncolorsP, ncolors, wanted_writable,
	     wanted_writable && *writable_pP);

  *ncolorsP = ncolors;
}


void
make_random_colormap (Display *dpy, Visual *visual, Colormap cmap,
		      XColor *colors, int *ncolorsP,
		      Bool bright_p,
		      Bool allocate_p,
		      Bool *writable_pP,
		      Bool verbose_p)
{
  Bool wanted_writable = (allocate_p && writable_pP && *writable_pP);
  int ncolors = *ncolorsP;
  int i;
  Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */

  if (*ncolorsP <= 0) return;

  /* If this visual doesn't support writable cells, don't bother trying. */
  if (wanted_writable && !has_writable_cells(screen, visual))
    *writable_pP = False;

  for (i = 0; i < ncolors; i++)
    {
      colors[i].flags = DoRed|DoGreen|DoBlue;
      if (bright_p)
	{
	  int H = random() % 360;			   /* range 0-360    */
	  double S = ((double) (random()%70) + 30)/100.0;  /* range 30%-100% */
	  double V = ((double) (random()%34) + 66)/100.0;  /* range 66%-100% */
	  hsv_to_rgb (H, S, V,
		      &colors[i].red, &colors[i].green, &colors[i].blue);
	}
      else
	{
	  colors[i].red   = random() % 0xFFFF;
	  colors[i].green = random() % 0xFFFF;
	  colors[i].blue  = random() % 0xFFFF;
	}
    }

  if (!allocate_p)
    return;

 RETRY_NON_WRITABLE:
  if (writable_pP && *writable_pP)
    {
      unsigned long *pixels = (unsigned long *)
	malloc(sizeof(*pixels) * (ncolors + 1));

      allocate_writable_colors (dpy, cmap, pixels, &ncolors);
      if (ncolors > 0)
	for (i = 0; i < ncolors; i++)
	  colors[i].pixel = pixels[i];
      free (pixels);
      if (ncolors > 0)
	XStoreColors (dpy, cmap, colors, ncolors);
    }
  else
    {
      for (i = 0; i < ncolors; i++)
	{
	  XColor color;
	  color = colors[i];
	  if (!XAllocColor (dpy, cmap, &color))
	    break;
	  colors[i].pixel = color.pixel;
	}
      ncolors = i;
    }

  /* If we tried for writable cells and got none, try for non-writable. */
  if (allocate_p && ncolors == 0 && writable_pP && *writable_pP)
    {
      ncolors = *ncolorsP;
      *writable_pP = False;
      goto RETRY_NON_WRITABLE;
    }

  if (verbose_p)
    complain(*ncolorsP, ncolors, wanted_writable,
	     wanted_writable && *writable_pP);

  *ncolorsP = ncolors;
}


void
rotate_colors (Display *dpy, Colormap cmap,
	       XColor *colors, int ncolors, int distance)
{
  int i;
  XColor *colors2 = (XColor *) malloc(sizeof(*colors2) * ncolors);
  if (ncolors < 2) return;
  distance = distance % ncolors;
  for (i = 0; i < ncolors; i++)
    {
      int j = i - distance;
      if (j >= ncolors) j -= ncolors;
      if (j < 0) j += ncolors;
      colors2[i] = colors[j];
      colors2[i].pixel = colors[i].pixel;
    }
  XStoreColors (dpy, cmap, colors2, ncolors);
  XFlush(dpy);
  memcpy(colors, colors2, sizeof(*colors) * ncolors);
  free(colors2);
}

--- NEW FILE: main.C ---
//-----------------------------------------------------------------------------
//
// Screen savers for KDE
//
// Copyright (c)  Martin R. Jones 1996
//

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <kprocess.h>
#include <qapp.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <qkeycode.h>
#include <qdialog.h>
#include <qpushbt.h>
#include <qbitmap.h>
#include <qpainter.h>

#include "xautolock.h"
#include "saver.h"
#include "main.h"
#include "main.moc"
#include <kmsgbox.h>

KLocale *glocale;

extern "C" {
  extern void startScreenSaver( Drawable d );
  extern void stopScreenSaver();
  extern int  setupScreenSaver();
  extern const char *getScreenSaverName();
  extern void exposeScreenSaver( int x, int y, int width, int height );
}

extern void initPasswd();
int mode = MODE_NONE, lock = FALSE, passOk = FALSE;
bool canGetPasswd;
static int lockOnce = FALSE;
static int only1Time = 0;
static int xs_timeout, xs_interval, xs_prefer_blanking, xs_allow_exposures;
static QString pidFile;
static KPasswordDlg *passDlg = NULL;
static QWidget *saverWidget = NULL;
static int desktopWidth = 0, desktopHeight = 0;
extern char *ProgramName;
extern Bool allowroot;

bool grabInput( QWidget *w );
void releaseInput();
void destroySaverWindow( QWidget *w );
static void lockNow( int );
static void cleanup( int );
void catchSignals();
void usage( char *name );

ssApp *globalKapp;

//----------------------------------------------------------------------------

ssApp::ssApp( int &argc, char **argv ) : KApplication( argc, argv )
{
	KConfig *kssConfig = new KConfig( kapp->kde_configdir() + "/kssrc", 
	                                  kapp->localconfigdir() + "/kssrc" );
	kssConfig->setGroup( "kss" );
	stars = kssConfig->readBoolEntry( "PasswordAsStars", true );
	delete kssConfig;
}

bool ssApp::x11EventFilter( XEvent *event )
{
	if ( passDlg )	// pass key presses to password dialog
	{
		if ( event->type == KeyPress )
		{
			XKeyEvent *xke = (XKeyEvent *) event;

			int key = 0;
			KeySym keysym = 0;
			XComposeStatus compose;
			char buffer[2] = "";
			XLookupString( xke, buffer, 1, &keysym, &compose );

			switch ( keysym )
			{
				case XK_BackSpace:
					key = Key_Backspace;
					break;

				case XK_Return:
					key = Key_Return;
					break;

				case XK_Escape:
					key = Key_Escape;
					break;
			}

			if ( buffer[0] != '\0' || key != 0 )
			{
			    QKeyEvent qke( Event_KeyPress, key, buffer[0], 0 );
			    passDlg->keyPressed( &qke );
			}
			return TRUE;
		}
		return FALSE;
	}

	if ( mode == MODE_INSTALL || mode == MODE_TEST )
	{
		if ( (event->type == KeyPress
			|| event->type == ButtonPress
			|| event->type == MotionNotify ) && !passDlg )
		{
			if ( !canGetPasswd || (!lock && !lockOnce) )
				qApp->exit_loop();
			else
			{
				passDlg = new KPasswordDlg( saverWidget, stars );
				connect(passDlg, SIGNAL(passOk()), SLOT(slotPassOk()));
				connect(passDlg, SIGNAL(passCancel()), SLOT(slotPassCancel()));
				passDlg->move( (QApplication::desktop()->width()
						- passDlg->width())/2,
					(QApplication::desktop()->height()
						- passDlg->height())/2 );
				passDlg->show();
			}
			return TRUE;
		}
		else if ( event->type == VisibilityNotify )
		{
			if ( event->xvisibility.state != VisibilityUnobscured)
			{
				if ( !passDlg )
                {
					saverWidget->raise();
                    QApplication::flushX();
                }
			}
		}
        else if ( event->type == ConfigureNotify )
        {
            if ( !passDlg )
            {
                saverWidget->raise();
                QApplication::flushX();
            }
        }
        else if ( event->type == Expose )
        {
            if (!passDlg)
            {
                exposeScreenSaver( event->xexpose.x,
                        event->xexpose.y,
                        event->xexpose.width,
                        event->xexpose.height );
            }
		}
	}

	return FALSE;
}

void ssApp::slotPassOk()
{
	passOk = TRUE;
    passDlg->hide();
	QApplication::flushX();
	delete passDlg;
	passDlg = NULL;
	qApp->exit_loop();
	QApplication::flushX();
}

void ssApp::slotPassCancel()
{
	passOk = FALSE;
    passDlg->hide();
	QApplication::flushX();
	delete passDlg;
	passDlg = NULL;
	grabInput( saverWidget );
	QApplication::flushX();
}

//----------------------------------------------------------------------------

bool grabInput( QWidget *w)
{
	int rv = XGrabKeyboard( qt_xdisplay(), QApplication::desktop()->winId(),
                True, GrabModeAsync, GrabModeAsync, CurrentTime );

    if (rv == AlreadyGrabbed)
    {
        return false;
    }

	rv = XGrabPointer( qt_xdisplay(), QApplication::desktop()->winId(), True,
			ButtonPressMask
			| ButtonReleaseMask | EnterWindowMask | LeaveWindowMask
			| PointerMotionMask | PointerMotionHintMask | Button1MotionMask
			| Button2MotionMask | Button3MotionMask | Button4MotionMask
			| Button5MotionMask | ButtonMotionMask | KeymapStateMask,
			GrabModeAsync, GrabModeAsync, None, w->cursor().handle(),
			CurrentTime );

    if (rv == AlreadyGrabbed)
    {
        return false;
    }

    return true;
}

void releaseInput()
{
	XUngrabKeyboard( qt_xdisplay(), CurrentTime );
	XUngrabPointer( qt_xdisplay(), CurrentTime );
}

QWidget *createSaverWindow()
{
	QWidget *w;

	// WStyle_Customize sets override_redirect
	w = new QWidget( NULL, "", WStyle_Customize | WStyle_NoBorder );

	/* set NoBackground so that the saver can capture the current
	 * screen state if neccessary
	 */
	w->setBackgroundMode( QWidget::NoBackground );

	XSetWindowAttributes attr;
	attr.event_mask = KeyPressMask | ButtonPressMask | MotionNotify |
		 VisibilityChangeMask | ExposureMask; // | StructureNotifyMask;
	XChangeWindowAttributes(qt_xdisplay(), w->winId(), CWEventMask, &attr);

	QBitmap bm( 1, 1, TRUE );
	QCursor c( bm, bm );
	w->setCursor( c );

	if (grabInput( w ) == false)
    {
        // The grab failed - we can't save the window now.
        destroySaverWindow(w);
        w = 0;
    }

	return w;
}

void destroySaverWindow( QWidget *w )
{
	releaseInput();
	delete w;
}

//----------------------------------------------------------------------------

QString lockName(QString s)
{
	// note that changes in the pidFile name have also to be done
	// in kdebase/kcontrol/display/scrnsave.cpp
	QString name = getenv( "HOME" );
	name += "/.kss-" + s + ".pid.";
	char ksshostname[200];
	gethostname(ksshostname, 200);
	name += ksshostname;
	return name;
}

int getLock(QString type)
{
	QString lockFile = lockName(type);
	int pid = -1;

	FILE *fp;
	if ( (fp = fopen( lockFile, "r" ) ) != NULL )
	{
		fscanf( fp, "%d", &pid );
		fclose( fp );
	}

	return pid;
}

void killProcess(int pid)
{
	if ( pid != getpid() && pid > 1 )
	{
		if( kill( pid, SIGTERM ) == 0 ) 
			sleep(1);
	}
}

void setLock(QString type)
{
	FILE *fp;
	pidFile = lockName(type);
	int pid = getLock( type );

	killProcess( pid );

	if ( (fp = fopen( pidFile, "w" ) ) != NULL )
	{
		// on some systems, it's long one some in, so a cast may help
		fprintf( fp, "%ld\n", static_cast<long>(getpid()) );
		fclose( fp );
	}
}

/* Verify, if kcheckpass is able to verify passwords.
 * I cannot use KProcess here, as it needs ProcessEvents */
bool canReadPasswdDatabase()
{
	KProcess chkpass;
	QString kcp_binName = "";
	kcp_binName += KApplication::kde_bindir();
	kcp_binName += "/kcheckpass";
	chkpass.clearArguments();
	chkpass << kcp_binName;
	bool ret = chkpass.start(KProcess::DontCare, KProcess::Stdin);
	if (ret == false)
          return false;

	chkpass.closeStdin();
	int timeout = 1000;
	while ( timeout != 0 ) {
	  if (! chkpass.isRunning() )
	    break;
	  else {
	    globalKapp->processEvents();
	    timeout--;
	    usleep(10000);
	  }
	}
	
	int canRead = ( chkpass.normalExit() && (chkpass.exitStatus() != 2) );
	return canRead;
}

//----------------------------------------------------------------------------

int main( int argc, char *argv[] )
{
	// drop root privileges temporarily
#ifdef HAVE_SETEUID
	seteuid(getuid());
#else
        setreuid(-1, getuid());
#endif // HAVE_SETEUID

	Window saveWin = 0;
	int timeout = 600;
	ProgramName = argv[0];
	ssApp a( argc, argv );
        globalKapp = &a;
	glocale = new KLocale("klock");

	if ( argc == 1 )
	    usage( argv[0] );

	enum parameter_code { 
	    install, setup, preview, inroot, test, delay, 
	    arg_lock, corners, descr, arg_nice, help, allow_root,
	    unknown
	} parameter;
	
	char *strings[] = { 
	    "-install", "-setup", "-preview", "-inroot", "-test", "-delay", 
	    "-lock", "-corners", "-desc", "-nice", "--help", "-allow-root",
	    0
	};

	int i = 1;
	while ( i < argc) {
	    parameter = unknown;

	    for ( int p = 0 ; strings[p]; p++)
		if ( !strcmp( argv[i], strings[p]) ) {
		    parameter = static_cast<parameter_code>(p);
		    break;
		}

	    switch (parameter) 
		{
		case install:
		    mode = MODE_INSTALL;
		    break;
		case setup:
		    mode = MODE_SETUP;
		    break;
		case preview:
		    mode = MODE_PREVIEW;
		    saveWin = atol( argv[++i] );
		    break;
		case inroot:
		    mode = MODE_PREVIEW;
		    saveWin = kapp->desktop()->winId();
		    break;
		case test:
		    mode = MODE_TEST;
		    break;
		case delay:
		    timeout = atoi( argv[++i] ) * 60;
		    if( timeout == 0 )
			only1Time = 1;
		    else if( timeout < 60 )
			timeout = 60;
		    break;
		case arg_lock:
		    lock = TRUE;
		    break;
		case corners:
		    setCorners( argv[++i] );
		    break;
		case descr:
		    printf( "%s\n", getScreenSaverName() );
		    exit( 0 );
		case arg_nice:
#ifdef HAVE_NICE
		    nice( atoi( argv[++i] ) );
#else
		    warning(glocale->translate(
					       "Option %s is not support on "
					       "this plattform!"), 
			    strings[arg_nice]);
#endif
		    break;
		case allow_root:
		    allowroot = 1;
		    break;
		case help:
		    usage( argv[0] );
		    break;
		default: // unknown
		    debug("unknown parameter");
		    break;
		}
	    i++;
	}

	// regain root privileges
#ifdef HAVE_SETEUID
	seteuid(0);
#else
    setreuid(-1, 0);
#endif // HAVE_SETEUID
	initPasswd();
	// ... and drop them again before doing anything important
	setuid(getuid());

	// now check, if I can verify passwords (might be a problem
	// only with shadow passwords, due to missing SUID on
	// kcheckpass program.
#ifdef HAVE_SHADOW
        canGetPasswd = canReadPasswdDatabase();
#else
	canGetPasswd = true;
#endif

    // Get the size of the desktop
    XWindowAttributes attr;
    if (XGetWindowAttributes(qt_xdisplay(), RootWindow(qt_xdisplay(),
        qt_xscreen()), &attr) == 0)
    {
        debug("Failed getting Root window size");
    }
    else
    {
        desktopWidth = attr.width;
        desktopHeight = attr.height;
    }

	catchSignals();
	if ( mode == MODE_INSTALL )
	{
		if (!canGetPasswd && lock) {
			QString tmp = glocale->translate(
			              "Warning: You won't be able to lock the screen!\n\n"
			              "Your system uses shadow passwords.\n"
			              "Please contact your system administrator.\n"
			              "Tell him that you need suid for the kcheckpass program!");
			KMsgBox::message(NULL, 
				 glocale->translate("Shadow Passwords"), 
				 tmp, KMsgBox::EXCLAMATION);
		}
		setLock("install");

		XGetScreenSaver( qt_xdisplay(), &xs_timeout, &xs_interval,
				&xs_prefer_blanking, &xs_allow_exposures );
		XSetScreenSaver( qt_xdisplay(), 0, xs_interval, xs_prefer_blanking,
			xs_allow_exposures );

        initAutoLock();
			
		while ( 1 )
		{
			if ( waitTimeout( timeout ) == FORCE_LOCK )
				lockOnce = TRUE;

			// if another saver is in test-mode, kill it
			killProcess(getLock("test"));

			saverWidget = createSaverWindow();

            if (saverWidget)
            {
                saverWidget->setFixedSize(desktopWidth, desktopHeight);
                saverWidget->move( 0, 0 );
                saverWidget->show();
                saverWidget->raise();
                QApplication::flushX();

                saveWin = saverWidget->winId();

                startScreenSaver( saveWin );
                a.enter_loop();
                stopScreenSaver();

                destroySaverWindow( saverWidget );

                lockOnce = FALSE;
                if( only1Time ) 
                    break;
            }
		}

        cleanupAutoLock();
	}
	else if ( mode == MODE_TEST )
	{
		if( lock ) {
			fprintf(stderr, glocale->translate(
	                        "\nplease don't use -test together with -lock.\n"
			        "use klock instead.\n\n") );
			exit(1);
		}
		setLock("test");
		saverWidget = createSaverWindow();
        if (saverWidget)
        {
            saverWidget->setFixedSize(desktopWidth, desktopHeight);
            saverWidget->move( 0, 0 );
            saverWidget->show();
            saverWidget->raise();
            QApplication::flushX();

            saveWin = saverWidget->winId();

            startScreenSaver( saveWin );
            a.enter_loop();
            stopScreenSaver();

            destroySaverWindow( saverWidget );
        }
	}
	else if ( mode == MODE_PREVIEW )
	{
		char mode[32];
		sprintf(mode, "preview%ld", (unsigned long) saveWin);
		setLock(mode);
		startScreenSaver( saveWin );
		a.exec();
	}
	else if ( mode == MODE_SETUP )
	{
		setupScreenSaver();
	}
	else
		usage( argv[0] );

    if ( !pidFile.isEmpty() )
    {
        remove( pidFile );
    }
	return 0;
}

//----------------------------------------------------------------------------

void catchSignals()
{
	// SIGUSR1 forces a lock
	signal(SIGUSR1, lockNow);

	// These signals are captured to clean-up before exiting
	signal(SIGINT, cleanup);		/* Interrupt */
	signal(SIGTERM, cleanup);		/* Terminate */

	signal(SIGABRT, cleanup);
	signal(SIGALRM, cleanup);
	signal(SIGFPE, cleanup);
	signal(SIGILL, cleanup);
	signal(SIGPIPE, cleanup);
	signal(SIGQUIT, cleanup);
	signal(SIGSEGV, cleanup);

#ifdef SIGBUS
	signal(SIGBUS, cleanup);
#endif
#ifdef SIGEMT
	signal(SIGEMT, cleanup);
#endif
#ifdef SIGPOLL
	signal(SIGPOLL, cleanup);
#endif
#ifdef SIGSYS
	signal(SIGSYS, cleanup);
#endif
#ifdef SIGTRAP
	signal(SIGTRAP, cleanup);
#endif
#ifdef SIGVTALRM
	signal(SIGVTALRM, cleanup);
#endif
#ifdef SIGXCPU
	signal(SIGXCPU, cleanup);
#endif
#ifdef SIGXFSZ
	signal(SIGXFSZ, cleanup);
#endif
}

static void lockNow( int )
{
	forceTimeout();
	// SIGUSR1 forces a lock
	signal(SIGUSR1, lockNow);
}

static void cleanup( int id )
{
    if ( !pidFile.isEmpty() )
    {
        remove( pidFile );
    }
	if ( mode == MODE_INSTALL )
	{
		if (id != SIGPIPE)
        {
			XSetScreenSaver( qt_xdisplay(), xs_timeout, xs_interval,
			                 xs_prefer_blanking, xs_allow_exposures );
            cleanupAutoLock();
        }
	}
	exit(1);
}

void usage( char *name )
{
	printf( glocale->translate(
	   "Usage: %s -install|-setup|-test|-desc|-preview wid|-inroot\n"\
	   "       [-corners xxxx] [-delay num] [-lock] [-allow-root] [-nice num]\n"), name ); 
	printf( glocale->translate(
	"  -corners xxxx     Placing cursor in corner performs action:\n"\
	"                     x = i  no action (ignore)\n"\
	"                     x = s  save screen\n"\
	"                     x = l  lock screen\n"\
	"                    order: top-left, top-right, bottom-left, bottom-right\n"\
	"  -delay num        Amount of idle time before screen saver\n"\
	"                     starts  (default 10min)\n"\
	"  -desc             Print the screen saver's description to stdout\n"\
	"  -install          Install screen saver\n"\
	"  -lock             Require password to stop screen saver\n"\
	"  -allow-root       Accept root password to unlock\n"\
	"  -nice num         Run with specified nice value\n\n"\
	"  -preview wid      Run in the specified XWindow\n"\
	"  -inroot           Run in the root window\n"\
	"  -setup            Setup screen saver\n"\
	"  -test             Invoke the screen saver immediately\n"));
	exit(1);
}


--- NEW FILE: kscreensaver.pam ---
#%PAM-1.0
auth       required     /lib/security/pam_pwdb.so shadow nullok

--- NEW FILE: xs_colors.h ---
/* xscreensaver, Copyright (c) 1992, 1997 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

#ifndef __COLORS_H__
#define __COLORS_H__

/* Like XFreeColors, but works on `XColor *' instead of `unsigned long *'
 */
extern void free_colors (Display *, Colormap, XColor *, int ncolors);


/* Allocates writable, non-contiguous color cells.  The number requested is
   passed in *ncolorsP, and the number actually allocated is returned there.
   (Unlike XAllocColorCells(), this will allocate as many as it can, instead
   of failing if they can't all be allocated.)
 */
extern void allocate_writable_colors (Display *dpy, Colormap cmap,
				      unsigned long *pixels, int *ncolorsP);


/* Generates a sequence of colors evenly spaced between the given pair
   of HSV coordinates.

   If closed_p is true, the colors will go from the first point to the
   second then back to the first.

   If allocate_p is true, the colors will be allocated from the map;
   if enough colors can't be allocated, we will try for less, and the
   result will be returned to ncolorsP.

   If writable_p is true, writable color cells will be allocated;
   otherwise, read-only cells will be allocated.
 */
extern void make_color_ramp (Display *dpy, Colormap cmap,
			     int h1, double s1, double v1,
			     int h2, double s2, double v2,
			     XColor *colors, int *ncolorsP,
			     Bool closed_p,
			     Bool allocate_p,
			     Bool writable_p);

/* Generates a sequence of colors evenly spaced around the triangle
   indicated by the thee HSV coordinates.

   If allocate_p is true, the colors will be allocated from the map;
   if enough colors can't be allocated, we will try for less, and the
   result will be returned to ncolorsP.

   If writable_p is true, writable color cells will be allocated;
   otherwise, read-only cells will be allocated.
 */
extern void make_color_loop (Display *, Colormap,
			     int h1, double s1, double v1,
			     int h2, double s2, double v2,
			     int h3, double s3, double v3,
			     XColor *colors, int *ncolorsP,
			     Bool allocate_p,
			     Bool writable_p);


/* Allocates a hopefully-interesting colormap, which will be a closed loop
   without any sudden transitions.

   If allocate_p is true, the colors will be allocated from the map;
   if enough colors can't be allocated, we will try for less, and the
   result will be returned to ncolorsP.  An error message will be
   printed on stderr (if verbose_p).

   If *writable_pP is true, writable color cells will be allocated;
   otherwise, read-only cells will be allocated.  If no writable cells
   cannot be allocated, we will try to allocate unwritable cells
   instead, and print a message on stderr to that effect (if verbose_p).
 */
extern void make_smooth_colormap (Display *dpy, Visual *visual,
				  Colormap cmap,
				  XColor *colors, int *ncolorsP,
				  Bool allocate_p,
				  Bool *writable_pP,
				  Bool verbose_p);

/* Allocates a uniform colormap which touches each hue of the spectrum,
   evenly spaced.  The saturation and intensity are chosen randomly, but
   will be high enough to be visible.

   If allocate_p is true, the colors will be allocated from the map;
   if enough colors can't be allocated, we will try for less, and the
   result will be returned to ncolorsP.  An error message will be
   printed on stderr (if verbose_p).

   If *writable_pP is true, writable color cells will be allocated;
   otherwise, read-only cells will be allocated.  If no writable cells
   cannot be allocated, we will try to allocate unwritable cells
   instead, and print a message on stderr to that effect (if verbose_p).
 */
extern void make_uniform_colormap (Display *dpy, Visual *visual,
				   Colormap cmap,
				   XColor *colors, int *ncolorsP,
				   Bool allocate_p,
				   Bool *writable_pP,
				   Bool verbose_p);

/* Allocates a random colormap (the colors are unrelated to one another.)
   If `bright_p' is false, the colors will be completely random; if it is
   true, all of the colors will be bright enough to see on a black background.

   If allocate_p is true, the colors will be allocated from the map;
   if enough colors can't be allocated, we will try for less, and the
   result will be returned to ncolorsP.  An error message will be
   printed on stderr (if verbose_p).

   If *writable_pP is true, writable color cells will be allocated;
   otherwise, read-only cells will be allocated.  If no writable cells
   cannot be allocated, we will try to allocate unwritable cells
   instead, and print a message on stderr to that effect (if verbose_p).
 */
extern void make_random_colormap (Display *dpy, Visual *visual,
				  Colormap cmap,
				  XColor *colors, int *ncolorsP,
				  Bool bright_p,
				  Bool allocate_p,
				  Bool *writable_pP,
				  Bool verbose_p);


/* Assuming that the array of colors indicates the current state of a set
   of writable color cells, this rotates the contents of the array by
   `distance' steps, moving the colors of cell N to cell (N - distance).
 */
extern void rotate_colors (Display *, Colormap,
			   XColor *, int ncolors, int distance);

#endif /* __COLORS_H__ */




More information about the dslinux-commit mailing list