[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: