+/* -*-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 -------------------------------------------------*/