LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   nonblocking keyboard input? (https://www.linuxquestions.org/questions/programming-9/nonblocking-keyboard-input-150615/)

rebelcan 02-26-2004 12:07 AM

nonblocking keyboard input?
 
does anybody know how to do nonblocking keyboard input for a console?

i'm trying to create a loop, but i don't want it to stop and wait for keyboard input if there isn't any.

any clues?

chewysplace 02-26-2004 12:10 AM

create a loop in what language?

rebelcan 02-26-2004 12:10 AM

c++

chewysplace 02-26-2004 12:14 AM

so your trying to make a program that outputs to the console, but for what reason would it stop and wait for a keyrequest? needz more detailz on tha program. example code would be nice.

rebelcan 02-26-2004 12:21 AM

void moveU( int &x,int &y, int &w, int &h, int &vx, int &vy, int &ph, int &ps) {
char move = ' ';
do {
for (int a=0; a<1000; a++);
system("clear");
if ( move == 'k' && ps<(h-3) ) {
ps += 1;
} else if ( move == 'i' && ps>1) {
ps -= 1;
}

drawScreen(h,w,x,y,ph,ps);
cout << "ps is: " << ps << ", ph is: " << ph;
cout << ", x is: " << x << ", y is: " << y << ", ";
cout << "your last choice was: " << move << endl;
move = 'a';
cout << "x to quit, i to move up, k to move down: ";
cin >> move;
} while ( move != 'x' ) ;

}

i want this function to be able to loop but not wait for keyboard input

chewysplace 02-26-2004 12:31 AM

i copied your code and made a quick run of it and dont see any problem because you are requesting a key to be pressed right here "cin >> move". i didnt mess with drawScreen() since i dont have the code for it but from what i can tell it works fine.

your loop is your while(move != x) which is dependent on a key press.

rebelcan 02-26-2004 12:41 AM

is there any way to change the code so it loops even if the user doesn't enter anything? like if they press a key it will take note of it and act on it, but otherwise it will just keep looping?

chewysplace 02-26-2004 12:44 AM

actualy i'm looking into it right now. rather interesting i think :)
i'll post something when i've figured it out.

rebelcan 02-26-2004 12:44 AM

thanks for the help :D

infamous41md 02-26-2004 12:52 AM

the coolest thing to do is use SIGIO and signal driven i/o for stdin. it's quite simple with a couple calls to fcntl() to set the file owner and signal driven i/o flag and installation of a signal handler for SIGIO. you can go about and do w/e you want, and when the user hits the keyboard you'll run the signal handler and read from the keyboard. then you'll get returned back to where you were.

infamous41md 02-26-2004 12:56 AM

here i found this on my comp:
Code:

/*
 * asynctest.c: use async notification to read stdin
 *
 * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
 * Copyright (C) 2001 O'Reilly & Associates
 *
 * The source code in this file can be freely used, adapted,
 * and redistributed in source or binary form, so long as an
 * acknowledgment appears in derived source files.  The citation
 * should list that the code comes from the book "Linux Device
 * Drivers" by Alessandro Rubini and Jonathan Corbet, published
 * by O'Reilly & Associates.  No warranty is attached;
 * we cannot take responsibility for errors or fitness for use.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>

int gotdata=0;
void sighandler(int signo)
{
    if (signo==SIGIO)
        gotdata++;
    return;
}

char buffer[4096];

int main(int argc, char **argv)
{
    int count;
    struct sigaction action;

    memset(&action, 0, sizeof(action));
    action.sa_handler = sighandler;
    action.sa_flags = 0;

    sigaction(SIGIO, &action, NULL);

    fcntl(STDIN_FILENO, F_SETOWN, getpid());
    fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC);

    while(1) {
        /* this only returns if a signal arrives */
        sleep(86400); /* one day */
        if (!gotdata)
            continue;
        count=read(0, buffer, 4096);
        /* buggy: if avail data is more than 4kbytes... */
        write(1,buffer,count);
        gotdata=0;
    }
}


chewysplace 02-26-2004 01:26 AM

dang, thats a bit to go through. but much thanx! gona go through it in the morning. me sleepies.

Rebelcan, i'll check here in the morning to see if anybody has answered it or not, either way i'm still gona work on it.

biosx 02-26-2004 01:32 AM

Just another idea....

You could use fork() and have one process handle the input from the user and have the other process drawing on the screen (or whatever you want to do).

:study: read up on fork()

Hko 02-26-2004 07:51 AM

Set the terminal to non-canonical mode, and use select() with a (small) timeout to read from stdin.

Or, see:

http://www.linuxquestions.org/quest...p?postid=161647

chewysplace 02-26-2004 11:28 AM

Hko, the link you gave is dead. what did you type in for a search?


All times are GMT -5. The time now is 08:14 AM.