3 * $Id: xcatch.c,v 1.2 1998/12/16 00:10:58 mdw Exp $
5 * Catch input and trap it in an X window
7 * (c) 1998 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the Edgeware X tools collection.
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.
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.
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.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.2 1998/12/16 00:10:58 mdw
33 * Fix tabbing in help text.
35 * Revision 1.1 1998/12/15 23:46:50 mdw
36 * New program: captures input and puts it in a window.
40 /*----- Header files ------------------------------------------------------*/
48 #include <sys/types.h>
56 #include <mLib/dstr.h>
57 #include <mLib/mdwopt.h>
58 #include <mLib/report.h>
59 #include <mLib/quis.h>
61 #include <mgLib/cancel.h>
62 #include <mgLib/msg.h>
64 /*----- Inportant state ---------------------------------------------------*/
66 static unsigned int flags
;
73 GtkWidget
*textbox
= 0;
76 /*----- Main code ---------------------------------------------------------*/
78 /* --- The window's closed --- */
80 static void killwin(GtkWidget
*w
, gpointer p
)
88 /* --- Some input has arrived --- */
90 static void ready(gpointer data
, gint fd
, GdkInputCondition c
)
95 /* --- Read the next buffer of data --- */
97 if (!(c
& GDK_INPUT_READ
))
99 count
= read(fd
, buf
, sizeof(buf
));
101 /* --- Decide what to do --- */
104 msg(":~OK", "error reading data: %s", strerror(errno
));
117 /* --- If there's no output window, create one --- */
124 win
= gtk_dialog_new();
125 gtk_signal_connect(GTK_OBJECT(win
), "destroy",
126 GTK_SIGNAL_FUNC(killwin
), 0);
128 t
= gtk_table_new(2, 2, 0);
129 gtk_container_border_width(GTK_CONTAINER(t
), 8);
130 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(win
)->vbox
), t
, 1, 1, 0);
133 textbox
= gtk_text_new(0, 0);
134 gtk_table_attach(GTK_TABLE(t
), textbox
, 0, 1, 0, 1,
135 GTK_EXPAND
| GTK_SHRINK
| GTK_FILL
,
136 GTK_EXPAND
| GTK_SHRINK
| GTK_FILL
,
138 gtk_text_set_editable(GTK_TEXT(textbox
), 0);
139 gtk_widget_set_usize(textbox
, 500, 100);
140 gtk_widget_show(textbox
);
142 w
= gtk_vscrollbar_new(GTK_TEXT(textbox
)->vadj
);
143 gtk_table_attach(GTK_TABLE(t
), w
, 1, 2, 0, 1,
144 0, GTK_EXPAND
| GTK_SHRINK
| GTK_FILL
, 0, 0);
147 w
= gtk_hscrollbar_new(GTK_TEXT(textbox
)->hadj
);
148 gtk_table_attach(GTK_TABLE(t
), w
, 0, 1, 1, 2,
149 GTK_EXPAND
| GTK_SHRINK
| GTK_FILL
, 0, 0, 0);
152 gtk_box_set_homogeneous(GTK_BOX(GTK_DIALOG(win
)->action_area
), 0);
153 w
= gtk_button_new_with_label("Dismiss");
154 gtk_signal_connect_object(GTK_OBJECT(w
), "clicked",
155 GTK_SIGNAL_FUNC(gtk_object_destroy
),
157 gtk_box_pack_end(GTK_BOX(GTK_DIALOG(win
)->action_area
), w
, 0, 0, 0);
158 GTK_WIDGET_SET_FLAGS(w
, GTK_CAN_DEFAULT
);
159 gtk_widget_grab_default(w
);
160 cancel(GTK_WINDOW(win
), w
);
163 gtk_widget_show(win
);
166 /* --- Append the new text --- */
168 gtk_text_insert(GTK_TEXT(textbox
), font
, 0, 0, buf
, count
);
171 /* --- Signal handler --- */
173 static void reap(int sig
)
175 while (waitpid(-1, 0, WNOHANG
) > 0)
179 /* --- Main program --- */
181 static void version(FILE *fp
)
183 fprintf(fp
, "%s (xtoys version " VERSION
")\n", QUIS
);
186 static void usage(FILE *fp
)
188 fprintf(fp
, "Usage: %s [-f file] [-F font] [command [args...]]\n", QUIS
);
191 int main(int argc
, char *argv
[])
197 gtk_init(&argc
, &argv
);
200 static struct option opt
[] = {
201 { "help", 0, 0, 'h' },
202 { "usage", 0, 0, 'u' },
203 { "version", 0, 0, 'v' },
204 { "file", gFlag_argReq
, 0, 'f' },
205 { "font", gFlag_argReq
, 0, 'F' },
208 int i
= mdwopt(argc
, argv
, "huvf:F:", opt
, 0, 0, 0);
220 "Catches input from a pipe or other source, and captures it in a window.\n"
221 "Nothing is displayed if there's no input.\n"
223 "Options provided:\n"
225 "-h, --help Display this help text\n"
226 "-u, --usage Display a quick usage summary\n"
227 "-v, --version Display the version number\n"
228 "-f, --file=FILE\t Read input from the named file\n"
229 "-F, --font=FONT\t Display output in the named font\n",
242 if ((fd
= open(optarg
, O_RDONLY
)) < 0) {
243 die(1, "couldn't open file: %s", strerror(errno
));
248 font
= gdk_font_load(optarg
);
256 if (flags
& f_bogus
) {
269 /* --- Set up a signal handler --- */
271 sa
.sa_handler
= reap
;
272 sigemptyset(&sa
.sa_mask
);
274 sigaction(SIGCHLD
, &sa
, 0);
276 /* --- Start a child program --- */
279 die(1, "couldn't open pipe: %s", strerror(errno
));
282 die(1, "couldn't fork: %s", strerror(errno
));
287 if (pfd
[1] != STDOUT_FILENO
)
288 dup2(pfd
[1], STDOUT_FILENO
);
289 if (pfd
[1] != STDERR_FILENO
)
290 dup2(pfd
[1], STDERR_FILENO
);
291 if (pfd
[1] != STDOUT_FILENO
&& pfd
[1] != STDERR_FILENO
)
293 execvp(argv
[optind
], argv
+ optind
);
296 dstr_putf(&d
, "%s: couldn't run `%s': %s\n",
297 QUIS
, argv
[optind
], strerror(errno
));
298 write(STDERR_FILENO
, d
.buf
, d
.len
);
306 gdk_input_add(fd
, GDK_INPUT_READ
, ready
, 0);
311 /*----- That's all, folks -------------------------------------------------*/