URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4229
[ Назад ]

Исходное сообщение
"Нужна прога для кодов клавиш"

Отправлено Pred , 04-Май-05 15:19 
Если кто знает может приведет текст проги чтобы узнать код клавиши при ее нажатии (очень надо, а я сам в Си плохо разбираюсь).
прога нужна под UnixWare (просто у меня есть одна но там используются библиотеки которых нет в UW, помойму она под Linux)
Заранее благодарен!

Содержание

Сообщения в этом обсуждении
"Нужна прога для кодов клавиш"
Отправлено dimus , 06-Май-05 08:00 
А что Вы понимаете под кодом клавиши?

"Нужна прога для кодов клавиш"
Отправлено Predator , 06-Май-05 09:07 
>А что Вы понимаете под кодом клавиши?


Нужен код образующийся при нажатии клавиши для использования в Си программе. Существующая программа использует коды которые работают под терминалами, которые я уже давно не использую. Надо узнать новый код чтобы прописать в проге.


"Нужна прога для кодов клавиш"
Отправлено MaximKuznetsov , 06-Май-05 11:33 
а /etc/termcap в UnixWare есть ?



"Нужна прога для кодов клавиш"
Отправлено Predator , 13-Май-05 09:24 
>а /etc/termcap в UnixWare есть ?


Есть и termcap и terminfo (все есть?)


"Нужна прога для кодов клавиш"
Отправлено MaximKuznetsov , 13-Май-05 09:54 
>>а /etc/termcap в UnixWare есть ?
>
>
>Есть и termcap и terminfo (все есть?)
терминалы в raw mode посылают не просто коды клавиш, а esc последовательности,которые прописанны в termcap; то есть покапавшись с termcap можно однозначно четко узнать что ожидается от терминала.

можно пойти другим путём
- найти (скорее всего установленна в системе)- готовую программу вывода кодов/esc-последовательностей. К сожалению очень давно подобным пользовался, не помню названия.
- вырезать кусок инициализации терминала из своеё программы, приделать к нему цикл - чтение кодов, вывод цифирь; полученные цифири подставить в исходную программу. Если программа использует curses, то скорее всего инициализация более чем типична - её можно просто из man`а взять.
- и наконец самый правильный путь - найти в сети или самому сделать по полученным данным termcap своего терминала и добавить в систему, не переделывая программу. Не забыть правильно указать переменную TERM.
есть вероятность что описалово нового терминала и так уже есть, просто Вы не поменяли эту переменную и всё работает с ним как со старым.



"Нужна прога для кодов клавиш"
Отправлено Alexander S. Salieff , 13-Май-05 15:48 
>Если кто знает может приведет текст проги чтобы узнать код клавиши при
>ее нажатии (очень надо, а я сам в Си плохо разбираюсь).
>
>прога нужна под UnixWare (просто у меня есть одна но там используются
>библиотеки которых нет в UW, помойму она под Linux)
>Заранее благодарен!

Короче, я в свое время возился с этим, правда под Linux, раскорячил и кастрировал стандартную showkey, вот такая вещь вышла - пашет тока в голом терминале (без Хсов, MC и прочего), что и понятно - raw_mode всетаки, показывает сканы, идущие с клавы:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/keyboard.h>

int fd;
int oldkbmode;
struct termios old;

static void clean_up(void)
{
if (ioctl(fd, KDSKBMODE, oldkbmode))
  {
  perror("KDSKBMODE");
  exit(1);
  }
if (tcsetattr(fd, 0, &old) == -1) perror("tcsetattr");
close(fd);
}

static void die(int x)
{
printf("caught signal %d, cleaning up...\n", x);
clean_up();
exit(1);
}

static void watch_dog(int x)
{
clean_up();
exit(0);
}

inline void set_signal_handlers(void)
{
/*
if we receive a signal, we want to exit nicely, in
order not to leave the keyboard in an unusable mode
*/
signal(SIGHUP, die);
signal(SIGINT, die);
signal(SIGQUIT, die);
signal(SIGILL, die);
signal(SIGTRAP, die);
signal(SIGABRT, die);
signal(SIGIOT, die);
signal(SIGFPE, die);
signal(SIGKILL, die);
signal(SIGUSR1, die);
signal(SIGSEGV, die);
signal(SIGUSR2, die);
signal(SIGPIPE, die);
signal(SIGTERM, die);
#ifdef SIGSTKFLT
signal(SIGSTKFLT, die);
#endif
signal(SIGCHLD, die);
signal(SIGCONT, die);
signal(SIGSTOP, die);
signal(SIGTSTP, die);
signal(SIGTTIN, die);
signal(SIGTTOU, die);
}

#define CONSOLE_DEV "/dev/console"

int main (int argc, char **argv)
{
struct termios new_con_mode;
unsigned char buf[18]; /* divisible by 3 */
int i, n;
char con_arg;

/*
fd=open(CONSOLE_DEV, O_RDWR);
if (fd<0)
  {
  perror("Cannot open "CONSOLE_DEV);
  exit(1);
  }
*/

for (fd=0; fd<3; ++fd)
  {
  con_arg=0;
  if (ioctl(fd, KDGKBTYPE, &con_arg)==0 && (con_arg==KB_101 || con_arg==KB_84)) goto lab_cons_ok;
/*
  if (ioctl(fd, KDGKBTYPE, &con_arg)!=0 || (con_arg!=KB_101 && con_arg!=KB_84))
   {
   fprintf(stderr, CONSOLE_DEV" Is not a console!!!\n");
   exit(1);
   }
*/
  }
fprintf(stderr, "Valid console not found!!!\n");
exit(1);

lab_cons_ok:
printf("Working with FD=%d\n", fd);

/* the program terminates when there is no input for 10 secs */
signal(SIGALRM, watch_dog);
set_signal_handlers();

if (ioctl(fd, KDGKBMODE, &oldkbmode))
  {
  perror("KDGKBMODE");
  exit(1);
  }

if (tcgetattr(fd, &old)==-1)
  {
  perror("tcgetattr");
  exit(1);
  }

if (tcgetattr(fd, &new_con_mode)==-1)
  {
  perror("tcgetattr");
  exit(1);
  }

new_con_mode.c_lflag &= ~ (ICANON | ECHO | ISIG);
new_con_mode.c_iflag = 0;
new_con_mode.c_cc[VMIN] = sizeof(buf);
new_con_mode.c_cc[VTIME] = 1;  /* 0.1 sec intercharacter timeout */

if (tcsetattr(fd, TCSAFLUSH, &new_con_mode)==-1) perror("tcsetattr");
if (ioctl(fd, KDSKBMODE, K_RAW))
  {
  perror("KDSKBMODE");
  exit(1);
  }

printf("press any key (program terminates 10s after last keypress)...\n");
while(1)
  {
  alarm(10);
  n=read(fd, buf, sizeof(buf));
  for (i=0; i<n; i++) printf("0x%02x ", buf[i]);
  printf("\n");
  }
clean_up();
exit(0);
}