MacII screen dimmer for A/UX

Kevin Brooks brooks at Apple.COM
Wed Jul 20 01:47:06 AEST 1988


In responce to a request for a screen dimmer program I thought I would
post this little program written by Earl Wallace.  It does the job through the 
brute forse method (the phys call).

To use, make the program suid root envoke with a timeout value and percentage
of dimness you would like 0-100%.

--------------------------------cut here----------------------------------

/****************************************************************************
 *
 * dim.c
 *
 * Earl Wallace, Apple Computer
 *
 ****************************************************************************/

#include <stdio.h>
#include <malloc.h>
#include <sys/stropts.h>
#include <sys/video.h>
#include <sys/signal.h>
#include <sys/var.h>
#include <a.out.h>
#ifdef	BSD_SIGNALS
#  include <compat.h>
#endif	/* BSD_SIGNALS */

#define	BACKGROUND 0
#define	FOREGROUND 1
#define	FD	   1			/* file desc of console */
#define	MEGABYTE   1024*1024

extern	int	strap();
extern	int	sioctl();
extern	int	SetColor();
extern	int	GetVideoSize();
extern	int	GetUvar();
extern	int	mclock();
extern	int	GetVideoAddress();
extern	int	GetVideoPixsize();
extern	char	*malloc();
extern	char	*optarg;
extern	int	optind, opterr;
extern	void	SaveScreen();

#ifdef	BSD_SIGNALS
  struct sigvec svec;
#endif	/* BSD_SIGNALS */

struct   video_size  vpixsize;
struct   var var;
long	 vsize[2];
unsigned int segment_size;
unsigned int page_size;
int	 pregion;
unsigned int	vram_size;
unsigned char	*vram_virt;
unsigned int	*vram;
unsigned char	*vram_phys;
char	 ans[80];
int	 dim_time = 300;			/* default:  300 seconds */
int	 dim_val  = 50;				/* dim value */
unsigned int	 *screen;
int	 screen_size;
int	 WeAreTheDimWits;
int	 errflg;
int	 colmax; 			/* vpixsize.pix_scr_x / 32 */
int	 linemax;			/* vpixsize.pix_scr_y      */
int	 nextline;			/* vpixsize.pix_mem_x / 32 */

/*==========================================================================*
 *
 * main
 *
 *==========================================================================*/

main(argc, argv, envp)
int  argc;
char *argv[], *envp[];
{
	register int	  offset1, offset2, line, col;
	register unsigned int *v, *s;
	register unsigned int byte;

	setbuf(stderr, NULL);

	/*
	 * parse command line
	 */
	while ((col=getopt(argc, argv, "t:p:")) != EOF) {
		switch(col) {
			case 't':	
				dim_time = atoi(optarg);
				break;
			case 'p':	
				dim_val = (255 * atoi(optarg)) / 100;
				break;
			case '?':
				++errflg;
		}
	}
	if (errflg) {
		fprintf(stderr, "%s: Usage: %s [-t dim_time] [-p dim_percentage]\n", 
			argv[0], argv[0]);
		exit(1);
	}

#ifdef	BSD_SIGNALS
	if (setcompat(getcompat()|COMPAT_BSDSIGNALS|COMPAT_SYSCALLS) < 0) {
		fprintf(stderr, "setcompat() failed - ");
		perror("");
		exit(1);
	}
	/* 
	 * The signal handler and mask are set
	 */
	svec.sv_handler = strap;		/* signal handling function */
	svec.sv_mask    = 0;			/* don't block any signals */
	svec.sv_onstack = 0;			/* don't use signal stack */
	if (sigvec(SIGINT, &svec, (struct sigvec *)0) < 0) {
		fprintf(stderr, "sigvec() SIGINT failed - ");
		perror("");
		exit(1);
	}
	if (sigvec(SIGQUIT, &svec, (struct sigvec *)0) < 0) {
		fprintf(stderr, "sigvec() SIGQUIT failed - ");
		perror("");
		exit(1);
	}
	if (sigvec(SIGTERM, &svec, (struct sigvec *)0) < 0) {
		fprintf(stderr, "sigvec() SIGTERM failed - ");
		perror("");
		exit(1);
	}
	if (sigsetmask(0) < 0) {
		fprintf(stderr, "sigsetmask() failed - ");
		perror("");
		exit(1);
	}
#else	/* NOT BSD_SIGNALS */
	signal(SIGINT,  strap);		/* catch keyboard break/interrupt */
	signal(SIGQUIT, strap);		/* catch keyboard quit signal */
	signal(SIGTERM, strap);		/* catch software term. signal */
#endif	/* BSD_SIGNALS */
	if (!isatty(0))
		setpgrp();		/* break from console process group */
	if (GetVideoSize(FD, vsize) < 0)
		exit(1);
	if (GetVideoAddress(FD, &vram_phys) < 0)
		exit(1);
	if (GetVideoPixsize(FD, &vpixsize) < 0)
		exit(1);
	if (GetUvar(&var) < 0)
		exit(1);
	segment_size = 1<<var.v_segshift;
	page_size = 1<<var.v_pageshift;
	pregion = 0;
	vram_virt = (unsigned char *) (5*MEGABYTE);
	vram_size = 1*MEGABYTE;
	if ((int)vram_virt % (int)segment_size) {
		fprintf(stderr, "virtual address 0x%x (%d) not on segment ",
			vram_virt, vram_virt);
		fprintf(stderr, "boundary.\nSegment size is 0x%x (%d).\n",
			segment_size, segment_size);
		exit (1);
	}
	if ((int)vram_size % (int)page_size) {
		fprintf(stderr, "Address space size 0x%x (%d) not a multiple ",
			vram_size, vram_size);
		fprintf(stderr, "of page size.\nPage size is 0x%x (%d).\n",
			page_size, page_size);
		exit (1);
	}
	if (phys(pregion, vram_virt, vram_size, vram_phys) < 0) {
		fprintf(stderr, "%s: phys() failed - ", argv[0]);
		perror("");
		exit (1);
	}

	/* I bet you want to know who uses vram, eh? */
	vram = (unsigned int *) (((unsigned int)vram_virt & ~page_size) + 32);

	/* allocate enough memory for a screen buffer save */
	screen_size = vpixsize.pix_scr_x * vpixsize.pix_scr_y;
	screen_size /= 8;			/* convert bits to bytes */
	if ((screen=(unsigned int *)malloc(screen_size)) == NULL) {
		fprintf(stderr, "%s: malloc(%d) failed - ", argv[0], screen_size);
		exit (1);
	}

	colmax = vpixsize.pix_scr_x / 32;
	linemax = vpixsize.pix_scr_y;
	nextline = vpixsize.pix_mem_x / 32;
	v = vram;
	s = screen;

	while (1) {
	    SaveScreen(s, v);
	    if (WeAreTheDimWits) {
	    	sleep(1);
	        if (CmpScreen(s, v) < 0) {
		    /* brighten screen... */
		    int xx;
		    for (xx=dim_val; xx < 255; xx += 5)
		    	SetColor(FD, xx, xx, xx, 0, 0, 0);
	    	    WeAreTheDimWits = 0;
		}
	    } else {
	    	sleep(dim_time);
	        if (CmpScreen(s, v) == 0) {
		    /* dim screen... */
		    int xx;
		    for (xx=255; xx > dim_val; --xx)
	    	        SetColor(FD, xx, xx, xx, 0, 0, 0);
	    	    ++WeAreTheDimWits;
		}
	    }
	}
}


/*==========================================================================*
 *
 * SaveScreen
 *
 *==========================================================================*/

void
SaveScreen(to, from)
register unsigned int *to, *from;
{
	register int line, col, offset1, offset2;

	for (line=0; line < linemax; ++line) {
		offset1 = line * nextline;	/* visible and invisible parts */
		offset2 = line * colmax;	/* visible part only */
	        for (col=0; col < colmax; ++col) {
		    to[col+offset2] = from[col+offset1];
		}
	}
}

/*==========================================================================*
 *
 * CmpScreen
 *
 *==========================================================================*/

int
CmpScreen(s1, s2)
register unsigned int *s1, *s2;
{
	register int line, col, offset1, offset2;

	for (line=0; line < linemax; ++line) {
		offset1 = line * nextline;	/* visible and invisible parts */
		offset2 = line * colmax;	/* visible part only */
	        for (col=0; col < colmax; ++col) {
		    if (s1[col+offset2] != s2[col+offset1])
			return (-1);		/* mismatch */
		}
	}
	return(0);				/* matched */
}


/*==========================================================================*
 *
 * SetColor
 *
 *==========================================================================*/

int
SetColor(fd, b_red, b_green, b_blue, f_red, f_green, f_blue)
register int fd, b_red, b_green, b_blue, f_red, f_green, f_blue;
{
	struct   video_color vcolor;
	register struct      video_color *c = &vcolor;

	c->color[BACKGROUND].red   = b_red<<8;
	c->color[BACKGROUND].green = b_green<<8;
	c->color[BACKGROUND].blue  = b_blue<<8;
	c->color[FOREGROUND].red   = f_red<<8;
	c->color[FOREGROUND].green = f_green<<8;
	c->color[FOREGROUND].blue  = f_blue<<8;
	if (sioctl(fd, VIDEO_SETCOLOR, -1, sizeof vcolor, c) < 0) {
		fprintf(stderr, "SetColor: sioctl() failed - ");
		perror("");
		return (-1);
	}
	return (0);
}


/*==========================================================================*
 *
 * sioctl
 *
 *==========================================================================*/

int
sioctl(fd, cmd, timout, len, dp)
int  fd, cmd, timout, len;
char *dp;
{
	static   struct strioctl sio;
	register struct	strioctl *s = &sio;

	s->ic_cmd    = cmd;
	s->ic_timout = timout;
	s->ic_len    = len;
	s->ic_dp     = dp;
	return (ioctl(fd, I_STR, s));
}


/*==========================================================================*
 *
 * strap (used with BSD and SYSV signals)
 *
 *==========================================================================*/

int
strap(sno)
int sno;
{
	/* set background to white and foreground to black */
	SetColor(FD, 255, 255, 255, 0, 0, 0);

	/* refreh the console screen */
	/* sioctl(FD, VIDEO_REFRESH, -1, 0, NULL); */
	/* fprintf(stderr, "Caught Signal %d - Program Aborted.\n", sno); */
	exit (-sno);
}


/*==========================================================================*
 *
 * GetVideoSize
 *
 * The argument "vs" is a pointer to an allocated array of two longs.
 * The array will be filled with information about the size of the display.
 * The first array long is the number of characters, in width, of the
 * display. The second long in the array is the number of characters, in
 * height, of the display.
 *
 *==========================================================================*/

GetVideoSize(fd, vs)
int fd;
long *vs;
{
	if (sioctl(fd, VIDEO_SIZE, -1, 2 * sizeof *vs, vs) < 0) {
		fprintf(stderr, "GetVideoSize: sioctl() failed - ");
		perror("");
		return (-1);
	}
	return (0);
}


/*==========================================================================*
 *
 * GetVideoAddress
 *
 * The argument "va" is a pointer to an allocated unsigned int.
 * This unsigned int will be filled with physical address of the video RAM on 
 * the Video Card.
 *==========================================================================*/

int
GetVideoAddress(fd, va)
int fd;
unsigned int *va;
{
	if (sioctl(fd, VIDEO_ADDR, -1, sizeof va, va) < 0) {
		fprintf(stderr, "GetVideoAddress: sioctl() failed - ");
		perror("");
		return (-1);
	}
	return (0);
}


/*==========================================================================*
 *
 * GetVideoPixsize
 *
 *==========================================================================*/

int
GetVideoPixsize(fd, vp)
int fd;
struct video_size *vp;
{
	if (sioctl(fd, VIDEO_PIXSIZE, -1, sizeof *vp, vp) < 0) {
		fprintf(stderr, "GetVideoPixsize: sioctl() failed - ");
		perror("");
		return (-1);
	}
	return (0);
}


/*==========================================================================*
 *
 * GetUvar
 *	
 * The argument "v" is a pointer to an allocated var structure.
 * This structure will be filled with information on the kernel.
 *
 *==========================================================================*/

int
GetUvar(v)
struct var *v;
{
	if (uvar(v) < 0) {
		fprintf(stderr, "GetUvar: uvar() failed - ");
		perror("");
		return (-1);
	}
	return (0);
}
Kevin Brooks
A/UX Specialiast, Apple Computer
UUCP: {mtxinu,sun,nsc,voder}!apple!brooks  DOMAIN: brooks at apple.apple.com
CSNET: brooks at apple.CSNET 		   ARPA: brooks%apple at csnet-relay.ARPA



More information about the Comp.unix.aux mailing list