Перехват нажатия клавиши на Linux
Перехват нажатия клавиш XGrabKeyboard
Нашёл готовое решение, немного допилил и получился вот такой говнокод: #include .
Получение нажатия клавиши из неактивного окна
Привет всем! Как можно получить нажатую клавишу, если окно приложения не активно?
Скомпилированная программа закрывается после нажатия клавиши
В общем такая проблема, написал прогу на c++ , скомпилировал, у меня всё работает.
Отлов нажатия клавиатуры в Linux
Здравствуйте, может кто то подсказать как сделать глобальный отлов нажатия клавиш клавиатуры? В.
хотел заметить — у тебя нерациональный код: терминал переключается туда-сюда каждую итерацию. по идее перед циклом включи, а после цикла верни обратно — либо прямо в мейне, либо выведи в функции допустим make_canon_on и make_canon_off ну или как-нибудь еще по вкусу.
Добавлено через 2 минуты
Вы извините меня, конечно, но решение Перехват нажатия клавиши на Linux
можно назвать таковым с большой натяжкой. Это просто обработка нажатия клавиши определённым образом, а не его перехват. Перехват, это когда у тебя активно окно, допустим, текстового редактора и рядом неактивное окно консоли. Ты жмёшь на клавишу и срабатывает перехватчик- код клавиши появляется в окне консоли. А-ля хук, только в линукске За сим считаю вопрос нерешённым и возобновляю тему, дабы не создавать новой с таким же в точности названием.
Глупость какая.
В UNIX ещё году в 1970 (лет за 20-25 до появлеия всяких виндаузов) была развита архитектура терминальной подсистемы UNIX. В частности, были определены режимы ввода: канонический + некононический.
А вы пытаетесь притянуть виндаунные стереотипы к совершенно другой архитектуре.
Вы можете в UNIX/Linux произвольно и тонко управлять всеми деталями ввода: эхо-отображение символов или нет, тайм-аут ожидания и мн. др.
Вы можете выполнять это в отдельном потоке или в отдельном окне . где угодно — только это уже к собственно вводу не имеет никакого касательства.
P.S. Кому интересно, можете посмотреть примеры кода Разработка программных проектов в Linux.
И кстати . всё, касающееся терминального ввода UNIX, нужно смотреть в коде C, а в C++ оно просто естественно мигрировало, как в наследника . поскольку код C++ в Linux не может даже выполняться без наличия библиотеки C API libc.so . что для некоторых является большим сюрпризом.
Источник
Перехват нажатия клавиши на Linux
Перехват нажатия клавиш XGrabKeyboard
Нашёл готовое решение, немного допилил и получился вот такой говнокод: #include .
Получение нажатия клавиши из неактивного окна
Привет всем! Как можно получить нажатую клавишу, если окно приложения не активно?
Скомпилированная программа закрывается после нажатия клавиши
В общем такая проблема, написал прогу на c++ , скомпилировал, у меня всё работает.
Отлов нажатия клавиатуры в Linux
Здравствуйте, может кто то подсказать как сделать глобальный отлов нажатия клавиш клавиатуры? В.
Такое можно сделать и в X11
А вот например в игре, когда человечек прыгает не вверх, а вперед, т.е. наприме если A — прыжок, B — бежать вперед, а когда нажимаешь вместе A и B — человечек прыгает вперед, а не вверх.
( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
cout 0
Объясните пожалуйста что и для чего тут делается.
Добавлено через 12 часов 49 минут
Объясните пожалуйста хоть что-нибудь.
погрызть или в тырнете поискать.
Добавлено через 4 минуты
если заинтересовался, тебе надо по библиотеке termios искать (заголовочный файл termios.h) — есть обстоятельное мануалище под названием:
Управление терминалами (curses/terminfo)
1/ ты сравниваешь char, а надо int
2/ для пользования курсорных и управляющих клавиш можно использовать макросы. Они описаны в ncurses.h
KEY_LEFT
KEY_RIGHT
KEY_UP
KEY_DOWN
коды их больше 255: 258, 259, 260
посмотри man getch
#include
для компиляции необходимо подключить -lncurses в gcc/g++
3/ примерчик на си:
Добавлено через 16 минут
для создания интерактивных консольных приложений тебе надо бы использовать ncurses.
termios необходимо для установления связи с терминалом и задания атрибутов ввода-вывода (в частности канон/неканон эхо/неэхо). При использовании ncurses можно обойтись используемыми в ней функциями.
Также если не хочется заморачиваться, и хочется покодить «по-быстрому», можно использовать команды баш:
system(«stty -icanon -echo»);
отключает канон и эхо
system(«stty icanon echo»);
соответственно включает
Источник
C ++ обрабатывает нажатие клавиш в многопоточной программе в Linux
Я пишу программу, которая захватывает видео с 4 камер одновременно, поэтому у меня есть 4 потока для управления каждой камерой. В каждом потоке я хочу, чтобы запись продолжалась до тех пор, пока я не нажму клавишу, и эта клавиша соответствует «q» или чему-то еще.
Для дескриптора нажатия клавиш я ищу в Интернете и нашел такой метод:
И в моем классе VideoCapture у меня есть такой код (не полный):
Когда программа запускается, как только я нажимаю клавишу ‘q’ 4 раза, программа завершает работу и управление возвращается обратно в оболочку. Но в некоторых определенных обстоятельствах (я точно не знаю, это происходит не каждый раз) это приводит к проблеме, то есть, когда я иду и набираю команды в оболочке, символы, которые я печатаю, не отображаются. Когда я нажимаю ввод, команды отправляются.
Я ищу эту проблему и нашел это: https://askubuntu.com/a/172747 , что указывает на то, что мои атрибуты терминала не были сброшены должным образом. Но в коде дескриптора клавиш я заметил, что это две строки кода
сбросил атрибуты терминала. Поэтому мне интересно, имеет ли это отношение к многопоточности. Я новичок в многопоточном программировании и не могу решить это сам, так может кто-нибудь мне помочь? Любые предложения высоко ценятся.
Решение
У вас есть несколько потоков, пытающихся изменить параметры (статического) терминала одновременно:
Без этого ваши терминальные атрибуты являются абсолютно случайными.
Исправления заключаются в том, чтобы либо защитить это с помощью мьютекса, либо если вы создаете другой поток для чтения с клавиатуры и устанавливаете флаг, когда нажимается «q»; что ваши другие темы могут читать, вы можете сделать что-то вроде
Это будет означать, что вам нужно всего лишь нажать q для остановки всех потоков сбора кадров.
Источник
Перехват нажатия клавиш XGrabKeyboard
Но что-то мне подсказывает, что должно быть нормальное решение. Пробовал XGrabKey, но заставить его перехватывать без модификаторов не получилось. Цель — сделать свой велосипед для перенастройки клавиш.
Можно попробовать читать устройство клавиатуры и искать там нажатия клавиш, но, имхо, это не лучшее решение, хотя работать будет не только в иксах.
Перехват нажатия клавиши на Linux
Здравствуйте уважаемые эксперты! С помощью WinApi функций было просто использовать функцию.
Отслеживание нажатия 2-х клавиш
Всем доброго дня. Суть вопроса вот в чем. Нужно в терминале (без граф оболочки) отслеживать.
Обработка нажатия клавиш клавиатуры в программе на C++
Здравствуйте, уважаемые форумчане и великие гуру! У меня есть такой вопрос: Как можно.
Отслеживание нажатия клавиш на C++
Здравствуте, прочитал статью про то как перехватывать нажатие клавиш средствами.
Оно то работает, но не совсем так, как надо, например кнопки громкости в кедах перестают работать, нужно перехватывать нажатия, но не обязательно всех клавиш. Конкретнее, постановка задачи такая: сделать программу, в которой можно будет перенастроить клавиши для всех окон «по умному», например, я хочу убрать порядком поднадоевший нумлок, сделать чтобы случайные нажатия не выключали его, забиндить стрелки на Alt+j/k/i/l, и некоторые другие клавиши, чтоб не тянуться через всю клаву к ним.
Добавлено через 1 минуту
За ссылку спасибо, поизучаю.
Источник
Linux: перехват клавиатуры приложением — lleo — LiveJournal
Dec. 27th, 2018
05:36 am — Linux: перехват клавиатуры приложением
С 2016 года я неспешно интересовался вопросом, как подключить к беспилотному unix-серверу клавиатурку так, чтобы с нее шли управляющие команды в нужное приложение. И вот после недавнего обсуждения я наконец состряпал нужное и поставил на боевое дежурство — исправно работает уже несколько недель. Огромное спасибо за помощь Byte и Dmitry Shmidt! Теперь поделюсь итоговыми результатами, может, кому пригодится.
Софтинка запускается как крохотный демон, почти не занимающий оперативной памяти, который потом (при нажатии кнопки, что ожидается редко) вызывает скрипт-обработчик и передает ему, что было нажато, а тот уж пуст разбирается, как поступить. Поэтому в качестве первого аргумента софтинке передается Vendor/Product нужного USB-устройства через двоеточие (например «1C4F:0002), либо путь до устройства в системе (вида «/dev/input . » — я не тестировал, но и это должно работать тоже). В качестве второго аргумента в кавычках — передам команду, которая будет выполнена в системе, конструкция %c в ней будет заменена на введенный символ. Например: «echo \»%c\» >> /tmp/111.txt» или «notify-send -t 300 \»KeyCode: %c\»» или так:
При отваливании из USB устройства и появлении его заново — корректно обрабатывает эти неполадки, терпеливо ждёт, поглядывая. Полный код софтинки:
#define VENDORID 0x1c4f
#define PRODUCTID 0x0002
int init_keyboard ( unsigned int VENDOR , unsigned int PRODUCT ) <
fd =- 1 ;
int count = 0 ;
struct dirent ** files = NULL ;
struct input_id id ;
int grab = 1 ;
if( fd >= 0 ) ioctl ( fd , EVIOCGRAB ,& grab );
else <
fprintf ( stderr , «Device not found or access denied. » );
return EXIT_FAILURE ;
>
return 0 ;
>
char remap_codes ( int scancode ) <
char r = ‘ ‘ ;
switch( scancode ) <
// NumLock = off + N // NumLock = o n
case 0x45 : r = 0 ; break;
// 000 -> 0 0 0 // 000 -> — N O —
case 0x52 : r = ‘0’ ; break; case 0x6E : r = ‘0’ ; break;
case 0x4f : r = ‘1’ ; break; case 0x6B : r = ‘1’ ; break;
case 0x50 : r = ‘2’ ; break; case 0x6C : r = ‘2’ ; break;
case 0x51 : r = ‘3’ ; break; case 0x6D : r = ‘3’ ; break;
case 0x4b : r = ‘4’ ; break; case 0x69 : r = ‘4’ ; break;
case 0x4c : r = ‘5’ ; break; //— NO —
case 0x4d : r = ‘6’ ; break; case 0x6A : r = ‘6’ ; break;
case 0x47 : r = ‘7’ ; break; case 0x66 : r = ‘7’ ; break;
case 0x48 : r = ‘8’ ; break; case 0x67 : r = ‘8’ ; break;
case 0x49 : r = ‘9’ ; break; case 0x68 : r = ‘9’ ; break;
case 0x53 : r = ‘.’ ; break; case 0x6F : r = ‘.’ ; break;
case 0x60 : r = ‘E’ ; break; // Enter
case 0x62 : r = ‘C’ ; break; // /
case 0x37 : r = ‘Z’ ; break; // *
case 0x4a : r = ‘M’ ; break; // —
case 0x4e : r = ‘P’ ; break; // +
case 0x0E : r = ‘B’ ; break; // Backspace
default:
printf ( «Scancode:0x%X — [%c]\n» , scancode ,( unsigned char ) scancode );
r =( unsigned char ) scancode ;
>
return r ;
>
char read_keyboard () <
struct input_event ev ;
ssize_t n ;
while( true ) <
n = read ( fd , & ev , sizeof ( struct input_event ));
if( n == ( ssize_t )- 1 ) <
if ( errno == EINTR ) continue;
else break;
> else if( n != sizeof ev ) <
errno = EIO ;
break;
>
if( ev . type == EV_KEY && ev . value == EV_KEY ) return remap_codes ( ev . code );
>
return ‘!’ ;
>
int connect_keyboard ( int argc , char * arg ) <
char name [ 256 ] = «Unknown» ;
if( argc > 1 ) <
// пробуем отсканировать VEND:PROD
unsigned int VEND = VENDORID , PROD = PRODUCTID ;
if( 2 == sscanf ( arg , «%x:%x» ,& VEND ,& PROD )) <
printf ( «\nConnecting to device %04x:%04x. » , VEND , PROD );
if( init_keyboard ( VEND , PROD )!= 0 ) < printf ( "FAILED\n" ); return( 1 ); >
printf ( «OK\n» );
> else <
// пробуем найти path
snprintf ( path , 200 , «%s» , arg );
printf ( «\nConnecting to device %s . » , path );
if(( fd = open ( path , O_RDONLY )) == — 1 ) < printf ( "FAILED\n" ); return( 1 ); >
printf ( «OK\n» );
>
> else < // откроем дефолтный девайс
printf ( «\nConnecting to default device %04x:%04 x. » , VENDORID , PRODUCTID );
if( init_keyboard ( VENDORID , PRODUCTID )!= 0 ) < printf ( "FAILED\n" ); return( 1 ); >
printf ( «OK\n» );
>
ioctl ( fd , EVIOCGNAME ( sizeof ( name )), name );
fprintf ( stderr , «Reading from: %s (%s)\n» , path , name );
return 0 ;
>
int main ( int argc , char * argv []) <
printf ( «Runnung. (Example: \»sudo ./keyboardn oid 1C4F:0002 \»echo \\\»%%c\\\» >> /tmp/1 11.txt\»)» );
char r = 0 ;
char action [ 300 ]= «notify-send -t 300 \»KeyCode: %c\»» ;
if( argc > 2 ) snprintf ( action , 1024 , «%s» , argv [ 2 ]); // скопировать строку акции
while( true ) <
if(!( r = read_keyboard ())) continue;
// printf(«Scancode:0x%X — [%c]\n»,r,(un signed char)r);
if( r == ‘!’ ) < // обрыв связи
sleep ( 1 );
close ( fd ); printf ( «port_disconnected\n» );
snprintf ( path , 100 , action , ‘?’ ); system ( path ); // подать сигнал
while( true ) < if( 0 == connect_keyboard ( argc , argv [ 1 ])) break; sleep ( 2 ); >// 10 сек
snprintf ( path , 100 , action , ‘!’ ); system ( path ); // подать сигнал что все в порядке
continue;
>
if( r == 0x0D || r == 0x0A || r == ‘»‘ || r == ‘\» ) r = ‘@’ ; // не надо нам энтеров и кавычек!
snprintf ( path , 100 , action , r );
printf ( «ACTION: `%s`\n» , path );
system ( path );
>
>
PS: Что любопытно: говорят, вот эти мелкие USB-карточки, которые имеют на борту кнопки, тоже определяются как устройство USB-клавиатуры. А значит, их можно втыкать во всякие там домашние роутеры и raspberry pi чтобы не только поиметь звуковые оповещения, но и запрограммировать в системе полезные команды по нажатию внешних кнопок, чего у таких устройств вечно не хватает. Но сам я эти звуковушки пока не тестировал, заказал на Алиэкспрессе сейчас (63 руб), как дойдет — потестирую.
Источник