From 90b2c5d453c6e561a00913baa7aa8b9c213f0173 Mon Sep 17 00:00:00 2001 From: mdw Date: Mon, 16 Nov 1998 23:04:38 +0000 Subject: [PATCH] Initial versions. --- .cvsignore | 1 + .links | 6 ++ .skelrc | 8 ++ Makefile.am | 57 +++++++++++++ README | 82 ++++++++++++++++++ configure.in | 54 ++++++++++++ xgetline.1 | 64 ++++++++++++++ xgetline.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ xscsize.1 | 59 +++++++++++++ xscsize.c | 143 +++++++++++++++++++++++++++++++ xshutdown.1 | 60 +++++++++++++ xshutdown.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++ xtell.1 | 47 +++++++++++ xtell.c | 113 +++++++++++++++++++++++++ xwait.1 | 65 ++++++++++++++ xwait.c | 176 ++++++++++++++++++++++++++++++++++++++ xwait.h | 8 ++ 17 files changed, 1445 insertions(+) create mode 100644 .cvsignore create mode 100644 .links create mode 100644 .skelrc create mode 100644 Makefile.am create mode 100644 README create mode 100644 configure.in create mode 100644 xgetline.1 create mode 100644 xgetline.c create mode 100644 xscsize.1 create mode 100644 xscsize.c create mode 100644 xshutdown.1 create mode 100644 xshutdown.c create mode 100644 xtell.1 create mode 100644 xtell.c create mode 100644 xwait.1 create mode 100644 xwait.c create mode 100644 xwait.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.cvsignore @@ -0,0 +1 @@ +build diff --git a/.links b/.links new file mode 100644 index 0000000..68709e4 --- /dev/null +++ b/.links @@ -0,0 +1,6 @@ +COPYING +install-sh +mdwopt.c +mdwopt.h +missing +mkinstalldirs diff --git a/.skelrc b/.skelrc new file mode 100644 index 0000000..73f6f57 --- /dev/null +++ b/.skelrc @@ -0,0 +1,8 @@ +;;; -*-emacs-lisp-*- + +(setq skel-alist + (append + '((full-title . "the Edgeware X tools collection") + (program . "X tools") + (author . "Straylight/Edgeware")) + skel-alist)) diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..10b4835 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,57 @@ +## -*-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 --------------------------------------------------- diff --git a/README b/README new file mode 100644 index 0000000..705c58c --- /dev/null +++ b/README @@ -0,0 +1,82 @@ +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. + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..c0b0dc8 --- /dev/null +++ b/configure.in @@ -0,0 +1,54 @@ +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 ------------------------------------------------- diff --git a/xgetline.1 b/xgetline.1 new file mode 100644 index 0000000..aa454ff --- /dev/null +++ b/xgetline.1 @@ -0,0 +1,64 @@ +.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. diff --git a/xgetline.c b/xgetline.c new file mode 100644 index 0000000..1da9ed1 --- /dev/null +++ b/xgetline.c @@ -0,0 +1,271 @@ +/* -*-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 +#include +#include + +#include +#include + +#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 -------------------------------------------------*/ diff --git a/xscsize.1 b/xscsize.1 new file mode 100644 index 0000000..30caf39 --- /dev/null +++ b/xscsize.1 @@ -0,0 +1,59 @@ +.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. diff --git a/xscsize.c b/xscsize.c new file mode 100644 index 0000000..ace018e --- /dev/null +++ b/xscsize.c @@ -0,0 +1,143 @@ +/* -*-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 +#include +#include + +#include +#include + +/*----- 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 -------------------------------------------------*/ diff --git a/xshutdown.1 b/xshutdown.1 new file mode 100644 index 0000000..17417b7 --- /dev/null +++ b/xshutdown.1 @@ -0,0 +1,60 @@ +.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). diff --git a/xshutdown.c b/xshutdown.c new file mode 100644 index 0000000..dd62b26 --- /dev/null +++ b/xshutdown.c @@ -0,0 +1,231 @@ +/* -*-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 +#include +#include + +#include +#include + +#include +#include + +#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 -------------------------------------------------*/ diff --git a/xtell.1 b/xtell.1 new file mode 100644 index 0000000..b04d22f --- /dev/null +++ b/xtell.1 @@ -0,0 +1,47 @@ +.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). diff --git a/xtell.c b/xtell.c new file mode 100644 index 0000000..7675814 --- /dev/null +++ b/xtell.c @@ -0,0 +1,113 @@ +/* -*-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 +#include +#include + +#include + +#include +#include + +#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 -------------------------------------------------*/ diff --git a/xwait.1 b/xwait.1 new file mode 100644 index 0000000..f9b9ccb --- /dev/null +++ b/xwait.1 @@ -0,0 +1,65 @@ +.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). diff --git a/xwait.c b/xwait.c new file mode 100644 index 0000000..7142217 --- /dev/null +++ b/xwait.c @@ -0,0 +1,176 @@ +/* -*-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 +#include +#include + +#include + +#include +#include + +#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 -------------------------------------------------*/ diff --git a/xwait.h b/xwait.h new file mode 100644 index 0000000..f55e6d7 --- /dev/null +++ b/xwait.h @@ -0,0 +1,8 @@ +#ifndef XWAIT_H +#define XWAIT_H + + +#define XWAIT_DIE "XWAIT_PROPERTY" +#define XWAIT_DIE_MSG "XWAIT_MESSAGE" + +#endif -- 2.11.0