HaWe
24.05.2016, 09:48
moin,
bisher hat folgende Lib gut mit dem alten Jessie funktioniert, um einen Tastendruck auf der Tastatur zu registrieren, aber ohne drauf zu warten und ohne die Taste auszulesen - grob analog zu kbhit() aus der Windows Lib <conio.h>-
mit der neuen Jessie Version seit 2016-05-10 geht die selbstgestrickte kbhit() Funktion aber ins Leere.
Bei Aufruf im 2. Beispiel, um z.B. auf die ESC Taste hin das Programm zu beenden (s.u.) paasiert jetzt nichts mehr, früher hingegen wurde daraufhin korrekt der Thread und auch das komplette Programm beendet:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <termio.h>
#include <unistd.h>
#include <linux/input.h>
#include <termios.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/select.h>
// keyboard dev
int fkbd;
char * kbdin = "/dev/input/event0";
struct input_event ev[64];
//************************************************** ***********
// "conio.h"
//************************************************** ***********
bool kbhit(void)
{
struct termios original;
tcgetattr(STDIN_FILENO, &original);
struct termios term;
memcpy(&term, &original, sizeof(term));
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
int characters_buffered = 0;
ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);
tcsetattr(STDIN_FILENO, TCSANOW, &original);
bool pressed = (characters_buffered != 0);
return pressed;
}
void echoOff(void)
{
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
void echoOn(void)
{
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag |= ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
int setupKbdin() {
if ((fkbd = open (kbdin, O_RDONLY)) == -1){
printf ("Fehler mit Tastatur");
return -1;
}
else return 0;
}
// SNIP***
//************************************************** ***********
void* thread1Go(void *) // medium priority: keyboard + heartbeat monitoring
{
int c; // keyboard key
while(_TASKS_ACTIVE_) {
c=0;
if (kbhit()) {
c = getchar(); // ESC to quit program
if( c==27 ) {
printf("\n\n ESC pressed - program terminated by user \n");
_TASKS_ACTIVE_=0; // semaphore to stop all tasks
printf("\n wait for tasks to join main()... \n\n");
return NULL;
}
}
}
return NULL;
}
//SNIP ***
Da die per Hand programmierte Funktion mit termios.h also wohl nicht mehr kompatibel ist, meine Fragen:
1.) wer kennt sich mit den termios Details aus und weiß, wie man den Code updaten kann, damit kbhit() wieder funktioniert?
oder
2.) wer weiß, wie man auf andere Weise (z.B., falls notwendig, auch per ncurses) so eine Funktion kbhit() nutzen kann?
bisher hat folgende Lib gut mit dem alten Jessie funktioniert, um einen Tastendruck auf der Tastatur zu registrieren, aber ohne drauf zu warten und ohne die Taste auszulesen - grob analog zu kbhit() aus der Windows Lib <conio.h>-
mit der neuen Jessie Version seit 2016-05-10 geht die selbstgestrickte kbhit() Funktion aber ins Leere.
Bei Aufruf im 2. Beispiel, um z.B. auf die ESC Taste hin das Programm zu beenden (s.u.) paasiert jetzt nichts mehr, früher hingegen wurde daraufhin korrekt der Thread und auch das komplette Programm beendet:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <termio.h>
#include <unistd.h>
#include <linux/input.h>
#include <termios.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/select.h>
// keyboard dev
int fkbd;
char * kbdin = "/dev/input/event0";
struct input_event ev[64];
//************************************************** ***********
// "conio.h"
//************************************************** ***********
bool kbhit(void)
{
struct termios original;
tcgetattr(STDIN_FILENO, &original);
struct termios term;
memcpy(&term, &original, sizeof(term));
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
int characters_buffered = 0;
ioctl(STDIN_FILENO, FIONREAD, &characters_buffered);
tcsetattr(STDIN_FILENO, TCSANOW, &original);
bool pressed = (characters_buffered != 0);
return pressed;
}
void echoOff(void)
{
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
void echoOn(void)
{
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag |= ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
int setupKbdin() {
if ((fkbd = open (kbdin, O_RDONLY)) == -1){
printf ("Fehler mit Tastatur");
return -1;
}
else return 0;
}
// SNIP***
//************************************************** ***********
void* thread1Go(void *) // medium priority: keyboard + heartbeat monitoring
{
int c; // keyboard key
while(_TASKS_ACTIVE_) {
c=0;
if (kbhit()) {
c = getchar(); // ESC to quit program
if( c==27 ) {
printf("\n\n ESC pressed - program terminated by user \n");
_TASKS_ACTIVE_=0; // semaphore to stop all tasks
printf("\n wait for tasks to join main()... \n\n");
return NULL;
}
}
}
return NULL;
}
//SNIP ***
Da die per Hand programmierte Funktion mit termios.h also wohl nicht mehr kompatibel ist, meine Fragen:
1.) wer kennt sich mit den termios Details aus und weiß, wie man den Code updaten kann, damit kbhit() wieder funktioniert?
oder
2.) wer weiß, wie man auf andere Weise (z.B., falls notwendig, auch per ncurses) so eine Funktion kbhit() nutzen kann?