Re: Anyone want to make a Debian XDM login screen?
Wichert Akkerman <wakkerma@wiggy.ml.org> writes:
> Previously Brian Mays wrote:
> > There is an easy way to get this button on your screen, assuming that you
> > have the TCL/TK packages installed.
>
> I've done the same thing (using Motif), but added a confirmation check..
> I've found that when I move the mouse or press a mousebutton when the
> screen is in powersaving can have very disconcerting effects with a
> reset-button out there..
I did something similar for my ancient Slackware 1.2 box.
My solution was a trivial Xt button called XShutdown. It includes a
confirmation stage, and calls "shutdown" itself (sorting out a console
for it's output while it's at it).
It should be check it works with ELF, latest X libraries, the current
sysvinit, but I don't anticipate any probplems.
Austin
------------------------------------------------------------
/* Copyright (c) Austin Donnelly 1995-1998
* and1000@cam.ac.uk
*
* This software is released under the GPL. It comes with NO WARRANTY.
*
* xshutdown.c
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Dialog.h>
/* globals */
char *progname;
Widget pshell, topLev;
/* prototypes */
void Shutdown_btn(Widget, XtPointer, XtPointer);
void Ok_btn(Widget, XtPointer, XtPointer);
void Cancel_btn(Widget, XtPointer, XtPointer);
void start_shutdown(void);
void popdown(Widget);
void die(const char *);
int main(int argc, char **argv)
{
XtAppContext app;
Widget box, shutdown, dialog, ok, cancel;
/* make the widget hierarchy */
topLev = XtVaAppInitialize(&app,
"XShutdown",
NULL, 0, /* no cmd line options */
&argc, argv,
NULL, /* app-defaults */
NULL); /* end of args */
box = XtVaCreateManagedWidget(
"box", /* name */
boxWidgetClass,
topLev, /* parent */
NULL);
shutdown = XtVaCreateManagedWidget(
"Shutdown",
commandWidgetClass,
box,
NULL);
/* now make the popup hierarchy */
pshell = XtVaCreatePopupShell("pshell",
transientShellWidgetClass,
topLev,
NULL);
dialog = XtVaCreateManagedWidget(
"dialog",
dialogWidgetClass,
pshell,
NULL);
ok = XtVaCreateManagedWidget(
"ok",
commandWidgetClass,
dialog,
NULL);
cancel = XtVaCreateManagedWidget(
"cancel",
commandWidgetClass,
dialog,
NULL);
/* callbacks */
XtAddCallback(shutdown, XtNcallback, Shutdown_btn, 0);
XtAddCallback(ok, XtNcallback, Ok_btn, shutdown);
XtAddCallback(cancel, XtNcallback, Cancel_btn, shutdown);
/* customisation */
XtVaSetValues(dialog,
XtNlabel, "Really shutdown?",
NULL);
progname = argv[0];
/* main code */
if (argc!=1)
{
printf("Usage: %s\n", progname);
printf("\tRun as root, when button clicked, does a shutdown(8)\n");
exit(1);
}
/* draw the things */
XtRealizeWidget(topLev);
XtAppMainLoop(app);
return 0;
}
void Shutdown_btn(Widget shutdown, XtPointer client_data, XtPointer call_data)
{
Position x, y;
Dimension width, height;
/* configure bits n bobs */
XtVaGetValues(topLev,
XtNwidth, &width,
XtNheight, &height,
NULL);
XtTranslateCoords(topLev,
(Position) width / 2,
(Position) height + 10,
&x, &y);
XtVaSetValues(pshell,
XtNx, x,
XtNy, y,
NULL);
XtSetSensitive(shutdown, FALSE);
/* show popup */
XtPopup(pshell, XtGrabNonexclusive);
}
void Ok_btn(Widget w, XtPointer client_data, XtPointer call_data)
{
popdown((Widget) client_data); /* popdown & resensitize shutdown */
start_shutdown(); /* fork off shutdown(8) */
}
void Cancel_btn(Widget w, XtPointer client_data, XtPointer call_data)
{
popdown((Widget) client_data); /* popdown & resensitize shutdown */
}
void popdown(Widget show)
{
XtPopdown(pshell);
XtSetSensitive(show, TRUE);
}
/* this code is enough to safely shutdown the machine */
void start_shutdown(void)
{
pid_t pid;
int infd, outfd, errfd;
if ((pid=fork())==-1)
die("fork");
if (pid==0) /* child */
{
/* open the console for /sbin/shutdown */
infd = open("/dev/tty1", O_RDONLY);
if (infd == -1) die("open /dev/tty1 for reading stdin");
outfd = open("/dev/tty1", O_WRONLY);
if (outfd == -1) die("open /dev/tty1 for writing stdout");
errfd = open("/dev/tty1", O_WRONLY | O_SYNC);
if (errfd == -1) die("open /dev/tty1 for writing stderr");
/* redirect IO to console */
/* can fail, but it's not the end of the world, so don't check */
dup2(infd, 0); /* stdin */
dup2(outfd, 1); /* stdout */
dup2(errfd, 2); /* stderr */
execl("/sbin/shutdown", "/sbin/shutdown",
"-t", "4", /* time between SIGTERM & SIGKILL (secs) */
"-h", "now", /* halt now, don't reboot */
"XShutdown", "clicked", "on", "console", /* message sent */
NULL);
die("execl");
}
}
void die(const char *msg)
{
fprintf(stderr, "%s: %s: %s\n",
progname,
msg,
strerror(errno)
);
exit(1);
}
------------------------------------------------------------
--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: