как на Си реализовать обработчик нажатия клавиш (как на Си реализовать обработчик нажатия клавиш)

Модератор: Модераторы разделов

v4567
Сообщения: 162
ОС: Devuan

как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Подскажите или натолкните на мысль, или на какой нибудь нормальный материал по данному вопросу.
Необходимо в виде линуксовой библиотеки написанной строго на Си (именно на Си не на Си++) реализовать обработчик нажатия клавиш. Что бы при помощи библиотеки можно было отловить нажатия некоторых клавиш.
За помощь заранее благодарен!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

В иксах или в консоли?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Запускается некоторая программа, которая написана не на Си и не на Си++ эта программа может вызывать библиотеки написанные на Си и использовать их.
Программа запускается в эмуляторе консоли - konsole она так же использует библиотеку ncurses.
Отвечая на Ваш вопрос - получается что в иксах.
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

В самой программе конечно можно реализовать ввод с клавиатуры, но он реализован не очень хорошо.
Есть функция которая при запуске ждёт ввода, при этом вся программа то же стоит и ждёт ввода.
Мне же нужно реализовать обработку прерываний от клавиатуры, потому что я не знаю в какой именно момент выполнения программы будет нажата какая нибудь клавиша. В самом языке нету функций для работы с прерываниями. Если интересно что за язык - язык интерпретируемый mumps - gt.m
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Не используя ncurses никак не получится?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

Получится, но будет значительно сложнее. Фактически надо будет сделать свою реализацию того же самого. Какой смысл?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Может можно при помощи системных вызовов ядра как то реализовать?

>> Получится, но будет значительно сложнее.

в двух словах хотя бы подскажите как

буду смотреть в сторону ncurses
Спасибо за помощь!
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Мне надо по сути делать обработку прерывания от клавиатуры.
То есть не так что программа остановилась и ждёт ввода. Насколько я понял getch работает именно так, или я ошибаюсь?
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Контактная информация:

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение eddy »

Да элементарно это делается: мой велосипед, например.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

v4567 писал(а):
15.07.2015 16:09
То есть не так что программа остановилась и ждёт ввода. Насколько я понял getch работает именно так, или я ошибаюсь?

(getch(3)) писал(а):

Код: Выделить всё

       The getch, wgetch, mvgetch and mvwgetch, routines  read  a
       character  from the window.  In no-delay mode, if no input
       is waiting, the value ERR is returned.  In delay mode, the
       program  waits until the system passes text through to the
       program.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение s.xbatob »

Вы свои требования высказали достаточно невразумительно. Но в любом случае это сложнее, чем кажется. Самое простое и близкое к тому, что вы написали - написать простое графическое приложение, в котором обрабатывать KeyPressEvent и KeyReleaseEvent. Если же вам нужно обрабатывать нажатие клавиши в "традиционном стиле" - как пришедший символ от терминала, то тут достаточно установить режим cbreak (что getch наверное и делает)
Но если вам надо одновременно ждать эти нажатия и делать что-либо ещё (или вообще делать несколько дел одновременно) - то это уже совсем другая задача. Тут надо либо разбиваться на потоки, либо организовывать свою задачу как управляемую событиями (а лучше - и то, и другое) Она не имеет прямого отношения ни к интерфейсу к системе, ни к языку программирования.
P.S. Ну и запускать в графической среде эмулятор символьного терминала, а в нём псевдографическое приложение - это извращение.
Спасибо сказали:
Аватара пользователя
yars
Сообщения: 1144
Статус: Slacker!
ОС: Slackware64-current

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение yars »

P.S. ...извращение

А мне что делать, если я в эмуляторе терминала запускаю консольный mc? Бежать на графический ФМ? Нафига? И что с того, что он псевдографический?
Slackware64-current/Xfce 4.12/Acer TravelMate 5760
-------------
Registered Linux User #557010
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение s.xbatob »

yars писал(а):
15.07.2015 18:54
P.S. ...извращение

А мне что делать, если я в эмуляторе терминала запускаю консольный mc? Бежать на графический ФМ? Нафига? И что с того, что он псевдографический?

Да, вы поняли всё правильно!
Спасибо сказали:
yoshakar
Сообщения: 259
ОС: Debian Stretch

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение yoshakar »

То есть, по-вашему, каждый раз при запуске псевдографического приложения надо обязательно переключаться в тру-консоль? Это хуже чем извращение, это просто идиотизм.
Или вообще не пользоваться псевдографическими приложениями? Иметь две программы - одна псевдографическая, полнофункциональная и удобная, с красивыйм и продуманным интерфейсом, и вторая - с урезанным функционалом, кривая, страшная и глючна - и пользоваться при этом именно последней - опять же идиотизм чистой воды.
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение s.xbatob »

Повторяю для непонятливых: запускать в графической среде эмулятор символьного терминала, а в нём псевдографическое приложение - это извращение.
И прошу не искажать и не фантазировать на эту тему.
И состояние и темпы развития многочисленных графических библиотек и когда-то не менее многочисленных, но давно вымерших, псевдографических - это подтверждает.

Только мы отвлеклись.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Контактная информация:

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение eddy »

s.xbatob писал(а):
16.07.2015 09:29
запускать в графической среде эмулятор символьного терминала, а в нём псевдографическое приложение - это извращение.

Говорить такое — вот истинное извращение!
Про mc пример был правильный. В линуксе нет (и, наверное, не будет — т.к. не надо, ведь есть mc!) ни одного хотя бы отдаленно напоминающего mc графического ФМ. Вот, скажем, у меня на работе на основном мониторе обычно geany с кодом открыт, а на дополнительном — xfce4-terminal с запущенным там mc. В geany код правлю, в mc по ФС навигацию осуществляю, а также запускаю make и т.п.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

iУведомление от модератора
Давайте не отвлекаться от темы, мы всё-таки в техническом разделе.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux
Контактная информация:

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение eddy »

Дык, по теме все уже сказали: select — чтобы узнать, не было ли активности; ~(ICANON | ECHO) — чтобы не было "эха".
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
sabir
Сообщения: 66
ОС: OpenBSD

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение sabir »

v4567 писал(а):
15.07.2015 15:43
Может можно при помощи системных вызовов ядра как то реализовать?

Код: Выделить всё

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <linux/input.h>

#define EV_PRESSED 1

int quit = 0;
int keyboard;

int init_keyboard()
{
    char *device = "/dev/input/event10";

    if((getuid()) != 0)
    {
        printf("You are not root! This may not work...\n");
        return -1;
    }

    if((keyboard = open(device, O_RDONLY)) == -1)
    {
        printf("%s is not a vaild device.\n", device);
        return -1;
    }

    return 0;
}

void * update_keyboard()
{
    struct input_event event;

    while(1)
    {
        read(keyboard, &event, sizeof(struct input_event));
        if(event.type == EV_KEY)
        {
            if(event.value == EV_PRESSED)
            {
                if(event.code == KEY_ESC) quit = 1;
            }
        }
    }
}

int main()
{
    if(init_keyboard() != 0) return -1;

    pthread_t thread;
    int id = 1;
    int result = 0;

    result = pthread_create(&thread, NULL, update_keyboard, &id);
    if(result != 0)
    {
        printf("Create thread failed\n");
        return -1;
    }

    while(!quit)
    {
        // тута выполняется страшно важная и полезная работа
    }

    return 0;
}

Обработчик клавиатуры запускается в отдельном процессе, не мешая работе основной программы. pthread_create - богомерзкая обертка над православным clone(), так же можно заюзать православный fork()
Код ожидает нажатия кнопки 'ESC', в качестве примера.
Работает только если есть права root или если поменять владельца "/dev/input/event10", где 'event10' клавиатура
Спасибо сказали:
yoshakar
Сообщения: 259
ОС: Debian Stretch

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение yoshakar »

sabir писал(а):
18.07.2015 14:06
Обработчик клавиатуры запускается в отдельном процессе
Таки всё-таки в отдельном треде, а не процессе. Вот если заюзать fork() - то будет в отдельном процессе. Кстати, задавшись вопросом, можно ли сделать по-номальному, без лишним тредов и процессов, можно на этом примере изучить тему "asynchronous I/O в Linux".
Спасибо сказали:
Аватара пользователя
sabir
Сообщения: 66
ОС: OpenBSD

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение sabir »

yoshakar писал(а):
18.07.2015 14:17
sabir писал(а):
18.07.2015 14:06
Обработчик клавиатуры запускается в отдельном процессе
Таки всё-таки в отдельном треде, а не процессе. Вот если заюзать fork() - то будет в отдельном процессе.

С чисто юридической точки зрения, таки да в отдельном треде/нити, ну а ежели по простому, по рабоче-крестьянски, то на этом форуме едва ли найдется пара-тройка людей, которые действительно понимают и смогут доходчиво объяснить другим, чем тред отличается от процесса, я имею ввиду на ядерном уровне, я например не понимаю.
yoshakar писал(а):
18.07.2015 14:17
Кстати, задавшись вопросом, можно ли сделать по-номальному, без лишним тредов и процессов, можно на этом примере изучить тему "asynchronous I/O в Linux"

Ну почему же нельзя, можно и в главном цикле обрабатывать, без clone() и fork() -ов всяких, но тогда теряется быстрая реакция на событие, т.е. если главный цикл большой и выполняется относительно долгое время или ожидает ввода/вывода, а реакция на нажатие кнопки нужна прямо сейчас, то форкнуть обработчик в отдельный процесс, на мой личный взгляд, совсем не лишнее. Впрочем, как и весь кодинг, все зависит от кодера и его убеждений.
Спасибо сказали:
yoshakar
Сообщения: 259
ОС: Debian Stretch

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение yoshakar »

sabir писал(а):
18.07.2015 14:36
чем тред отличается от процесса, я имею ввиду на ядерном уровне
Зачем же на ядерном? Можно и попроще для начала: у тредов память общая, а у процесов - нет. То есть чтобы передать данные из одного треда в другой (например, передать код нажатой клавши в цикл, делающий "страшно важную работу") достаточно объявить статическую переменную. А из процесса в процесс - придётся устраивать специальный канал общения. Есть и ещё разница, но это самое главное.

sabir писал(а):
18.07.2015 14:36
Ну почему же нельзя, можно и в главном цикле обрабатывать, без clone() и fork() -ов всяких, но тогда теряется быстрая реакция на событие
Да, и так можно, но я говорил именно об асинхронном вводе-выводе, то есть и без тредов/процессов и без задержек обработки.
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Всем огромное спасибо за помощь!!!
А особенно спасибо Bizdelnick и sabir !!

Да, и так можно, но я говорил именно об асинхронном вводе-выводе, то есть и без тредов/процессов и без задержек обработки.


Может получиться, но надо выискивать где в программе во время выполнения вставлять обработчик нажатия клавиш - но это не правильно. Может получиться так что клавиша будет нажата когда выполняется не обработчик нажатия клавиш и тогда получится так что программа не выполнит то что должна выполнить после нажатия определённой клавиши.

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

Подскажите пожалуйста ещё вот что.

Как программно реализовать (в linux) переключение в буквенно-цифровой (25x80) режим из графики и обратно, если сценарии инициализации системы — SysV init scripts, а в inittab прописан только один терминал, в котором грузится графика и по Ctrl+Alt+F* в другие терминалы не переключиться.

Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

v4567 писал(а):
19.07.2015 19:36
Кусок кода который должен обрабатывать прерывание от клавиатуры просто загрузился в озу и не выполняется, а выполняться начнёт когда сработает прерывание от клавиатуры.

Ну так Вы ж не в DOS'е вроде бы работаете. В нормальных системах прерывания обрабатывает ядро, а не прикладные программы.

v4567 писал(а):
19.07.2015 19:36
Как программно реализовать (в linux) переключение в буквенно-цифровой (25x80) режим из графики и обратно, если сценарии инициализации системы — SysV init scripts, а в inittab прописан только один терминал, в котором грузится графика и по Ctrl+Alt+F* в другие терминалы не переключиться.

Пропишите в inittab второй терминал. К. О.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
v4567
Сообщения: 162
ОС: Devuan

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение v4567 »

Ну так Вы ж не в DOS'е вроде бы работаете. В нормальных системах прерывания обрабатывает ядро, а не прикладные программы.


Да я и спрашивал (просто мне не хватило конкретики в вопросе) при помощи каких функций (ядра или сторонних библиотек) можно осуществить отлов нажатия клавиш. Уже разобрался, помогли.

Пропишите в inittab второй терминал. К. О.


В общем не получится прописать в inittab, необходимо осуществить это программно. Вопрос ещё вот в чём, если в ядре запрещены дополнительные терминалы и программно нужно переключаться не в дополнительный терминал, а переводить имеющийся в режим (25x80), а потом обратно.

Спасибо сказали:
Аватара пользователя
Stauffenberg
Сообщения: 2042
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Stauffenberg »

v4567 писал(а):
19.07.2015 19:36
Может получиться, но надо выискивать где в программе во время выполнения вставлять обработчик нажатия клавиш - но это не правильно. Может получиться так что клавиша будет нажата когда выполняется не обработчик нажатия клавиш и тогда получится так что программа не выполнит то что должна выполнить после нажатия определённой клавиши.

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


На С это реализуется еще проще.
man signal
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

Stauffenberg писал(а):
20.07.2015 17:42
man signal

Это-то тут причём?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Stauffenberg
Сообщения: 2042
Статус: ☮ PEACE ☮
ОС: открытая и свободная

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Stauffenberg »

Bizdelnick писал(а):
20.07.2015 18:48
Stauffenberg писал(а):
20.07.2015 17:42
man signal

Это-то тут причём?

Предлагаете мне рассказать Вам об устройстве драйвера терминала? О том, как в UNIX можно "обрабатывать нажатия клавиш" (таких, например, как Ctrl-C), и обрабатывать их по своему усмотрению?
Labor omnia vincit

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: как на Си реализовать обработчик нажатия клавиш

Сообщение Bizdelnick »

Stauffenberg писал(а):
20.07.2015 22:00
Таких, например, как Ctrl-C.

А ещё, например, каких?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Ответить