2012-04-18 31 views
5

Tôi cố gắng để xử lý một tín hiệu thay đổi kích thước (SIGWINCH)Không thể xác định kích thước thiết bị đầu cuối với 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); 
} 

Khi tôi gỡ lỗi mã này, trong resizeSignalHandler var x, y là luôn luôn giống nhau (kích thước không thay đổi). Tôi cũng đã thử xác định kích thước với ioctl, nhưng không có gì thay đổi.

Tôi đã tìm ra rằng nhiều người trước tôi gặp vấn đề này http://www.mail-archive.com/[email protected]/msg11253.html Đôi khi, họ giải quyết (thay đổi/etc/profile; O (sic!)), Nhưng đôi khi không. Có cách nào thay thế cho mac os x terminal, có thể ncurses được dành riêng cho xterm và tương tự.

+0

Bạn có thể làm cho OSX hạn cư xử như xterm nên đó không phải là vấn đề. Bạn có thực sự thử nghiệm trong thiết bị đầu cuối hoặc trong thuật ngữ giả của XCode không? – Geoffroy

+0

Nó không thể được kiểm tra trong xcode. Trong terminal. – badeleux

Trả lời

-1

Tôi không có máy mac và không thể kiểm tra điều này. Nhưng tôi cho rằng bash terminal giả đang chạy trên các bản cập nhật $ LINES và $ COLUMNS nhưng các bản cập nhật này không được chuyển tới thiết bị đầu cuối giả mà chương trình của bạn được gán cho. Điều này là do bạn nói tín hiệu WINCH bị bắt, nhưng các thông số này không được cập nhật. Giải pháp thay thế là thực hiện "/usr/X11/bin/resize"/"/usr/bin/resize" trong trình xử lý tín hiệu. Có lẽ điều đó sẽ cập nhật đúng $ LINES và $ COLUMNS.

+0

thực sự nó hoạt động. Nhưng khi tôi cố gắng đọc các biến shell (bởi echo $ LINES) nó trả về các giá trị không chính xác (như ioctl, getmaxyx, vv), thankfully/usr/X11/bin/resize trả về trực tiếp thông tin chính xác - vì vậy tôi chỉ cần trấu thông tin cần thiết từ chuỗi . – badeleux

0

Tôi không chắc chắn, nhưng tôi nghĩ bạn phải gọi ioctl(1, TIOCGWINSZ, struct winsize*) để nhận thông số đầu cuối được cập nhật. Xem man tty_ioctl.

+0

như tôi đã nói, nó không hiệu quả với tôi. – badeleux

1

Đó là do các giá trị bạn nhận được với getmaxyx được tự động cập nhật bằng trình xử lý tín hiệu nghe SIGWINCH. Bạn cần phải lưu các con trỏ đến các tín hiệu cũ với một cái gì đó như:

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

và sau đó gọi nó trong resizeSignalHandler:

old_callback(a); 
1

getmaxyx(...) cho sai (không cập nhật) kích thước thiết bị đầu cuối vì tùy chỉnh handler SIGWINCH tín hiệu .

Bạn có thể sử dụng ioctl(fileno(stdout), TIOCGWINSZ, struct winsize*) để nhận thông số đầu cuối được cập nhật. Nhưng điều này sẽ không cập nhật dữ liệu được trả về bởi getmaxyt(...).

Để cập nhật getmaxyx(...) dữ liệu, bạn nên gọi resize_term(size.ws_row, size.ws_col)

Vì vậy, mã xử lý tín hiệu sẽ giống như thế:

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); 
} 
Các vấn đề liên quan