추가 읽기

추가 읽기

저는 X와 같은 시스템이 어떻게 작동하는지 (개념적으로) 더 잘 이해하려고 노력하고 있습니다. 내가 이해한 바에 따르면 X는 키보드 이벤트를 수신하기 위해 차단 읽기를 수행하는 내부 이벤트 루프가 있으며 /dev/input/event0, 예를 들어 커널은 사용자 입력을 읽는 방법으로 이를 노출합니다. 그런 다음 해당 이벤트를 가져오고 (사용자 공간에서) 일부 처리를 수행한 다음 일종의 이벤트 큐 형식을 사용하여 활성 창에 전달합니다. 이것이 본질적으로 어떻게 작동하는지 오해하고 있다면 정정해 주십시오.

그러나 이것이 내가 혼란스러워지는 곳입니다. X에서 /dev/input/event0또는를 eventXX직접 읽고 따라서 이러한 이벤트가 소비되는 경우 다른 프로세스가 읽기 작업을 수행하도록 하려면 어떻게 해야 합니까 eventXX? Python 프로세스가 장치에서 데이터를 읽고, 명령줄에서 데이터를 읽는 등의 작업을 수행하도록 할 수 있습니다.

내 이해(그리고 이것이 내가 틀릴 수도 있음)는 문자 장치의 출력이 단일 프로세스에 의해 소비되므로 두 프로세스가 read호출 되는 경우 호출 /dev/...중 하나만 지정된 데이터를 반환한다는 것입니다. read그렇다면 X가 문자 장치에서 모든 데이터를 가져오면 다른 프로세스가 어떻게 동일한 키보드 데이터를 읽을 수 있습니까?

답변1

Xorg 및 기타 프로그램공유 I/O 장치 협상. 두 가지 모드로 작동합니다. 활성화되면 입력 장치 kevent(…EV_ENABLE…)또는 파일 설명자를 위한 유사한 장치를 폴링하고 디스플레이 장치에 씁니다. 비활성 상태에서는 입력 장치를 폴링하지 않거나 kevent(…EV_DISABLE…)파일 설명자에 유사한 장치를 사용하지 않으며 디스플레이 장치에 쓰지 않습니다.

주어진 시간에 오직 하나의 프로그램만이 I/O 장치에 접근할 수 있습니다. 관찰한 바와 같이 여러 프로그램에서 이 작업을 수행하면 디스플레이가 손상되고 개별 입력 이벤트가 어디서 끝나는지 확실하지 않기 때문입니다. (Linux에 내장된 터미널 에뮬레이터는 여기서는 프로그램으로 간주됩니다.프로세스. 폴링을 사용하는 대신 입력 장치 드라이버에 내부 후크가 있고 입력 스트림의 열기 및 닫기를 제어하고 업데이트된 문자 단위를 디스플레이 장치에 구현해야 할 때를 알려주는 플래그가 있으므로 동일한 효과를 얻을 수 있습니다. )

그들은커널 가상 터미널협상의 수단으로. 이것이 Xorg 서버가 KVT를 배포하는 이유입니다. 프로세스에 신호를 이해하고 보낼 수 있는 해당 유형의 장치만 포함하는 KVT 장치별 프로토콜을 사용하면 ioctl()각 장치는 디스플레이 및 HID(인간 입력 장치)에 대한 책임을 지는 시기와 커널의 사용 시기를 협상할 수 있습니다. 내장 터미널 에뮬레이터 또는 기타 일부 프로그램(다른 X 서버 포함).

logind이 아이디어 는 완전히 독립적인 보조 디스플레이 등과 같이 KVT 하위 시스템에서 사용되지 않는 I/O 장치에 대한 협력 프로그램 간의 동일한 협상을 허용하거나 처음에 Linux가 없는 경우 systemd 프로그램에서 재창조되었습니다. . 동일한 원칙이 적용됩니다. 파일 설명자는 프로그램이 비활성 상태일 때 프로그램에서 사용되지 않습니다.

추가 읽기

답변2

여러 독자가 입력 하위 시스템 이벤트의 복사본을 받고 있으며 적어도 내 시스템(Linux 5.10)에서는 키보드 및 마우스 이벤트가 발생합니다. 적어도 glob과 일치하는 모든 장치:

/dev/input/by-path/*-event-{kbd,mouse}

Xorg, systemd-loginacpid모두 켜져 있지만(표시된 대로 ) lsof나에게는 이런 방식으로 작동합니다.

evtest(1)내 키보드의 "shift 키 누르기/해제"와 같이 주어지지 않는 한 테스트 읽기에 long을 사용할 수 있습니다 --grab(분명히 X는 그것을 "잡지" 않습니다).

 $ sudo evtest /dev/input/by-path/platform-i8042-serio-0-event-kbd |& grep ^Event:
Event: time 1642971418.691004, type 4 (EV_MSC), code 4 (MSC_SCAN), value 36
Event: time 1642971418.691004, type 1 (EV_KEY), code 54 (KEY_RIGHTSHIFT), value 1
Event: time 1642971418.691004, -------------- SYN_REPORT ------------
Event: time 1642971418.729131, type 4 (EV_MSC), code 4 (MSC_SCAN), value 36
Event: time 1642971418.729131, type 1 (EV_KEY), code 54 (KEY_RIGHTSHIFT), value 0
Event: time 1642971418.729131, -------------- SYN_REPORT ------------

(유형 4는 논리 키보드 이벤트 유형 1에서 발생하는 원시 스캔 코드입니다.) 단일 읽기는 유형 0, 코드 0( , ) 패킷이 관련 입력 패킷 그룹을 분리하는 struct input_event배수(x86_64에서 24바이트)를 반환합니다. 이는 다차원 입력이 가능한 터치패드 및 마우스와 더 관련이 있습니다.EV_SYNSYN_REPORT

(패키지 메타데이터에 따르면 evemu-tools요즘에는 대신 테스트용으로 사용해야 하는데 evtest시도하지 않았습니다.)

키보드 유휴 시간을 모니터링하기 위해 이벤트 장치를 성공적으로 사용했으며 스크립트는 X 또는 콘솔에서 입력된 이벤트를 올바르게 읽는 반면 다른 독자는 계속해서 모든 키 누르기의 복사본을 얻습니다.

자세한 내용은 다음 문서를 참조하세요.

  • /usr/include/linux/input.h
  • /usr/include/linux/input-event-codes.h
  • /usr/src/linux/Documentation/input/input.rst

관련 정보