перехват нажатия клавиш

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

v4567v
Интересующийся
Сообщения: 3
Зарегистрирован: 23 ноя 2016, 00:02
Контактная информация:

перехват нажатия клавиш

Непрочитанное сообщение v4567v » 23 ноя 2016, 00:28

Здравствуйте, форумчане.
Подскажите пожалуйста как перехватывать нажатия клавиш?
Есть программа которая запускается и работает в буквенно-графическом режиме 80x25, так же она может запускаться и работать в графическом эмуляторе терминала, например в konsole.
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
Ещё нужно работать с сигналами. Например при нажатии на Ctrl+z останавливать выполнение программы. Потом при по команде bg переводить её работу в фон, по команде fg - на передний план.
Интересует именно как перехватывать нажатие клавиш и работа с сигналами без использования библиотеки ncurses. Именно без ncurses!!!
Нужна реальная информация, что бы с её помощью можно было это реализовать программно.
Если информации очень много, то тогда дайте ссылки в интернете этой информации, только желательно (очень!) на русском языке.
Сам я искал в интернете, но конкретики так и не нашёл, или вода или не то, (может не так искал).
За помощь заранее благодарен!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение Olej » 23 ноя 2016, 02:33

v4567v писал(а): Подскажите пожалуйста как перехватывать нажатия клавиш?
Есть программа которая запускается и работает в буквенно-графическом режиме 80x25, так же она может запускаться и работать в графическом эмуляторе терминала, например в konsole.
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
То, что вы называете "есть программа" - это сильно неопределённо...
Вы её собираетесь писать, или она у вас есть уже готовая и к ней нужны какие-то доделки?
Если писать, то на чём (язык, библиотеки) вы её собираетесь писать?
Я надеюсь (меня смущает ваше "буквенно-графическом режиме 80x25") что программу вы собираетесь делать в операционной системе Linux (которой только и посвящён этот форум)?
И т.д. ...
Нужна реальная информация, что бы с её помощью можно было это реализовать программно.
Если информации очень много, то тогда дайте ссылки в интернете этой информации, только желательно (очень!) на русском языке.
Посмотрите сюда: Разработка программных проектов в Linux.
А если у вас возникнут проблемы по реализации - обращайтесь сюда: обсудим и поможем. ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение Olej » 23 ноя 2016, 11:22

v4567v писал(а): Подскажите пожалуйста как перехватывать нажатия клавиш?
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
Не совсем понятно что вы хотите, но я предполагаю, что:
- то что вы называете "перехватывать" - это неканонический режим ввода терминала, по той ссылке, что я давал выше, это глава "Терминал, режим ввода: канонический и неканонический", стр. 280
- а по реакции на сигналы там целый раздел "Сигналы UNIX", стр. 262.
И на всё это приведены готовые фрагменты кода.

v4567v
Интересующийся
Сообщения: 3
Зарегистрирован: 23 ноя 2016, 00:02
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение v4567v » 24 ноя 2016, 21:03

Olej писал(а): Вы её собираетесь писать, или она у вас есть уже готовая и к ней нужны какие-то доделки?
Если писать, то на чём (язык, библиотеки) вы её собираетесь писать?
Я надеюсь (меня смущает ваше "буквенно-графическом режиме 80x25") что программу вы собираетесь делать в операционной системе Linux (которой только и посвящён этот форум)?
И т.д. ...
Есть субд mumps У неё свой интерпретируемый язык - одна из веток языка GT.m В нём реализована возможность работы с терминалом 80x25, помимо этого в нём есть возможность работы с сетью.
На нём написана целая система естественно 80x25 но запускать можно и в графическом эмуляторе терминала, общая база разнесена - на разных компьютерах.
Кстати исходя из практики, для ввода и вывода текстовой информации, кроме клавиатуры и терминала 80x25 ничего и не нужно. Люди которые долго работают, информацию могут вводить не глядя на клавиатуру и экран, на автомате. Тыкая мышкой в графике такой скорости ввода не получишь никогда.
Хочу дописать, переписать многие вещи на Си. Естественно всё в linux.
Но для начала, так сказать для тренировки, хочу написать игру морской бой - консольный вариант.
Что бы можно было запускать в буквенно-цифровом режиме, и в графическом эмуляторе терминала.

Теперь конкретно по перехвату клавиш. Я только сейчас кажется понял как это надо делать.
Необходимо осуществить неканонический ввод, в результате я буду получать код нажатой клавиши, а дальше уже обрабатывать её (узнать какая клавиша нажата и выполнить соответствующее действие) мне придётся делать программно самому. Правильно я понял или нет?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение Olej » 25 ноя 2016, 00:06

v4567v писал(а): Теперь конкретно по перехвату клавиш. Я только сейчас кажется понял как это надо делать.
Необходимо осуществить неканонический ввод, в результате я буду получать код нажатой клавиши, а дальше уже обрабатывать её (узнать какая клавиша нажата и выполнить соответствующее действие) мне придётся делать программно самому. Правильно я понял или нет?
Правильно.
Я вам выше даже написал конкретные страницы в тексте, где описаны примеры кода делающие это (и, естественно, в архиве лежит работающий и проверенный код).

v4567v
Интересующийся
Сообщения: 3
Зарегистрирован: 23 ноя 2016, 00:02
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение v4567v » 28 дек 2016, 11:24

Наконец-таки я вернулся к написанию морского боя, всё это время был сильно занят на работе.
И поразмыслив, почитав предложенные книги, статьи возникли следующие вопросы.
Первый момент общий по поводу библиотеки Си - glibc.
Я понимаю так, что библиотека glibc виртуальная, в ней нет ассемблерного кода, а значит она вызывает системные вызовы ядра и работает только через них и никак иначе, что логично. Правильно ли я понимаю?
Если это так, то из этого следует второй момент.
Если я не ошибаюсь то файл текущего терминала /dev/tty, не важно какой это терминал: виртуальный и открыт в графическом эмуляторе терминала, не виртуальный соединённый через com порт, буквенно цифровой 80x25 и т.д. файл текущего открытого терминала в котором работают всё равно будет /dev/tty правильно я понимаю, это так?
Далее если это так, то используя только системные вызовы ядра, повторяю только системные вызовы ядра, в терминал я могу при неканоническом вводе, вводить символы и выводить их, следующими системными вызовами ядра write и read при этом в начале не забыв для файла терминала /dev/tty назначить дескриптор - функцией open, а в конце работы закрыть этот файл системным вызовом close. Правильно ли я понимаю?
Если всё выше изложенное правильно то тогда идём дальше.
Как мне при помощи системных вызовов ядра, опять же повторяю только системных вызовов ядра, не использую функции библиотеки glibc, получить информацию о терминале. Например геометрию терминала, сколько в открытом терминале символов по горизонтали и строк и т. д.
Конкретно какая мне ещё будет нужна другая информация кроме числа символов и строк я ещё не знаю. Но число символов и число строк нужно что бы правильно "разрисовать" интерфейс программы в терминале. Он будет состоять из символов псевдо-графики, для морского боя хватит.
Да вот ещё нужно узнать какая локализация, koi8-r, utf8 или ещё какая и наверное перевести локализацию в utf8.
В библиотеке glibc очень много функций для работы с терминалом:
isatty, tcsetattr, tcgetattr и т.д. очень много всяких структур данных. Конечно при помощи этих функций и структур данных можно работать с терминалом. Но я хотел бы узнать как можно полноценно работать с терминалом не используя библиотеку glibc, а пользуясь только системными вызовами ядра.
Ну например как я уже писал выше, ввести данные и вывести я уже знаю как write, read, open, close, а вот как получить какое в используемом терминале /dev/tty количество символов и строк при помощи системных вызовов ядра?
Те кто будут читать эти строки могут задать резонный вопрос, а зачем использовать только системные вызовы ядра, используй библиотеку glibc.
Я хочу прежде всего разобраться, поэтому хотелось бы узнать как работать с терминалом используя только системные вызовы ядра!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: перехват нажатия клавиш

Непрочитанное сообщение Olej » 28 дек 2016, 18:19

v4567v писал(а):Наконец-таки я вернулся к написанию морского боя, всё это время был сильно занят на работе.
Вы так долго думали, что я совершенно начисто забыл про что вы там говорили...
v4567v писал(а): И поразмыслив, почитав предложенные книги, статьи возникли следующие вопросы.
Первый момент общий по поводу библиотеки Си - glibc.
Я понимаю так, что библиотека glibc виртуальная, в ней нет ассемблерного кода, а значит она вызывает системные вызовы ядра и работает только через них и никак иначе, что логично. Правильно ли я понимаю?
Почему это вы так решили, про какую-то там "виртуальность" ... и почему это в ней нет кода?
Кстати, ассемблерного кода, на всё огромное количество кода ядра ... и ещё кой чего, в Linux почти нет вообще... какой-то совершенно мизер в начальной инициализации таблиц защищённого режима процессора x86 и т.д.
Во всех остальных местах, где нужен ассемблер, и для десятка разных аппаратных платформ, которые поддерживает Linux, используются инлайновые ассемблерные вставки в код C, инлайновый ассемблер, макросы языка C.

В библиотеке glibc.so как-раз и содержится интерфейс из C:
- подготовка параметров...
- вызов int80h или команда sysenter (что одно и то же)...
- вот это прерывание и есть сам системный вызов
- никаким другим вызовом/действием из адресного пространства пользователя (вашего) вы не можете передать управление в код ядра, который выполняется совсем в другом кольце защиты процессора
v4567v писал(а): Если я не ошибаюсь то файл текущего терминала /dev/tty, не важно какой это терминал: виртуальный и открыт в графическом эмуляторе терминала, не виртуальный соединённый через com порт, буквенно цифровой 80x25 и т.д. файл текущего открытого терминала в котором работают всё равно будет /dev/tty правильно я понимаю, это так?
Будет.
Но только не /dev/tty, а /dev/tty0, /dev/tty1, /dev/tty0, ... и так до /dev/tty63.
v4567v писал(а): Далее если это так, то используя только системные вызовы ядра, повторяю только системные вызовы ядра, в терминал я могу при неканоническом вводе, вводить символы и выводить их, следующими системными вызовами ядра write и read при этом в начале не забыв для файла терминала /dev/tty назначить дескриптор - функцией open, а в конце работы закрыть этот файл системным вызовом close. Правильно ли я понимаю?
Вы и так можете всегда использовать write() и read(), и не нужно вам ничего для этого открывать-закрывать, потому что у вашего приложения всегда будут открыты файловые дескрипторы: 0 - терминал ввода + 1 - терминал вывода.
v4567v писал(а): Он будет состоять из символов псевдо-графики, для морского боя хватит.
А для морского боя и подобных штучек с прямым управлением экраном терминала в UNIX 100 лет как используется пакет ncurses.
v4567v писал(а): Конечно при помощи этих функций и структур данных можно работать с терминалом. Но я хотел бы узнать как можно полноценно работать с терминалом не используя библиотеку glibc, а пользуясь только системными вызовами ядра.
Ну например как я уже писал выше, ввести данные и вывести я уже знаю как write, read, open, close, а вот как получить какое в используемом терминале /dev/tty количество символов и строк при помощи системных вызовов ядра?
Глупость какая!!!

И каким образом вы будете вызывать системные вызовы?
Заготавливая в ассемблерном коде параметры в регистрах для int 80h?
Просто технически как вы будете это делать?

Библиотека glibc.so только это и делает - ретранслирует C-соглашения о параметрах вызова в загрузку регистров и вызов int 80h.
И это только на архитектуре Intel x86.
А ещё эта библиотека делает столь же корректное преобразование параметров всё тех же C системных вызовов в соответствующие прерывания на разных десятке архитектур, где работает Linux (C-вызов тот же - а прерывания на каждом разное!).

А ещё через glibc.so, как через единственный в Linux интерфейс системных вызовов работают программы со всех (!) языков программирования в Linux (за редчайшим исключением, как может делать Go, например).

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 11 гостей