brooks@Apple.COM (Kevin Brooks) (07/19/88)
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@apple.apple.com CSNET: brooks@apple.CSNET ARPA: brooks%apple@csnet-relay.ARPA