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