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