chiark / gitweb /
Expunge revision histories in files.
[xtoys] / xmsg.c
1 /* -*-c-*-
2  *
3  * $Id: xmsg.c,v 1.2 2004/04/08 01:36:29 mdw Exp $
4  *
5  * Display a message to the user
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of the Edgeware X tools collection.
13  *
14  * X tools is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * X tools is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with X tools; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Header files ------------------------------------------------------*/
30
31 #include <ctype.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include <mLib/darray.h>
38 #include <mLib/dstr.h>
39 #include <mLib/mdwopt.h>
40 #include <mLib/quis.h>
41 #include <mLib/report.h>
42
43 #include <mgLib/msg.h>
44
45 /*----- Data structures ---------------------------------------------------*/
46
47 typedef struct button {
48   unsigned f;
49   const char *text;
50 } button;
51
52 #define f_cancel 1u
53 #define f_default 2u
54
55 DA_DECL(button_v, button);
56
57 /*----- Main code ---------------------------------------------------------*/
58
59 /* --- @version@ --- */
60
61 static void version(FILE *fp)
62 {
63   fprintf(fp, "%s (xtoys version " VERSION ")\n", QUIS);
64 }
65
66 /* --- @usage@ --- */
67
68 static void usage(FILE *fp)
69 {
70   fprintf(fp, "Usage: %s [-f] [-t TITLE] [-c|d BUTTON] MSG [BUTTON...]\n",
71           QUIS);
72 }
73
74 /* --- @findbutton@ --- */
75
76 static button *findbutton(button_v *bv, const char *tag)
77 {
78   size_t i, n = DA_LEN(bv);
79   button *b = DA(bv);
80   char *q;
81
82   if (!tag)
83     return (0);
84   for (i = 0; i < n; i++) {
85     if (strcmp(b[i].text, tag) == 0)
86       return (&b[i]);
87   }
88   while (*tag && isspace((unsigned char)*tag))
89     tag++;
90   i = strtoul(tag, &q, 0);
91   if (!*q && i < n)
92     return (&b[i]);
93   die(EXIT_FAILURE, "unknown button `%s'", tag);
94   return (0);
95 }
96    
97
98 /* --- @main@ --- *
99  *
100  * Main program.
101  */
102
103 int main(int argc, char *argv[])
104 {
105   const char *title;
106   const char *message;
107   const char *b_cancel = 0, *b_default = 0;
108   button_v bv = DA_INIT;
109   button *b;
110   dstr d = DSTR_INIT;
111   size_t n, i;
112   unsigned f = 0;
113
114 #define f_focus 256u
115
116   ego(argv[0]);
117   gtk_init(&argc, &argv);
118
119   /* --- Parse options --- */
120
121   title = QUIS;
122   for (;;) {
123     static struct option opt[] = {
124       { "help",         0,              0,      'h' },
125       { "usage",        0,              0,      'u' },
126       { "version",      0,              0,      'v' },
127       { "focus",        0,              0,      'f' },
128       { "title",        OPTF_ARGREQ,    0,      't' },
129       { "cancel",       OPTF_ARGREQ,    0,      'c' },
130       { "default",      OPTF_ARGREQ,    0,      'd' },
131       { 0,              0,              0,      0 }
132     };
133     int i;
134
135     i = getopt_long(argc, argv, "huv t:c:d:q", opt, 0);
136
137     if (i < 0)
138       break;
139
140     switch (i) {
141       case 'h':
142         version(stdout);
143         fputs("\n", stdout);
144         usage(stdout);
145         fputs(
146 "\n"
147 "Pops up a message box containing a message and some buttons, reporting\n"
148 "which button was selected.\n"
149 "\n"
150 "Options available are:\n"
151 "\n"
152 "-h, --help             Display this help text\n"
153 "-u, --usage            Display a short usage summary\n"
154 "-v, --version          Display the program's version number\n"
155 "\n"
156 "-f, --focus            Give the window the focus (obsolete mdw thing)\n"
157 "-t, --title=TITLE      Select the title string in the message box\n"
158 "-c, --cancel=BUTTON    Select which button is to have the Cancel action\n"
159 "-d, --default=BUTTON   Select which button is the default\n",
160           stdout);
161         exit(0);
162         break;
163       case 'u':
164         usage(stdout);
165         exit(0);
166         break;
167       case 'v':
168         version(stdout);
169         exit(0);
170         break;
171
172       case 'f':
173         f |= f_focus;
174         break;
175       case 't':
176         title = optarg;
177         break;
178       case 'c':
179         b_cancel = optarg;
180         break;
181       case 'd':
182         b_default = optarg;
183         break;
184
185       default:
186         usage(stderr);
187         exit(EXIT_FAILURE);
188     }
189   }
190
191   if (optind >= argc) {
192     usage(stderr);
193     exit(EXIT_FAILURE);
194   }
195   message = argv[optind++];
196
197   if (optind >= argc) {
198     DA_ENSURE(&bv, 1);
199     b = &DA(&bv)[0];
200     b->f = 0;
201     b->text = "OK";
202     DA_UNSAFE_EXTEND(&bv, 1);
203   } else for (; optind < argc; optind++) {
204     DA_ENSURE(&bv, 1);
205     b = &DA(&bv)[DA_LEN(&bv)];
206     b->f = 0;
207     b->text = argv[optind];
208     DA_UNSAFE_EXTEND(&bv, 1);    
209   }
210
211   if ((b = findbutton(&bv, b_cancel)) != 0)
212     b->f |= f_cancel;
213   else
214     DA(&bv)[DA_LEN(&bv) - 1].f |= f_cancel;
215
216   if ((b = findbutton(&bv, b_default)) != 0)
217     b->f |= f_default;
218   else
219     DA(&bv)[0].f |= f_default;
220
221   b = DA(&bv);
222   n = DA_LEN(&bv);
223   if (f & f_focus)
224     DPUTC(&d, '!');
225   for (i = 0; i < n; i++) {
226     if (b[i].f & f_default)
227       DPUTC(&d, ':');
228     if (b[i].f & f_cancel)
229       DPUTC(&d, '~');
230     DPUTS(&d, b[i].text);
231     DPUTC(&d, ',');
232   }
233   d.buf[--d.len] = 0;
234
235   i = msg(title, d.buf, "%s", message);
236   if (n > 1)
237     puts(b[i].text);
238   return (0);
239 }
240
241 /*----- That's all, folks -------------------------------------------------*/