chiark / gitweb /
Debianization fixes.
[xtoys] / xmsg.c
1 /* -*-c-*-
2  *
3  * $Id: xmsg.c,v 1.1 2002/01/13 14:42:18 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 /*----- Revision history --------------------------------------------------* 
30  *
31  * $Log: xmsg.c,v $
32  * Revision 1.1  2002/01/13 14:42:18  mdw
33  * New program to display messages and get answers.
34  *
35  */
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #include <ctype.h>
40 #include <errno.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include <mLib/darray.h>
46 #include <mLib/dstr.h>
47 #include <mLib/mdwopt.h>
48 #include <mLib/quis.h>
49 #include <mLib/report.h>
50
51 #include <mgLib/msg.h>
52
53 /*----- Data structures ---------------------------------------------------*/
54
55 typedef struct button {
56   unsigned f;
57   const char *text;
58 } button;
59
60 #define f_cancel 1u
61 #define f_default 2u
62
63 DA_DECL(button_v, button);
64
65 /*----- Main code ---------------------------------------------------------*/
66
67 /* --- @version@ --- */
68
69 static void version(FILE *fp)
70 {
71   fprintf(fp, "%s (xtoys version " VERSION ")\n", QUIS);
72 }
73
74 /* --- @usage@ --- */
75
76 static void usage(FILE *fp)
77 {
78   fprintf(fp, "Usage: %s [-f] [-t TITLE] [-c|d BUTTON] MSG [BUTTON...]\n",
79           QUIS);
80 }
81
82 /* --- @findbutton@ --- */
83
84 static button *findbutton(button_v *bv, const char *tag)
85 {
86   size_t i, n = DA_LEN(bv);
87   button *b = DA(bv);
88   char *q;
89
90   if (!tag)
91     return (0);
92   for (i = 0; i < n; i++) {
93     if (strcmp(b[i].text, tag) == 0)
94       return (&b[i]);
95   }
96   while (*tag && isspace((unsigned char)*tag))
97     tag++;
98   i = strtoul(tag, &q, 0);
99   if (!*q && i < n)
100     return (&b[i]);
101   die(EXIT_FAILURE, "unknown button `%s'", tag);
102   return (0);
103 }
104    
105
106 /* --- @main@ --- *
107  *
108  * Main program.
109  */
110
111 int main(int argc, char *argv[])
112 {
113   const char *title;
114   const char *message;
115   const char *b_cancel = 0, *b_default = 0;
116   button_v bv = DA_INIT;
117   button *b;
118   dstr d = DSTR_INIT;
119   size_t n, i;
120   unsigned f = 0;
121
122 #define f_focus 256u
123
124   ego(argv[0]);
125   gtk_init(&argc, &argv);
126
127   /* --- Parse options --- */
128
129   title = QUIS;
130   for (;;) {
131     static struct option opt[] = {
132       { "help",         0,              0,      'h' },
133       { "usage",        0,              0,      'u' },
134       { "version",      0,              0,      'v' },
135       { "focus",        0,              0,      'f' },
136       { "title",        OPTF_ARGREQ,    0,      't' },
137       { "cancel",       OPTF_ARGREQ,    0,      'c' },
138       { "default",      OPTF_ARGREQ,    0,      'd' },
139       { 0,              0,              0,      0 }
140     };
141     int i;
142
143     i = getopt_long(argc, argv, "huv t:c:d:q", opt, 0);
144
145     if (i < 0)
146       break;
147
148     switch (i) {
149       case 'h':
150         version(stdout);
151         fputs("\n", stdout);
152         usage(stdout);
153         fputs(
154 "\n"
155 "Pops up a message box containing a message and some buttons, reporting\n"
156 "which button was selected.\n"
157 "\n"
158 "Options available are:\n"
159 "\n"
160 "-h, --help             Display this help text\n"
161 "-u, --usage            Display a short usage summary\n"
162 "-v, --version          Display the program's version number\n"
163 "\n"
164 "-f, --focus            Give the window the focus (obsolete mdw thing)\n"
165 "-t, --title=TITLE      Select the title string in the message box\n"
166 "-c, --cancel=BUTTON    Select which button is to have the Cancel action\n"
167 "-d, --default=BUTTON   Select which button is the default\n",
168           stdout);
169         exit(0);
170         break;
171       case 'u':
172         usage(stdout);
173         exit(0);
174         break;
175       case 'v':
176         version(stdout);
177         exit(0);
178         break;
179
180       case 'f':
181         f |= f_focus;
182         break;
183       case 't':
184         title = optarg;
185         break;
186       case 'c':
187         b_cancel = optarg;
188         break;
189       case 'd':
190         b_default = optarg;
191         break;
192
193       default:
194         usage(stderr);
195         exit(EXIT_FAILURE);
196     }
197   }
198
199   if (optind >= argc) {
200     usage(stderr);
201     exit(EXIT_FAILURE);
202   }
203   message = argv[optind++];
204
205   if (optind >= argc) {
206     DA_ENSURE(&bv, 1);
207     b = &DA(&bv)[0];
208     b->f = 0;
209     b->text = "OK";
210     DA_UNSAFE_EXTEND(&bv, 1);
211   } else for (; optind < argc; optind++) {
212     DA_ENSURE(&bv, 1);
213     b = &DA(&bv)[DA_LEN(&bv)];
214     b->f = 0;
215     b->text = argv[optind];
216     DA_UNSAFE_EXTEND(&bv, 1);    
217   }
218
219   if ((b = findbutton(&bv, b_cancel)) != 0)
220     b->f |= f_cancel;
221   else
222     DA(&bv)[DA_LEN(&bv) - 1].f |= f_cancel;
223
224   if ((b = findbutton(&bv, b_default)) != 0)
225     b->f |= f_default;
226   else
227     DA(&bv)[0].f |= f_default;
228
229   b = DA(&bv);
230   n = DA_LEN(&bv);
231   if (f & f_focus)
232     DPUTC(&d, '!');
233   for (i = 0; i < n; i++) {
234     if (b[i].f & f_default)
235       DPUTC(&d, ':');
236     if (b[i].f & f_cancel)
237       DPUTC(&d, '~');
238     DPUTS(&d, b[i].text);
239     DPUTC(&d, ',');
240   }
241   d.buf[--d.len] = 0;
242
243   i = msg(title, d.buf, "%s", message);
244   if (n > 1)
245     puts(b[i].text);
246   return (0);
247 }
248
249 /*----- That's all, folks -------------------------------------------------*/