2012-04-18 13 views
5

próbuję obsłużyć sygnał zmiany rozmiaru (SIGWINCH)Nie można określić końcową wielkość z 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); 
} 

Kiedy debugowania tego kodu, w resizeSignalHandler var x, y były zawsze takie same (wielkość nie uległa zmianie). Próbowałem również określić rozmiar za pomocą ioctl, ale nic się nie zmieniło.

zorientowali się, że wiele osób przede mną miał ten problem http://www.mail-archive.com/[email protected]/msg11253.html Czasem rozwiązał ten (Zmiana/etc/profile; O (sic!)), Ale czasami nie. Czy istnieje alternatywa dla terminalu mac os x, może ncurses jest dedykowany dla xterm i podobnych.

+0

Można dokonać OSX termin zachowuje się jak xterm więc to nie jest problem. Czy naprawdę testujesz w terminalu lub w fałszywym terminie XCode? – Geoffroy

+0

Nie można go przetestować w xcode. W terminalu. – badeleux

Odpowiedz

-1

Nie mam komputera Mac, i nie mogę tego przetestować. Ale przypuszczam, że pseudo terminalowe działa na aktualizacjach $ LINES i $ COLUMNS, ale te aktualizacje nie są przekazywane do pseudo terminalu, do którego jest przypisany twój program. Dzieje się tak, ponieważ mówisz, że sygnał WINCH został złapany, ale te parametry nie zostały zaktualizowane. Obejście problemu polega na wykonaniu polecenia "/usr/X11/bin/resize"/"/usr/bin/resize" w procedurze obsługi sygnału. Prawdopodobnie to poprawnie zaktualizuje $ LINES i $ COLUMNS.

+0

tak naprawdę to działa. Ale kiedy próbuję odczytać zmienne powłoki (przez echo $ LINES), zwraca niepoprawne wartości (jak ioctl, getmaxyx itp.), Na szczęście/usr/X11/bin/resize bezpośrednio zwraca poprawne informacje - więc po prostu łuskę potrzebowałem informacji z łańcucha . – badeleux

0

Nie jestem pewien, ale myślę, że musisz zadzwonić pod numer ioctl(1, TIOCGWINSZ, struct winsize*), aby uzyskać zaktualizowane parametry terminala. Zobacz man tty_ioctl.

+0

jak powiedziałem, to nie działało dla mnie. – badeleux

1

To dlatego, że wartości, które otrzymujesz z getmaxyx, są aktualizowane samodzielnie przez program obsługi sygnału, który nasłuchuje na SIGWINCH. Trzeba zapisać wskaźnik do starego sygnału z czymś takim:

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

a następnie wywołać go w resizeSignalHandler:

old_callback(a); 
1

getmaxyx(...) daje niewłaściwy (nie aktualizowany) rozmiary zacisków z powodu niestandardowej obsługi SIGWINCH sygnału .

Możesz użyć ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*), aby uzyskać zaktualizowane parametry terminala. Ale to nie zaktualizuje danych zwróconych przez getmaxyt(...).

Aby zaktualizować getmaxyx(...) danych, należy zadzwonić resize_term(size.ws_row, size.ws_col)

więc sygnał kod obsługi powinna wyglądać następująco:

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); 
} 
Powiązane problemy