2015-02-01 7 views
1

현재 XKeysymToKeycode()을 호출하고 대문자로 전달할 때마다 KeySym이 소문자 인 KeyCode을 반환하는 Xlib에 문제가 있습니다. 구글은 실제로이 질문에 대한 답이나 내가 사용하고있는 기능에 관한 많은 문서를 갖고 있지는 않다. 여기 XKeysymToKeycode()가 모든 키를 소문자로 만드는 이유는 무엇입니까?

내가 사용하고있는 코드입니다 :

#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 
#include <X11/keysym.h> 
#include <X11/extensions/XTest.h> 

int main(void) { 
    Display *display; 
    char *ptr; 
    char c[2] = {0, 0}; 
    KeySym ksym; 
    KeyCode kcode; 

    display = XOpenDisplay(0); 
    ptr = "Test"; 

    while (*ptr) { 
     c[0] = *ptr; 
     ksym = XStringToKeysym(c); 
     printf("Before XKeysymToKeycode(): %s\n", XKeysymToString(ksym)); 
     kcode = XKeysymToKeycode(display, ksym); 
     printf("Key code after XKeysymToKeycode(): %s\n", XKeysymToString(XKeycodeToKeysym(display, kcode, 0))); 
     ptr++; 
    } 

    XCloseDisplay(display); 

    return 0; 
}  

gcc -o sendkeys sendkeys_min.c -lX11 -lXtst -g -Wall -Wextra -pedantic -ansi가 컴파일 할 수 있습니다

전류 출력은 다음과 같다 (이 sendkeys_min.c로 저장 한 가정.) :

Before XKeysymToKeycode(): T 
Key code after XKeysymToKeycode(): t 
Before XKeysymToKeycode(): e 
Key code after XKeysymToKeycode(): e 
Before XKeysymToKeycode(): s 
Key code after XKeysymToKeycode(): s 
Before XKeysymToKeycode(): t 
Key code after XKeysymToKeycode(): t 

예상 출력은 물론 "Test"의 첫 번째 T가 XKeysymToKeycode()을 통과 한 후에도 여전히 대문자임을 나타냅니다. (이것은 실제 프로그램이 아니라 여기에 게시 할 수있는 간소화 된 버전입니다. 실제 프로그램에서 결과 키 코드와 함께 키 이벤트를 보내고 보내지는 키가 여전히 여기에 표시되어 있습니다 (모두 소문자가됩니다))

답변

3

KeySymsKeyCodes은 의미 상으로 다르고 그 사이에는 1-1의 관계가 없습니다.

  • KeyCode은 키보드의 키를 나타내는 임의의 작은 정수입니다. Xlib은 키 코드가 [8, 255] 인 것을 요구하지만 다행스럽게도 대부분의 키보드는 100 개가 넘는 키를 가지고 있습니다.

  • KeySym은 키와 관련된 실제 문자를 나타냅니다. 거의 항상 이러한 것들이있을 것입니다 : 대문자와 소문자는 대부분의 터미널 레이아웃에서 같은 키에 해당합니다.

따라서 "대문자"또는 "소문자"KeyCode과 같은 것은 없습니다. Keysym에 해당하는 KeyCode을 얻으면 사실 정보가 손실됩니다.

Xlib에서 일부 키는 할당되지 않았지만 Xlib에서는 주어진 키에 적어도 네 개의 대응하는 KeySyms (소문자, 대문자, 소문자, 대문자, 대문자, 대문자)이 있습니다. KeyCode에 해당하는 KeySym을 요청하면 색인을 제공해야합니다. 인덱스 0 (코드에서와 같이)은 변경되지 않은 수정되지 않은 문자를 가져옵니다.

주어진 키 누르기의 경우 KeySym으로의 변환은 수정 자 키의 상태를 고려합니다. 이 중 8 개가 있습니다 (ShiftLock 수정 자 포함). 상황을 복잡하게하는 Lock을 무시하면 일반적으로 시프트 수정 자 키는 소문자를 대문자로 변환합니다 (영숫자 키의 경우).

키보드 처리는 간단한 요약보다 훨씬 복잡하지만 시작일뿐입니다.

당신의 작업에 대해서는 아마도 XkbKeysymToModifiers을 봐야 할 것입니다.

+0

좋아, 나에게 의미가있다. 그러나 문제는 원래 프로그램에서 KeyCode를 KeySym으로 다시 변환하지 않는다는 것이다.키 이벤트를 보내기 위해이 키 이벤트를 사용하고 키 이벤트를 보낼 때 키는 소문자로 전송됩니다. 그렇다면 내가 대문자가되기 원하는 키를 누르기 전에 Shift 키를 누르는 중요한 이벤트를 보내야한다고 가정합니다. – AppleDash

+0

@AppleDash : 키 누름 이벤트를 제작하는 경우 최소한 (수정 자 키의 비트 마스크 포함) 이벤트 구조의 'state'멤버를 설정해야합니다. 대부분의 앱은 수정 자 키 누름과 해제에 신경 쓰지 않습니다. 솔직히 X의 내부 구조가 어떻게 처리되는지 모르겠습니다. 그래서 내 추측은 국가를 세우는 것만으로도 충분하지만, 그 기반을 다룰 실제적인 경험이 없다는 것입니다. – rici

+0

좋아, 고마워. 너는 도움이되었다. – AppleDash