2017-01-19 14 views
0

私はDebian Stretch上でuinputを使って仮想キーボードを作ろうとしています。 "Toto!"のような文字列を入力でき、キーボードはこの文字列を書きます。 しかし、私はCの文字からキーボードで扱われるキーコードへの変換に悩まされています。 私は私のソリューションをコンピュータのロケールで動作させ、マクロはUSキーボードの周りに定義したいので、私はevent-codes.hで定義されたマクロを使用していません。charをカーネルに変換するキーコード(uinput用)

はここuinputを使用して作成したデバイスです:

int setup_uinput_device(){ 
/* Temporary variable */ 
    int i=0; 
/* Open the input device */ 
    uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY); 
    if (fcntl(uinp_fd, F_GETFD) == -1) 
    { 
     printf("Unable to open /dev/uinput\n"); 
     return -1; 
    } 
    memset(&uinp,0,sizeof(uinp)); /* Intialize the uInput device to NULL */ 
    strncpy(uinp.name, "Custom Keyboard", UINPUT_MAX_NAME_SIZE); 
    uinp.id.bustype = BUS_USB; 
    // Setup the uinput device 
    ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY); 
    ioctl(uinp_fd, UI_SET_EVBIT, EV_REL); 
    ioctl(uinp_fd, UI_SET_EVBIT, EV_REP); 
    for (i=0; i < 256; i++) { 
     ioctl(uinp_fd, UI_SET_KEYBIT, i); 
    } 
    /* Create input device into input sub-system */ 
    write(uinp_fd, &uinp, sizeof(uinp)); 
    if (ioctl(uinp_fd, UI_DEV_CREATE)) 
    { 
     printf("Unable to create UINPUT device.\n"); 
     return -1; 
    } 
    return 0; 
} 

このリンクに示されているように、私はすでに、X11のライブラリを使用して解決策を試してみた: Convert ASCII character to x11 keycode 残念ながら、私はuinputを使用して作成することができたキーボードX11が使用するものとは異なるキーコードを取ります。 (私のキーボードは、dumpkeysコマンドを使用して取得できるのと同じキーコードをとると思います)。 X11のキーコードを正しく変換する(カーネル?)キーコードに変換することは確実ですが、依存関係の数を低く抑えたいと思います。

私は現在、linux.hに示されているようにEVIOCGKEYCODEを使用しようとしていますが、それがどのように動作するのかを理解するのが難しく、本当に欲しいものの逆をすると思います。

int main(int argc, char *argv[]) { 
    setup_uinput_device(); 
    struct input_keymap_entry mapping; 
    int i =0; 
    /* Set the max value at 130 just for the purpose of testing */  
    for (i=0; i<130; i++) { 
     mapping.scancode[0] = i; 
     if(ioctl(fd, EVIOCGKEYCODE_V2, mapping)) { 
      perror("evdev ioctl"); 
     } 
     printf("Scancode= %d, Keycode = %d\n", 
       mapping.scancode[0], mapping.keycode); 
    } 
    /* Simple function to destroy the device */ 
    destroy_uinput_device(); 
    return 0; 
} 

私は次のエラーを取得する: "evdevのioctlの:無効な引数"

は、ここでの例です。 私はPS2キーボードで使用されていた古い方法だと読んだので、うまくいきません。

私が検討する最後の解決策は、後で使うことができるテーブルやマップのダンプキーの結果を解析することですが、パフォーマンス上の問題が発生すると思います。既に存在するかもしれないものを再作成したくありません。

答えて

0

だからトライアウトの多くの後、私は最終的に、カーネルによって使用されるキーコードはX11で使用されるものマイナス8

は、私が第1の符号化を管理しなければならなかっただろうと同じであることを理解することができました。私は(€のような)マルチバイトエンコードされた文字を管理するために、次のコードを使用しました:

char *str = "Test €"; 
    size_t mbslen; /* Number of multibyte characters in source */ 
    wchar_t *wcs; /* Pointer to converted wide character string */ 
    wchar_t *wp; 
    setlocale(LC_ALL, ""); 

    mbslen = mbstowcs(NULL, str, 0); 
    if (mbslen == (size_t) -1) { 
      perror("mbstowcs"); 
      exit(ERROR_FAILURE); 
    } 

    wcs = calloc(mbslen + 1, sizeof(wchar_t)); 
    if (wcs == NULL) { 
      perror("calloc"); 
      exit(ERROR_FAILURE); 
    } 

    /* Convert the multibyte character string in str to a wide character string */ 
    if (mbstowcs(wcs, str, mbslen + 1) == (size_t) -1) { 
      perror("mbstowcs"); 
      exit(ERROR_FAILURE); 
    } 

そして、このconversion table from ucs to keysymを使用して、私は私が「exampleに基づいて、キーコードの対応する配列とWIDECHAR配列を変換するために管理しました私の元の質問で提供されています。

最後のステップは、私のuinputキーボードにX11キーコードマイナス8を入力することでした。