v10i069: xlock, Part03/03
Patrick Naughton
naughton at Eng
Wed Nov 14 05:18:27 AEST 1990
Submitted-by: naughton at Eng (Patrick Naughton)
Posting-number: Volume 10, Issue 69
Archive-name: xlock/part03
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 3)."
# Contents: xlock.c
# Wrapped by naughton at wind on Tue Oct 30 11:26:51 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xlock.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xlock.c'\"
else
echo shar: Extracting \"'xlock.c'\" \(21618 characters\)
sed "s/^X//" >'xlock.c' <<'END_OF_FILE'
X#ifndef lint
Xstatic char sccsid[] = "@(#)xlock.c 23.16 90/10/29 XLOCK SMI";
X#endif
X/*-
X * xlock.c - X11 client to lock a display and show a screen saver.
X *
X * Copyright (c) 1988-90 by Patrick Naughton and Sun Microsystems, Inc.
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind. The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof. In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X * Comments and additions should be sent to the author:
X *
X * naughton at eng.sun.com
X *
X * Patrick J. Naughton
X * MS 14-01
X * Windows and Graphics Group
X * Sun Microsystems, Inc.
X * 2550 Garcia Ave
X * Mountain View, CA 94043
X *
X * Revision History:
X * 29-Oct-90: added cast to XFree() arg.
X * added volume arg to call to XBell().
X * 28-Oct-90: center prompt screen.
X * make sure Xlib input buffer does not use up all of swap.
X * make displayed text come from resource file for better I18N.
X * add backward compatible signal handlers for pre 4.1 machines.
X * 31-Aug-90: added blank mode.
X * added swarm mode.
X * moved usleep() and seconds() out to usleep.c.
X * added SVR4 defines to xlock.h
X * 29-Jul-90: added support for multiple screens to be locked by one xlock.
X * moved global defines to xlock.h
X * removed use of allowsig().
X * 07-Jul-90: reworked commandline args and resources to use Xrm.
X * moved resource processing out to resource.c
X * 02-Jul-90: reworked colors to not use dynamic colormap.
X * 23-May-90: added autoraise when obscured.
X * 15-Apr-90: added hostent alias searching for host authentication.
X * 18-Feb-90: added SunOS3.5 fix.
X * changed -mono -> -color, and -saver -> -lock.
X * allow non-locking screensavers to display on remote machine.
X * added -echokeys to disable echoing of '?'s on input.
X * cleaned up all of the parameters and defaults.
X * 20-Dec-89: added -xhost to allow access control list to be left alone.
X * added -screensaver (don't disable screen saver) for the paranoid.
X * Moved seconds() here from all of the display mode source files.
X * Fixed bug with calling XUngrabHosts() in finish().
X * 19-Dec-89: Fixed bug in GrabPointer.
X * Changed fontname to XLFD style.
X * 23-Sep-89: Added fix to allow local hostname:0 as a display.
X * Put empty case for Enter/Leave events.
X * Moved colormap installation later in startup.
X * 20-Sep-89: Linted and made -saver mode grab the keyboard and mouse.
X * Replaced SunView code for life mode with Jim Graham's version,
X * so I could contrib it without legal problems.
X * Sent to expo for X11R4 contrib.
X * 19-Sep-89: Added '?'s on input.
X * 27-Mar-89: Added -qix mode.
X * Fixed GContext->GC.
X * 20-Mar-89: Added backup font (fixed) if XQueryLoadFont() fails.
X * Changed default font to lucida-sans-24.
X * 08-Mar-89: Added -nice, -mode and -display, built vector for life and hop.
X * 24-Feb-89: Replaced hopalong display with life display from SunView1.
X * 22-Feb-89: Added fix for color servers with n < 8 planes.
X * 16-Feb-89: Updated calling conventions for XCreateHsbColormap();
X * Added -count for number of iterations per color.
X * Fixed defaulting mechanism.
X * Ripped out VMS hacks.
X * Sent to expo for X11R3 contrib.
X * 15-Feb-89: Changed default font to pellucida-sans-18.
X * 20-Jan-89: Added -verbose and fixed usage message.
X * 19-Jan-89: Fixed monochrome gc bug.
X * 16-Dec-88: Added SunView style password prompting.
X * 19-Sep-88: Changed -color to -mono. (default is color on color displays).
X * Added -saver option. (just do display... don't lock.)
X * 31-Aug-88: Added -time option.
X * Removed code for fractals to separate file for modularity.
X * Added signal handler to restore host access.
X * Installs dynamic colormap with a Hue Ramp.
X * If grabs fail then exit.
X * Added VMS Hacks. (password 'iwiwuu').
X * Sent to expo for X11R2 contrib.
X * 08-Jun-88: Fixed root password pointer problem and changed PASSLENGTH to 20.
X * 20-May-88: Added -root to allow root to unlock.
X * 12-Apr-88: Added root password override.
X * Added screen saver override.
X * Removed XGrabServer/XUngrabServer.
X * Added access control handling instead.
X * 01-Apr-88: Added XGrabServer/XUngrabServer for more security.
X * 30-Mar-88: Removed startup password requirement.
X * Removed cursor to avoid phosphor burn.
X * 27-Mar-88: Rotate fractal by 45 degrees clockwise.
X * 24-Mar-88: Added color support. [-color]
X * wrote the man page.
X * 23-Mar-88: Added HOPALONG routines from Scientific American Sept. 86 p. 14.
X * added password requirement for invokation
X * removed option for command line password
X * added requirement for display to be "unix:0".
X * 22-Mar-88: Recieved Walter Milliken's comp.windows.x posting.
X *
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <string.h>
X#include <pwd.h>
X
X#include "xlock.h"
X#include <X11/cursorfont.h>
X
Xextern char *crypt();
Xextern char *getenv();
X
Xchar *ProgramName; /* argv[0] */
Xperscreen Scr[MAXSCREENS];
XDisplay *dsp = NULL; /* server display connection */
Xint screen; /* current screen */
Xvoid (*callback) () = NULL;
Xvoid (*init) () = NULL;
X
Xstatic int screens; /* number of screens */
Xstatic Window win[MAXSCREENS]; /* window used to cover screen */
Xstatic Window icon[MAXSCREENS]; /* window used during password typein */
Xstatic Window root[MAXSCREENS]; /* convenience pointer to the root window */
Xstatic GC textgc[MAXSCREENS]; /* graphics context used for text rendering */
Xstatic XColor fgcol[MAXSCREENS];/* used for text rendering */
Xstatic XColor bgcol[MAXSCREENS];/* background of text screen */
Xstatic int iconx[MAXSCREENS]; /* location of left edge of icon */
Xstatic int icony[MAXSCREENS]; /* location of top edge of icon */
Xstatic Cursor mycursor; /* blank cursor */
Xstatic Pixmap lockc;
Xstatic Pixmap lockm; /* pixmaps for cursor and mask */
Xstatic char no_bits[] = {0}; /* dummy array for the blank cursor */
Xstatic int passx; /* position of the ?'s */
Xstatic int passy;
Xstatic XFontStruct *font;
Xstatic int sstimeout; /* screen saver parameters */
Xstatic int ssinterval;
Xstatic int ssblanking;
Xstatic int ssexposures;
X
X#define FALLBACK_FONTNAME "fixed"
X#define ICONW 64
X#define ICONH 64
X
X#define AllPointerEventMask \
X (ButtonPressMask | ButtonReleaseMask | \
X EnterWindowMask | LeaveWindowMask | \
X PointerMotionMask | PointerMotionHintMask | \
X Button1MotionMask | Button2MotionMask | \
X Button3MotionMask | Button4MotionMask | \
X Button5MotionMask | ButtonMotionMask | \
X KeymapStateMask)
X
X
X/* VARARGS1 */
Xvoid
Xerror(s1, s2)
X char *s1,
X *s2;
X{
X fprintf(stderr, s1, ProgramName, s2);
X exit(1);
X}
X
X/*
X * Server access control support.
X */
X
Xstatic XHostAddress *XHosts; /* the list of "friendly" client machines */
Xstatic int HostAccessCount; /* the number of machines in XHosts */
Xstatic Bool HostAccessState; /* whether or not we even look at the list */
X
Xstatic void
XXGrabHosts(dsp)
X Display *dsp;
X{
X XHosts = XListHosts(dsp, &HostAccessCount, &HostAccessState);
X if (XHosts)
X XRemoveHosts(dsp, XHosts, HostAccessCount);
X XEnableAccessControl(dsp);
X}
X
Xstatic void
XXUngrabHosts(dsp)
X Display *dsp;
X{
X if (XHosts) {
X XAddHosts(dsp, XHosts, HostAccessCount);
X XFree((char *)XHosts);
X }
X if (HostAccessState == False)
X XDisableAccessControl(dsp);
X}
X
X
X/*
X * Simple wrapper to get an asynchronous grab on the keyboard and mouse.
X * If either grab fails, we sleep for one second and try again since some
X * window manager might have had the mouse grabbed to drive the menu choice
X * that picked "Lock Screen..". If either one fails the second time we print
X * an error message and exit.
X */
Xstatic void
XGrabKeyboardAndMouse()
X{
X Status status;
X
X status = XGrabKeyboard(dsp, win[0], True,
X GrabModeAsync, GrabModeAsync, CurrentTime);
X if (status != GrabSuccess) {
X sleep(1);
X status = XGrabKeyboard(dsp, win[0], True,
X GrabModeAsync, GrabModeAsync, CurrentTime);
X
X if (status != GrabSuccess)
X error("%s: couldn't grab keyboard! (%d)\n", status);
X }
X status = XGrabPointer(dsp, win[0], True, AllPointerEventMask,
X GrabModeAsync, GrabModeAsync, None, mycursor,
X CurrentTime);
X if (status != GrabSuccess) {
X sleep(1);
X status = XGrabPointer(dsp, win[0], True, AllPointerEventMask,
X GrabModeAsync, GrabModeAsync, None, mycursor,
X CurrentTime);
X
X if (status != GrabSuccess)
X error("%s: couldn't grab pointer! (%d)\n", status);
X }
X}
X
X
X/*
X * Assuming that we already have an asynch grab on the pointer,
X * just grab it again with a new cursor shape and ignore the return code.
X */
Xstatic void
XXChangeGrabbedCursor(cursor)
X Cursor cursor;
X{
X#ifndef DEBUG
X (void) XGrabPointer(dsp, win[0], True, AllPointerEventMask,
X GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
X#endif
X}
X
X
X/*
X * Restore all grabs, reset screensaver, restore colormap, close connection.
X */
Xstatic void
Xfinish()
X{
X XSync(dsp, False);
X if (!nolock && !allowaccess)
X XUngrabHosts(dsp);
X XUngrabPointer(dsp, CurrentTime);
X XUngrabKeyboard(dsp, CurrentTime);
X if (!enablesaver)
X XSetScreenSaver(dsp, sstimeout, ssinterval, ssblanking, ssexposures);
X XFlush(dsp);
X XCloseDisplay(dsp);
X}
X
X
Xstatic int
XReadXString(s, slen)
X char *s;
X int slen;
X{
X XEvent event;
X char keystr[20];
X char c;
X int i;
X int bp;
X int len;
X int thisscreen = screen;
X char *pwbuf = (char *) malloc(slen);
X
X#ifdef DEBUG
X XSetInputFocus(dsp, win[screen], RevertToPointerRoot, CurrentTime);
X#endif
X for (screen = 0; screen < screens; screen++)
X if (thisscreen == screen)
X init(icon[screen]);
X else
X init(win[screen]);
X bp = 0;
X nice(-nicelevel); /* make sure we can read the keys... */
X while (True) {
X unsigned long lasteventtime = seconds();
X while (!XPending(dsp)) {
X for (screen = 0; screen < screens; screen++)
X if (thisscreen == screen)
X callback(icon[screen]);
X else
X callback(win[screen]);
X XFlush(dsp);
X usleep(delay);
X if (seconds() - lasteventtime > timeout) {
X nice(nicelevel);
X free(pwbuf);
X screen = thisscreen;
X return 1;
X }
X }
X screen = thisscreen;
X XNextEvent(dsp, &event);
X switch (event.type) {
X case KeyPress:
X len = XLookupString((XKeyEvent *) & event, keystr, 20, NULL, NULL);
X for (i = 0; i < len; i++) {
X c = keystr[i];
X switch (c) {
X case 8: /* ^H */
X case 127: /* DEL */
X if (bp > 0)
X bp--;
X break;
X case 10: /* ^J */
X case 13: /* ^M */
X s[bp] = '\0';
X nice(nicelevel);
X free(pwbuf);
X return 0;
X case 21: /* ^U */
X bp = 0;
X break;
X default:
X s[bp] = c;
X if (bp < slen - 1)
X bp++;
X else
X XSync(dsp, True); /* flush input buffer */
X
X }
X }
X if (echokeys) {
X memset(pwbuf, '?', slen);
X XSetForeground(dsp, Scr[screen].gc, bgcol[screen].pixel);
X XFillRectangle(dsp, win[screen], Scr[screen].gc,
X passx, passy - font->ascent,
X XTextWidth(font, pwbuf, slen),
X font->ascent + font->descent);
X XDrawString(dsp, win[screen], textgc[screen],
X passx, passy, pwbuf, bp);
X }
X /*
X * eat all events if there are more than enough pending... this
X * keeps the Xlib event buffer from growing larger than all
X * available memory and crashing xlock.
X */
X if (XPending(dsp) > 100) { /* 100 is arbitrarily big enough */
X register Status status;
X do {
X status = XCheckMaskEvent(dsp,
X KeyPressMask | KeyReleaseMask, &event);
X } while (status);
X XBell(dsp, 100);
X }
X break;
X
X case ButtonPress:
X if (((XButtonEvent *) & event)->window == icon[screen]) {
X nice(nicelevel);
X free(pwbuf);
X return 1;
X }
X break;
X
X case VisibilityNotify:
X if (event.xvisibility.state != VisibilityUnobscured) {
X#ifndef DEBUG
X XRaiseWindow(dsp, win[screen]);
X#endif
X s[0] = '\0';
X nice(nicelevel);
X free(pwbuf);
X return 1;
X }
X break;
X
X case KeymapNotify:
X case KeyRelease:
X case ButtonRelease:
X case MotionNotify:
X case LeaveNotify:
X case EnterNotify:
X break;
X
X default:
X fprintf(stderr, "%s: unexpected event: %d\n",
X ProgramName, event.type);
X break;
X }
X }
X}
X
X
Xstatic int
XgetPassword()
X{
X#define PASSLENGTH 20
X char buffer[PASSLENGTH];
X char userpass[PASSLENGTH];
X char rootpass[PASSLENGTH];
X struct passwd *pw;
X XWindowAttributes xgwa;
X char *user = getenv(USERNAME);
X int y,
X left,
X done;
X
X XGetWindowAttributes(dsp, win[screen], &xgwa);
X
X XChangeGrabbedCursor(XCreateFontCursor(dsp, XC_left_ptr));
X
X XSetForeground(dsp, Scr[screen].gc, bgcol[screen].pixel);
X XFillRectangle(dsp, win[screen], Scr[screen].gc,
X 0, 0, xgwa.width, xgwa.height);
X
X XMapWindow(dsp, icon[screen]);
X XRaiseWindow(dsp, icon[screen]);
X
X left = iconx[screen] + ICONW + font->max_bounds.width;
X y = icony[screen] + font->ascent;
X
X XDrawString(dsp, win[screen], textgc[screen],
X left, y, text_name, strlen(text_name));
X XDrawString(dsp, win[screen], textgc[screen],
X left + 1, y, text_name, strlen(text_name));
X XDrawString(dsp, win[screen], textgc[screen],
X left + XTextWidth(font, text_name, strlen(text_name)), y,
X user, strlen(user));
X
X y += font->ascent + font->descent + 2;
X XDrawString(dsp, win[screen], textgc[screen],
X left, y, text_pass, strlen(text_pass));
X XDrawString(dsp, win[screen], textgc[screen],
X left + 1, y, text_pass, strlen(text_pass));
X
X passx = left + 1 + XTextWidth(font, text_pass, strlen(text_pass))
X + XTextWidth(font, " ", 1);
X passy = y;
X
X y = icony[screen] + ICONH + font->ascent + 2;
X XDrawString(dsp, win[screen], textgc[screen],
X iconx[screen], y, text_info, strlen(text_info));
X
X XFlush(dsp);
X
X y += font->ascent + font->descent + 2;
X
X pw = getpwnam("root");
X strcpy(rootpass, pw->pw_passwd);
X
X pw = getpwnam(user);
X strcpy(userpass, pw->pw_passwd);
X
X done = False;
X while (!done) {
X if (ReadXString(buffer, PASSLENGTH)) {
X XChangeGrabbedCursor(mycursor);
X XUnmapWindow(dsp, icon[screen]);
X XSetForeground(dsp, Scr[screen].gc, bgcol[screen].pixel);
X return 1;
X }
X XSetForeground(dsp, Scr[screen].gc, bgcol[screen].pixel);
X XFillRectangle(dsp, win[screen], Scr[screen].gc,
X iconx[screen], y - font->ascent,
X XTextWidth(font, text_invalid, strlen(text_invalid)),
X font->ascent + font->descent + 2);
X
X XDrawString(dsp, win[screen], textgc[screen],
X iconx[screen], y, text_valid, strlen(text_valid));
X
X done = !((strcmp(crypt(buffer, userpass), userpass))
X && (!allowroot || strcmp(crypt(buffer, rootpass), rootpass)));
X
X if (!done) {
X XSync(dsp, True); /* flush input buffer */
X sleep(1);
X XFillRectangle(dsp, win[screen], Scr[screen].gc,
X iconx[screen], y - font->ascent,
X XTextWidth(font, text_valid, strlen(text_valid)),
X font->ascent + font->descent + 2);
X
X XDrawString(dsp, win[screen], textgc[screen],
X iconx[screen], y, text_invalid, strlen(text_invalid));
X }
X }
X return 0;
X}
X
X
Xstatic void
XjustDisplay()
X{
X XEvent event;
X
X for (screen = 0; screen < screens; screen++)
X init(win[screen]);
X do {
X while (!XPending(dsp)) {
X for (screen = 0; screen < screens; screen++)
X callback(win[screen]);
X XFlush(dsp);
X usleep(delay);
X }
X XNextEvent(dsp, &event);
X#ifndef DEBUG
X if (event.type == VisibilityNotify)
X XRaiseWindow(dsp, event.xany.window);
X#endif
X } while (event.type != ButtonPress && event.type != KeyPress);
X for (screen = 0; screen < screens; screen++)
X if (event.xbutton.root == RootWindow(dsp, screen))
X break;
X}
X
X
Xstatic void
Xsigcatch()
X{
X finish();
X error("%s: caught terminate signal.\nAccess control list restored.\n");
X}
X
X
Xstatic void
XlockDisplay()
X{
X if (!allowaccess) {
X#ifdef SYSV
X sigset_t oldsigmask;
X sigset_t newsigmask;
X
X sigemptyset(&newsigmask);
X sigaddset(&newsigmask, SIGHUP);
X sigaddset(&newsigmask, SIGINT);
X sigaddset(&newsigmask, SIGQUIT);
X sigaddset(&newsigmask, SIGTERM);
X sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
X#else
X int oldsigmask;
X
X oldsigmask = sigblock(sigmask(SIGHUP) |
X sigmask(SIGINT) |
X sigmask(SIGQUIT) |
X sigmask(SIGTERM));
X#endif
X
X signal(SIGHUP, sigcatch);
X signal(SIGINT, sigcatch);
X signal(SIGQUIT, sigcatch);
X signal(SIGTERM, sigcatch);
X
X XGrabHosts(dsp);
X
X#ifdef SYSV
X sigprocmask(SIG_SETMASK, &oldsigmask, &oldsigmask);
X#else
X sigsetmask(oldsigmask);
X#endif
X }
X do {
X justDisplay();
X } while (getPassword());
X}
X
X
Xint
Xmain(argc, argv)
X int argc;
X char *argv[];
X{
X XSetWindowAttributes xswa;
X XGCValues xgcv;
X
X ProgramName = strrchr(argv[0], '/');
X if (ProgramName)
X ProgramName++;
X else
X ProgramName = argv[0];
X
X GetResources(argc, argv);
X
X CheckResources();
X
X font = XLoadQueryFont(dsp, fontname);
X if (font == NULL) {
X fprintf(stderr, "%s: can't find font: %s, using %s...\n",
X ProgramName, fontname, FALLBACK_FONTNAME);
X font = XLoadQueryFont(dsp, FALLBACK_FONTNAME);
X if (font == NULL)
X error("%s: can't even find %s!!!\n", FALLBACK_FONTNAME);
X }
X screens = ScreenCount(dsp);
X if (screens > MAXSCREENS)
X error("%s: can only support %d screens.\n", MAXSCREENS);
X for (screen = 0; screen < screens; screen++) {
X XColor tmp;
X Screen *scr = ScreenOfDisplay(dsp, screen);
X Colormap cmap = DefaultColormapOfScreen(scr);
X
X root[screen] = RootWindowOfScreen(scr);
X if (mono || CellsOfScreen(scr) == 2) {
X XAllocNamedColor(dsp, cmap, "Black", &fgcol[screen], &tmp);
X XAllocNamedColor(dsp, cmap, "White", &bgcol[screen], &tmp);
X Scr[screen].pixels[0] = fgcol[screen].pixel;
X Scr[screen].pixels[1] = bgcol[screen].pixel;
X Scr[screen].npixels = 2;
X } else {
X int colorcount = NUMCOLORS;
X u_char red[NUMCOLORS];
X u_char green[NUMCOLORS];
X u_char blue[NUMCOLORS];
X int i;
X
X if (!XAllocNamedColor(dsp, cmap, background,
X &bgcol[screen], &tmp)) {
X fprintf(stderr, "couldn't allocate: %s\n", background);
X XAllocNamedColor(dsp, cmap, "White", &bgcol[screen], &tmp);
X }
X if (!XAllocNamedColor(dsp, cmap, foreground,
X &fgcol[screen], &tmp)) {
X fprintf(stderr, "couldn't allocate: %s\n", foreground);
X XAllocNamedColor(dsp, cmap, "Black", &fgcol[screen], &tmp);
X }
X hsbramp(0.0, saturation, 1.0, 1.0, saturation, 1.0, colorcount,
X red, green, blue);
X Scr[screen].npixels = 0;
X for (i = 0; i < colorcount; i++) {
X XColor xcolor;
X
X xcolor.red = red[i] << 8;
X xcolor.green = green[i] << 8;
X xcolor.blue = blue[i] << 8;
X xcolor.flags = DoRed | DoGreen | DoBlue;
X
X if (!XAllocColor(dsp, cmap, &xcolor))
X break;
X
X Scr[screen].pixels[i] = xcolor.pixel;
X Scr[screen].npixels++;
X }
X if (verbose)
X fprintf(stderr, "%d pixels allocated\n", Scr[screen].npixels);
X }
X
X xswa.override_redirect = True;
X xswa.background_pixel = BlackPixelOfScreen(scr);
X xswa.event_mask = KeyPressMask | ButtonPressMask | VisibilityChangeMask;
X
X win[screen] = XCreateWindow(dsp, root[screen],
X 0, 0,
X WidthOfScreen(scr),
X HeightOfScreen(scr),
X 0, CopyFromParent, InputOutput, CopyFromParent,
X CWOverrideRedirect | CWBackPixel | CWEventMask, &xswa);
X
X xswa.background_pixel = bgcol[screen].pixel;
X xswa.event_mask = ButtonPressMask;
X
X iconx[screen] = (DisplayWidth(dsp, screen) -
X XTextWidth(font, text_info, strlen(text_info))) / 2;
X
X icony[screen] = DisplayHeight(dsp, screen) / 6;
X icon[screen] = XCreateWindow(dsp, win[screen],
X iconx[screen], icony[screen],
X ICONW, ICONH,
X 1, CopyFromParent,
X InputOutput, CopyFromParent,
X CWBackPixel | CWEventMask, &xswa);
X
X XMapWindow(dsp, win[screen]);
X XRaiseWindow(dsp, win[screen]);
X
X xgcv.foreground = WhitePixelOfScreen(scr);
X xgcv.background = BlackPixelOfScreen(scr);
X Scr[screen].gc = XCreateGC(dsp, win[screen],
X GCForeground | GCBackground, &xgcv);
X
X xgcv.foreground = fgcol[screen].pixel;
X xgcv.background = bgcol[screen].pixel;
X xgcv.font = font->fid;
X textgc[screen] = XCreateGC(dsp, win[screen],
X GCFont | GCForeground | GCBackground, &xgcv);
X }
X lockc = XCreateBitmapFromData(dsp, root[0], no_bits, 1, 1);
X lockm = XCreateBitmapFromData(dsp, root[0], no_bits, 1, 1);
X mycursor = XCreatePixmapCursor(dsp, lockc, lockm,
X &fgcol[screen], &bgcol[screen], 0, 0);
X XFreePixmap(dsp, lockc);
X XFreePixmap(dsp, lockm);
X
X
X if (!enablesaver) {
X XGetScreenSaver(dsp, &sstimeout, &ssinterval,
X &ssblanking, &ssexposures);
X XSetScreenSaver(dsp, 0, 0, 0, 0); /* disable screen saver */
X }
X#ifndef DEBUG
X GrabKeyboardAndMouse();
X#endif
X
X srandom(getpid());
X
X nice(nicelevel);
X
X if (nolock)
X justDisplay();
X else
X lockDisplay();
X
X finish();
X
X return 0;
X}
END_OF_FILE
if test 21618 -ne `wc -c <'xlock.c'`; then
echo shar: \"'xlock.c'\" unpacked with wrong size!
fi
# end of 'xlock.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list