home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Source: /mit/sipbsrc/uus/src/xscreensaver/RCS/savescreen.c,v $
- * $Author: jik $
- *
- * This file is part of xscreensaver. It contains the code for the
- * actual locking/blanking of the screen, with the floating icon and
- * the handling of passwords.
- *
- * Author: Jonathan Kamens, MIT Project Athena and
- * MIT Student Information Processing Board
- *
- * Coyright (c) 1989 by Jonathan Kamens. This code may be distributed
- * freely as long as this notice is kept intact in its entirety and
- * every effort is made to send all corrections and improvements to
- * the code back to the author. Also, don't try to make any money off
- * of it or pretend that you wrote it.
- */
-
- #ifndef lint
- static char rcsid_savescreen_c[] = "$Header: savescreen.c,v 1.18 89/02/28 06:55:18 jik Exp $";
- #endif
-
- #include <stdio.h>
- #include <X11/Xos.h>
- #include <signal.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Command.h>
- #include <X11/Shell.h>
- #include <X11/List.h>
- #include <X11/Form.h>
- #include "xsaver.h"
- #include "scaling.h"
- #include "globals.h"
-
-
- extern char *time_string(), *elapsed_string(), *timeleft_string(),
- *malloc();
- extern Cursor blank_cursor();
- extern Widget PasswordWindow(), PromptBox();
- extern long random();
- extern Boolean correct_password();
- extern void XtMoveWidget();
-
- static void build_root(), lock_command(), unlock_command(), build_float(),
- MoveFloat(), ActivateFloat(), ActivateClock(), UpdateClock(),
- ReallyLockScreen(), SaveScreen(), do_timeout(), PasswordTimeout(),
- LockScreen(), UpdateFloat();
- static int new_off(), maybe_new_off_opposite_sign();
- static char **breakup();
-
- void ActivateRoot(), RaiseRoot(), RemoveRoot(), GetPassword();
-
- static WidgetandWidth time_w, elapsed_w, timeout_w, icon_w;
- static int x_off = 0, y_off = 0;
- static int delay;
- Boolean activated = False, getting_password = False;
- static Dimension max_float_x, max_float_y;
- static int lock_command_pid = 0;
- static String lockedTransString =
- "<Key>: GetPassword(Locked)\n\
- <BtnDown>,<BtnUp>: GetPassword(Locked)\n\
- <Visible>: RaiseRoot()\n";
- static XtTranslations lockedTrans = (XtTranslations) NULL;
- static Widget root_shell = (Widget) NULL, float_widget = (Widget) NULL;
-
-
-
-
- #define PASSWORD_TIMEOUT 30 /* time, in seconds, before a password */
- /* prompt will time out */
-
-
-
-
-
-
- static void build_root()
- {
- Arg arglist[10];
- int i = 0;
- Cursor cursor;
-
- if (! root_shell) {
- XtSetArg(arglist[i], XtNborderWidth, 0); i++;
- XtSetArg(arglist[i], XtNx, 0); i++;
- XtSetArg(arglist[i], XtNy, 0); i++;
- XtSetArg(arglist[i], XtNwidth, display_width); i++;
- XtSetArg(arglist[i], XtNheight, display_height); i++;
- if (defs.use_background) {
- XtSetArg(arglist[i], XtNbackgroundPixmap,
- ParentRelative); i++;
- }
- root_shell = XtCreatePopupShell("rootShell",
- overrideShellWidgetClass,
- top_widget, arglist, i);
-
- root_widget = XtCreateManagedWidget("root", widgetClass,
- root_shell, arglist, i); i = 0;
-
- XtRealizeWidget(root_shell);
-
- /* Here lies the direct Xlib trickery your mother warned you */
- /* about when she taught you tou use Xtk. */
- cursor = blank_cursor();
- XDefineCursor(dpy, XtWindow(root_shell), cursor);
- XDefineCursor(dpy, XtWindow(root_widget), cursor);
- }
-
- /* Setting the coordinates to 0, 0 appears not to work in some */
- /* cases, in particular when people specify Geometry *class* in */
- /* the resources, so we are going to reposition the window after */
- /* we create it. */
- XtMoveWidget(root_shell, 0, 0);
- }
-
-
-
-
-
-
- /* ARGSUSED */
- void ActivateRoot()
- {
- ActivateClock();
-
- build_root();
- build_float();
-
- activated = True;
-
- XSetScreenSaver(dpy, 0, saver.interval, saver.prefer_blanking,
- saver.allow_exposures);
- XtMapWidget(root_shell);
- if (XGrabPointer(dpy, XtWindow(root_widget), True, ButtonPressMask,
- GrabModeAsync, GrabModeAsync, XtWindow(root_widget),
- blank_cursor(), CurrentTime) != GrabSuccess)
- fprintf(stderr, "%s: Error grabbing pointer!\n", whoami);
- if (XGrabKeyboard(dpy, XtWindow(root_widget), False, GrabModeAsync,
- GrabModeAsync, CurrentTime) != GrabSuccess)
- fprintf(stderr, "%s: Error grabbing keyboard!\n", whoami);
- XtSetKeyboardFocus(root_shell, root_widget);
-
- if (lock_flag)
- LockScreen();
- else
- SaveScreen();
- }
-
-
-
- static void LockScreen()
- {
- if (! lockedTrans)
- lockedTrans = XtParseTranslationTable(lockedTransString);
- if (! (*defs.ekey || *defs.key)) {
- String str = "Initial";
- Cardinal num = 1;
- GetPassword(root_widget, (XEvent *) NULL, &str, &num);
- }
- else
- ReallyLockScreen();
- }
-
-
-
- static void ReallyLockScreen()
- {
- lock_command();
- XtOverrideTranslations(root_widget, lockedTrans);
- ActivateFloat();
- }
-
-
- static void SaveScreen()
- {
- static String rootTranslations =
- "<Key>: RemoveRoot()\n\
- <BtnDown>,<BtnUp>: RemoveRoot()\n\
- <Visible>: RaiseRoot()\n";
- XtTranslations trans = (XtTranslations) NULL;
-
- if (! trans)
- trans = XtParseTranslationTable(rootTranslations);
- XtOverrideTranslations(root_widget, trans);
- ActivateFloat();
- }
-
-
-
-
-
- static void PasswordTimeout()
- {
- if (getting_password) {
- char *str = "Timeout";
- Cardinal num = 1;
- GetPassword(root_shell, (XEvent *) NULL, &str, &num);
- }
- }
-
-
-
-
-
- #define DOING_NOTHING 0
- #define GETTING_LOCKED_PASSWORD 3
- #define GETTING_FIRST_INITIAL_PASSWORD 1
- #define GETTING_SECOND_INITIAL_PASSWORD 2
-
- /* ARGSUSED */
- void GetPassword(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- static char password[MAXPASSWORD];
- static char *ptr;
- static String gettingPasswordTranslations =
- "<Key>Return: GetPassword(Done)\n\
- <Key>: GetPassword(Reading)\n\
- <Visible>: RaiseRoot()\n";
- static XtTranslations gettingPasswordTrans = (XtTranslations) NULL;
- static Widget prompt;
- static int state = DOING_NOTHING;
- Arg arglist[2];
- int i = 0;
-
- if (! gettingPasswordTrans)
- gettingPasswordTrans =
- XtParseTranslationTable(gettingPasswordTranslations);
- if (**params == 'L') {
- ptr = password;
- state = GETTING_LOCKED_PASSWORD;
- getting_password = True;
- prompt = PasswordWindow(state);
- XtSetArg(arglist[i], XtNtranslations, gettingPasswordTrans); i++;
- XtSetValues(root_shell, arglist, i);
- XtSetValues(root_widget, arglist, i); i = 0;
- XtMapWidget(prompt);
- XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
- }
- else if (**params == 'I') {
- ptr = password;
- state = GETTING_FIRST_INITIAL_PASSWORD;
- getting_password = True;
- prompt = PasswordWindow(state);
- XtOverrideTranslations(root_widget, gettingPasswordTrans);
- XtMapWidget(prompt);
- XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
- }
- else if (**params == 'R') {
- XtAddTimeOut(PASSWORD_TIMEOUT * 1000, PasswordTimeout, NULL);
- if (ptr - password < MAXPASSWORD - 1) {
- char key_buf[5];
- int num_read;
-
- num_read = XLookupString(event, key_buf, 5,
- (KeySym *) NULL,
- (XComposeStatus *) NULL);
- if (num_read == 1) {
- *ptr = *key_buf;
- ptr++;
- }
- }
- }
- else if (**params == 'D') {
- XtUnmapWidget(prompt);
- XtDestroyWidget(prompt);
- *ptr = '\0';
- if (state == GETTING_LOCKED_PASSWORD) {
- getting_password = False;
- state = DOING_NOTHING;
- if (correct_password(password)) {
- RemoveRoot(root_shell, (XEvent *) NULL, (String *) NULL,
- (Cardinal *) NULL);
- bzero(password, strlen(password));
- }
- else {
- ReallyLockScreen();
- bzero(password, strlen(password));
- }
- }
- else if (state == GETTING_FIRST_INITIAL_PASSWORD) {
- ptr = password;
- if (*ptr) {
- state = GETTING_SECOND_INITIAL_PASSWORD;
- strcpy(defs.key, password);
- bzero(password, strlen(password));
- prompt = PasswordWindow(state);
- XtMapWidget(prompt);
- }
- else { /* User just hit return. That's a no-no, so ask */
- /* for a password again */
- char *param = "Initial";
- Cardinal num = 1;
-
- XBell(dpy, 100);
- state = DOING_NOTHING;
- GetPassword(root_shell, (XEvent *) NULL, ¶m, &num);
- }
- }
- else if (state == GETTING_SECOND_INITIAL_PASSWORD) {
- if (! strcmp(password, defs.key)) {
- getting_password = False;
- install_password();
- bzero(password, strlen(password));
- ReallyLockScreen();
- }
- else {
- char *param = "Initial";
- Cardinal num = 1;
-
- bzero(password, strlen(password));
- bzero(defs.key, strlen(defs.key));
- state = DOING_NOTHING;
- GetPassword(root_shell, (XEvent *) NULL, ¶m, &num);
- }
- }
- }
- else if (**params == 'T') {
- XtUnmapWidget(prompt);
- XtDestroyWidget(prompt);
- getting_password = False;
- bzero(password, ptr - password);
- if (state == GETTING_LOCKED_PASSWORD)
- ReallyLockScreen();
- else if (state == GETTING_FIRST_INITIAL_PASSWORD)
- RemoveRoot((Widget) NULL, (XEvent *) NULL, (String *) NULL,
- (Cardinal *) NULL);
- else if (state == GETTING_SECOND_INITIAL_PASSWORD)
- RemoveRoot((Widget) NULL, (XEvent *) NULL, (String *) NULL,
- (Cardinal *) NULL);
- }
- }
-
-
-
-
-
- static void ActivateClock()
- {
- struct timeval tim;
-
- gettimeofday(&tim, (struct timezone *) NULL);
- times.start = times.current = times.saver = tim.tv_sec;
- }
-
-
-
-
-
-
- static void UpdateClock()
- {
- struct timeval tim;
- gettimeofday(&tim, (struct timezone *) NULL);
- times.current = tim.tv_sec;
- }
-
-
-
-
-
-
-
- static void ActivateFloat()
- {
- Arg arglist[5];
- int i = 0;
- Position x, y;
- Dimension width, height, border;
-
- if (! x_off) {
- XtSetArg(arglist[i], XtNwidth, &width); i++;
- XtSetArg(arglist[i], XtNheight, &height); i++;
- XtSetArg(arglist[i], XtNborderWidth, &border); i++;
- XtGetValues(float_widget, arglist, i); i = 0;
-
- max_float_x = display_width - width - 2 * border;
- max_float_y = display_height - height - 2 * border;
- x = random() % max_float_x;
- y = random() % max_float_y;
- x_off = new_off();
- y_off = new_off();
-
- delay = calc_delay(x_off, y_off, defs.velocity);
-
- XtMoveWidget(float_widget, x, y);
- XtMapWidget(float_widget);
- }
- else
- UpdateFloat();
-
- XtAddTimeOut(delay, MoveFloat, NULL);
- }
-
-
-
-
-
- static void do_timeout()
- {
- unlock_command();
- exit(0);
- }
-
-
-
- static void MoveFloat()
- {
- Arg arglist[5];
- int i = 0;
- Position x, y;
- int changed_off = 0;
-
- if (getting_password || (! activated))
- return;
- if (lock_flag && defs.timeout) {
- if ((times.current - times.start) >= defs.timeout * 60)
- do_timeout();
- }
- UpdateFloat();
- XtSetArg(arglist[i], XtNx, &x); i++;
- XtSetArg(arglist[i], XtNy, &y); i++;
- XtGetValues(float_widget, arglist, i);
- if (x + x_off > max_float_x) {
- changed_off += maybe_new_off_opposite_sign(&x_off);
- }
- else if (x + x_off < 0) {
- changed_off += maybe_new_off_opposite_sign(&x_off);
- }
- if (y + y_off > max_float_y) {
- changed_off += maybe_new_off_opposite_sign(&y_off);
- }
- else if (y + y_off < 0) {
- changed_off += maybe_new_off_opposite_sign(&y_off);
- }
- x += x_off; y += y_off;
- if (changed_off)
- delay = calc_delay(x_off, y_off, defs.velocity);
- XtMoveWidget(float_widget, x, y);
- XtAddTimeOut(delay, MoveFloat, NULL);
- }
-
-
-
-
- static void UpdateFloat()
- {
- Arg arglist[5];
- int i = 0;
- Dimension width, new_width;
-
- XtSetArg(arglist[i], XtNwidth, &width); i++;
- XtGetValues(float_widget, arglist, i); i = 0;
- UpdateClock();
- XtFormDoLayout(float_widget, False);
- XtSetArg(arglist[i], XtNwidth, &icon_w.width); i++;
- XtGetValues(icon_w.widget, arglist, i); i = 0;
- if (defs.d_time) {
- char *tm = time_string(TIME_FORMAT, NoForce);
- if (tm) {
- XtSetArg(arglist[i], XtNlabel, tm); i++;
- XtSetValues(time_w.widget, arglist, i); i = 0;
- XtSetArg(arglist[i], XtNwidth, &time_w.width); i++;
- XtGetValues(time_w.widget, arglist, i); i = 0;
- }
- }
- if (defs.d_elapsed) {
- char *tm = elapsed_string(ELAPSED_FORMAT, NoForce);
- if (tm) {
- XtSetArg(arglist[i], XtNlabel, tm); i++;
- XtSetValues(elapsed_w.widget, arglist, i); i = 0;
- XtSetArg(arglist[i], XtNwidth, &elapsed_w.width); i++;
- XtGetValues(elapsed_w.widget, arglist, i); i = 0;
- }
- }
- if (defs.d_timeout && lock_flag && defs.timeout) {
- char *tm = timeleft_string(TIMELEFT_FORMAT, NoForce);
- if (tm) {
- XtSetArg(arglist[i], XtNlabel, tm); i++;
- XtSetValues(timeout_w.widget, arglist, i); i = 0;
- XtSetArg(arglist[i], XtNwidth, &timeout_w.width); i++;
- XtGetValues(timeout_w.widget, arglist, i); i = 0;
- }
- }
- XtFormDoLayout(float_widget, True);
- XtSetArg(arglist[i], XtNwidth, &new_width); i++;
- XtGetValues(float_widget, arglist, i); i = 0;
- if (new_width != width) {
- XtFormDoLayout(float_widget, False);
- center(icon_w.widget, icon_w.width, new_width);
- if (defs.d_time)
- center(time_w.widget, time_w.width, new_width);
- if (defs.d_elapsed)
- center(elapsed_w.widget, elapsed_w.width, new_width);
- if (defs.d_timeout && lock_flag && defs.timeout)
- center(timeout_w.widget, timeout_w.width, new_width);
- XtFormDoLayout(float_widget, True);
- }
- }
-
-
-
-
- static int maybe_new_off_opposite_sign(foo)
- int *foo;
- {
- int off = - *foo;
- int changed = 0;
-
- if (! (random() % 4)) {
- off = random() % 5 + 1;
- off = (*foo < 0 ? off : - off);
- changed++;
- }
- *foo = off;
-
- return(changed);
- }
-
-
-
-
-
-
-
- static int new_off()
- {
- int foo;
-
- foo = random() % 11 - 5;
- if (! foo)
- foo = (random() % 1 ? 1 : -1);
-
- return(foo);
- }
-
-
-
-
-
-
-
-
- static void build_float()
- {
- PromptLine lines[MAXPROMPT];
- int i = 0, max_strlen = 0;
- Widget *return_widgets;
- static String float_name = "float";
- static String msg_name = "message";
-
- if (! float_widget) {
-
- /* The first one should pick up a bitmap from the defaults */
- lines[i] = default_line;
- lines[i].use_default = True;
- lines[i].name = float_name;
- lines[i].str = "floatIcon"; i++;
- if (defs.d_time) {
- lines[i] = default_line;
- lines[i].name = float_name;
- lines[i].str = time_string(TIME_FORMAT, Force);
- max_strlen = ((strlen(lines[i].str) > max_strlen) ?
- strlen(lines[i].str) : max_strlen); i++;
- }
- if (defs.d_elapsed) {
- lines[i] = default_line;
- lines[i].name = float_name;
- lines[i].str = elapsed_string(ELAPSED_FORMAT, Force);
- max_strlen = ((strlen(lines[i].str) > max_strlen) ?
- strlen(lines[i].str) : max_strlen); i++;
- }
-
- if (defs.d_timeout && lock_flag && defs.timeout) {
- lines[i] = default_line;
- lines[i].name = float_name;
- lines[i].str = timeleft_string(TIMELEFT_FORMAT, Force);
- max_strlen = ((strlen(lines[i].str) > max_strlen) ?
- strlen(lines[i].str) : max_strlen); i++;
- }
- if (*defs.lock_message) {
- int num_lines;
- char **msg_lines;
- int a;
-
- if (max_strlen < 25)
- max_strlen = 25;
- msg_lines = breakup(defs.lock_message, max_strlen, &num_lines);
- for (a = 0; (a < num_lines) && (i < MAXPROMPT); a++, i++) {
- lines[i] = default_line;
- if (a == 0)
- lines[i].spread = 10;
- lines[i].name = msg_name;
- lines[i].str = msg_lines[a];
- }
- }
-
- return_widgets = (Widget *) malloc(sizeof(Widget) * i);
- if (! return_widgets) {
- perror(whoami);
- exit(1);
- }
- float_widget = PromptBox(root_widget, "float", lines, i,
- return_widgets); i = 0;
- icon_w.widget = return_widgets[i]; i++;
- if (defs.d_time) {
- time_w.widget = return_widgets[i]; i++;
- }
- if (defs.d_elapsed) {
- elapsed_w.widget = return_widgets[i]; i++;
- }
- if (defs.d_timeout && lock_flag && defs.timeout) {
- timeout_w.widget = return_widgets[i]; i++;
- }
- }
- }
-
-
-
-
-
- static char **breakup(str, max, num)
- String str;
- int max;
- int *num;
- {
- char **foo;
- int lines = 0;
- char *ptr, *ptr2;
- char temp;
-
- foo = (char **) malloc(0);
-
- ptr = str;
- while (strlen(ptr) > max) {
- lines++;
- for (ptr2 = ptr + max; (ptr2 > ptr) && (*ptr2 != ' '); ptr2--);
- if (ptr2 == ptr) {
- temp = *(ptr + max);
- *(ptr + max) = '\0';
- ptr2 = ptr + max;
- }
- else {
- temp = 0;
- *ptr2 = '\0';
- ptr2++;
- }
- foo = (char **) realloc(foo, sizeof(char *) * lines);
- foo[lines - 1] = malloc(strlen(ptr) + 1);
- strcpy(foo[lines - 1], ptr);
- if (temp)
- *ptr2 = temp;
- ptr = ptr2;
-
- }
- if (*ptr) {
- lines++;
- foo = (char **) realloc(foo, sizeof(char *) * lines);
- foo[lines - 1] = malloc(strlen(ptr) + 1);
- strcpy(foo[lines - 1], ptr);
- }
- *num = lines;
- return(foo);
- }
-
-
-
-
- /* ARGSUSED */
- void RaiseRoot(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- XRaiseWindow(dpy, XtWindow(root_shell));
- }
-
-
-
- /* ARGSUSED */
- void RemoveRoot(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
-
- unlock_command();
- XtUnmapWidget(root_shell);
- XUngrabPointer(dpy, CurrentTime);
- XUngrabKeyboard(dpy, CurrentTime);
- XSetScreenSaver(dpy, saver.timeout, saver.interval, saver.prefer_blanking,
- saver.allow_exposures);
- activated = False;
- }
-
-
-
-
- static void lock_command()
- {
- if ((! lock_command_pid) && (*defs.lock_command)) {
- if ((lock_command_pid = fork()) == -1) {
- fprintf(stderr, "%s: Error forking to execute lock command!",
- whoami);
- lock_command_pid = 0;
- }
- else if (! lock_command_pid) {
- setpgrp(getpid(), getpid());
- XtCloseDisplay(dpy);
- system(defs.lock_command);
- exit(0);
- }
- }
- }
-
-
-
-
-
- static void unlock_command()
- {
- if (lock_command_pid) {
- killpg(lock_command_pid, SIGKILL);
- lock_command_pid = 0;
- }
- if (lock_flag && *defs.unlock_command) {
- int pid;
-
- if ((pid = fork()) == -1)
- fprintf(stderr,
- "%s: Error forking to execute unlock command.\n",
- whoami);
- else if (! pid) {
- XtCloseDisplay(dpy);
- system(defs.unlock_command);
- exit(0);
- }
- }
- }
-
-
-
-