views:

42

answers:

2

My perl program needs to jump between ncurses and a raw console as it executes a system call in a loop, like this (simplified for problem emphasis):

  1. init Cdk
  2. present menu
  3. deinit Cdk
  4. run system call

Unfortunately Cdk appears to initialize ncurses at the use Cdk import and not instantiation (Cdk::init()) and so I don't know how to disable it. This behavior seems completely absurd to me; apart from the loop described above, my program also has a special mode where a database is initialized - this part does not present any kind of menu (only raw console output) yet it would seem that I now have to format all my output with menus - whilst not even using a menu! And again, just to print the program help output now seems to require me to generate a Cdk widget - insane.

Is there a way to easily jump in and out of ncurses when using Cdk or am I screwed?

Some example code:

#!/usr/bin/perl

use Cdk;

eval {popupLabel(["popup before init"]);}; # will fail as init() isn't called
print "Test after use\n";                  # won't be printed (which is a problem!)
Cdk::init();
print "Test after init\n";                 # won't be printed
popupLabel(["popup after init"]);
Cdk::end();
print "Test after end\n";                  # won't be printed
A: 

The following (which uses the newer Curses module) seems to do what you want: bits of Curses, and bits of non-Curses intermingled:

use strict;
use warnings;
use Curses;

# Non-Curses
print "Press a key...\n";
<STDIN>;

# Curses
initscr();
addstr(14, 0, "hit a key: ");
refresh();
my $ch = getch();
endwin();

# Non-Curses
print "Hi again, press a key...\n";
<STDIN>;

# Curses again
initscr();
addstr(14, 0, "hit another key: ");
refresh();
my $ch2 = getch();
endwin();

# Non-Curses
print "bye!\n";

At least this module was released this January and not (like Cdk, released 1998) last century...

mfontani
Sure I can use Curses on its own; however this does not give me the menu widget I'd like. I'm trying fiercely to get Curses::UI::Listbox (Curses::UI has a simple way of exiting curses with the leave_curses method) to function with callbacks, but it keeps terminating as soon as the callback accesses a list element. perldebug isn't providing much insight in cbreak-mode either..
gamen
I would suggest you open another question related to that, and show the exact code that is giving you that problem!
mfontani
I would, except that I solved it and posted it here as an answer to my original question. I don't know if that's the right behavior here on SO :/ perhaps I should change the title of my question so as to clarify what was done.
gamen
A: 

Well, I got what I wanted, scrapping Cdk for Curses::UI. Thanks mfontani for posting an answer!

Here's my example solution which uses Curses::UI and Curses::UI::Listbox:

#!/usr/bin/perl

use Curses::UI;
use Curses::UI::Listbox;

my $cui = Curses::UI->new(-color_support => 1,
              -clear_on_exit => 0);

my $win = $cui->add('window_id', 'Window');

sub user_select {
    my ($cui, $obj) = @_;

    my $item = $obj->get_active_value();

    $cui->leave_curses();

    print "You selected $item!\n";
    sleep(1);
}

my $listbox = $win->add(
            'mylistbox', 'Listbox',
            -onchange    => sub{ user_select($cui, @_) },
            -border      => 1,
            -values      => [1, 2, 3],
            -labels      => { 1 => 'One', 
                      2 => 'Two', 
                      3 => 'Three' },
    );
$listbox->focus();
$cui->mainloop;
gamen