Question on reading Keyboard input

Hi,

I’m porting an old DOS based app to QNX 6.3.

In this app there is code to read keyboard input from a user in a realtime that goes something like this:

while (1)
{
    if (keyPress())   // Look for a keyboard press
    {
        key = getKeyPress();   // Get the keystroke
        break;
    }
    delay(50);
}

So the code basically loops forever checking for a keyboard press from the user every 50 ms.

Can this be done under from a QNX console somehow? I scanned the help files but I only seem to see code under photon that can do something similar to the above code.

TIA,

Tim

Hello,

I think the devi-* drivers can be started with -rP on the text console, and then a path /dev/devi/keyboard0, /dev/devi/mouse0 appears, from which you can read(). The structures are defined in dcmd_hid.h or io-hid.h or something. I would definitly get the Input Driver DDK since this contains source code for several input drivers that should help.

In a separate thread you would then use select() to wait for input, rather than polling.

Best regards,
Albrecht

Albrecht,

OK. I did as you suggested.

Without photon running I started io-hid as follows:

io-hid &

Then I started devi-hid as follows:

devi-hid -rP kbd

At this point I get a /dev/devi/keyboard0

So I quickly did a ‘cat /dev/devi/keyboard0’ and typed some characters on my keyboard. I expected them to be outputting from cat similar to when I do a ‘cat /dev/ser1’ and when I move my serial mouse I see stuff outputted.

So either using ‘cat’ doesn’t work in that way with /dev/devi/keyboard0 or something else is wrong.

Note that whatever keyboard driver starts when the system launches in console mode is still running because I launch io-hid by hand. Could this be interfering with io-hid and devi-hid getting the keyboard input?

I was expecting my code could do something as simple as spawning off a thread that did something like:

char buffer[255];
fd = open ("/dev/devi/keyboard0", O_RDONLY);

while (1)
{
    read(fd, buffer, sizeof(buffer));
    // parse the keystroke and do with it what I want
}

Will this not work since read does a blocking wait for keystrokes to arrive (I do this with reading from my serial ports and it works very nicely)

If what I want to do is not this simple I will re-write that part of the code that waits for input to simply do a scanf() on keyboard input. Much more clumsy but will work if that code is also spun off into it’s own thread.

TIA,

Tim

Hello,

I think you have to provide an input driver for io-hid, either USB (for USB Keyboards) or PS2. I tried io-hid -dusb and then the cat command worked fine with a USB keyboard. Similarly it should work with the PS2 input driver for io-hid but I never tried.

Best regards,
Albrecht

Hello,Tim
Using termios can meet you require well ,The following code may be helpful for you.

#include <termios.h>
#include <unistd.h> // for read()
#include <time.h>

static struct termios initial_settings, new_settings;
static int peek_character = -1;

void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}

void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}

int kbhit()
{
unsigned char ch;
int nread;

if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1) 
{
peek_character = ch;
return 1;
}
return 0;
}

int readch()
{
char ch;

if(peek_character != -1) 
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}


int main()
{

   init_keyboard();
   while(1)
    {

        if(kbhit()==1)//
         {
              char temp=getch();//get input code
               swith(temp)
                  .....
         }
    }
   close_keyborad();

}

Liuxs,

Thanks for the coding example.

That’s exacty what I was looking for!

Tim

how do photon do it? in raphic mode
how do photon read scancode of keyboard

You would want a widget to collect the key press raw events. The structures sent to the callback should have all the information you need.

Do photon use read(/dev/kbd/,…)?
how do kb up , down left, right in terminal?

There are special keyboard sequences you get from down, left, and right. The same is true for function keys.

These sequences not 1 byte
how do photon read scancode?

Please read above. This was already answered.

i read source code of photon and saw function _readxv()
i found this function and i saw that this function return msgsendv(…
from where do it reading?

Excellent response!!! some typos, but basically worked. here is my code as it worked on a QNX system:

[code]/*

  • keyboard_test.c
  • Created on: Nov 5, 2012
  •  Author: jleslie
    

*/

#include <termios.h>
#include <unistd.h> // for read()
#include <time.h>

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

static struct termios initial_settings, new_settings;
static int peek_character = -1;

void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}

void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}

int kbhit()
{
unsigned char ch;
int nread;

if (peek_character != -1) return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}

int readch()
{
char ch;

if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}


int main()
{

int notdone = 1;

   printf("keyboard test.  type a q to quit\n");
   init_keyboard();
   while(notdone)
    {

        if(kbhit()==1)//
         {
              char temp=getchar();//get input code
               printf("the character hit was:%c:(%i)\n",temp,temp);
               switch (temp){
                   case 'q':
                   case 'Q':
                         notdone = 0;
         	             break;

                  default:;

               }//switch
         }//then
    }//while
   close_keyboard();
   exit(0);

}

[/code]