From: mdw Date: Mon, 16 Nov 1998 23:04:38 +0000 (+0000) Subject: Initial versions. X-Git-Tag: 1.0.0~1 X-Git-Url: https://git.distorted.org.uk/~mdw/xtoys/commitdiff_plain/90b2c5d453c6e561a00913baa7aa8b9c213f0173 Initial versions. --- 90b2c5d453c6e561a00913baa7aa8b9c213f0173 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