xref: /freebsd/contrib/dialog/dialog.pl (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
1# Functions that handle calling dialog(1) -*-perl-*-
2# $Id: dialog.pl,v 1.4 2001/10/13 00:40:22 tom Exp $
3
4# Return values are 1 for success and 0 for failure (or cancel)
5# Resultant text (if any) is in dialog_result
6
7# Unfortunately, the gauge requires use of /bin/sh to get going.
8# I didn't bother to make the others shell-free, although it
9# would be simple to do.
10
11# Note that dialog generally returns 0 for success, so I invert the
12# sense of the return code for more readable boolean expressions.
13
14$scr_lines = 24;
15
16require "flush.pl";
17
18sub rhs_clear {
19    return system("dialog --clear");
20}
21
22sub rhs_textbox {
23    local ( $title, $file, $width, $height ) = @_;
24
25    system("dialog --title \"$title\" --textbox $file $height $width");
26
27    return 1;
28}
29
30sub rhs_msgbox {
31    local ( $title, $message, $width ) = @_;
32    local ( $tmp, $height, $message_len );
33
34    $message = &rhs_wordwrap($message, $width);
35    $message_len = split(/^/, $message);
36    $tmp = $message;
37    if (chop($tmp) eq "\n") {
38	$message_len++;
39    }
40    $height = 4 + $message_len;
41
42    $tmp = system("dialog --title \"$title\" --msgbox \"$message\" $height $width");
43    if ($tmp) {
44	return 0;
45    } else {
46	return 1;
47    }
48}
49
50sub rhs_infobox {
51    local ( $title, $message, $width ) = @_;
52    local ( $tmp, $height, $message_len );
53
54    $message = &rhs_wordwrap($message, $width);
55    $message_len = split(/^/, $message);
56    $tmp = $message;
57    if (chop($tmp) eq "\n") {
58	$message_len++;
59    }
60    $height = 2 + $message_len;
61
62    return system("dialog --title \"$title\" --infobox \"$message\" $height $width");
63}
64
65sub rhs_yesno {
66    local ( $title, $message, $width ) = @_;
67    local ( $tmp, $height, $message_len );
68
69    $message = &rhs_wordwrap($message, $width);
70    $message_len = split(/^/, $message);
71    $tmp = $message;
72    if (chop($tmp) eq "\n") {
73	$message_len++;
74    }
75    $height = 4 + $message_len;
76
77    $tmp = system("dialog --title \"$title\" --yesno \"$message\" $height $width");
78    # Dumb: dialog returns 0 for "yes" and 1 for "no"
79    if (! $tmp) {
80	return 1;
81    } else {
82	return 0;
83    }
84}
85
86sub rhs_gauge {
87    local ( $title, $message, $width, $percent ) = @_;
88    local ( $tmp, $height, $message_len );
89
90    $gauge_width = $width;
91
92    $message = &rhs_wordwrap($message, $width);
93    $message_len = split(/^/, $message);
94    $tmp = $message;
95    if (chop($tmp) eq "\n") {
96	$message_len++;
97    }
98    $height = 5 + $message_len;
99
100    open(GAUGE, "|dialog --title \"$title\" --gauge \"$message\" $height $width $percent");
101}
102
103sub rhs_update_gauge {
104    local ( $percent ) = @_;
105
106    &printflush(GAUGE, "$percent\n");
107}
108
109sub rhs_update_gauge_and_message {
110    local ( $message, $percent ) = @_;
111
112    $message = &rhs_wordwrap($message, $gauge_width);
113    $message =~ s/\n/\\n/g;
114    &printflush(GAUGE, "XXX\n$percent\n$message\nXXX\n");
115}
116
117sub rhs_stop_gauge {
118    close GAUGE;
119}
120
121sub rhs_inputbox {
122    local ( $title, $message, $width, $instr ) = @_;
123    local ( $tmp, $height, $message_len );
124
125    $message = &rhs_wordwrap($message, $width);
126    $message_len = split(/^/, $message);
127    $tmp = $message;
128    if (chop($tmp) eq "\n") {
129	$message_len++;
130    }
131    $height = 7 + $message_len;
132
133    return &return_output(0, "dialog --title \"$title\" --inputbox \"$message\" $height $width \"$instr\"");
134}
135
136sub rhs_menu {
137    local ( $title, $message, $width, $numitems ) = @_;
138    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
139
140    shift; shift; shift; shift;
141
142    @list = ();
143    for ($i = 0; $i < $numitems; $i++) {
144        $ent = shift;
145        $list[@list] = "\"$ent\"";
146	$ent = shift;
147        $list[@list] = "\"$ent\"";
148    }
149
150    $message = &rhs_wordwrap($message, $width);
151
152    $message_len = split(/^/, $message);
153    $tmp = $message;
154    if (chop($tmp) eq "\n") {
155	$message_len++;
156    }
157
158    $height = $message_len + 6 + $numitems;
159    if ($height <= $scr_lines) {
160        $menuheight = $numitems;
161    } else {
162        $height = $scr_lines;
163        $menuheight = $scr_lines - $message_len - 6;
164    }
165
166    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
167}
168
169sub rhs_menul {
170    local ( $title, $message, $width, $numitems ) = @_;
171    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
172
173    shift; shift; shift; shift;
174
175    @list = ();
176    for ($i = 0; $i < $numitems; $i++) {
177        $ent = shift;
178        $list[@list] = "\"$ent\"";
179        $list[@list] = "\"\"";
180    }
181
182    $message = &rhs_wordwrap($message, $width);
183
184    $message_len = split(/^/, $message);
185    $tmp = $message;
186    if (chop($tmp) eq "\n") {
187	$message_len++;
188    }
189
190    $height = $message_len + 6 + $numitems;
191    if ($height <= $scr_lines) {
192        $menuheight = $numitems;
193    } else {
194        $height = $scr_lines;
195        $menuheight = $scr_lines - $message_len - 6;
196    }
197
198    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
199}
200
201sub rhs_menua {
202    local ( $title, $message, $width, %items ) = @_;
203    local ( $tmp, $ent, $height, $menuheight, @list, $message_len );
204
205    @list = ();
206    foreach $ent (sort keys (%items)) {
207        $list[@list] = "\"$ent\"";
208        $list[@list] = "\"$items{$ent}\"";
209    }
210
211    $message = &rhs_wordwrap($message, $width);
212
213    $message_len = split(/^/, $message);
214    $tmp = $message;
215    if (chop($tmp) eq "\n") {
216	$message_len++;
217    }
218
219    $numitems = keys(%items);
220    $height = $message_len + 6 + $numitems;
221    if ($height <= $scr_lines) {
222        $menuheight = $numitems;
223    } else {
224        $height = $scr_lines;
225        $menuheight = $scr_lines - $message_len - 6;
226    }
227
228    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
229}
230
231sub rhs_checklist {
232    local ( $title, $message, $width, $numitems ) = @_;
233    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
234
235    shift; shift; shift; shift;
236
237    @list = ();
238    for ($i = 0; $i < $numitems; $i++) {
239        $ent = shift;
240        $list[@list] = "\"$ent\"";
241        $ent = shift;
242        $list[@list] = "\"$ent\"";
243        $ent = shift;
244	if ($ent) {
245	    $list[@list] = "ON";
246	} else {
247	    $list[@list] = "OFF";
248	}
249    }
250
251    $message = &rhs_wordwrap($message, $width);
252
253    $message_len = split(/^/, $message);
254    $tmp = $message;
255    if (chop($tmp) eq "\n") {
256	$message_len++;
257    }
258
259    $height = $message_len + 6 + $numitems;
260    if ($height <= $scr_lines) {
261        $menuheight = $numitems;
262    } else {
263        $height = $scr_lines;
264        $menuheight = $scr_lines - $message_len - 6;
265    }
266
267    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
268}
269
270sub rhs_checklistl {
271    local ( $title, $message, $width, $numitems ) = @_;
272    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
273
274    shift; shift; shift; shift;
275
276    @list = ();
277    for ($i = 0; $i < $numitems; $i++) {
278        $ent = shift;
279        $list[@list] = "\"$ent\"";
280        $list[@list] = "\"\"";
281	$list[@list] = "OFF";
282    }
283
284    $message = &rhs_wordwrap($message, $width);
285
286    $message_len = split(/^/, $message);
287    $tmp = $message;
288    if (chop($tmp) eq "\n") {
289	$message_len++;
290    }
291
292    $height = $message_len + 6 + $numitems;
293    if ($height <= $scr_lines) {
294        $menuheight = $numitems;
295    } else {
296        $height = $scr_lines;
297        $menuheight = $scr_lines - $message_len - 6;
298    }
299    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
300}
301
302sub rhs_checklista {
303    local ( $title, $message, $width, %items ) = @_;
304    local ( $tmp, $ent, $height, $menuheight, @list, $message_len );
305
306    shift; shift; shift; shift;
307
308    @list = ();
309    foreach $ent (sort keys (%items)) {
310	$list[@list] = "\"$ent\"";
311	$list[@list] = "\"$items{$ent}\"";
312	$list[@list] = "OFF";
313    }
314
315    $message = &rhs_wordwrap($message, $width);
316
317    $message_len = split(/^/, $message);
318    $tmp = $message;
319    if (chop($tmp) eq "\n") {
320	$message_len++;
321    }
322
323    $numitems = keys(%items);
324    $height = $message_len + 6 + $numitems;
325    if ($height <= $scr_lines) {
326        $menuheight = $numitems;
327    } else {
328        $height = $scr_lines;
329        $menuheight = $scr_lines - $message_len - 6;
330    }
331
332    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
333}
334
335sub rhs_radiolist {
336    local ( $title, $message, $width, $numitems ) = @_;
337    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
338
339    shift; shift; shift; shift;
340
341    @list = ();
342    for ($i = 0; $i < $numitems; $i++) {
343        $ent = shift;
344        $list[@list] = "\"$ent\"";
345        $ent = shift;
346        $list[@list] = "\"$ent\"";
347        $ent = shift;
348	if ($ent) {
349	    $list[@list] = "ON";
350	} else {
351	    $list[@list] = "OFF";
352	}
353    }
354
355    $message = &rhs_wordwrap($message, $width);
356
357    $message_len = split(/^/, $message);
358    $tmp = $message;
359    if (chop($tmp) eq "\n") {
360	$message_len++;
361    }
362
363    $height = $message_len + 6 + $numitems;
364    if ($height <= $scr_lines) {
365        $menuheight = $numitems;
366    } else {
367        $height = $scr_lines;
368        $menuheight = $scr_lines - $message_len - 6;
369    }
370
371    return &return_output(0 , "dialog --title \"$title\" --radiolist \"$message\" $height $width $menuheight @list");
372}
373
374sub return_output {
375    local ( $listp, $command ) = @_;
376    local ( $res ) = 1;
377
378    pipe(PARENT_READER, CHILD_WRITER);
379    # We have to fork (as opposed to using "system") so that the parent
380    # process can read from the pipe to avoid deadlock.
381    my ($pid) = fork;
382    if ($pid == 0) {	# child
383	close(PARENT_READER);
384	open(STDERR, ">&CHILD_WRITER");
385	exec($command);
386	die("no exec");
387    }
388    if ($pid > 0) {	# parent
389	close( CHILD_WRITER );
390    	if ($listp) {
391	    @dialog_result = ();
392	    while (<PARENT_READER>) {
393		chop;
394		$dialog_result[@dialog_result] = $_;
395	    }
396	}
397	else { $dialog_result = <PARENT_READER>; }
398	close(PARENT_READER);
399	waitpid($pid,0);
400	$res = $?;
401    }
402
403    # Again, dialog returns results backwards
404    if (! $res) {
405	return 1;
406    } else {
407	return 0;
408    }
409}
410
411sub rhs_wordwrap {
412    local ( $intext, $width ) = @_;
413    local ( $outtext, $i, $j, @lines, $wrap, @words, $pos, $pad );
414
415    $outtext = "";
416    $pad = 3;			# leave 3 spaces around each line
417    $pos = $pad;		# current insert position
418    $wrap = 0;			# 1 if we have been auto wraping
419    $insert_nl = 0;		# 1 if we just did an absolute
420				# and we should preface any new text
421				# with a new line
422    @lines = split(/\n/, $intext);
423    for ($i = 0; $i <= $#lines; $i++) {
424        if ($lines[$i] =~ /^>/) {
425	    $outtext .= "\n" if ($insert_nl);
426            $outtext .= "\n" if ($wrap);
427	    $lines[$i] =~ /^>(.*)$/;
428            $outtext .= $1;
429	    $insert_nl = 1;
430            $wrap = 0;
431            $pos = $pad;
432        } else {
433            $wrap = 1;
434            @words = split(/\s+/,$lines[$i]);
435            for ($j = 0; $j <= $#words; $j++) {
436		if ($insert_nl) {
437		    $outtext .= "\n";
438		    $insert_nl = 0;
439		}
440                if ((length($words[$j]) + $pos) > $width - $pad) {
441                    $outtext .= "\n";
442                    $pos = $pad;
443                }
444                $outtext .= $words[$j] . " ";
445                $pos += length($words[$j]) + 1;
446            }
447        }
448    }
449
450    return $outtext;
451}
452
453############
4541;
455