--- /dev/null
+COPYING
+install-sh
+mdwopt.c
+mdwopt.h
+missing
+mkinstalldirs
--- /dev/null
+;;; -*-emacs-lisp-*-
+
+(setq skel-alist
+ (append
+ '((full-title . "the Edgeware X tools collection")
+ (program . "X tools")
+ (author . "Straylight/Edgeware"))
+ skel-alist))
--- /dev/null
+## -*-makefile-*-
+##
+## $Id: Makefile.am,v 1.1 1998/11/16 23:00:49 mdw Exp $
+##
+## Makefile for X tools
+##
+## (c) 1998 Straylight/Edgeware
+##
+
+##----- Licensing notice ----------------------------------------------------
+##
+## This file is part of the Edgeware X tools collection.
+##
+## X tools is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## X tools is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with X tools; if not, write to the Free Software Foundation,
+## Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+##----- Revision history ----------------------------------------------------
+##
+## $Log: Makefile.am,v $
+## Revision 1.1 1998/11/16 23:00:49 mdw
+## Initial versions.
+##
+
+AUTOMAKE_OPTIONS = foreign
+
+bin_PROGRAMS = xwait xtell xscsize @GTK_PROGS@
+EXTRA_PROGRAMS = xshutdown xgetline
+man_MANS = xwait.1 xtell.1 xshutdown.1 xscsize.1 xgetline.1
+EXTRA_DIST = $(man_MANS)
+
+xshutdown_SOURCES = xshutdown.c xwait.h mdwopt.c mdwopt.h
+xshutdown_LDADD = @GTK_LIBS@
+
+xgetline_SOURCES = xgetline.c mdwopt.c mdwopt.h
+xgetline_LDADD = @GTK_LIBS@
+
+xwait_SOURCES = xwait.c xwait.h
+xwait_LDADD = @X_LIBS@ -lX11
+
+xtell_SOURCES = xtell.c xwait.h
+xtell_LDADD = @X_LIBS@ -lX11
+
+xscsize_SOURCES = xscsize.c
+xscsize_LDADD = @X_LIBS@ -lX11
+
+##----- That's all, folks ---------------------------------------------------
--- /dev/null
+X tools, -*-text-*-
+
+
+ This is just a small collection of small X-based toys. There's
+ nothing especially clever here, just some stuff I've found to be
+ useful. It's a bit of a mixed bag, really; just saves me some
+ effort if I package them all up together. The collection may
+ grow in future, if I can be bothered to write any more X toys.
+
+ A couple of the toys require GTK. Sorry: I like GTK and I don't
+ want to play with Athena or Xt or anything like that again,
+ because they're nasty.
+
+ The tools are described more fully in the accompanying manual
+ pages. There's not much to know about any of them, though.
+
+
+xgetline
+
+ Pops up a little window (with configurable text in it) asking
+ the user to type in a piece of text, and then writes it to
+ stdout. It's useful when a shell script wants to solicit a
+ string from the user, and particularly handy in window manager
+ config files. You can also turn off echo of the string being
+ typed in, which may be useful for input of passwords, but that's
+ not ever-so recommended.
+
+ The basic idea is that you say something like
+
+ if name=`xgetline -p Name`; then
+ echo "Hello, $name, pleased to meet you!"
+ else
+ echo "You're no fun, are you?"
+ fi
+
+ and everything is lovely.
+
+
+xscsize
+
+ Returns the size of an X display. The idea is that you can do
+ something like
+
+ eval `xscsize`
+
+ in a `.xinitrc' file and then play with XWIDTH and XHEIGHT to
+ decide exactly where to put various windows depending on how big
+ the screen is. This sort of thing is quite handy if you use the
+ same setup on lots of different systems or screens.
+
+
+xwait, xtell, xshutdown
+
+ The traditional thing to do at the end of a `.xinitrc' file is
+ to wait for the window manager to exit. This is unhelpful when
+ the window manager doesn't like its configuration file, for
+ example, because your entire session goes away. The idea
+ (filched shamelessly from SGI, actually) is to end the script
+ with a program which hangs around until told to go away by
+ another X client. (I could have used any old IPC mechanism
+ here, but it seemed silly to use something other than X.)
+
+ The manual pages provide the low-level detail. Basically,
+ though, you run `xwait', and it sleeps. When you run `xtell',
+ it tells the `xwait' program to kill itself. `xshutdown' does
+ essentially the same thing, only it pops up a pretty window
+ asking you if you're sure before it does it.
+
+
+Notes and things
+
+ All the code here is released under the GNU General Public
+ License (included in the file COPYING in the distribution).
+
+ I tested the code under Linux and not much else, but I'm usually
+ fairly conservative about portability and there shouldn't be
+ much hassle involved.
+
+ If anyone wants to do an Xaw version of the GTK bits then I'll
+ include that in the distribution; people using Motif or Qt need
+ not apply.
+
--- /dev/null
+dnl -*-fundamental-*-
+dnl
+dnl $Id: configure.in,v 1.1 1998/11/16 23:00:49 mdw Exp $
+dnl
+dnl Configuration script for X tools
+dnl
+dnl (c) 1998 Straylight/Edgeware
+dnl
+
+dnl ----- Licensing notice --------------------------------------------------
+dnl
+dnl This file is part of the Edgeware X tools collection.
+dnl
+dnl X tools is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl X tools is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with X tools; if not, write to the Free Software Foundation,
+dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+dnl ----- Revision history --------------------------------------------------
+dnl
+dnl $Log: configure.in,v $
+dnl Revision 1.1 1998/11/16 23:00:49 mdw
+dnl Initial versions.
+dnl
+
+AC_INIT(xwait.c)
+AM_INIT_AUTOMAKE(xtoys, 1.0)
+AC_PROG_CC
+mdw_GCC_FLAGS
+AC_PROG_INSTALL
+AC_ARG_PROGRAM
+
+AM_PATH_GTK(1.0.0,
+ [CFLAGS="$CFLAGS $GTK_CFLAGS"
+ GTK_PROGS="xgetline xshutdown"],
+ [AC_MSG_WARN([You appear not to have GTK.])
+ GTK_PROGS=""])
+AC_SUBST(GTK_PROGS)
+
+AC_PATH_XTRA
+CFLAGS="$CFLAGS $X_CFLAGS"
+
+AC_OUTPUT(Makefile)
+
+dnl ----- That's all, folks -------------------------------------------------
--- /dev/null
+.TH xgetline 1 "15 November 1998" "Edgeware tools"
+.SH NAME
+xgetline \- request a line of text in an X dialogue box
+.SH SYNOPSIS
+.B xgetline
+.RB [ \-t
+.IR title ]
+.RB [ \-p
+.IR prompt ]
+.RB [ \-d
+.IR default ]
+.SH DESCRIPTION
+The
+.B xgetline
+program reads a line of text from the user via a pretty GTK dialogue
+box. The title bar contents, prompt string, and default text are all
+configurable. If the user enters a string and clicks the
+.B OK
+button (or
+presses
+.IR enter ),
+the string is echoed to standard output and
+.B xgetline
+returns an exit status of zero. If the user cancels the dialogue box
+(by closing it, or pressing
+.IR escape ),
+.B xgetline
+echoes nothing and returns an exit status of one.
+.PP
+The
+.B xgetline
+program is intended to be used in window manager configuration files, to
+allow users to fill in bits of text (e.g., hostnames or shell commands)
+in generally useful places. For example, the author has the following
+shell command attached to a hotkey:
+.PP
+.RS 5
+.ft B
+.nf
+cmd=`xgetline -t "Shell command in window" -p "Command:"` &&
+ xterm -T "$cmd" -e sh -c "$cmd"
+.ft R
+.fi
+.SS OPTIONS
+.TP 5
+.BI "\-t, \-\-title " title
+Sets the title of the dialogue box to
+.IR title .
+The default title is
+.RB ` "Input request" '.
+.TP 5
+.BI "\-p, \-\-prompt " prompt
+Sets the prompt string in the dialogue box to
+.IR prompt .
+The default is to have no prompt string.
+.TP 5
+.BI "\-d, \-\-default " default
+Sets the default text in the entry field to
+.IR default .
+The default default is the empty string.
+.SH AUTHOR
+Mark Wooding (mdw@nsict.org).
+.SH BUGS
+Hopefully none.
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id: xgetline.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
+ *
+ * Fetch a line of text from the user
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Edgeware X tools collection.
+ *
+ * X tools is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * X tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with X tools; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------*
+ *
+ * $Log: xgetline.c,v $
+ * Revision 1.1 1998/11/16 23:00:49 mdw
+ * Initial versions.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "mdwopt.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @cancel@ --- *
+ *
+ * Arguments: @GtkWidget *w@ = widget raising the signal
+ * @gpointer *p@ = pointer to integer result code
+ *
+ * Returns: ---
+ *
+ * Use: Sets the result code to zero (failure) and ends the loop.
+ */
+
+static void cancel(GtkWidget *w, gpointer *p)
+{
+ int *ip = (int *)p;
+ *ip = 0;
+ gtk_main_quit();
+}
+
+/* --- @done@ --- *
+ *
+ * Arguments: @GtkWidget *w@ = widget raising the signal
+ * @gpointer *p@ = pointer to integer result code
+ *
+ * Returns: ---
+ *
+ * Use: Sets the result code nonzero (success) and ends the loop.
+ */
+
+static void done(GtkWidget *w, gpointer *p)
+{
+ int *ip = (int *)p;
+ *ip = 1;
+ gtk_main_quit();
+}
+
+/* --- @check_escape@ --- *
+ *
+ * Arguments: @GtkWidget *w@ = widget raising the signal
+ * @GdkEventKey *ev@ = pointer to event data
+ * @gpointer *p@ = widget to activate in response
+ *
+ * Returns: ---
+ *
+ * Use: Activates a widget when an escape keypress is detected.
+ */
+
+static gboolean check_escape(GtkWidget *w, GdkEventKey *ev, gpointer *p)
+{
+ if (ev->keyval == GDK_Escape) {
+ if (p)
+ gtk_widget_activate(GTK_WIDGET(p));
+ else
+ gtk_object_destroy(GTK_OBJECT(w));
+ return (1);
+ }
+ return (0);
+}
+
+/* --- @main@ --- *
+ *
+ * Arguments: @int argc@ = number of command line arguments
+ * @char *argv[]@ = addresses of arguments
+ *
+ * Returns: Zero if OK, and we read a string; nonzero if the user
+ * cancelled.
+ *
+ * Use: Reads a string from the user, and returns it on standard
+ * output.
+ */
+
+int main(int argc, char *argv[])
+{
+ /* --- Configuration variables --- */
+
+ char *prompt = 0;
+ char *dfl = "";
+ char *title = "Input request";
+ int left;
+ unsigned f = 0;
+ int ok = 0;
+
+ enum {
+ f_invis = 1,
+ f_duff = 2
+ };
+
+ /* --- User interface bits --- */
+
+ GtkWidget *win;
+ GtkWidget *box;
+ GtkWidget *entry;
+ GtkWidget *btn;
+
+ /* --- Crank up the toolkit --- *
+ *
+ * Have to do this here: GTK snarfs some command line options which my
+ * parser would barf about.
+ */
+
+ gtk_init(&argc, &argv);
+
+ /* --- Parse options from command line --- */
+
+ for (;;) {
+
+ /* --- Long options structure --- */
+
+ static struct option opt[] = {
+ { "help", 0, 0, 'h' },
+ { "title", required_argument, 0, 't' },
+ { "prompt", required_argument, 0, 'p' },
+ { "default", required_argument, 0, 'd' },
+ { "password", 0, 0, 'i' },
+ { "invisible", 0, 0, 'i' },
+ { 0, 0, 0, 0 }
+ };
+ int i;
+
+ /* --- Fetch an option --- */
+
+ i = getopt_long(argc, argv, "ht:p:d:i", opt, 0);
+ if (i < 0)
+ break;
+
+ /* --- Work out what to do with it --- */
+
+ switch (i) {
+ case 't':
+ title = optarg;
+ break;
+ case 'p':
+ prompt = optarg;
+ break;
+ case 'd':
+ dfl = optarg;
+ break;
+ case 'i':
+ f |= f_invis;
+ break;
+ default:
+ f |= f_duff;
+ break;
+ }
+ }
+
+ if (f & f_duff) {
+ fprintf(stderr, "xgetline: bad arguments\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* --- Create the main window --- */
+
+ win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(win), title);
+ gtk_window_position(GTK_WINDOW(win), GTK_WIN_POS_MOUSE);
+ gtk_signal_connect(GTK_OBJECT(win), "destroy",
+ GTK_SIGNAL_FUNC(cancel), &ok);
+
+ /* --- Create the box for laying out the widgets inside --- */
+
+ left = (prompt ? 1 : 0);
+ box = gtk_table_new(left + 2, 1, 0);
+
+ /* --- Maybe create a prompt widget --- */
+
+ if (prompt) {
+ GtkWidget *w = gtk_label_new(prompt);
+ gtk_table_attach(GTK_TABLE(box), w,
+ 0, 1, 0, 1, 0, GTK_EXPAND, 4, 2);
+ gtk_widget_show(w);
+ }
+
+ /* --- Create the entry widget --- */
+
+ entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(entry), dfl);
+ gtk_table_attach(GTK_TABLE(box), entry,
+ left, left + 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND, 4, 2);
+ if (f & f_invis)
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_widget_show(entry);
+
+ /* --- Create the default action widget --- */
+
+ btn = gtk_button_new_with_label("OK");
+ gtk_table_attach(GTK_TABLE(box), btn,
+ left + 1, left + 2, 0, 1, 0, GTK_EXPAND, 2, 2);
+ GTK_WIDGET_SET_FLAGS(btn, GTK_CAN_DEFAULT);
+ gtk_widget_show(btn);
+
+ /* --- Add the box into the main window --- */
+
+ gtk_container_add(GTK_CONTAINER(win), box);
+ gtk_widget_show(box);
+
+ /* --- Last minute configuration things --- */
+
+ gtk_widget_grab_default(btn);
+ gtk_signal_connect(GTK_OBJECT(btn), "clicked",
+ GTK_SIGNAL_FUNC(done), &ok);
+ gtk_signal_connect_object(GTK_OBJECT(entry), "activate",
+ GTK_SIGNAL_FUNC(gtk_widget_activate),
+ GTK_OBJECT(btn));
+ gtk_signal_connect(GTK_OBJECT(win), "key_press_event",
+ GTK_SIGNAL_FUNC(check_escape), 0);
+
+ /* --- Go go go --- */
+
+ gtk_widget_show(win);
+ gtk_main();
+
+ /* --- Output the result --- */
+
+ if (ok) {
+ char *p = gtk_entry_get_text(GTK_ENTRY(entry));
+ puts(p);
+ }
+
+ return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+.TH xscsize 1 "15 November 1998" "Edgeware tools"
+.SH NAME
+xscsize \- return size of an X display to a shell script
+.SH SYNOPSIS
+.B xscsize
+.RB [ \-bcx ]
+.RB [ \-d
+.IR display ]
+.SH DESCRIPTION
+The
+.B xscsize
+program interrogates an X display and writes the size of the root
+window to standard output in the form of a shell variable assignment
+statement. The dimensions are returned in the
+.B XWIDTH
+and
+.B XHEIGHT
+variables.
+.PP
+Command line options can be used to force output in either Bourne or C
+shell syntax. In the absence of any explicit instructions,
+.B xscsize
+looks at the
+.B SHELL
+environment variable to help make its mind up.
+.PP
+Typical use would be something like
+.RS 5
+.ft B
+.nf
+eval `xscsize`
+.ft R
+.fi
+.SS OPTIONS
+.TP 5
+.B \-b
+Output the assignments in Bourne shell syntax (usable by Bourne,
+POSIX, Korn, Z and Bourne Again shells).
+.TP 5
+.B \-c
+Output the assignments in C shell syntax (usable by C and Terminal C
+shells).
+.TP 5
+.B \-x
+Output a variable export command, so that the screen size is inherited
+by child processes. The default is to just set local shell variables.
+.SH ENVIRONMENT
+.TP
+.B XWIDTH
+Set to the width of the display in pixels.
+.B XHEIGHT
+Set to the height of the display in pixels.
+.B SHELL
+Used to decide the nature of the calling shell. If absent, a Bourne
+shell is assumed.
+.SH AUTHOR
+Mark Wooding (mdw@nsict.org).
+.SH BUGS
+Hopefully none.
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id: xscsize.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
+ *
+ * Return X display size to shell script
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Edgeware X tools collection.
+ *
+ * X tools is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * X tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with X tools; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------*
+ *
+ * $Log: xscsize.c,v $
+ * Revision 1.1 1998/11/16 23:00:49 mdw
+ * Initial versions.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <getopt.h>
+#include <X11/Xlib.h>
+
+/*----- Main code ---------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ const char *display = 0;
+ unsigned f = 0;
+ unsigned long wd, ht;
+
+ enum {
+ f_sh = 1,
+ f_csh = 2,
+ f_shell = 3,
+ f_export = 4
+ };
+
+ /* --- Parse command line options --- */
+
+ for (;;) {
+ int i = getopt(argc, argv, "d:bcx");
+ if (i < 0)
+ break;
+ switch (i) {
+ case 'd':
+ display = optarg;
+ break;
+ case 'b':
+ f |= f_sh;
+ break;
+ case 'c':
+ f |= f_csh;
+ break;
+ case 'x':
+ f |= f_export;
+ break;
+ default:
+ fprintf(stderr, "Usage: xscsize [-bcx] [-d DISPLAY]\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* --- Sort out the shell type --- *
+ *
+ * If the shell name contains the string `csh' then assume it's a C shell.
+ * Otherwise assume it's Bourne. This seems to work in practice.
+ */
+
+ if (!(f & f_shell)) {
+ const char *s = getenv("SHELL");
+ if (!s)
+ f |= f_sh;
+ if (strstr(s, "csh"))
+ f |= f_csh;
+ else
+ f |= f_sh;
+ }
+
+ if ((f & f_sh) && (f & f_csh)) {
+ fprintf(stderr, "xscsize: make your mind up about your shell type\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* --- Get the important information --- */
+
+ {
+ Display *dpy = XOpenDisplay(display);
+ int sc;
+ if (!dpy) {
+ fprintf(stderr, "xscsize: couldn't open display\n");
+ exit(EXIT_FAILURE);
+ }
+ sc = DefaultScreen(dpy);
+ wd = DisplayWidth(dpy, sc);
+ ht = DisplayHeight(dpy, sc);
+ XCloseDisplay(dpy);
+ }
+
+ /* --- Do the output thing --- */
+
+ if (f & f_sh) {
+ printf("XWIDTH=%lu XHEIGHT=%lu", wd, ht);
+ if (f & f_export)
+ printf("; export XWIDTH XHEIGHT");
+ }
+ if (f & f_csh) {
+ if (f & f_export)
+ printf("setenv XWIDTH %lu; setenv XHEIGHT %lu", wd, ht);
+ else
+ printf("set XWIDTH=%lu XHEIGHT=%lu", wd, ht);
+ }
+ putchar('\n');
+
+ /* --- Done --- */
+
+ return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+.TH xshutdown 1 "15 November 1998" "Edgeware tools"
+.SH NAME
+xshutdown \- asks for user confirmation before waking an xwait process
+.SH SYNOPSIS
+.B xshutdown
+.RB [ \-\-display
+.IR display ]
+.RB [ \-a
+.IR atom ]
+.RB [ \-m
+.IR message ]
+.RB [ \-t
+.IR title ]
+.SH DESCRIPTION
+The
+.B xshutdown
+program pops up a pretty GTK confirmation box asking the user whether he
+(or she) wants to shutdown the current session. If so, it sends a
+message to a waiting
+.B xwait
+process, by setting a named property on the X root window to a particular
+value.
+.SS OPTIONS
+.TP 5
+.BI "\-\-display " display
+Attempt to connect to
+.I display
+rather than the display named in the usual environment variable.
+.TP 5
+.BI "\-a, \-\-atom " atom
+Sets
+.B xshutdown
+to to set the property named
+.IR atom .
+The default property to set is
+.BR XWAIT_PROPERTY .
+.TP 5
+.BI "\-m, \-\-msg " message
+Sets
+.B xshutdown
+to set the given property to
+.IR message .
+The default message to set is
+.BR XWAIT_MESSAGE .
+.TP 5
+.BI "\-p, \-\-prompt " prompt
+Sets the prompt in the confirmation box to
+.IR prompt .
+.TP 5
+.BI "\-t, \-\-title " title
+Sets the window title to be
+.IR title .
+.SH AUTHOR
+Mark Wooding (mdw@nsict.org).
+.SH BUGS
+None currently known.
+.SH SEE ALSO
+.BR xwait (1),
+and
+.BR xtell (1).
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id: xshutdown.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
+ *
+ * Pretty GTK interface to waking up an xwait
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Edgeware X tools collection.
+ *
+ * X tools is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * X tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with X tools; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------*
+ *
+ * $Log: xshutdown.c,v $
+ * Revision 1.1 1998/11/16 23:00:49 mdw
+ * Initial versions.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdkprivate.h>
+
+#include "mdwopt.h"
+#include "xwait.h"
+
+/*----- Static variables --------------------------------------------------*/
+
+static char *atom = XWAIT_DIE;
+static char *msg = XWAIT_DIE_MSG;
+
+static Atom xwait_die;
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @cancel@ --- *
+ *
+ * Just end the main loop.
+ */
+
+static void cancel(GtkWidget *w, gpointer *p)
+{
+ gtk_main_quit();
+}
+
+/* --- @ok@ --- *
+ *
+ * Send the xwait process a message.
+ */
+
+static void ok(GtkWidget *w, gpointer *p)
+{
+ XTextProperty prop;
+ XStringListToTextProperty(&msg, 1, &prop);
+ XSetTextProperty(gdk_display, DefaultRootWindow(gdk_display),
+ &prop, xwait_die);
+ gtk_main_quit();
+}
+
+/* --- @main@ --- *
+ *
+ * Main program.
+ */
+
+int main(int argc, char *argv[])
+{
+ char *prompt = "Are you sure you want to shut down this session?";
+ char *title = "xshutdown";
+ gtk_init(&argc, &argv);
+
+ /* --- Parse options --- */
+
+ for (;;) {
+ static struct option opt[] = {
+ { "atom", required_argument, 0, 'a' },
+ { "msg", required_argument, 0, 'm' },
+ { "prompt", required_argument, 0, 'p' },
+ { "title", required_argument, 0, 't' },
+ { 0, 0, 0, 0 }
+ };
+ int i;
+
+ i = getopt_long(argc, argv, "a:m:p:t:", opt, 0);
+
+ if (i < 0)
+ break;
+
+ switch (i) {
+ case 'a':
+ atom = optarg;
+ break;
+ case 'm':
+ msg = optarg;
+ break;
+ case 'p':
+ prompt = optarg;
+ break;
+ case 't':
+ title = optarg;
+ break;
+ default:
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ xwait_die = XInternAtom(gdk_display, atom, False);
+
+ /* --- Decide whether there's an xwait listening --- *
+ *
+ * If not, pop up an error box and quit.
+ */
+
+ {
+ XTextProperty prop;
+
+ if (!XGetTextProperty(gdk_display, DefaultRootWindow(gdk_display),
+ &prop, xwait_die)) {
+ char buf[64];
+ GtkWidget *win = gtk_dialog_new();
+ GtkWidget *w;
+
+ /* --- Make the main window --- */
+
+ gtk_window_set_title(GTK_WINDOW(win), "xshutdown");
+ gtk_signal_connect(GTK_OBJECT(win), "destroy",
+ GTK_SIGNAL_FUNC(cancel), 0);
+
+ gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(win)->action_area), 0);
+
+ /* --- Make the label --- */
+
+ sprintf(buf, "no xwait listening for `%s'\n", atom);
+ w = gtk_label_new(buf);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(win)->vbox), w, 1, 1, 0);
+ gtk_misc_set_padding(GTK_MISC(w), 8, 8);
+ gtk_widget_show(w);
+
+ /* --- Make the little button --- */
+
+ w = gtk_button_new_with_label("OK");
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(win)->action_area), w, 0, 0, 0);
+ GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(w);
+ gtk_signal_connect(GTK_OBJECT(w), "clicked",
+ GTK_SIGNAL_FUNC(cancel), 0);
+ gtk_widget_show(w);
+
+ /* --- Make everything work --- */
+
+ gtk_widget_show(win);
+ gtk_main();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* --- Main code --- */
+
+ {
+ GtkWidget *win;
+ GtkWidget *w;
+
+ /* --- Make the main dialogue box --- */
+
+ win = gtk_dialog_new();
+ gtk_window_set_title(GTK_WINDOW(win), title);
+ gtk_signal_connect(GTK_OBJECT(win), "destroy",
+ GTK_SIGNAL_FUNC(cancel), 0);
+
+ gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(win)->action_area), 0);
+
+ /* --- Make the prompt label --- */
+
+ w = gtk_label_new(prompt);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(win)->vbox), w, 1, 1, 0);
+ gtk_misc_set_padding(GTK_MISC(w), 8, 8);
+ gtk_widget_show(w);
+
+ /* --- Make the OK button --- */
+
+ w = gtk_button_new_with_label("OK");
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(win)->action_area), w, 0, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(ok), 0);
+ GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
+ gtk_widget_show(w);
+ gtk_widget_grab_default(w);
+
+ /* --- And the cancel button --- */
+
+ w = gtk_button_new_with_label("Cancel");
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(win)->action_area), w, 0, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(w), "clicked", GTK_SIGNAL_FUNC(cancel), 0);
+ GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
+ gtk_widget_show(w);
+
+ /* --- Show the completed window --- */
+
+ gtk_widget_show(win);
+ }
+
+ /* --- Let rip --- */
+
+ gtk_main();
+ return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+.TH xtell 1 "15 November 1998" "Edgeware tools"
+.SH NAME
+xtell \- prods a waiting xwait process
+.SH SYNOPSIS
+.B xtell
+.RB [ \-d
+.IR display ]
+.RB [ \-a
+.IR atom ]
+.RB [ \-m
+.IR message ]
+.SH DESCRIPTION
+The
+.B xtell
+program sets a named property on the X root window to a particular
+value. This is primarily useful for communicating with
+.BR xwait (1).
+.SS OPTIONS
+.TP 5
+.BI "\-d " display
+Attempt to connect to
+.I display
+rather than the display named in the usual environment variable.
+.TP 5
+.BI "\-a " atom
+Sets
+.B xtell
+to to set the property named
+.IR atom .
+The default property to set to is
+.BR XWAIT_PROPERTY .
+.TP 5
+.BI "\-m " message
+Sets
+.B xtell
+to set the given property to
+.IR message .
+The default message to set is
+.BR XWAIT_MESSAGE .
+.SH AUTHOR
+Mark Wooding (mdw@nsict.org).
+.SH BUGS
+None currently known.
+.SH SEE ALSO
+.BR xwait (1),
+and
+.BR xshutdown (1).
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id: xtell.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
+ *
+ * Wake up a waiting xwait process
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Edgeware X tools collection.
+ *
+ * X tools is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * X tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with X tools; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------*
+ *
+ * $Log: xtell.c,v $
+ * Revision 1.1 1998/11/16 23:00:49 mdw
+ * Initial versions.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "xwait.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ char *display = 0;
+ Display *dpy;
+ Atom xwait_die;
+ char *atom = XWAIT_DIE;
+ char *msg = XWAIT_DIE_MSG;
+
+ /* --- Parse options --- */
+
+ for (;;) {
+ int i = getopt(argc, argv, "d:a:m:");
+ if (i < 0)
+ break;
+ switch (i) {
+ case 'd':
+ display = optarg;
+ break;
+ case 'a':
+ atom = optarg;
+ break;
+ case 'm':
+ msg = optarg;
+ break;
+ default:
+ fprintf(stderr, "Usage: xtell [-d DISPLAY] [-a ATOM] [-m MSG]\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* --- Connect to the display --- */
+
+ dpy = XOpenDisplay(display);
+ if (!dpy) {
+ fprintf(stderr, "xtell: couldn't open display\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* --- Find the right atom --- */
+
+ xwait_die = XInternAtom(dpy, atom, False);
+
+ /* --- Set the property value --- */
+
+ {
+ XTextProperty prop;
+ if (!XGetTextProperty(dpy, DefaultRootWindow(dpy), &prop, xwait_die)) {
+ fprintf(stderr, "xtell: no xwait listening for `%s'\n", atom);
+ exit(EXIT_FAILURE);
+ }
+ XStringListToTextProperty(&msg, 1, &prop);
+ XSetTextProperty(dpy, DefaultRootWindow(dpy), &prop, xwait_die);
+ }
+
+ /* --- Done --- */
+
+ XCloseDisplay(dpy);
+ return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+.TH xwait 1 "15 November 1998" "Edgeware tools"
+.SH NAME
+xwait \- wait until prodded by another X client
+.SH SYNOPSIS
+.B xwait
+.RI [ \-f ]
+.RB [ \-d
+.IR display ]
+.RB [ \-a
+.IR atom ]
+.RB [ \-m
+.IR message ]
+.SH DESCRIPTION
+The
+.B xwait
+program waits until it notices that a particular property on the X root
+window has been assigned a particular value, at which point the program
+exits. The property can be set using the
+.BR xtell (1)
+and
+.BR xshutdown (1)
+programs. It's mostly useful for putting at the end of a user's
+.B .xinitrc
+file, so that it can be triggered to end the session.
+.PP
+The property, and the value to listen for, can be configured at
+the command line. When
+.B xwait
+exits, it removes the property from the root window.
+.SS OPTIONS
+.TP 5
+.B \-f
+Force
+.B xwait
+to start up, even though there may be an existing process already
+listening for the particular atom in question.
+.TP 5
+.BI "\-d " display
+Attempt to connect to
+.I display
+rather than the display named in the usual environment variable.
+.TP 5
+.BI "\-a " atom
+Sets
+.B xwait
+to listen for the property named
+.IR atom .
+The default property to listen to is
+.BR XWAIT_PROPERTY .
+.TP 5
+.BI "\-m " message
+Sets
+.B xwait
+to wait for the given property to be set to
+.IR message .
+The default message to wait for is
+.BR XWAIT_MESSAGE .
+.SH AUTHOR
+Mark Wooding (mdw@nsict.org).
+.SH BUGS
+None currently known.
+.SH SEE ALSO
+.BR xtell (1),
+and
+.BR xshutdown (1).
--- /dev/null
+/* -*-c-*-
+ *
+ * $Id: xwait.c,v 1.1 1998/11/16 23:00:49 mdw Exp $
+ *
+ * Wait until prodded by another X client
+ *
+ * (c) 1998 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the Edgeware X tools collection.
+ *
+ * X tools is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * X tools is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with X tools; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*----- Revision history --------------------------------------------------*
+ *
+ * $Log: xwait.c,v $
+ * Revision 1.1 1998/11/16 23:00:49 mdw
+ * Initial versions.
+ *
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "xwait.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ char *display = 0;
+ Display *dpy;
+ Atom xwait_die;
+ XEvent ev;
+ char *atom = XWAIT_DIE;
+ char *msg = XWAIT_DIE_MSG;
+ unsigned f = 0;
+
+ enum {
+ f_force = 1
+ };
+
+ /* --- Parse options --- */
+
+ for (;;) {
+ int i = getopt(argc, argv, "d:a:m:f");
+ if (i < 0)
+ break;
+ switch (i) {
+ case 'd':
+ display = optarg;
+ break;
+ case 'a':
+ atom = optarg;
+ break;
+ case 'm':
+ msg = optarg;
+ break;
+ case 'f':
+ f |= f_force;
+ break;
+ default:
+ fprintf(stderr,
+ "Usage: xwait [-f] [-d DISPLAY] [-a ATOM] [-m MSG]\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* --- Connect to the X display --- */
+
+ dpy = XOpenDisplay(display);
+ if (!dpy) {
+ fprintf(stderr, "xwait: couldn't open display\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* --- Fetch the property name atom --- */
+
+ xwait_die = XInternAtom(dpy, atom, False);
+
+ /* --- Mark ourselves as listening to all the screens --- */
+
+ {
+ int i;
+ int nsc = ScreenCount(dpy);
+
+ /* --- First pass: make sure there's not a process already here --- */
+
+ if ((f & f_force) == 0) {
+ for (i = 0; i < nsc; i++) {
+ Window win = RootWindow(dpy, i);
+ XTextProperty prop;
+
+ if (XGetTextProperty(dpy, win, &prop, xwait_die)) {
+ fprintf(stderr, "xwait: already waiting for `%s'\n", atom);
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ /* --- Second pass: set up listening to the property --- */
+
+ for (i = 0; i < nsc; i++) {
+ Window win = RootWindow(dpy, i);
+ XTextProperty prop;
+ char *imsg = "XWAIT_READY";
+
+ XStringListToTextProperty(&imsg, 1, &prop);
+ XSetTextProperty(dpy, win, &prop, xwait_die);
+ XSelectInput(dpy, win, PropertyChangeMask);
+ }
+ }
+
+ /* --- Now wait for an event --- */
+
+ for (;;) {
+ XNextEvent(dpy, &ev);
+ switch (ev.type) {
+ case PropertyNotify:
+ if (ev.xproperty.atom == xwait_die) {
+ XTextProperty prop;
+ char **sl;
+ int c;
+
+ if (XGetTextProperty(dpy, ev.xproperty.window, &prop, xwait_die)) {
+ XTextPropertyToStringList(&prop, &sl, &c);
+ if (strcmp(sl[0], msg) == 0)
+ goto exit;
+ XFreeStringList(sl);
+ }
+ }
+ }
+ }
+
+ /* --- Finished: remove the property from all the screens --- */
+
+exit:
+ {
+ int i;
+ int nsc = ScreenCount(dpy);
+
+ for (i = 0; i < nsc; i++)
+ XDeleteProperty(dpy, RootWindow(dpy, i), xwait_die);
+ }
+
+ /* --- Go away --- */
+
+ XCloseDisplay(dpy);
+ return (0);
+}
+
+/*----- That's all, folks -------------------------------------------------*/
--- /dev/null
+#ifndef XWAIT_H
+#define XWAIT_H
+
+
+#define XWAIT_DIE "XWAIT_PROPERTY"
+#define XWAIT_DIE_MSG "XWAIT_MESSAGE"
+
+#endif