New program to display messages and get answers.
authormdw <mdw>
Sun, 13 Jan 2002 14:42:30 +0000 (14:42 +0000)
committermdw <mdw>
Sun, 13 Jan 2002 14:42:30 +0000 (14:42 +0000)
Makefile.am
xmsg.1 [new file with mode: 0644]
xmsg.c [new file with mode: 0644]

index ae84f4c..d8c0a2d 100644 (file)
@@ -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.
 ##
 
 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 (file)
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 (file)
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 <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 -------------------------------------------------*/