2012-04-18 10 views
5

Estoy tratando de manejar una señal de cambio de tamaño (SIGWINCH)No se puede determinar el tamaño del terminal con ncurses

void Server::resizeSignalHandler(int a) 
{ 
signal(SIGWINCH, SIG_IGN); 

endwin(); 
initscr(); 
refresh(); 
clear(); 

int x,y; 
getmaxyx(stdscr, y, x); 

wmove(upScreen, 0, 0); 
wmove(downScreen, y/2, 0); 
wresize(upScreen, y/2, x); 
wresize(downScreen, y/2, x); 
wclear(upScreen); 
wclear(downScreen); 
waddstr(upScreen, "test1"); 
waddstr(downScreen, "test2"); 
wrefresh(upScreen); 
wrefresh(downScreen); 
refresh(); 

signal(SIGWINCH, Server::resizeSignalHandler); 

} 
Server::Server() 
{ 
//ncurses screen initialization 
initscr(); 

if (!upScreen) { 
    upScreen = newwin(0, 0, 1, 1); 
} 
if (!downScreen) { 
    downScreen = newwin(0, 0, 1, 1); 
} 
//adjusting screen when user resize terminal 
signal(SIGWINCH, Server::resizeSignalHandler); 

//configuring screens 
Server::resizeSignalHandler(0); 

waddstr(Server::upScreen, "lalfasdfsafd as"); 
waddstr(downScreen, "supreme!"); 
wrefresh(Server::upScreen); 
wrefresh(downScreen); 
} 

Cuando estaba depurando el código, en resizeSignalHandler var x, y siempre eran los mismos (tamaño no cambió) También probé determinar el tamaño con ioctl, pero nada ha cambiado.

me di cuenta de que muchas personas antes que yo tenía este problema http://www.mail-archive.com/[email protected]/msg11253.html A veces, ellos resolvieron que (cambiar/etc/profile; O (sic)!), Pero a veces no. ¿Existe alguna alternativa al terminal mac os x, tal vez ncurses está dedicado para xterm y similar.

+0

Puede hacer OSX término se comporta como xterm de manera que no es el problema. ¿Estás realmente probando en la terminal o en el término falso de XCode? – Geoffroy

+0

No se puede probar en xcode. En la terminal. – badeleux

Respuesta

-1

No tengo una máquina mac, y no puedo probar esto. Pero supongo que la pseudo terminal bash se ejecuta en las actualizaciones $ LINES y $ COLUMNS, pero estas actualizaciones no se pasan al pseudo-terminal al que está asignado su programa. Esto se debe a que dice que la señal WINCH está atrapada, pero esos params no están actualizados. Una solución alternativa es ejecutar "/usr/X11/bin/resize"/"/usr/bin/resize" en el controlador de señal. Probablemente eso actualizaría correctamente $ LINES y $ COLUMNS.

+0

realmente funciona. Pero cuando trato de leer variables de shell (por echo $ LINES) devuelve valores incorrectos (como ioctl, getmaxyx etc.), afortunadamente/usr/X11/bin/resize devuelve directamente la información correcta, así que simplemente cáscara la información necesaria de la cadena . – badeleux

0

No estoy seguro, pero creo que debe llamar al ioctl(1, TIOCGWINSZ, struct winsize*) para obtener los parámetros de terminal actualizados. Ver man tty_ioctl.

+0

como dije, no funcionó para mí. – badeleux

1

Eso es porque los valores que obtienes con getmaxyx se actualizan ellos mismos por un manejador de señal que escucha SIGWINCH. Tendrá que guardar el puntero a la señal de edad con algo como:

old_callback = signal(SIGWINCH, Server::resizeSignalHandler); 

y luego llamarlo en resizeSignalHandler:

old_callback(a); 
1

getmaxyx(...) da mal (no actualizada) tamaños de los terminales debido a la costumbre manejador SIGWINCH señal .

Puede usar ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*) para obtener los parámetros de terminal actualizados. Pero esto no actualizará los datos devueltos por getmaxyt(...).

Para actualizar los datos getmaxyx(...), debe llamar resize_term(size.ws_row, size.ws_col)

Así que el código manejador de la señal debe ser similar:

void on_terminal_resize(int n) { 
    struct winsize size; 

    if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { 
     resize_term(size.ws_row, size.ws_col); 
    } 
    // Your code goes here... 
    signal(SIGWINCH, on_terminal_resize); 
} 
Cuestiones relacionadas