vesper@3d.dec.com.UUCP (07/01/88)
---cut here---
/*
* XLOCK V1.2
*
* A Terminal Locker for X11
*
* Copyright (c) 1988 by Patrick J. Naughton
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* Original version posted to comp.windows.x by:
* Walter Milliken
* (milliken@heron.bbn.com)
* BBN Advanced Computers, Inc., Cambridge, MA
*
* Comments and additions may be sent the author at:
*
* naughton@sun.soe.clarkson.edu
*
* or by Snail Mail:
* Patrick J. Naughton
* 23 Pleasant Street, #3
* Potsdam, NY 13676
* or
* (315) 265-2853 (voice)
*
*
* Revision History:
* 1-Jul-88: AFV (vesper@3d.dec.com)
* Fixed color support (allocates every free color map entry
* with a random color)
* Made sure the GrabKeyboard works else beep and die
* Rudimentary support for VMS (password `Secret')
* Added message area
* Added -fg, -bg and -font switches
* Beep on bad password
* 30-Mar-88: Removed startup password requirement (why did I add that?)
* Removed cursor to avoid phosphor burn.
* 27-Mar-88: Rotate fractal by 45 degrees clockwise. (aesthetics)
* 24-Mar-88: Added color support. [-color]
* wrote the man page.
* 23-Mar-88: Added HOPALONG routines from Scientific American Sept. 86 p. 14.
* added password requirement for invokation
* removed option for command line password
* added requirement for display to be "unix:0".
* 22-Mar-88: Recieved Walter Milliken's comp.windows.x posting.
*
*/
#include <stdio.h>
#ifndef VMS
#include <pwd.h>
#endif
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifndef VMS
char *crypt();
#endif
#ifdef VMS
#define random rand
#define srandom srand
#endif
static char no_bits[] = {0};
Display *dsp = NULL; /* current display (must be inited) */
Window w; /* window used to cover screen */
GContext gc;
int width; /* width of screen */
int height; /* height of screen */
Window rootw; /* root window */
int screen; /* current screen */
Colormap cmap; /* colormap of current screen */
Cursor mycursor; /* blank cursor */
unsigned long bg_pixel; /* pixel value for black */
unsigned long fg_pixel; /* pixel value for white */
XColor bg_color; /* color value for black */
XColor fg_color; /* color value for white */
XColor random_color; /* generate random colors if -c is specified */
XComposeStatus compose;
int centerx, centery, iter, maxiter, range, color;
double a, b, c, i, j;
ReadXString(s, slen)
char *s;
int slen;
{
int bp;
char c;
XEvent evt;
char keystr[20];
int len;
int i;
bp = 0;
while (1) {
if (XPending(dsp)) {
XNextEvent(dsp, &evt);
if (evt.type == KeyPress) {
len = XLookupString(&evt.xkey, keystr, 20, NULL, &compose);
for (i = 0; i < len; i++) {
c = keystr[i];
switch (c) {
case 8: /* ^H */
if (bp > 0) bp--;
break;
case 13: /* ^M */
s[bp] = '\0';
return;
case 21: /* ^U */
bp = 0;
break;
default:
s[bp] = c;
if (bp < slen-1) bp++;
}
}
}
}
else iterate();
}
}
main(argc, argv)
int argc;
char *argv[];
{
char buf [20];
XSetWindowAttributes attrs;
XGCValues xgcv;
struct passwd * pw;
Pixmap lockc, lockm;
char text [200];
register char * cp;
int text_length;
Window window_text;
int ascent;
int descent;
int direction;
XCharStruct overall;
int width_text;
int height_text;
register int i;
int x;
int y;
char * fg_color_name;
char * bg_color_name;
char * font_name;
int stat;
XFontStruct * font;
int delay;
color = 0;
fg_color_name = NULL;
bg_color_name = NULL;
font_name = NULL;
cp = text;
*cp++ = ' ';
for (i = 1; i < argc; i++) {
if (strcmp("-color", argv[i]) == 0) color = 1;
else if (strcmp ("-fg", argv[i]) == 0) {
if (++i >= argc) break;
fg_color_name = argv[i];
}
else if (strcmp ("-bg", argv[i]) == 0) {
if (++i >= argc) break;
bg_color_name = argv[i];
}
else if (strcmp ("-font", argv[i]) == 0) {
if (++i >= argc) break;
font_name = argv[i];
}
else {
strcpy (cp, argv[i]);
cp += strlen (cp);
*cp++ = ' ';
}
}
text_length = cp - text;
if (text_length == 1) text_length = 0;
#ifdef VMS
dsp = XOpenDisplay (NULL);
#else
dsp = XOpenDisplay("unix:0");
#endif
if (dsp == NULL) exit(1);
rootw = DefaultRootWindow(dsp);
screen = DefaultScreen(dsp);
width = DisplayWidth(dsp, screen);
height = DisplayHeight(dsp, screen);
centerx = width / 2;
centery = height / 2;
range = (int) sqrt((double)centerx*centerx+(double)centery*centery);
cmap = DefaultColormap(dsp, screen);
bg_pixel = -1;
if (bg_color_name != NULL) {
stat = XParseColor (dsp, cmap, bg_color_name, &bg_color);
if (stat != 0) {
stat = XAllocColor (dsp, cmap, &bg_color);
}
if (stat != 0) bg_pixel = bg_color.pixel;
}
if (bg_pixel == -1) {
bg_pixel = BlackPixel(dsp, screen);
bg_color.pixel = bg_pixel;
XQueryColor(dsp, cmap, &bg_color);
}
fg_pixel = -1;
if (fg_color_name != NULL) {
stat = XParseColor (dsp, cmap, fg_color_name, &fg_color);
if (stat != 0) {
stat = XAllocColor (dsp, cmap, &fg_color);
}
if (stat != 0) fg_pixel = fg_color.pixel;
}
if (fg_pixel == -1) {
fg_pixel = WhitePixel(dsp, screen);
fg_color.pixel = fg_pixel;
XQueryColor(dsp, cmap, &fg_color);
}
attrs.background_pixel = bg_pixel;
attrs.override_redirect = True;
attrs.event_mask = KeyPressMask;
w = XCreateWindow(dsp, rootw, 0, 0, width, height, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &attrs);
lockc = XCreateBitmapFromData(dsp, w, no_bits, 8, 1);
lockm = XCreateBitmapFromData(dsp, w, no_bits, 8, 1);
mycursor = XCreatePixmapCursor(dsp, lockc, lockm,
&bg_color, &bg_color,
0, 0);
XFreePixmap(dsp, lockc);
XFreePixmap(dsp, lockm);
xgcv.foreground = fg_pixel;
xgcv.background = bg_pixel;
gc = (GContext) XCreateGC(dsp, w, GCForeground | GCBackground, &xgcv);
if (font_name != NULL) {
font = XLoadQueryFont (dsp, font_name);
if (font != NULL) {
XSetFont (dsp, gc, font->fid);
}
}
if (text_length > 0) {
XQueryTextExtents (dsp, XGContextFromGC (gc), text, text_length,
&direction, &ascent, &descent, &overall);
width_text = overall.rbearing - overall.lbearing;
height_text = ascent + descent;
x = ( DisplayWidth (dsp, screen) - width_text ) / 2;
y = 2 * height_text;
window_text = XCreateSimpleWindow (dsp, w, x, y,
width_text, height_text, 2, fg_pixel, bg_pixel);
}
XMapWindow(dsp, w);
stat = XGrabKeyboard(dsp, w, True, GrabModeAsync, GrabModeAsync,
CurrentTime);
if (stat == AlreadyGrabbed) {
sleep (2);
stat = XGrabKeyboard(dsp, w, True, GrabModeAsync, GrabModeAsync,
CurrentTime);
if (stat == AlreadyGrabbed) {
fprintf (stderr, "Keyboard already grabbed!!!\n");
XBell (dsp, 100);
XFlush (dsp, True);
exit (1);
}
}
if (stat != GrabSuccess) {
fprintf (stderr, "XGrabKeyboard failed, code = %d\n", stat);
exit (1);
}
stat = XGrabPointer(dsp, w, False, 0, GrabModeAsync, GrabModeAsync, None,
mycursor, CurrentTime);
if (stat != GrabSuccess) {
fprintf (stderr, "XGrabPointer failed, code = %d\n", stat);
}
XGrabServer (dsp);
XRaiseWindow (dsp, w);
if (text_length > 0) {
XMapWindow (dsp, window_text);
XDrawString (dsp, window_text, gc, 0, ascent, text, text_length);
}
#ifndef VMS
pw = getpwuid(getuid());
#endif
srandom(time(NULL));
do {
inithop();
ReadXString(buf, 20);
#ifdef VMS
stat = strcmp (buf, "Secret");
#else
stat = strcmp(crypt(buf, pw->pw_passwd), pw->pw_passwd);
#endif
if (stat != 0) XBell (dsp, 20);
} while (stat != 0);
XUngrabServer (dsp);
XUngrabPointer(dsp, CurrentTime);
XUngrabKeyboard(dsp, CurrentTime);
XDestroyWindow(dsp, w);
}
iterate()
{
double oldj;
register int k;
static int stat = 1;
for (k=0;k<500;k++) {
oldj = j;
j = a - i;
i = oldj + (i<0?sqrt(fabs(b*i - c)):-sqrt(fabs(b*i - c)));
if (color) {
if (stat == 0) {
XSetForeground(dsp, gc, iter);
}
else {
random_color.red = random ();
random_color.green = random ();
random_color.blue = random ();
stat = XAllocColor (dsp, cmap, &random_color);
XSetForeground (dsp, gc, random_color.pixel);
}
}
XDrawPoint(dsp, w, gc,
centerx + (int)(i+j), /* sneaky way to rotate +45 deg. */
centery - (int)(i-j));
iter++;
}
if (iter > maxiter) inithop();
}
inithop()
{
a = random() % (range * 100) * (random()%2?-1.0:1.0) / 100.0;
b = random() % (range * 100) * (random()%2?-1.0:1.0) / 100.0;
c = random() % (range * 100) * (random()%2?-1.0:1.0) / 100.0;
if (!(random()%3)) a /= 10.0;
if (!(random()%2)) b /= 100.0;
maxiter = (color?10000+random()%20000:20000+random()%50000);
iter = 0;
i = j = 0.0;
XClearWindow(dsp, w);
}
---cut here---naughton%wind@Sun.COM (Patrick Naughton) (07/07/88)
The message Referenced above appeared on comp.windows.x on July 1st
without my prior knowledge. This "vesper@3d.dec.com" person took it
upon him/herself to take a four month (two revision) old version of
xlock, make some changes to it and post it to the net.
The source very clearly documented that I was maintaining this code and
that additions should be sent to me for integration, "Comments and
additions may be sent the author at:"... The three other contributors
to xlock never had problems interpreting that simple statement over five
revisions.
Ever since the poorly modified version of xlock appeared on the net, I
have been swamped with requests/complaints about "Which version is the
latest?"
The answer is this:
Throw away the hacked V1.2 and wait a couple of days till I get a
chance to test V1.6 with vesper's changes integrated. I'll post the
full file then, (the diffs would be as big as the file... I never
released 1.5... too busy driving from NY to CA...).
-Patrick
______________________________________________________________________
Patrick J. Naughton ARPA: naughton@Sun.COM
Window Systems Group UUCP: ...!sun!naughton
Sun Microsystems, Inc. AT&T: (415) 336 - 1080