перехват нажатия клавиш
Модератор: Olej
перехват нажатия клавиш
Здравствуйте, форумчане.
Подскажите пожалуйста как перехватывать нажатия клавиш?
Есть программа которая запускается и работает в буквенно-графическом режиме 80x25, так же она может запускаться и работать в графическом эмуляторе терминала, например в konsole.
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
Ещё нужно работать с сигналами. Например при нажатии на Ctrl+z останавливать выполнение программы. Потом при по команде bg переводить её работу в фон, по команде fg - на передний план.
Интересует именно как перехватывать нажатие клавиш и работа с сигналами без использования библиотеки ncurses. Именно без ncurses!!!
Нужна реальная информация, что бы с её помощью можно было это реализовать программно.
Если информации очень много, то тогда дайте ссылки в интернете этой информации, только желательно (очень!) на русском языке.
Сам я искал в интернете, но конкретики так и не нашёл, или вода или не то, (может не так искал).
За помощь заранее благодарен!
Подскажите пожалуйста как перехватывать нажатия клавиш?
Есть программа которая запускается и работает в буквенно-графическом режиме 80x25, так же она может запускаться и работать в графическом эмуляторе терминала, например в konsole.
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
Ещё нужно работать с сигналами. Например при нажатии на Ctrl+z останавливать выполнение программы. Потом при по команде bg переводить её работу в фон, по команде fg - на передний план.
Интересует именно как перехватывать нажатие клавиш и работа с сигналами без использования библиотеки ncurses. Именно без ncurses!!!
Нужна реальная информация, что бы с её помощью можно было это реализовать программно.
Если информации очень много, то тогда дайте ссылки в интернете этой информации, только желательно (очень!) на русском языке.
Сам я искал в интернете, но конкретики так и не нашёл, или вода или не то, (может не так искал).
За помощь заранее благодарен!
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: перехват нажатия клавиш
То, что вы называете "есть программа" - это сильно неопределённо...v4567v писал(а): Подскажите пожалуйста как перехватывать нажатия клавиш?
Есть программа которая запускается и работает в буквенно-графическом режиме 80x25, так же она может запускаться и работать в графическом эмуляторе терминала, например в konsole.
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
Вы её собираетесь писать, или она у вас есть уже готовая и к ней нужны какие-то доделки?
Если писать, то на чём (язык, библиотеки) вы её собираетесь писать?
Я надеюсь (меня смущает ваше "буквенно-графическом режиме 80x25") что программу вы собираетесь делать в операционной системе Linux (которой только и посвящён этот форум)?
И т.д. ...
Посмотрите сюда: Разработка программных проектов в Linux.Нужна реальная информация, что бы с её помощью можно было это реализовать программно.
Если информации очень много, то тогда дайте ссылки в интернете этой информации, только желательно (очень!) на русском языке.
А если у вас возникнут проблемы по реализации - обращайтесь сюда: обсудим и поможем.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: перехват нажатия клавиш
Не совсем понятно что вы хотите, но я предполагаю, что:v4567v писал(а): Подскажите пожалуйста как перехватывать нажатия клавиш?
Необходимо перехватывать нажатия клавиш, например клавишу Esc - по её нажатию завершать программу и т. д.
- то что вы называете "перехватывать" - это неканонический режим ввода терминала, по той ссылке, что я давал выше, это глава "Терминал, режим ввода: канонический и неканонический", стр. 280
- а по реакции на сигналы там целый раздел "Сигналы UNIX", стр. 262.
И на всё это приведены готовые фрагменты кода.
Re: перехват нажатия клавиш
Есть субд mumps У неё свой интерпретируемый язык - одна из веток языка GT.m В нём реализована возможность работы с терминалом 80x25, помимо этого в нём есть возможность работы с сетью.Olej писал(а): Вы её собираетесь писать, или она у вас есть уже готовая и к ней нужны какие-то доделки?
Если писать, то на чём (язык, библиотеки) вы её собираетесь писать?
Я надеюсь (меня смущает ваше "буквенно-графическом режиме 80x25") что программу вы собираетесь делать в операционной системе Linux (которой только и посвящён этот форум)?
И т.д. ...
На нём написана целая система естественно 80x25 но запускать можно и в графическом эмуляторе терминала, общая база разнесена - на разных компьютерах.
Кстати исходя из практики, для ввода и вывода текстовой информации, кроме клавиатуры и терминала 80x25 ничего и не нужно. Люди которые долго работают, информацию могут вводить не глядя на клавиатуру и экран, на автомате. Тыкая мышкой в графике такой скорости ввода не получишь никогда.
Хочу дописать, переписать многие вещи на Си. Естественно всё в linux.
Но для начала, так сказать для тренировки, хочу написать игру морской бой - консольный вариант.
Что бы можно было запускать в буквенно-цифровом режиме, и в графическом эмуляторе терминала.
Теперь конкретно по перехвату клавиш. Я только сейчас кажется понял как это надо делать.
Необходимо осуществить неканонический ввод, в результате я буду получать код нажатой клавиши, а дальше уже обрабатывать её (узнать какая клавиша нажата и выполнить соответствующее действие) мне придётся делать программно самому. Правильно я понял или нет?
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Re: перехват нажатия клавиш
Правильно.v4567v писал(а): Теперь конкретно по перехвату клавиш. Я только сейчас кажется понял как это надо делать.
Необходимо осуществить неканонический ввод, в результате я буду получать код нажатой клавиши, а дальше уже обрабатывать её (узнать какая клавиша нажата и выполнить соответствующее действие) мне придётся делать программно самому. Правильно я понял или нет?
Я вам выше даже написал конкретные страницы в тексте, где описаны примеры кода делающие это (и, естественно, в архиве лежит работающий и проверенный код).
Re: перехват нажатия клавиш
Наконец-таки я вернулся к написанию морского боя, всё это время был сильно занят на работе.
И поразмыслив, почитав предложенные книги, статьи возникли следующие вопросы.
Первый момент общий по поводу библиотеки Си - 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.
Я хочу прежде всего разобраться, поэтому хотелось бы узнать как работать с терминалом используя только системные вызовы ядра!
И поразмыслив, почитав предложенные книги, статьи возникли следующие вопросы.
Первый момент общий по поводу библиотеки Си - 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: перехват нажатия клавиш
Вы так долго думали, что я совершенно начисто забыл про что вы там говорили...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.
Вы и так можете всегда использовать write() и read(), и не нужно вам ничего для этого открывать-закрывать, потому что у вашего приложения всегда будут открыты файловые дескрипторы: 0 - терминал ввода + 1 - терминал вывода.v4567v писал(а): Далее если это так, то используя только системные вызовы ядра, повторяю только системные вызовы ядра, в терминал я могу при неканоническом вводе, вводить символы и выводить их, следующими системными вызовами ядра write и read при этом в начале не забыв для файла терминала /dev/tty назначить дескриптор - функцией open, а в конце работы закрыть этот файл системным вызовом close. Правильно ли я понимаю?
А для морского боя и подобных штучек с прямым управлением экраном терминала в UNIX 100 лет как используется пакет ncurses.v4567v писал(а): Он будет состоять из символов псевдо-графики, для морского боя хватит.
Глупость какая!!!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, например).
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя