Ncurses and realtime (implemented in C, unix)

橙三吉。 提交于 2019-12-05 09:13:29

There are a couple of functions you could use:

  1. nodelay
  2. timeout

int nodelay(WINDOW *win, bool bf);

Set bf true to make getch() non-blocking

void timeout(int delay);

Delay is in milliseconds, so if you set it to 1000, the getch will timeout after a second.

In both cases getch will return ERR if there is no input.

The solution here is EITHER to use non-blocking IO or to use threads. However, using threads will give you a new problem, which is that only one thread can use curses at any given time, so you will need to use locks or some such to prevent the other thread(s) from using curses at that point in time. Of course, one solution for that is to have one thread responsible for updating the screen content, and other threads simply send messages to that thread with "I want to put on the screen at X, Y"

This is a very ugly hack which supports just a single stdio function: fgetc(). Others could be added, btw. It works by setting a timer, an if the alarm goes off before a single character is read, a -2 value is returned instead (remember : -1 means EOF)

It won't work with any of the other curses's wgetXXX(), functions, which may call fgetc() (etc) directly. YMMV.

But, in the general case, I think you should investigate wgetch_events().

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>

sigjmp_buf the_jump;

int my_fgetc(FILE *fp, unsigned timeout);
void sig_handler(int signr);

void sig_handler(int signr) {
        switch (signr) {
        case SIGALRM:
              siglongjmp(the_jump,1);
              break;
        default:
              break;
        }
}

int my_fgetc(FILE *fp, unsigned timeout)
{
alarm( timeout);

switch (sigsetjmp(the_jump, -1)) {
case 0:
        alarm(0);
        return fgetc (fp);
case 1:
        return -2;
default:
        return -3;
        }
}

int main()
{
int rc;
signal(SIGALRM, sig_handler);

rc = setvbuf(stdin, NULL, _IONBF, 0);
printf("setvbuf(_IONBF) = %d\n", rc);
while (1) {
        rc = my_fgetc(stdin, 1);
        printf("my_fgetc(NULL) = %d\n", rc);
        }

return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!