## -*-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
##
##----- 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.
##
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)
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
--- /dev/null
+.\" -*-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.
--- /dev/null
+/* -*-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 <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mLib/darray.h>
+#include <mLib/dstr.h>
+#include <mLib/mdwopt.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+
+#include <mgLib/msg.h>
+
+/*----- 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 -------------------------------------------------*/