OS/2, eCS & ArcaOS - Technical > Programming

getting a single keypress?

(1/2) > >>

Dave Yeo:
Trying to fix the terminal control in mpg123 so things like pause work.
Example program which works on other systems but not on OS/2, at that sometimes hangs the system.
Ideas to get this to work?

--- Code: ---
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>

int term_fd = -1;

int get_key(int do_delay, char *val)
{
fd_set r;
struct timeval t;
t.tv_sec=0;
t.tv_usec=(do_delay) ? 1000 : 0;
FD_ZERO(&r);
FD_SET(term_fd,&r);
int n = select(term_fd+1,&r,NULL,NULL,&t);
if(n > 0 && FD_ISSET(term_fd,&r) && read(term_fd,val,1) == 1)
return 1;
return 0;
}


int main(int argc, char **argv)
{
if(argc >= 2)
term_fd = open("/dev/tty", O_RDONLY);
else
term_fd = STDIN_FILENO;
if(term_fd < 0)
{
perror("failure opening terminal input");
return 1;
}
fprintf(stderr, "terminal fd: %d\n", term_fd);

struct termios old_tio;
int termsetup = 0;
if(!tcgetattr(term_fd, &old_tio))
{
fprintf(stderr, "proper terminal setup\n");
struct termios tio = old_tio;
tio.c_lflag &= ~(ICANON|ECHO);
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
tcsetattr(term_fd,TCSANOW,&tio);
termsetup = 1;
}

char val = 0;
while(val != 'q')
{
if(get_key(1, &val))
fprintf(stderr, "got key: %c\n", val);
}

if(termsetup)
tcsetattr(term_fd,TCSAFLUSH,&old_tio);
if(term_fd > 0)
close(term_fd);
return 0;
}


--- End code ---

Pete:
Hi Dave

Not really a "c" coder myself but this does not look right

int get_key(int do_delay, char *val)
{
.
.
.
   int n = select(term_fd+1,&r,NULL,NULL,&t);
   if(n > 0 && FD_ISSET(term_fd,&r) && read(term_fd,val,1) == 1)
      return 1;
   return 0;
}


I would expect an If/Else statement:-

   if(n > 0 && FD_ISSET(term_fd,&r) && read(term_fd,val,1) == 1)
      return 1
           else
           return 0;
}


As I said I am not a "c" coder...


Regards

Pete


Dave Yeo:
Yea, I'm not a C coder either. This is the code we ended up with, modded to also show the hex value,

--- Code: ---#define INCL_KBD
#define INCL_DOSPROCESS
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>

int term_fd = -1;

int get_key(int do_delay, char *val)
{
KBDKEYINFO key;
key.chChar = 0;
key.chScan = 0;
// optionally: sleep for a tiny bit
        DosSleep(5);
if(!KbdCharIn(&key,IO_NOWAIT,0) && key.chChar)
{
*val = key.chChar;
return 1;
}
return 0;
}


int main(int argc, char **argv)
{
if(argc >= 2)
term_fd = open("CON:", O_RDONLY);
else
term_fd = STDIN_FILENO;
if(term_fd < 0)
{
perror("failure opening terminal input");
return 1;
}
fprintf(stderr, "terminal fd: %d\n", term_fd);

struct termios old_tio;
int termsetup = 0;
if(!tcgetattr(term_fd, &old_tio))
{
fprintf(stderr, "proper terminal setup\n");
struct termios tio = old_tio;
tio.c_lflag &= ~(ICANON|ECHO);
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
tcsetattr(term_fd,TCSANOW,&tio);
termsetup = 1;
}

char val = 0;
while(val != 'q')
{
if(get_key(1, &val))
fprintf(stderr, "got key: %c %x\n", val, val);
}

if(termsetup)
tcsetattr(term_fd,TCSAFLUSH,&old_tio);
if(term_fd > 0)
close(term_fd);
return 0;
}

--- End code ---
Only problem is that it gets a scan code first, which is ignored. Executable attached.
[/code]

Lars:
And why can't you use the standard RTL function "getchar"? Is that not available?

Dave Yeo:
It didn't seem to work while a program was running.

Navigation

[0] Message Index

[#] Next page

Go to full version