2016-01-09 2 views
0

Пользовательский интерфейс моего приложения состоит из двух окон: консоли (обработано ncurses) и окна X11 для графики. Я хотел бы централизованно обрабатывать ключевые события. То есть независимо от того, какое из двух окон активно, один и тот же цикл событий должен обрабатывать все ключевые события. У меня уже есть цикл событий для событий X11. Все, что еще нужно сделать, - переслать все события консоли в окно X11.Пересылка ncurses ключевых событий в окно X11

Основной строительный блок для этой цели находится here. Единственное, что мне нужно, это уметь переводить из значения, возвращаемого getch() в X11 keycode. Примерно через четыре часа поиска в Интернете я нашел код this, который является частью qemu. Однако, когда я сравниваю отображение, которое он предоставляет с выходом xev, эти два не совпадают. Например, для ключа Homexev дает 110, а упомянутое отображение дает 71 | 0x0100, что составляет 327. Являются ли эти два разных типа keycodes? Что мне не хватает?

+0

Эти два не связаны друг с другом (за исключением тривиального случая, когда используется набор символов POSIX). –

+0

@ThomasDickey Знаете ли вы о любом существующем сопоставлении, которое я могу повторно использовать? – AlwaysLearning

+0

Не из рук в руки: вы можете создать сопоставление от специальных ключей проклятия к специальным клавишам X, но я не помню, чтобы с этой целью можно было использовать таблицу многократного использования. –

ответ

1

Хм, рамки для смешивания приложений, по определению, сложны.

Я думаю, что лучший способ добиться того, что вы хотите, состоит в том, чтобы иметь два отдельных процесса или потоки, один для консоли, а другой для приложения X11. В каждом случае у вас будет соответствующий обработчик цикла событий. Чтобы объединить их вместе, используйте канал IPC, будь то труба или сокет. Вы должны иметь возможность сделать сокет/трубу входным для обработчика цикла событий X11 с его собственным обратным вызовом. У вас может быть опция select() на стороне консоли, ожидающая сокета или STDIN; это позволяет вам называть getch(), когда готов к нажатию клавиши или считывается из сокета, когда X11 отправил что-то через сокет. Если вы использовали что-то вроде ZeroMQ вместо сокета, еще лучше.

Итак, что бы вы отправили через сокет? Вам нужно будет определить свою собственную структуру событий для перехода между консолью и приложением X11. Каждая сторона будет заполнять и отправлять одну из них, когда ей нужно отправить что-то другому. Типы событий, которые вам нужно описать, включают в себя такие вещи, как quit, keypress (+ keypress data) и т. Д.

Скорее всего, вы уложите конец X11 так, чтобы обратный вызов сокета прочитал структуру из сокет, интерпретировал его и решил, что вызов должен быть вызван непосредственно. Если ваши нажатия клавиш предназначены только для выбора пунктов меню, кнопок и т. Д., То это может быть не слишком-плохой (но не блестящий) способ избежать проблемы с отображением.

Это означает наличие двух обработчиков цикла событий, сокета и двух процессов/потоков. Но он избегает смешивания двух в одну вещь. Это также означает, что ваша консоль может быть на совершенно другой машине! Если вы использовали zeromq, вы могли бы легко иметь несколько консолей, подключенных к приложению X11 в конфигурации PUSH/PULL; возможно, абсурдно, но возможно.