home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
GRAPHICS
/
ssaver.lzh
/
SRC
/
ssaver.c
< prev
Wrap
C/C++ Source or Header
|
1995-11-04
|
15KB
|
763 lines
/* K-Windows Screen Saver Master Program */
/* uses _gs_active() to get active flag status - bgp 4/13/95 */
#include <stdio.h>
#include <types.h>
#include <ctype.h>
#include <modes.h>
#include <mouse.h>
#include <wind.h>
#include <sgstat.h>
#include "saver.h"
#define TIMER_SIG 254
#define MOUSE_SIG 253
void screensaver();
int childWindow = -1;
int gotsig = FALSE;
int got_msig = FALSE;
int quit = FALSE; /* exit flag */
int password = FALSE; /* should we do locking? (Password prompt) */
int locked = FALSE; /* flag to tell us we've locked the screen */
int cycle_savers = TRUE; /* flag to tell to cycle screensavers */
int force_event = FALSE;
/* Times for different events to occur */
/* delay between changing screensavers - default 5 minutes */
int cycle_delay = 5 * 60;
/* delay after activation to lock screen - default immediatly */
int lock_delay = 0;
/* seconds of inactivity befor starting screensaver - default 10 minutes */
int init_delay = 10 * 60;
MSRET ms;
int evID;
char saver[128];
extern int errno;
char *helpmsg[] = {
"Syntax: SSaver [<opts>]\n",
"Function: K-Windows screen saver\n",
"Options:\n",
" -a[=][<n>] activate after 'n' minutes\n",
" (default = 10)\n",
" -c[=][<n>] cycle savers every 'n' minutes\n",
" (default = 5) 0 = never\n",
" -l[=][<n>] lock screen 'n' minutes after activation\n",
" (default = 0 or lock immediatly)\n",
" -f force - startup even if event already exists\n",
"\n",
NULL
};
usage()
{
int i = 0;
while (helpmsg[i])
fputs(helpmsg[i++],stderr);
cleanup(0);
}
int sig_trap(sig)
int sig;
{
if (sig == TIMER_SIG)
gotsig++; /* increment our timer */
if (sig == MOUSE_SIG)
got_msig = TRUE;
if (sig == 2 || sig == 3 || sig == 9)
quit = TRUE; /* someone trying to kill us */
}
getoptions(argc, argv)
int argc;
char **argv;
{
register int j, i; /* Temp variables */
int tempint;
char *ptr, /* temp pointer */
*scan; /* pointer */
i = 1;
for (i = 1; i < argc; i++)
{
ptr = argv[i];
if (ptr[0] == '-')
{
scan = &ptr[1];
while (*scan != '\0')
{
switch(toupper(*scan)) {
case 'A' :
scan++;
if (*scan == '=')
scan++;
if (*scan && (tempint = atoi(scan)) > 0)
init_delay = tempint * 60;
while (*scan)
scan++;
scan--;
break;
case 'C' :
scan++;
if (*scan == '=')
scan++;
if (*scan && (tempint = atoi(scan)) > 0)
cycle_delay = tempint * 60;
if (cycle_delay == 0)
cycle_savers = FALSE;
while (*scan)
scan++;
scan--;
break;
case 'F' :
force_event = TRUE;
break;
case 'L' :
password = TRUE;
scan++;
if (*scan == '=')
scan++;
if (*scan && (tempint = atoi(scan)) > 0)
lock_delay = tempint * 60;
while (*scan)
scan++;
scan--;
break;
case '?' :
case 'H' :
usage();
break;
default :
fprintf(stderr,"Unknown option '-%c'\n",*scan);
usage();
}
scan++;
}
}
}
}
main(argc, argv)
int argc;
char **argv;
{
int wd;
char device[32];
int i;
/* get options here */
getoptions(argc,argv);
/*
* get device name
* - this is the ONLY getstat we do on our parent's path!
* - do this as soon as possible!
*/
_gs_devn(1, &device[1]);
/* add slash to name */
device[0] = '/';
/* open new path to device */
if ((wd = open(device, S_IREAD | S_IWRITE)) == -1) {
fprintf(stderr, "cannot open %s...\n", device);
exit(errno);
}
if (isKWindowsDevice(wd) == 0) {
fprintf(stderr, "ssaver must be run from a K-Windows console\n");
exit(0);
}
/* lower out priority */
setpr(getpid(),80);
/* attempt to create event
* if it exists, then assume screen saver is already running
* and exit appropriately
*/
if ((evID = _ev_creat(0, 0, 0, EV_NAME)) == -1) {
if (!force_event) {
fprintf(stderr, "screen saver already running.\n");
exit(0);
} else if ((evID = _ev_link(EV_NAME)) != -1) {
_ev_set(evID, 0, 0x8000); /* wake up everybody */
} else {
fprintf(stderr, "can't create/link to event.\n");
exit(0);
}
}
/* close and dup in/out/err paths */
for (i = 0; i < 3; i++)
{
close(i);
dup(wd);
}
close(wd);
/* install our signal handler */
intercept(sig_trap);
do {
quit = FALSE;
if (got_timeout())
screensaver();
} while (! quit);
cleanup(0);
}
get_password(path,procid)
int path;
int procid;
{
int x,y;
int echo;
int valid = FALSE;
char string[40];
struct sgbuf opts;
kill(procid,SLEEP_SIG);
tsleep(0x80000020);
_gs_scsz(path,&x,&y);
_gs_opt(path,&opts);
echo = opts.sg_echo;
opts.sg_echo = 0;
opts.sg_kbich = 0;
opts.sg_kbach = 0;
opts.sg_eofch = 0;
_ss_opt(path,&opts);
drain(path);
MCurSw(path,0);
OWSet(path,1,(x-24)/2,(y-7)/2,24,7,255,0);
_ss_wset(path,WT_DBOX,0);
CurOff(path);
CurXY(path,3,1);
write(path,"Screen is Locked",16);
CurXY(path,4,3);
write(path,"Enter Password",14);
read_password(path,string,30);
opts.sg_echo = echo;
_ss_opt(path,&opts);
CurXY(path,0,3);
DelLine(path);
CurXY(path,5,3);
write(path,"Verifying...",12);
if (strcmp(string,"password") == 0) {
valid = TRUE;
}
sleep(2);
CurXY(path,0,3);
DelLine(path);
switch(valid) {
case TRUE:
CurXY(path,3,3);
write(path,"Unlocking Screen",16);
sleep(1);
break;
case FALSE:
CurXY(path,7,3);
write(path,"Invalid",7);
sleep(2);
break;
}
OWEnd(path);
_gs_active(path);
kill(procid,WAKE_SIG);
sleep(1);
return (valid);
}
read_password(path,buf,len)
int path;
char *buf;
int len;
{
int currwin, thiswin;
int numchars = 0;
int done = FALSE;
int prompt_time = 60;
int timeout;
char ch;
/* get our window device number */
_gs_wdev(path, &thiswin);
/* mouse click flag */
got_msig = FALSE;
/* set up a mouse signal */
_ss_msig(path,MOUSE_SIG);
/* clear buf */
buf[0] = '\0';
/* Loop till mouse click, newline is typed or we have len - 2 chars */
while (! done && numchars < len - 2)
{
/* clear ch */
ch = '\0';
timeout = prompt_time * 256;
/* loop till there is data waiting or a mouse click */
while (_gs_rdy(path) <= 0 && ! got_msig)
{
/* force 'em back to our screen */
_gs_currscr(path,&currwin); /* get the displayed device */
if (currwin != thiswin) /* if they are different */
_ss_select(path, thiswin); /* select this screen */
tsleep(0x80000020);
timeout -= 0x20; /* decrement prompt timer */
if (timeout <= 0) /* if no input in 1 minute */
{
done = TRUE; /* go back to screen saver */
break;
}
}
/* if data ready, get a char */
if (_gs_rdy(path) > 0)
{
read(path,&ch,1);
}
/* was the mouse clicked? */
if (got_msig)
{
done = TRUE;
}
switch(ch) {
case '\x0': /* nothing typed */
break;
case '\x0d':
case '\x0a':
done = TRUE;
break;
case '\x7f': /* del char */
case '\x08': /* backspace */
if (numchars)
numchars--;
buf[numchars] = '\0';
break;
case '\x15': /* Ctrl-U */
case '\x18': /* Ctrl-X */
numchars = 0;
buf[numchars] = '\0';
break;
default:
if (isprint(ch)) /* is it printable? */
{
buf[numchars] = ch;
numchars++;
buf[numchars] = '\0';
}
}
}
if (!got_msig) /* if no mouse was clicked, */
_ss_rel(path); /* release pending signal */
got_msig = FALSE; /* reset mouse signal flag */
}
int active()
{
/* never activate if we have gotten input */
if (_gs_active(STDOUT))
return(TRUE);
_gs_mous(STDOUT, &ms); /* get mouse position */
/* never activate if mouse_x != 0 and mouse_y == 0 */
if (ms.pt_acx != 0 && ms.pt_acy == 0)
return(TRUE);
return (FALSE);
}
void reset_timer()
{
_gs_mous(STDOUT, &ms);
gotsig = 0;
/* activate if mouse_x == 0 && mouse_y == 0 */
if (ms.pt_acx | ms.pt_acy)
return; /* our timer is 0 */
gotsig = init_delay; /* activate we're at the hot spot */
}
int forkSaver()
{
int cid;
int orgStdin, orgStdout, orgStderr;
char *argv[2];
extern char **environ;
extern int os9forkc();
/* choose a screen saver */
if (chooseSaver(saver) == 0) {
strcpy(saver, "saver_black");
}
argv[0] = saver;
argv[1] = NULL;
if (childWindow == -1) {
/* open path to new window -- child will _ss_select() its window */
if ((childWindow = open("/w", S_IWRITE | S_IREAD)) == -1) {
/* error opening new window */
return(-1);
}
}
/* duplicate paths */
orgStdin = dup(0);
orgStdout = dup(1);
orgStderr = dup(2);
/* close paths */
close(0);
dup(childWindow);
close(1);
dup(childWindow);
close(2);
dup(childWindow);
/* set the event value to 1 so that we may wait until our child
* uses _ev_signal()
*/
_ev_set(evID, 1, 0);
/* fork screen saver */
cid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3);
/* restore paths */
close(0);
dup(orgStdin);
close(1);
dup(orgStdout);
close(2);
dup(orgStderr);
/* close extra paths */
close(orgStdin);
close(orgStdout);
close(orgStderr);
/* wait for child to start up completely */
while (_ev_wait(evID, 0, 0) != 0);
/* return child ID */
return(cid);
}
/*
* Wait till the key/mouse is inactive for 'timeout' seconds
*
* RETURNS:
* TRUE if keyboard and mouse have timed out
* FALSE if quit signal was recieved
*/
int got_timeout()
{
int id;
/* clear gotsig */
gotsig = 0;
/* set alarm every second */
if ((id = alm_cycle(TIMER_SIG,0x80000100)) == -1) {
cleanup(errno);
}
do {
sleep(0);
if (active()) /* if our flag is set */
reset_timer();
} while (gotsig < init_delay && ! quit);
/* delete the alarm */
alm_delete(id);
/* was the timer reached? or did we get a kill signal? */
return((quit) ? FALSE : TRUE);
}
/* fork off our pretty pictures, etc. */
void screensaver()
{
int cid; /* child ID */
int is_active;
int cycle_time = cycle_delay * 256;
int lock_time;
char ch;
/* at this point we fork the screen saver */
if ((cid = forkSaver()) == -1)
return;
locked = FALSE;
if (password == TRUE)
lock_time = lock_delay * 256;
do {
/* decrement out time for this screensaver to live */
tsleep(0x80000020);
/* check to see if we should get a password */
if (! locked && password == TRUE) {
lock_time -= 0x20; /* decrement time till password required */
if (lock_time <= 0) /* is it time? */
locked = TRUE; /* yep, need a password now */
}
/* are we cycling screensavers? */
if (cycle_savers == TRUE)
{
cycle_time -= 0x20; /* decrement cycle time by our last sleep */
if (cycle_time <= 0)/* is it time? */
{
kill(cid,QUIT_SIG); /* Tell saver_xxx to shutdown */
while (cid != wait(0)); /* Wait for it to exit */
/* drain any pending characters */
drain(childWindow);
/* reset window to undefined for next screensaver */
DWEnd(childWindow);
/* invoke the next screensaver */
if ((cid = forkSaver()) == -1)
return;
/* reset cycle_time */
cycle_time = cycle_delay * 256;
}
}
/* grab the active flag */
is_active = _gs_active(STDOUT);
/* if active and we what a password to unlock */
if (is_active && locked)
is_active = get_password(childWindow,cid);
} while (! is_active && ! quit);
/* Send a signal to the program to quit */
kill(cid, QUIT_SIG);
while (cid != wait(0));
/* drain any pending characters */
drain(childWindow);
/* close our path to child's window */
close(childWindow);
childWindow = -1;
}
drain(path)
int path;
{
char ch;
/* drain any pending characters */
while(_gs_rdy(path) > 0)
read(path,&ch,1);
}
cleanup(code)
int code;
{
_ev_unlink(evID); /* unlink the event */
_ev_delete(EV_NAME); /* delete the event */
exit(code);
}
/* this function reads the ssaver.list file in search of a
* screen saver program to run for this incarnation.
*
* Returns:
* 0 - can't open ssaver.list
* 1 - everything's OK
*/
int chooseSaver(saver_name)
char *saver_name;
{
int dpath, t, e;
char text[128];
dpath = open("/dd/sys/ssaver.list", S_IREAD);
if (dpath == -1)
{
dpath = open("/dd/sys/.ssaver.list", S_IREAD);
if (dpath == -1) return(0);
}
t = 0;
while(1)
{
if (readln(dpath, text, 80) < 1) break;
if (isalpha(text[0]) || text[0]=='/') t++;
}
e = rrand(t);
lseek(dpath, 0, 0);
t = 0;
while(t < e)
{
readln(dpath,text,80);
if (isalpha(text[0]) || text[0] == '/') t++;
}
strcpy(saver_name, text);
close(dpath);
return(1);
}
static int rndval = 100000; /* BGP */
/* rrand( val ) : return a pseudo-random value between 1 and val.
** IF val is -1, it is used as a seed.
** IF val is negative the better the seed.
*/
rrand( val )
int val;
{
int bit0, bit1, bit14, num, i;
/* see if -1 */
if ( val < 0 ) {
rndval = -val;
}
for ( i = 0; i < 10; i++ )
{
bit0 = rndval & 1;
bit1 = (rndval & 2) >> 1;
bit14 = bit0 ^ bit1;
rndval >>=1;
rndval |= (bit14 << 14);
}
num = rndval % val;
return( num ? num : val );
}
/*
* this function returns 1 if the current path is open
* under a K-Windows device, else it returns 0
*
* Boisy G. Pitre -- 12/8/94
*/
#include <module.h>
isKWindowsDevice(path)
int path;
{
char device[32], driver[8];
mod_dev *descAddr;
/* get the name of the path's device */
if (_gs_devn(path, device) == -1) {
/* failed to get device */
return(0);
}
/* attempt to link to path's device ONLY if it's a descriptor */
if ((descAddr = modlink(device, mktypelang(MT_DEVDESC, ML_ANY))) == -1) {
/* failed to link to path's device */
return(0);
}
munlink(descAddr); /* unlink to be nice */
/* copy driver string and check to see if it's windio */
strncpy(driver, (int)descAddr + descAddr->_mpdev, 6);
driver[6] = '\0';
if (strucmp(driver, "WINDIO") != 0) {
return(0);
}
/* it's more than likely a K-Windows window */
return(1);
}
int strucmp (str1, str2)
register char *str1, *str2;
{
register char *p;
if ((p = index (str1,'\n')) != NULL) *p ='\0';
if ((p = index (str2,'\n')) != NULL) *p ='\0';
while (toupper (*str1) == toupper (*str2) && *str1 && *str2) {
++str1;
++str2;
}
if (*str1 == *str2) return(0);
if (*str1 > *str2) return(1);
return(-1);
}
/*
* this function returns the edition number of windio
* or -1 if the windio driver cannot be found
*
* Boisy G. Pitre -- 12/8/94
*/
int KWindowsEdition()
{
struct modhcom *windioDrv;
/* attempt to link to windio driver */
if ((windioDrv = modlink("windio", mktypelang(MT_DEVDRVR, ML_ANY))) == -1) {
/* failed to link to windio driver */
return(-1);
}
munlink("windio"); /* unlink to be nice */
return((int)windioDrv->_medit);
}