2014-12-20 18 views
11

Voglio agganciare la gestione degli eventi dei tasti del desktop di Linux.hook in gestione evento chiave linux

Premere CapsLock dovrebbe immettere una sorta di riga di comando.

Alcuni dei comandi che voglio implementare:

  • d/x: cancella dalla posizione corrente del cursore fino carattere x. (ispirato da vi)
  • a: Vai all'inizio della riga, come pos1. (ispirato da emacs).
  • k: Elimina fino alla fine della riga. (ispirato da emacs).
  • ...

I comandi dovrebbe funzionare in qualsiasi campo di testo: Browser, Mail Client, terminale di GNOME, ...

per quanto ne so basso xmodmap livello non mi aiuterà qui.

È possibile qualcosa del genere?

Dove devo posizionare il gancio?

piattaforma di destinazione attuale è Ubuntu> = 14.04

Background: voglio mantenere le mie dita che punta su F e J, e utilizzare il computer senza guardare la tastiera. Funziona per la A-Z da diversi anni, ma chiavi come Pos1/End non sono di facile accesso.

Si prega di lasciare un commento se non si capisce una parte di questa domanda. Grazie.

Aggiornamento

Questa domanda è solo a come agganciare nella gestione degli eventi chiave. L'altra roba (riga di comando) è un argomento diverso. Come si può prendere ad esempio CapsLock x?

Update2 Vedo che non esiste una soluzione semplice e immediata. Se non hai una risposta, ma sai dove posso trovare più aiuto (come chiedere sulla mailing list FOO), per favore dimmi.

Update3 Dal momento che alcune persone non capiscono quello che voglio, cerco di spiegarlo: Se io uso emacs o bash mi sento come essere in controllo se il computer: è come volare, con solo pochissimi movimenti Posso dire al computer di fare ciò che voglio. Modificare il testo nella textarea del browser, in LibreOffice o nell'usare il thunderbird fa sparire questa sensazione. I movimenti del cursore sono ingombranti, non sembra di volare. Voglio controllare il desktop, non solo una singola applicazione, e tenere le dita puntate sui tasti F e J.

+3

Cari giù elettori: Ti prego, dimmi che cosa c'è di sbagliato con questa domanda. Cosa posso fare per migliorarlo? Due persone hanno votato perché "troppo ampio". Non capisco Cosa c'è di troppo in questa domanda? – guettli

+0

Se questo lavoro in nessuna schermata X è attivo? – Basilevs

+0

@Basilevs No, per me è sufficiente se X-desktop è in esecuzione. Non è necessario che sia disponibile se la schermata di accesso X richiede l'utente/password o la console di testo (Ctrl-Alt-F1). – guettli

risposta

4

Il modo brute-force sarebbe modificare/ricreare il pacchetto xserver-xorg-input-evdev e sostituire /usr/lib/xorg/modules/input/evdev_drv.so. Vorrei iniziare tentando di modificare la funzione EvdevQueueKbdEvent() in xf86-input-evdev-2.9.0/src/evdev.c. Non sembra una soluzione molto elegante, ma penso che avrai la flessibilità di modificare la coda degli eventi della tastiera.

È possibile una soluzione meno intrusiva utilizzando XGRabKey() (alcuni dettagli here) e/o XGrabKeyboard().

Alcune informazioni, che possono essere utili here (relativo all'estensione XTest).

+1

Grazie mille. Questo è il primo feedback positivo che ottengo. La modifica di evdev.c non sembra molto flessibile. La mia estensione dovrebbe essere compilata per ogni xserver. Forse è possibile sostituire il metodo in fase di esecuzione ... – guettli

+0

@guettli, sì, questa è una specie di "analisi di fattibilità". In realtà penso che si possa costruire e distribuire il driver evdev' modificato/rinominato se non viene trovata una soluzione beter, ma potrebbe richiedere più lavoro durante la prototipazione. E non sono sicuro che sia il problema più grande che avrai nel breve periodo. – kestasx

3

Un altro modo di guardare la tua domanda: vuoi qualche specialista window manager. Leggi le specifiche EWMH per i dettagli. Leggi prima di una panoramica di X11.

Oppure considerare alcuni esistenti X window manager. Ce ne sono molti. Sospetto che ratpoison o xmonad (o forse sawfish, ecc.) Possano essere configurati per soddisfare le tue esigenze. (Ma io non conosco bene queste WM).

Pensaci due volte prima di implementare il tuo gestore di finestre da zero. Potrebbe significare anni di lavoro! AFAIU, un WM può reindirizzare, filtrare, afferrare o sintetizzare eventi di tastiera o mouse.

Naturalmente, con wayland le cose saranno diverse.

+0

Sì, l'implementazione di un gestore di finestre richiede molto lavoro. Non voglio reinventare la ruota. La mia soluzione dovrebbe funzionare per ogni gestore di finestre.Voglio solo catturare e modificare gli eventi della tastiera sulla loro strada dal finger press all'applicazione X. – guettli

+0

Per definizione, un gestore di finestre può (o anche deve) catturare tali eventi di tastiera e può prenderli. Hai bisogno di un gestore di finestre. Scegline uno (o adattalo) in base alle tue esigenze. Per favore segui i link che ti ho dato, sono rilevanti! –

+0

So che ho bisogno di un gestore di finestre. Ma una soluzione che ti obbliga a usare un gestore di finestre speciale non è facile da usare. E penso che sia possibile risolvere questo problema con ogni gestore di finestre. – guettli

9

UPDATE

Invece di dire al server X di ignorare il dispositivo, è possibile utilizzare EVIOCGRAB ioctl, che ho aggiunto al programma qui di seguito.

Hai bisogno di fare le seguenti cose:

1.Accertarsi di avere modulo CONFIG_UINPUT compilato e caricato. Credo che Ubuntu ce l'abbia già. Se non vedi il dispositivo /dev/uinput, prova a eseguire modprobe -v uinput per caricare il modulo.

2.Run programma seguente come root e dare così il percorso del dispositivo di tastiera, ad esempio:

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

Il seguente programma crea un dispositivo di ingresso falso chiamato uinput-sample e inoltra tutti gli eventi da un dato dispositivo di input ad esso. L'ho adattato dal campione indicato in http://thiemonge.org/getting-started-with-uinput

È possibile modificarlo per fare le cose che si desidera fare.

#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

Grazie per la risposta. Posso scrivere C, ma preferisco Python. Voglio portare la tua soluzione su http://tjjr.fi/sw/python-uinput/ nei prossimi giorni. – guettli

+0

@guettli, controlla la mia altra risposta per la soluzione python –

+0

Python-uinput può essere utilizzato per creare dispositivi ed emettere eventi, non per afferrare, clonare e monitorare dispositivi esistenti. – tuomasjjrasanen

3

Ecco anche un progetto Python usando uinput conducente:

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

+0

Grazie mille. Sembra esattamente quello che stavo cercando – guettli

+0

@guettli, fantastico. sentiti libero di accettare la risposta ... dato che qualcun altro ha ricevuto il premio :) –

Problemi correlati