522 lines
13 KiB
C
522 lines
13 KiB
C
#if !defined( lint ) && !defined( SABER )
|
|
|
|
static const char sccsid[] = "@(#)xmlock.c 4.08 98/02/18 xlockmore";
|
|
|
|
#endif
|
|
|
|
/*-
|
|
* xmlock.c - main file for xmlock, the gui interface to xlock.
|
|
*
|
|
* Copyright (c) 1996 by Charles Vidal
|
|
*
|
|
* See xlock.c for copying information.
|
|
*
|
|
* Revision History:
|
|
* Jun-03: Code added from Xlockup by Thad Phetteplace
|
|
* tdphette@dexter.glaci.com
|
|
* Sun -- works (both timeouts seem connected to the same device)
|
|
* Linux -- mouse timeout works, keyboard timeout does not work
|
|
* Cygwin -- mouse timout does not work, keyboard timeout does not work
|
|
* Alpha -- "does something" ;)
|
|
* Since keyboard timeout does not seem to help, it was removed.
|
|
* Nov-96: Continual minor improvements by Charles Vidal and David Bagley.
|
|
* Oct-96: written.
|
|
*/
|
|
|
|
/*-
|
|
XmLock Problems
|
|
1. Allowing only one in -inroot. Need a way to kill it.
|
|
2. XLock resources need to be read and used to set initial values.
|
|
3. Integer and floating point and string input.
|
|
*/
|
|
|
|
/*
|
|
* 01/2001
|
|
* I'm confused because the source is old and really not well programming
|
|
* I put boolean option and option in the menubar
|
|
* I have had the option.h
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <sys/signal.h>
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#else
|
|
#define HAVE_UNISTD_H 1
|
|
#endif /* HAVE_CONFIG_H */
|
|
#if HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/stat.h>
|
|
|
|
#ifdef VMS
|
|
#include "vms_x_fix.h"
|
|
#include <descrip.h>
|
|
#include <lib$routines.h>
|
|
#endif
|
|
|
|
#ifdef USE_MB
|
|
#include <X11/Xlocale.h>
|
|
#endif
|
|
|
|
#include <Xm/PanedW.h>
|
|
#include <Xm/RowColumn.h>
|
|
#include <Xm/ToggleB.h>
|
|
#include <Xm/List.h>
|
|
#include <Xm/PushB.h>
|
|
#include <Xm/Form.h>
|
|
#include <Xm/Label.h>
|
|
#include <Xm/Scale.h>
|
|
|
|
#if USE_XMU
|
|
#include <X11/Xmu/Editres.h>
|
|
#endif
|
|
|
|
#include "option.h"
|
|
|
|
#ifdef SOLARIS2
|
|
extern int kill(pid_t, int);
|
|
extern pid_t wait(int *);
|
|
#else
|
|
#if 0
|
|
extern int kill(int, int);
|
|
extern pid_t wait(int *);
|
|
|
|
#endif
|
|
#endif
|
|
|
|
#include "bitmaps/m-xlock.xbm" /* icon bitmap */
|
|
|
|
#define SKIPDELAY 60000 /* 1 minute */
|
|
#define MAXMIN 120
|
|
|
|
/* like an enum */
|
|
enum ACTION {
|
|
LAUNCH=0,
|
|
ROOT,
|
|
WINDOW
|
|
};
|
|
|
|
/* extern variable */
|
|
extern Widget Menuoption;
|
|
extern Widget Toggles[TOGGLES];
|
|
extern OptionStruct Opt[];
|
|
|
|
extern char *r_Toggles[];
|
|
|
|
static pid_t numberprocess = -1; /* PID of xlock */
|
|
|
|
/*************************
|
|
* To know the number of element
|
|
* in the Opt Array
|
|
**************************/
|
|
extern int getNumberofElementofOpt();
|
|
|
|
/* Widget */
|
|
Widget toplevel;
|
|
static Widget Labelxlock;
|
|
static Widget timeoutSlider;
|
|
|
|
static time_t timenow;
|
|
|
|
/* If this worked on all systems it would be 30 min or 1800 */
|
|
static long timeout = 0;
|
|
|
|
static Widget ScrolledListModes, PushButtons[PUSHBUTTONS];
|
|
|
|
/*Resource string */
|
|
#include "modes.h"
|
|
|
|
#if 0
|
|
static XmStringCharSet char_set = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;
|
|
#endif
|
|
|
|
/* some resources of buttons and toggles not really good programming :( */
|
|
|
|
static char *r_PushButtons[PUSHBUTTONS] =
|
|
{
|
|
(char *) "Launch",
|
|
(char *) "In Root",
|
|
(char *) "In Window",
|
|
};
|
|
|
|
static int numberinlist = 0;
|
|
|
|
static void checkTime();
|
|
/* CallBack */
|
|
|
|
void exitcallback(Widget w, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
if (numberprocess != -1) {
|
|
(void) kill(numberprocess, SIGKILL);
|
|
/*(void) wait(&n);*/
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
static void
|
|
callLocker(int choice)
|
|
{
|
|
int i;
|
|
char command[500];
|
|
|
|
#ifdef VMS
|
|
int mask = 17;
|
|
struct dsc$descriptor_d vms_image;
|
|
|
|
#endif
|
|
|
|
(void) sprintf(command, "%s ", XLOCK);
|
|
|
|
/* booleans (+/-) options */
|
|
|
|
for (i = 0; i < TOGGLES; i++) {
|
|
if (XmToggleButtonGetState(Toggles[i])) {
|
|
(void) strcat(command, "-");
|
|
(void) strcat(command, r_Toggles[i]);
|
|
(void) strcat(command, " ");
|
|
}
|
|
}
|
|
/*
|
|
sizeof(Opt)/sizeof(OptionStruct) is not good to
|
|
know the number of element in Opt
|
|
so I have made a function getNumberofElementofOpt
|
|
*/
|
|
for (i = 0; i < getNumberofElementofOpt(); i++)
|
|
if (Opt[i].userdata != NULL) {
|
|
(void) strcat(command, "-");
|
|
(void) strcat(command, Opt[i].cmd);
|
|
(void) strcat(command, " ");
|
|
(void) strcat(command, Opt[i].userdata);
|
|
(void) strcat(command, " ");
|
|
}
|
|
|
|
switch (choice) {
|
|
case LAUNCH:
|
|
/* the default value then nothing to do */
|
|
break;
|
|
case WINDOW:
|
|
(void) strcat(command, "-inwindow ");
|
|
break;
|
|
case ROOT:
|
|
(void) strcat(command, "-inroot ");
|
|
break;
|
|
}
|
|
(void) strcat(command, "-mode ");
|
|
(void) strcat(command, LockProcs[numberinlist].cmdline_arg);
|
|
#ifdef VMS
|
|
vms_image.dsc$w_length = strlen(command);
|
|
vms_image.dsc$a_pointer = command;
|
|
vms_image.dsc$b_class = DSC$K_CLASS_S;
|
|
vms_image.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
(void) printf("%s\n", command);
|
|
(void) lib$spawn(&vms_image, 0, 0, &mask);
|
|
#else
|
|
if (choice != LAUNCH)
|
|
(void) strcat(command, " & ");
|
|
(void) printf("%s\n", command);
|
|
(void) system(command);
|
|
#endif
|
|
if (choice == LAUNCH)
|
|
(void) XtAppAddTimeOut(XtWidgetToApplicationContext(toplevel),
|
|
SKIPDELAY, (XtTimerCallbackProc) checkTime, toplevel);
|
|
}
|
|
|
|
/*----------------------------------------------------------*/
|
|
/* Code taken from Xlockup by Thad Phetteplace */
|
|
/* tdphette@dexter.glaci.com used by permission */
|
|
/* CHECKTIME: This routine is called periodicaly by the */
|
|
/* openwin event handler. It checks the last access */
|
|
/* time/date stamp on the mouse and keyboard devices */
|
|
/* and compares it to the timeout value. */
|
|
/*----------------------------------------------------------*/
|
|
|
|
static void checkTime()
|
|
{
|
|
struct stat statmouse;
|
|
#if 0
|
|
struct stat statkeybd;
|
|
#endif
|
|
|
|
(void) time( &timenow ); /* get current time */
|
|
/* next does not work on Cygwin */
|
|
(void) stat("/dev/mouse", &statmouse ); /* get mouse status */
|
|
#if 0
|
|
/* does not seem to help on Solaris and hinders on Linux */
|
|
(void) stat("/dev/kbd", &statkeybd ); /* get keyboard status */
|
|
#endif
|
|
|
|
/* check if last access time was larger than timeout */
|
|
if (timeout > 0 && (timenow-statmouse.st_atime >= timeout) /* &&
|
|
(timenow-statkeybd.st_atime >= timeout)*/) {
|
|
callLocker(LAUNCH);
|
|
}
|
|
#ifdef DEBUG
|
|
printf("timeout %ld, timenow - amouse %ld\n",
|
|
timeout, timenow - statmouse.st_atime);
|
|
printf("timeout %ld, timenow - akeybd %ld\n",
|
|
timeout, timenow - statkeybd.st_atime);
|
|
#endif
|
|
(void) XtAppAddTimeOut(XtWidgetToApplicationContext(toplevel),
|
|
SKIPDELAY, (XtTimerCallbackProc) checkTime, toplevel);
|
|
}
|
|
|
|
static void
|
|
f_PushButtons(Widget w, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
callLocker((int) client_data);
|
|
}
|
|
|
|
static void
|
|
f_ScrolledListModes(Widget w, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
char numberwidget[50];
|
|
char str[50];
|
|
int n;
|
|
|
|
numberinlist = ((XmListCallbackStruct *) call_data)->item_position - 1;
|
|
(void) sprintf(numberwidget, "%ld", XtWindow(Labelxlock));
|
|
(void) sprintf(str, "%s", LockProcs[numberinlist].cmdline_arg);
|
|
if (numberprocess != -1) {
|
|
(void) kill(numberprocess, SIGKILL);
|
|
(void) wait(&n);
|
|
}
|
|
#ifdef VMS
|
|
#define FORK vfork
|
|
#else
|
|
#define FORK fork
|
|
#endif
|
|
if ((numberprocess = FORK()) == -1)
|
|
(void) fprintf(stderr, "Fork error\n");
|
|
else if (numberprocess == 0) {
|
|
(void) execlp(XLOCK, XLOCK, "-parent", numberwidget,
|
|
"-mode", str, "-geometry", WINDOW_GEOMETRY,
|
|
"-delay", "100000",
|
|
"-nolock", "-inwindow", "+install", 0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
TimeoutSlider(Widget w, XtPointer clientData, XmScaleCallbackStruct * cbs)
|
|
{
|
|
timeout = cbs->value * 60;
|
|
}
|
|
|
|
/* Setup Widget */
|
|
|
|
/**********************/
|
|
|
|
static void
|
|
Setup_Widget(Widget father)
|
|
{
|
|
Arg args[15];
|
|
int i, ac;
|
|
Widget PushButtonRow, exitwidgetB;
|
|
char string[160];
|
|
XmString label_str;
|
|
XmString TabXmStr[numprocs];
|
|
|
|
/* buttons in the bottom */
|
|
ac = 0;
|
|
XtSetArg(args[ac], XmNorientation, XmHORIZONTAL);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNtopAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
|
|
Menuoption = XmCreateMenuBar(father, (char *) "MenuBar", args,ac);
|
|
XtManageChild(Menuoption);
|
|
|
|
ac = 0;
|
|
XtSetArg(args[ac], XmNwidth, WINDOW_WIDTH);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNheight, WINDOW_HEIGHT);
|
|
ac++;
|
|
|
|
XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
|
|
XtSetArg(args[ac], XmNtopWidget, Menuoption); ac++;
|
|
|
|
#if 0
|
|
int ModeLabel;
|
|
XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
|
|
|
|
XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
|
|
|
|
XtSetArg(args[ac], XmNleftWidget, ModeLabel); ac++;
|
|
#endif
|
|
|
|
Labelxlock = XmCreateLabel(father, (char *) "Window", args, ac);
|
|
XtManageChild(Labelxlock);
|
|
|
|
/* buttons in the bottom */
|
|
ac = 0;
|
|
|
|
XtSetArg(args[ac], XmNorientation, XmHORIZONTAL);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
PushButtonRow = XmCreateRowColumn(father, (char *) "PushButtonRow", args, ac);
|
|
|
|
for (i = 0; i < PUSHBUTTONS; i++) {
|
|
ac = 0;
|
|
#ifndef USE_MB
|
|
label_str = XmStringCreate(r_PushButtons[i], XmSTRING_DEFAULT_CHARSET);
|
|
XtSetArg(args[ac], XmNlabelString, label_str);
|
|
ac++;
|
|
#endif
|
|
PushButtons[i] = XmCreatePushButton(PushButtonRow,
|
|
r_PushButtons[i], args, ac);
|
|
#ifndef USE_MB
|
|
XmStringFree(label_str);
|
|
#endif
|
|
XtAddCallback(PushButtons[i], XmNactivateCallback,
|
|
f_PushButtons, (XtPointer) i);
|
|
XtManageChild(PushButtons[i]);
|
|
}
|
|
/*
|
|
* For the exit button
|
|
*/
|
|
ac = 0;
|
|
#ifndef USE_MB
|
|
label_str = XmStringCreate((char *) "Exit",
|
|
XmSTRING_DEFAULT_CHARSET);
|
|
XtSetArg(args[ac], XmNlabelString, label_str);
|
|
ac++;
|
|
#endif
|
|
exitwidgetB = XmCreatePushButton(PushButtonRow,
|
|
(char *) "Exit", args, ac);
|
|
#ifndef USE_MB
|
|
XmStringFree(label_str);
|
|
#endif
|
|
XtAddCallback(exitwidgetB, XmNactivateCallback, exitcallback,
|
|
(XtPointer) NULL);
|
|
XtManageChild(exitwidgetB);
|
|
timeoutSlider = XtVaCreateManagedWidget("timeout",
|
|
xmScaleWidgetClass, PushButtonRow,
|
|
XtVaTypedArg, XmNtitleString, XmRString, "Timeout", 8,
|
|
XmNminimum, 0,
|
|
XmNmaximum, MAXMIN,
|
|
XmNvalue, timeout / 60,
|
|
XmNshowValue, True,
|
|
XmNorientation, XmHORIZONTAL, NULL);
|
|
XtAddCallback(timeoutSlider, XmNvalueChangedCallback,
|
|
(XtCallbackProc) TimeoutSlider, (XtPointer) NULL);
|
|
|
|
XtManageChild(PushButtonRow);
|
|
|
|
/* list and toggles in row like that (row(list)(TogglesRow(toggles...))) */
|
|
ac = 0;
|
|
XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNtopWidget, Labelxlock);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNbottomWidget, PushButtonRow);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNitems, TabXmStr);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNitemCount, numprocs);
|
|
ac++;
|
|
XtSetArg(args[ac], XmNvisibleItemCount, 10);
|
|
ac++;
|
|
|
|
|
|
for (i = 0; i < (int) numprocs; i++) {
|
|
(void) sprintf(string, "%-14s%s", LockProcs[i].cmdline_arg,
|
|
LockProcs[i].desc);
|
|
TabXmStr[i] = XmStringCreate(string, XmSTRING_DEFAULT_CHARSET);
|
|
}
|
|
ScrolledListModes = XmCreateScrolledList(father, (char *) "ScrolledListModes",
|
|
args, ac);
|
|
XtAddCallback(ScrolledListModes, XmNbrowseSelectionCallback,
|
|
f_ScrolledListModes, NULL);
|
|
XtManageChild(ScrolledListModes);
|
|
|
|
#if 0
|
|
int TogglesRow, Row;
|
|
TogglesRow = XmCreateRowColumn(Row, (char *) "TogglesRow", NULL, 0);
|
|
for (i = 0; i < TOGGLES; i++) {
|
|
#ifndef USE_MB
|
|
ac = 0;
|
|
label_str = XmStringCreate(r_Toggles[i], XmSTRING_DEFAULT_CHARSET);
|
|
XtSetArg(args[ac], XmNlabelString, label_str);
|
|
ac++;
|
|
#endif
|
|
Toggles[i] = XmCreateToggleButton(TogglesRow, r_Toggles[i], args, ac);
|
|
#ifndef USE_MB
|
|
XmStringFree(label_str);
|
|
#endif
|
|
XtManageChild(Toggles[i]);
|
|
}
|
|
XtManageChild(TogglesRow);
|
|
|
|
XtManageChild(Row);
|
|
#endif
|
|
|
|
for (i = 0; i < (int) numprocs; i++) {
|
|
XmStringFree(TabXmStr[i]);
|
|
}
|
|
}
|
|
|
|
extern void setup_Option(Widget MenuBar);
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
Widget form;
|
|
Arg args[15];
|
|
|
|
#ifdef USE_MB
|
|
setlocale(LC_ALL, "");
|
|
XtSetLanguageProc(NULL, NULL, NULL);
|
|
#endif
|
|
|
|
/* PURIFY 4.0.1 on Solaris 2 reports an unitialized memory read on the next
|
|
line. */
|
|
toplevel = XtInitialize(argv[0], "XmLock", (XrmOptionDescRec*) NULL, 0,
|
|
&argc, argv);
|
|
XtSetArg(args[0], XtNiconPixmap,
|
|
XCreateBitmapFromData(XtDisplay(toplevel),
|
|
RootWindowOfScreen(XtScreen(toplevel)),
|
|
(char *) image_bits, image_width, image_height));
|
|
XtSetValues(toplevel, args, 1);
|
|
/* creation Widget */
|
|
/* PURIFY 4.0.1 on Solaris 2 reports an unitialized memory read on the next
|
|
line. */
|
|
form = XmCreateForm(toplevel, (char *) "Form", (Arg *) NULL, 0);
|
|
Setup_Widget(form);
|
|
setup_Option(Menuoption);
|
|
XtManageChild(form);
|
|
XtRealizeWidget(toplevel);
|
|
(void) XtAppAddTimeOut(XtWidgetToApplicationContext(toplevel),
|
|
SKIPDELAY, (XtTimerCallbackProc) checkTime, toplevel);
|
|
#if USE_XMU
|
|
/* With this handler you can use editres */
|
|
XtAddEventHandler(toplevel, (EventMask) 0, TRUE,
|
|
(XtEventHandler) _XEditResCheckMessages, NULL);
|
|
#endif
|
|
XtMainLoop();
|
|
#ifdef VMS
|
|
return 1;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|