使用设置了timeout()的getch()时的重绘延迟

时间:2014-08-07 11:28:13

标签: c timeout ncurses getch

我有ncurses程序,我需要对用户输入和术语大小调整进行即时响应,并在重绘之间延迟1秒。

  • 使用sleep(1)我在启动时立即重绘并调整术语大小,但用户输入延迟1秒。
  • 使用timeout(1 * 1000)getch()我可以获得输入的即时响应,但启动时重新延迟1秒并调整大小。

以下是演示此问题的示例程序:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ncurses.h>

static sig_atomic_t resize;

void sighandler(int sig) {
    if (sig == SIGWINCH)
        resize = 1;
}

int main(int argc, char *argv[]) {
    double delay = 1.0;
    char key = ERR;
    WINDOW *testwin;

    if (argc > 1)
        delay = strtod(argv[1], NULL);

    signal(SIGWINCH, sighandler);
    initscr();
    timeout(delay * 1000);
    testwin = newwin(LINES, COLS, 0, 0);

    while (key != 'q') {
        if (key != ERR)
            resize = 1;

        if (resize) {
            endwin();
            refresh();
            clear();

            werase(testwin);
            wresize(testwin, LINES, COLS);
            resize = 0;
        }

        box(testwin, 0, 0);
        wnoutrefresh(testwin);
        doupdate();

        key = getch();
    }

    delwin(testwin);
    endwin();
    return EXIT_SUCCESS;
}

2 个答案:

答案 0 :(得分:3)

我正在考虑select和/或线程:一个线程可以监控调整大小,而另一个线程可以等待用户输入。

您可以使用select来同步线程,它可以等待多个文件描述符:例如,当您检测到唤醒主进程的事件时,您可以在管道上写入。很酷的是,即使没有发生任何事件,你也可以设置一个超时唤醒(然后你可以暂停一秒钟来触发重绘)。

答案 1 :(得分:0)

我设法通过删除clear();

来解决调整大小延迟
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ncurses.h>

static sig_atomic_t resize;

void sighandler(int sig) {
    if (sig == SIGWINCH)
        resize = 1;
}

int main(int argc, char *argv[]) {
    double delay = 1.0;
    char key = ERR;
    WINDOW *testwin;

    if (argc > 1)
        delay = strtod(argv[1], NULL);

    signal(SIGWINCH, sighandler);
    initscr();
    timeout(delay * 1000);
    testwin = newwin(LINES, COLS, 0, 0);

    while (key != 'q') {
        key = getch();

        if (key != ERR)
            resize = 1;

        if (resize) {
            endwin();
            refresh();

            werase(testwin);
            wresize(testwin, LINES, COLS);
            resize = 0;
        }

        box(testwin, 0, 0);
        wnoutrefresh(testwin);
        doupdate();
    }

    delwin(testwin);
    endwin();
    return EXIT_SUCCESS;
}