2012-04-18 15 views
5

Sto cercando di gestire un segnale di ridimensionamento (SIGWINCH)Impossibile determinare la dimensione del terminale 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); 
} 

Quando mi è stato debug di questo codice, in resizeSignalHandler var x, y erano sempre gli stessi (dimensione non è cambiata). Ho anche provato a determinare la dimensione con ioctl, ma non è cambiato nulla.

ho capito che molte persone prima di me avevano questo problema http://www.mail-archive.com/[email protected]/msg11253.html A volte, hanno risolto che (modificando/etc/profile; O (sic)!), Ma a volte non. C'è qualche alternativa a mac os x terminal, forse ncurses è dedicato a xterm e simili.

+0

È possibile effettuare termine OSX si comporta come xterm in modo che non è questo il problema. Stai davvero provando nel terminale o nel finto termine di XCode? – Geoffroy

+0

Non può essere testato in xcode. Nel terminale. – badeleux

risposta

-1

Non ho una macchina mac e non posso testarlo. Ma suppongo che lo pseudo terminal bash sia in esecuzione sugli aggiornamenti $ LINES e $ COLUMNS ma questi aggiornamenti non vengono passati allo pseudo terminale a cui è assegnato il programma. Questo perché dici che il segnale WINCH viene catturato, ma quei parametri non vengono aggiornati. Una soluzione alternativa è eseguire "/usr/X11/bin/resize"/"/usr/bin/resize" nel gestore di segnale. Probabilmente aggiornerebbe correttamente $ LINES e $ COLUMNS.

+0

effettivamente funziona. Ma quando sto cercando di leggere le variabili di shell (da echo $ LINES) restituisce valori errati (come ioctl, getmaxyx ecc.), Per fortuna/usr/X11/bin/ridimensiona restituisce direttamente le informazioni corrette - quindi ho semplicemente bisogno di informazioni dalla stringa . – badeleux

0

Non sono sicuro, ma penso che sia necessario chiamare ioctl(1, TIOCGWINSZ, struct winsize*) per ottenere i parametri del terminale aggiornati. Vedi man tty_ioctl.

+0

come ho detto, non ha funzionato per me. – badeleux

1

Questo perché i valori ottenuti con getmaxyx vengono aggiornati autonomamente da un gestore di segnale che ascolta SIGWINCH. È necessario salvare il puntatore al vecchio segnale con qualcosa di simile:

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

e quindi chiamare in resizeSignalHandler:

old_callback(a); 
1

getmaxyx(...) dà sbagliato (non aggiornato) dimensioni dei terminali a causa della consuetudine gestore SIGWINCH segnale .

È possibile utilizzare ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*) per ottenere i parametri del terminale aggiornati. Ma questo non aggiornerà i dati restituiti da getmaxyt(...).

per aggiornare i dati getmaxyx(...), si dovrebbe chiamare resize_term(size.ws_row, size.ws_col)

Così il codice di gestore di segnale dovrebbe essere simile:

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); 
} 
Problemi correlati