From 2b6e1eca160e4ee835c26c4b1d6cf67552707413 Mon Sep 17 00:00:00 2001 From: mdw Date: Sun, 13 Jan 2002 14:42:30 +0000 Subject: [PATCH] New program to display messages and get answers. --- Makefile.am | 12 ++- xmsg.1 | 83 ++++++++++++++++++++ xmsg.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 xmsg.1 create mode 100644 xmsg.c diff --git a/Makefile.am b/Makefile.am index ae84f4c..d8c0a2d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## -*-makefile-*- ## -## $Id: Makefile.am,v 1.8 1999/11/11 19:50:13 mdw Exp $ +## $Id: Makefile.am,v 1.9 2002/01/13 14:42:30 mdw Exp $ ## ## Makefile for X tools ## @@ -28,6 +28,9 @@ ##----- Revision history ---------------------------------------------------- ## ## $Log: Makefile.am,v $ +## Revision 1.9 2002/01/13 14:42:30 mdw +## New program to display messages and get answers. +## ## Revision 1.8 1999/11/11 19:50:13 mdw ## Build separately from libraries. ## @@ -56,10 +59,10 @@ AUTOMAKE_OPTIONS = foreign -GTK_PROGS = xshutdown xgetline xcatch +GTK_PROGS = xshutdown xgetline xcatch xmsg bin_PROGRAMS = xwait xtell xscsize @GTK_PROGS@ EXTRA_PROGRAMS = $(GTK_PROGS) -man_MANS = xwait.1 xtell.1 xshutdown.1 xscsize.1 xgetline.1 xcatch.1 +man_MANS = xwait.1 xtell.1 xshutdown.1 xscsize.1 xgetline.1 xcatch.1 xmsg.1 EXTRA_DIST = $(man_MANS) CLEANFILES = $(GTK_PROGS) @@ -79,6 +82,9 @@ xwait_LDADD = @X_LIBS@ -lX11 xtell_SOURCES = xtell.c xwait.h xatom.c xatom.h xtell_LDADD = @X_LIBS@ -lX11 +xmsg_SOURCES = xmsg.c +xmsg_LDADD = @MGLIB_LIBS@ @GTK_LIBS@ + xscsize_SOURCES = xscsize.c xscsize_LDADD = @X_LIBS@ -lX11 diff --git a/xmsg.1 b/xmsg.1 new file mode 100644 index 0000000..57cb3e1 --- /dev/null +++ b/xmsg.1 @@ -0,0 +1,83 @@ +.\" -*-nroff-*- +.TH xmsg 1 "20 December 2001" "Edgeware tools" +.SH NAME +xmsg \- pops up a message box +.SH SYNOPSIS +.ll +5i +.B xmsg +.RB [ \-\-display +.IR display ] +.RB [ \-f ] +.RB [ \-t +.IR title ] +.RB [ \-c | \-d +.IR button ] +.if n \{\ +.br +\h'1i' +.. +\} +.I message +.RI [ button ...] +.ll -5i +.SH DESCRIPTION +The +.B xmsg +program pops up a pretty GTK message box, containing the listed buttons +(shown right to left along the bottom). The button strings are listed, +one per argument, after the message. If no buttons are requested, an +.B OK +button is provided anyway. +.PP +A button may be selected as being the default (i.e., may be chosen by +pressing +.IR enter ), +using the +.B \-d +option: the argument must either match a button name, or be an index +(zero-based) of the requested button. If you don't select a default, +the first (rightmost) button becomes the default anyway. +.PP +Similarly, a button may be selected as being the `cancel' action (i.e., +may be chosen by closing the window or pressing +.IR escape ), +using +the +.B \-c +option. Again, the argument must either match a button name or be an +index of a button. If you don't select a cancel button, the last +(leftmost) button because the cancel button. +.PP +If there is more than one button, the name of the selected button is +printed on standard output when the program exits. +.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 +.B "\-f, \-\-focus " +Sets a magical property to ensure that the window acquires the focus +under a customized +.BR fvwm (3) +version I don't use any more. +.TP 5 +.BI "\-t, \-\-title " title +Sets the title for the window. If you don't specify a title, the window +is labelled +.RB ` xmsg '. +.TP 5 +.BI "\-c, \-\-cancel " button +Selects the given +.I button +as being the cancel button. +.TP 5 +.BI "\-d, \-\-default " button +Selects the given +.I button +as being the default button. +.SH AUTHOR +Mark Wooding (mdw@nsict.org). +.SH BUGS +None currently known. diff --git a/xmsg.c b/xmsg.c new file mode 100644 index 0000000..23336a9 --- /dev/null +++ b/xmsg.c @@ -0,0 +1,249 @@ +/* -*-c-*- + * + * $Id: xmsg.c,v 1.1 2002/01/13 14:42:18 mdw Exp $ + * + * Display a message to the user + * + * (c) 2001 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: xmsg.c,v $ + * Revision 1.1 2002/01/13 14:42:18 mdw + * New program to display messages and get answers. + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct button { + unsigned f; + const char *text; +} button; + +#define f_cancel 1u +#define f_default 2u + +DA_DECL(button_v, button); + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @version@ --- */ + +static void version(FILE *fp) +{ + fprintf(fp, "%s (xtoys version " VERSION ")\n", QUIS); +} + +/* --- @usage@ --- */ + +static void usage(FILE *fp) +{ + fprintf(fp, "Usage: %s [-f] [-t TITLE] [-c|d BUTTON] MSG [BUTTON...]\n", + QUIS); +} + +/* --- @findbutton@ --- */ + +static button *findbutton(button_v *bv, const char *tag) +{ + size_t i, n = DA_LEN(bv); + button *b = DA(bv); + char *q; + + if (!tag) + return (0); + for (i = 0; i < n; i++) { + if (strcmp(b[i].text, tag) == 0) + return (&b[i]); + } + while (*tag && isspace((unsigned char)*tag)) + tag++; + i = strtoul(tag, &q, 0); + if (!*q && i < n) + return (&b[i]); + die(EXIT_FAILURE, "unknown button `%s'", tag); + return (0); +} + + +/* --- @main@ --- * + * + * Main program. + */ + +int main(int argc, char *argv[]) +{ + const char *title; + const char *message; + const char *b_cancel = 0, *b_default = 0; + button_v bv = DA_INIT; + button *b; + dstr d = DSTR_INIT; + size_t n, i; + unsigned f = 0; + +#define f_focus 256u + + ego(argv[0]); + gtk_init(&argc, &argv); + + /* --- Parse options --- */ + + title = QUIS; + for (;;) { + static struct option opt[] = { + { "help", 0, 0, 'h' }, + { "usage", 0, 0, 'u' }, + { "version", 0, 0, 'v' }, + { "focus", 0, 0, 'f' }, + { "title", OPTF_ARGREQ, 0, 't' }, + { "cancel", OPTF_ARGREQ, 0, 'c' }, + { "default", OPTF_ARGREQ, 0, 'd' }, + { 0, 0, 0, 0 } + }; + int i; + + i = getopt_long(argc, argv, "huv t:c:d:q", opt, 0); + + if (i < 0) + break; + + switch (i) { + case 'h': + version(stdout); + fputs("\n", stdout); + usage(stdout); + fputs( +"\n" +"Pops up a message box containing a message and some buttons, reporting\n" +"which button was selected.\n" +"\n" +"Options available are:\n" +"\n" +"-h, --help Display this help text\n" +"-u, --usage Display a short usage summary\n" +"-v, --version Display the program's version number\n" +"\n" +"-f, --focus Give the window the focus (obsolete mdw thing)\n" +"-t, --title=TITLE Select the title string in the message box\n" +"-c, --cancel=BUTTON Select which button is to have the Cancel action\n" +"-d, --default=BUTTON Select which button is the default\n", + stdout); + exit(0); + break; + case 'u': + usage(stdout); + exit(0); + break; + case 'v': + version(stdout); + exit(0); + break; + + case 'f': + f |= f_focus; + break; + case 't': + title = optarg; + break; + case 'c': + b_cancel = optarg; + break; + case 'd': + b_default = optarg; + break; + + default: + usage(stderr); + exit(EXIT_FAILURE); + } + } + + if (optind >= argc) { + usage(stderr); + exit(EXIT_FAILURE); + } + message = argv[optind++]; + + if (optind >= argc) { + DA_ENSURE(&bv, 1); + b = &DA(&bv)[0]; + b->f = 0; + b->text = "OK"; + DA_UNSAFE_EXTEND(&bv, 1); + } else for (; optind < argc; optind++) { + DA_ENSURE(&bv, 1); + b = &DA(&bv)[DA_LEN(&bv)]; + b->f = 0; + b->text = argv[optind]; + DA_UNSAFE_EXTEND(&bv, 1); + } + + if ((b = findbutton(&bv, b_cancel)) != 0) + b->f |= f_cancel; + else + DA(&bv)[DA_LEN(&bv) - 1].f |= f_cancel; + + if ((b = findbutton(&bv, b_default)) != 0) + b->f |= f_default; + else + DA(&bv)[0].f |= f_default; + + b = DA(&bv); + n = DA_LEN(&bv); + if (f & f_focus) + DPUTC(&d, '!'); + for (i = 0; i < n; i++) { + if (b[i].f & f_default) + DPUTC(&d, ':'); + if (b[i].f & f_cancel) + DPUTC(&d, '~'); + DPUTS(&d, b[i].text); + DPUTC(&d, ','); + } + d.buf[--d.len] = 0; + + i = msg(title, d.buf, "%s", message); + if (n > 1) + puts(b[i].text); + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/ -- 2.11.0