2014-12-20 3 views
11

리눅스 데스크탑 키 이벤트 핸들링에 연결하고 싶습니다.리눅스 키 이벤트 핸들링에 끼어 들기

CapsLock을 누르면 일종의 명령 행을 입력해야합니다.

제가 구현하려는 일부 명령

:

  • D/X : 문자 x 때까지 현재 커서 위치에서 삭제합니다. (vi에서 영감을 얻음)
  • a : pos1과 같이 줄의 시작 부분으로 이동합니다. (emacs에 의해 영감을).
  • k : 줄 끝까지 삭제하십시오. (emacs에 의해 영감을). 텍스트 필드에 작업을해야
  • ...

명령 : 브라우저, 메일 클라이언트, 그놈 터미널, ...

AFAIK 낮은 수준의 xmodmap을 날 여기 도움이되지 않습니다.

이렇게 할 수 있나요?

어디에서 후크를 끼워야합니까?

현재 대상 플랫폼은 우분투> = 14.04

배경이다 : 나는 F와 J 내 가리키는 손가락을 유지하고, 키보드를 보지 않고 컴퓨터를 사용하고 싶습니다. 몇 년 전부터 A-Z에서 작동하지만 Pos1/End와 같은 키는 쉽게 액세스 할 수 없습니다.

이 질문의 일부를 이해하지 못하는 경우 의견을 남기십시오. 고맙습니다.

업데이트

이 질문은 키 이벤트 처리에 후크하는 방법에 관한 것입니다. 다른 것들 (명령 행)은 다른 주제입니다. 예를 들어 CapsLock x을 어떻게 잡을 수 있습니까?

업데이트 2 나는 쉽고 간단한 해결책이 없다고 생각합니다. 너는 대답이 없다, 그러나 나는 너에게 더 많은 도움을 찾을 수있는 것을 안다. (메일 링리스트 FOO에 묻는다.) 나에게 말해줘.

갱신 3 어떤 사람들은 내가 원하는 것을 이해하지 않기 때문에, 나는 그것을 설명하려고 : 나는 이맥스 또는 떠들썩한 파티를 사용하는 경우 내가 컨트롤에있는 것 같은 느낌 경우 컴퓨터 : 그것은 단지 거의 움직임, 비행처럼 나는 내가 원하는 것을 컴퓨터에 할 수있다. 웹 브라우저 textarea, LibreOffice 또는 thunderbird에서 텍스트를 편집하면이 느낌이 사라집니다. 커서 이동은 번거롭고 비행과 같은 느낌이 들지 않습니다. 단일 응용 프로그램뿐만 아니라 데스크탑을 제어하고 F 및 J 키에 포인팅 핑거를 유지하려고합니다.

+3

친애 아래 유권자 :이 질문에 문제가 있는지 알려주세요. 그것을 개선하기 위해 무엇을 할 수 있습니까? "너무 광범위하기"때문에 두 명이 투표했습니다. 나는 그것을 얻지 않는다. 이 질문에 대해 너무 광범위합니까? – guettli

+0

이 X 화면이 작동하지 않아야합니까? – Basilevs

+0

@Basilevs 아니오, X-desktop이 실행 중이면 충분합니다. X 로그인 화면에서 사용자/암호 또는 텍스트 콘솔 (Ctrl-Alt-F1)을 묻는 경우에는 사용할 필요가 없습니다. – guettli

답변

4

무차별 대입 방식은 xserver-xorg-input-evdev 패키지를 수정/다시 작성하고 /usr/lib/xorg/modules/input/evdev_drv.so을 바꾸는 것입니다. 나는 함수를 xf86-input-evdev-2.9.0/src/evdev.c에서 수정하려고 시도 할 것입니다. 매우 우아한 솔루션으로 보이지는 않지만 키보드 이벤트 큐를 수정할 수있는 유연성을 얻을 것이라고 생각합니다.

(일부 세부 사항은 here) 및/또는 XGrabKeyboard()을 사용하면 방해 할 수있는 해결책이 부족할 수 있습니다.here (XTEST 확장에 대한) 도움이 될 수있다

일부 정보.

+1

대단히 감사합니다. 이것은 내가 얻은 첫 번째 긍정적 인 피드백입니다. evdev.c 수정은 매우 유연하지 않습니다. 내 확장 프로그램은 모든 x 서버용으로 컴파일해야합니다. 어쩌면 런타임에 메서드를 대체 할 수 있습니다 ... – guettli

+0

@guettli, 예, 이것은 "타당성 분석"입니다. 실제로 저는 beter 해가 발견되지 않으면 수정되거나 이름이 변경된'evdev' 드라이버를 빌드하고 배포 할 수 있다고 생각합니다. 그러나 프로토 타입을 작성하는 동안 더 많은 작업이 필요할 수 있습니다. 그리고 나는 그것이 당신이 단기간에 가질 수있는 가장 큰 문제인지 확신하지 못합니다. – kestasx

3

질문을 보는 또 다른 방법 : 일부 전문 window manager를 원한다. 자세한 내용은 EWMH 사양을 읽어보십시오. X11의 개요 전에 읽으십시오.

또는 기존 X window manager을 고려하십시오. 그들 중 많은 수가 있습니다. ratpoison 또는 xmonad (또는 아마도 sawfish 등)이 필요에 맞게 구성 될 수 있습니다. (그러나 나는이 WMs 잘 모른다).

처음부터 윈도우 매니저를 구현하기 전에 두 번 생각하십시오. 그것은 수년간의 노력을 의미 할 수 있습니다! AFAIU, WM은 키보드 또는 마우스 이벤트를 리디렉션, 필터링, 잡아 또는 통합 할 수 있습니다. 물론

, wayland와 상황이 다를 것이다.

+0

예, 창 관리자를 구현하는 것은 많은 작업입니다. 나는 바퀴를 재발 명하고 싶지 않다. 내 솔루션은 모든 창 관리자를 위해 작동해야합니다.손가락 누르기에서부터 X 응용 프로그램에 이르기까지 키보드 이벤트를 잡아서 수정하고 싶습니다. – guettli

+0

정의에 따르면, 창 관리자는 그러한 키보드 이벤트를 포착 할 수 있고 (또는 가져야 할 필요가있을 수도 있습니다), 잡을 수 있습니다. 당신은 창 관리자가 필요합니다. 필요에 맞게 하나를 선택하십시오 (또는 하나를 선택하십시오). 내가 준 링크를 따라 가세요. 관련이 있습니다! –

+0

창 관리자가 필요하다는 것을 알고 있습니다. 그러나 특별한 창 관리자를 사용해야하는 솔루션은 사용자에게 친숙하지 않습니다. 그리고 모든 창 관리자와 함께 이것을 해결할 수 있다고 생각합니다. – guettli

9

UPDATE

대신 장치를 무시하도록 X 서버를 말하는, 당신은 내가 아래 프로그램에 추가 EVIOCGRAB IOCTL을 사용할 수 있습니다.

당신은 다음과 같은 작업을 수행해야합니다

1.Make 확실히 당신이 CONFIG_UINPUT 모듈 컴파일 및로드. 나는 우분투가 이미 가지고 있다고 믿는다. /dev/uinput 장치가 보이지 않으면 modprobe -v uinput을 실행하여 모듈을로드하십시오.

2.Run 다음 프로그램 루트로하고 그것을 키보드 장치의 경로를 제공, 예 :

./process /dev/input/by-id/usb-Microsoft_Wired_Keyboard_600-event-kbd

다음 프로그램이 주어진에서 uinput-sample라는 가짜 입력 장치 및 앞으로 모든 이벤트를 생성 입력 장치. 나는 당신이하고 싶은 일을 수정할 수 있습니다 http://thiemonge.org/getting-started-with-uinput

에 주어진 샘플에서 적응. 여기

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <linux/input.h> 
#include <linux/uinput.h> 

#define die(str, args...) do { \ 
     perror(str); \ 
     exit(EXIT_FAILURE); \ 
    } while(0) 

int 
main(int argc, char* argv[]) 
{ 
    int     fdo, fdi; 
    struct uinput_user_dev uidev; 
    struct input_event  ev; 
    int     i; 

    if(argc != 2) die("error: specify input device"); 

    fdo = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 
    if(fdo < 0) die("error: open"); 

    fdi = open(argv[1], O_RDONLY); 
    if(fdi < 0) die("error: open"); 

    if(ioctl(fdi, EVIOCGRAB, 1) < 0) die("error: ioctl"); 

    if(ioctl(fdo, UI_SET_EVBIT, EV_SYN) < 0) die("error: ioctl"); 
    if(ioctl(fdo, UI_SET_EVBIT, EV_KEY) < 0) die("error: ioctl"); 
    if(ioctl(fdo, UI_SET_EVBIT, EV_MSC) < 0) die("error: ioctl"); 

    for(i = 0; i < KEY_MAX; ++i) 
     if(ioctl(fdo, UI_SET_KEYBIT, i) < 0) die("error: ioctl"); 

    memset(&uidev, 0, sizeof(uidev)); 
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample"); 
    uidev.id.bustype = BUS_USB; 
    uidev.id.vendor = 0x1; 
    uidev.id.product = 0x1; 
    uidev.id.version = 1; 

    if(write(fdo, &uidev, sizeof(uidev)) < 0) die("error: write"); 
    if(ioctl(fdo, UI_DEV_CREATE) < 0) die("error: ioctl"); 

    while(1) 
    { 
     if(read(fdi, &ev, sizeof(struct input_event)) < 0) 
      die("error: read"); 

     ev.time.tv_sec = 0; 
     ev.time.tv_usec = 0; 

     if(write(fdo, &ev, sizeof(struct input_event)) < 0) 
      die("error: write"); 
    } 

    if(ioctl(fdo, UI_DEV_DESTROY) < 0) die("error: ioctl"); 

    close(fdi); 
    close(fdo); 

    return 0; 
} 
+0

답변 해 주셔서 감사합니다. 나는 C를 쓸 수 있지만 파이썬을 선호한다. 다음 날에 당신의 솔루션을 http://tjjr.fi/sw/python-uinput/에 포팅하고 싶습니다. – guettli

+0

@guettli, 파이썬 솔루션에 대한 저의 다른 대답을 확인하십시오 –

+0

Python-uinput은 장치를 생성하고 이벤트를 생성하는 데 사용할 수 있습니다. 기존 장치를 잡거나 복제하거나 모니터링하는 데 사용할 수 없습니다. – tuomasjjrasanen

3

또한 드라이버를 uinput 사용하여 파이썬 프로젝트입니다 :

http://hetgrotebos.org/wiki/uinput-mapper

+0

고맙습니다. 정확히 내가 뭘 찾고있는 것 같아 – guettli

+0

@ guettli, 끝내. 다른 사람이 현상금을 가지고 있기 때문에 대답을 받아 들일 자유롭게 느껴라. :) –