Quale tasto ho premuto?


15

Il compito è scrivere codice per identificare quale tasto viene premuto sulla tastiera. Si può presumere che venga premuto un solo tasto alla volta e che esista un layout di tastiera statunitense standard. Questo è il layout con @ sopra 2.

Il codice dovrebbe generare un identificativo univoco per qualsiasi tasto premuto. Ciò include PrtScn, Blocco scorrimento, Pausa, Maiusc sinistro, Maiusc destro, Ctrl sinistro, Ctrl destro, Blocco maiuscole, Tab, Invio, Invio sul tastierino numerico, Blocco numeri, Inserisci, Ins sul tastierino numerico, Backspace, Canc, F1 ... F12, Esc, tasto Windows sinistro, tasto Windows destro, Alt, AltGr, tasto applicazione (menu di scelta rapida) e così via.

Il tuo codice dovrebbe continuare ad aspettare la pressione dei tasti e mostrare la loro identità fino a quando non viene ucciso. Dovrebbe generare l'identificatore non appena viene rilasciata una chiave. Non dovrebbe eseguire alcuna altra azione dalla pressione dei tasti che riceve e non dovrebbe generare nulla a parte l'identificatore univoco.

Nella risposta, si prega di mostrare ciò che si codice output per le seguenti pressioni di tasti: Tab, Pausa, Invio, Invio sul tastierino numerico, tasto Windows sinistro, tasto Windows destro, Inserisci e Ins sul tastierino numerico.

Se hai una tastiera molto diversa, la sfida è ancora quella di produrre un identificatore diverso per ogni singolo tasto della tastiera.


1
In JS (browser JS, comunque), è impossibile verificare se alcuni tasti sono premuti (ad es. Blocco maiuscole, Blocco numerico, Blocco scorrimento, PrtScn). Questo significa che JS non può rispondere?
ETHproductions,

2
@ETHproductions Lo fa davvero. Ci scusiamo con gli amanti di JS ovunque.

2
Requisiti modificati dopo aver fornito 5 risposte (di cui una ora eliminata). Non è proprio giusto ...
Olivier Grégoire,

6
Non credo sia giusto / giusto richiedere l'output per tasti che non sono su molte tastiere come il tasto Windows ecc.
Notts90 è disattivato su codidact.org il

1
@ Notts90 Non fanno parte del layout standard della tastiera americana? upload.wikimedia.org/wikipedia/commons/thumb/5/51/…

Risposte:


22

codice macchina x86, eseguibile DOS, 29 * 28 byte

FAE464D0E873FAE460D0E073F4D41005212192B402CD2188F2CD21EBE3

Questo è un eseguibile COM per MS-DOS , richiede un hardware compatibile con PC IBM .
In particolare un controller 8042 PS / 2 o più probabilmente una sua emulazione tramite SMM .
Per farla breve, dovrebbe funzionare immediatamente su qualsiasi PC tradizionale.

Il codice sorgente è

BITS 16

 ;Disable the interrupts so we don't compete with the IRQ 1 (the 8042 main
 ;device IRQ) handler (the ISR n. 9 by default) for the reading of the codes.
 cli

_wait:

 ;Is 'Output buffer full (OBF)' bit set?

 in al, 64h                ;Read the 8042 status register             
 shr al, 1                 ;Move bit 0 (OBF) into the carry flag

jnc _wait                  ;Keep spinning if CF = OBF not set

 ;Read the scan code S
 in al, 60h

 ;Is S a break code?

 shl al, 1                 ;Bit 7 is set if it is
jnc _wait

 ;PART 2

 ;AL = S mod 10h := y, AH = S / 10h := x
 aam 16
 add ax, 2121h             ;Make both quantities in the printable ASCII range (skip space though)

 ;Print y
 xchg dx, ax
 mov ah, 02h
 int 21h                   ;int 21/ah=02 prints the char in DL

 ;DH is still valid here, it holds x. We print it now
 mov dl, dh
 int 21h

 ;Never terminate
jmp _wait

Ho diviso il programma in due parti.

La prima parte riguarda la lettura degli scancodes . Gli scancodes sono valori numerici associati ad ogni chiave.
Si noti che questi sono codici hardware, non dipendono dal sistema operativo o dal set di caratteri. Sono come una coppia codificata (colonna, riga) della chiave.
Ogni tasto ha uno scancode, anche quei tasti funzione bizzarri non standard presenti su alcune tastiere (ad es. Il tasto "apri calc").
Alcune chiavi hanno scancode multi-byte, hanno prefissi progettati per rendere decodificabile il flusso semplicemente guardando la sequenza di byte.
Quindi ogni chiave ottiene il suo identificatore univoco, anche CTRL, MAIUSC, WinKeys e così via.

Vengono elaborati solo i "codici di interruzione", inviati quando viene rilasciata una chiave, i "codici di creazione" vengono ignorati.
I former hanno il bit più alto (bit 7 per un byte) impostato, quindi è facile riconoscerli.

La seconda parte riguarda la stampa di un byte.
La stampa è sempre lunga nell'assemblaggio, non abbiamo builtin.
Per farla breve, e poiché era necessario scrivere un identificatore della chiave, ho abbandonato i numeri decimali o esadecimali a favore di una codifica personale.

Un byte xy, dove x è il nibble superiore e y il inferiore è stampato come due caratteri successivi c 0 e c 1 definiti come:

c 0 = 0x21 + y
c 1 = 0x21 + x

Si noti che il bocconcino inferiore viene stampato per primo (questo mi ha risparmiato uno scambio).
La logica è quella di mappare ciascuno dei 16 possibili valori di un bocconcino in caratteri ASCII consecutivi da '!'.
In poche parole questo è un numero esadecimale ma con

  1. I bocconcini si scambiarono
  2. !"#$%&'()*+,-./01 come cifra (als) anziché 0123456789abcdef

Eseguendolo in DOSBox e premendo un tasto casuale (alcuni dei quali è un tasto speciale, ma nota che DOSBox come processo di Windows non è in grado di acquisire tutti i tasti) produce

DOSBox che esegue l'identificatore chiave

Si noti che questo programma non termina mai (inoltre, prende il controllo completo del PC disabilitando gli interrupt) come credo fosse inteso dalla domanda (semplicemente non c'è uccisione di processi in DOS).


* Ridotto grazie a CodyGray .


L'uso INdell'istruzione ha funzionato per essere più piccolo in termini di byte rispetto alla chiamata degli interrupt del BIOS ROM (ad es. int 16h, Funzione 10h)?
Cody Gray,

@CodyGray Molto probabilmente no, è possibile saltare l'intero loop. In qualche modo sono saltato direttamente inall'istruzione. Questo è in realtà un ottimo punto che hai. Se non l'hai già fatto, perché non pubblicarlo come risposta? :)
Margaret Bloom,

1
Bene, ora stai parlando pazzo! Sembra molto più lavoro che commentare la tua risposta esistente. :-p Sto giocando a mettere insieme qualcosa. Un consiglio divertente, però: quando si gioca a golf, xchgcon l'accumulatore come uno dei registri è 1 byte, quindi è meglio di un 2 byte mov.
Cody Gray,

1
Va bene, il problema int 16hè che non ottengo i codici di scansione per i tasti Maiusc, Blocco scorrimento o Pausa / Interruzione (forse altri), e questo è richiesto dalla sfida. La tua soluzione di lettura dell'input direttamente dall'I / O funziona, anche se mi sembra che restituisca lo stesso valore per tutte le chiavi nel cluster Ins / Del / Home / End / PgUp / PgDown.
Cody Gray,

1
@PeterCordes: anche PAUSE ha un comportamento strano, IIUC invia il codice di interruzione insieme al codice di creazione alla pressione del tasto e non invia nulla al rilascio del tasto. O è quello che ho capito dall'Enciclopedia di programmazione di giochi per PC.
ninjalj,

12

Java 7 o versione successiva, 246 228 byte

import java.awt.event.*;class K{public static void main(String[]a){new java.awt.Frame(){{addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent e){System.out.println(e);}});show();setFocusTraversalKeysEnabled(0<0);}};}}

Ungolfed:

import java.awt.event.*;
class K{
    static void main(String[]a){
        new java.awt.Frame(){
            {
                addKeyListener(new KeyAdapter(){
                    public void keyPressed(KeyEvent e){
                        System.out.println(e);
                    }
                });
                show();
                setFocusTraversalKeysEnabled(0<0);
            }
        };
    }
}

-18 grazie a @ OlivierGrégoire per show(), 0<0eimport java.awt.event.*;

Che si traduce in:

inserisci qui la descrizione dell'immagine

Gestisce anche le maiuscole per i caratteri maiuscoli, il tasto Windows, i blocchi maiuscole, ecc ... Puoi vederlo anche stampare i "modificatori", che sono "tasti trattenuti".

java.awt.event.KeyEvent[KEY_PRESSED,keyCode=27,keyText=Escape,keyChar=Escape,keyLocation=KEY_LOCATION_STANDARD,rawCode=27,primaryLevelUnicode=27,scancode=1,extendedKeyCode=0x1b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=192,keyText=Back Quote,keyChar='`',keyLocation=KEY_LOCATION_STANDARD,rawCode=192,primaryLevelUnicode=96,scancode=41,extendedKeyCode=0xc0] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=9,keyText=Tab,keyChar=Tab,keyLocation=KEY_LOCATION_STANDARD,rawCode=9,primaryLevelUnicode=9,scancode=15,extendedKeyCode=0x9] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=20,keyText=Caps Lock,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=20,primaryLevelUnicode=0,scancode=58,extendedKeyCode=0x14] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=16,keyText=Shift,keyChar=Undefined keyChar,modifiers=Shift,extModifiers=Shift,keyLocation=KEY_LOCATION_LEFT,rawCode=16,primaryLevelUnicode=0,scancode=42,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyText=Ctrl,keyChar=Undefined keyChar,modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_LEFT,rawCode=17,primaryLevelUnicode=0,scancode=29,extendedKeyCode=0x11] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=524,keyText=Windows,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_LEFT,rawCode=91,primaryLevelUnicode=0,scancode=91,extendedKeyCode=0x20c] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=18,keyText=Alt,keyChar=Undefined keyChar,modifiers=Alt,extModifiers=Alt,keyLocation=KEY_LOCATION_LEFT,rawCode=18,primaryLevelUnicode=0,scancode=56,extendedKeyCode=0x12] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=32,primaryLevelUnicode=32,scancode=57,extendedKeyCode=0x20] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=18,keyText=Alt,keyChar=Undefined keyChar,modifiers=Alt,extModifiers=Alt,keyLocation=KEY_LOCATION_RIGHT,rawCode=18,primaryLevelUnicode=0,scancode=56,extendedKeyCode=0x12] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=17,keyText=Ctrl,keyChar=Undefined keyChar,modifiers=Ctrl,extModifiers=Ctrl,keyLocation=KEY_LOCATION_RIGHT,rawCode=17,primaryLevelUnicode=0,scancode=29,extendedKeyCode=0x11] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=37,keyText=Left,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=37,primaryLevelUnicode=0,scancode=75,extendedKeyCode=0x25] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=16,keyText=Shift,keyChar=Undefined keyChar,modifiers=Shift,extModifiers=Shift,keyLocation=KEY_LOCATION_RIGHT,rawCode=16,primaryLevelUnicode=0,scancode=42,extendedKeyCode=0x10] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=38,keyText=Up,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=38,primaryLevelUnicode=0,scancode=72,extendedKeyCode=0x26] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=39,keyText=Right,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=39,primaryLevelUnicode=0,scancode=77,extendedKeyCode=0x27] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=96,keyText=NumPad-0,keyChar='0',keyLocation=KEY_LOCATION_NUMPAD,rawCode=96,primaryLevelUnicode=48,scancode=82,extendedKeyCode=0x60] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=110,keyText=NumPad .,keyChar='.',keyLocation=KEY_LOCATION_NUMPAD,rawCode=110,primaryLevelUnicode=46,scancode=83,extendedKeyCode=0x6e] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_NUMPAD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=107,keyText=NumPad +,keyChar='+',keyLocation=KEY_LOCATION_NUMPAD,rawCode=107,primaryLevelUnicode=43,scancode=78,extendedKeyCode=0x6b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=109,keyText=NumPad -,keyChar='-',keyLocation=KEY_LOCATION_NUMPAD,rawCode=109,primaryLevelUnicode=45,scancode=74,extendedKeyCode=0x6d] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=106,keyText=NumPad *,keyChar='*',keyLocation=KEY_LOCATION_NUMPAD,rawCode=106,primaryLevelUnicode=42,scancode=55,extendedKeyCode=0x6a] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=34,keyText=Page Down,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=34,primaryLevelUnicode=0,scancode=81,extendedKeyCode=0x22] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=33,keyText=Page Up,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=33,primaryLevelUnicode=0,scancode=73,extendedKeyCode=0x21] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=35,keyText=End,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=35,primaryLevelUnicode=0,scancode=79,extendedKeyCode=0x23] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=36,keyText=Home,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=36,primaryLevelUnicode=0,scancode=71,extendedKeyCode=0x24] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=46,primaryLevelUnicode=0,scancode=83,extendedKeyCode=0x7f] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=155,keyText=Insert,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=45,primaryLevelUnicode=0,scancode=82,extendedKeyCode=0x9b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=123,keyText=F12,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=123,primaryLevelUnicode=0,scancode=88,extendedKeyCode=0x7b] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=122,keyText=F11,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=122,primaryLevelUnicode=0,scancode=87,extendedKeyCode=0x7a] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=121,keyText=F10,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=121,primaryLevelUnicode=0,scancode=68,extendedKeyCode=0x79] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=120,keyText=F9,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=120,primaryLevelUnicode=0,scancode=67,extendedKeyCode=0x78] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=119,keyText=F8,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=0,scancode=66,extendedKeyCode=0x77] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=118,keyText=F7,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=118,primaryLevelUnicode=0,scancode=65,extendedKeyCode=0x76] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=117,keyText=F6,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=117,primaryLevelUnicode=0,scancode=64,extendedKeyCode=0x75] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=116,keyText=F5,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=116,primaryLevelUnicode=0,scancode=63,extendedKeyCode=0x74] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=115,keyText=F4,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=115,primaryLevelUnicode=0,scancode=62,extendedKeyCode=0x73] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=114,keyText=F3,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=114,primaryLevelUnicode=0,scancode=61,extendedKeyCode=0x72] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=113,keyText=F2,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=113,primaryLevelUnicode=0,scancode=60,extendedKeyCode=0x71] on frame0
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=112,keyText=F1,keyChar=Undefined keyChar,keyLocation=KEY_LOCATION_STANDARD,rawCode=112,primaryLevelUnicode=0,scancode=59,extendedKeyCode=0x70] on frame0

I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Dennis,

11

HTML (con Javascript), 46 31 caratteri, 46 31 byte

Usando questo per differenziare il tastierino numerico invio e ritorno, LControl e RControl ... Non più da quando gli apripisti hanno trovato il modo di farlo con una chiamata di funzione signle.

<body onkeyup=alert(event.code)

Uscite specifiche:

LE USCITE CHE SONO ANCORA CON I NUMERI SONO QUELLI CHE NON POSSO TESTARE SUL MIO COMPUTER PORTATILE,
ATTENDERE CHE HANNO L'ACCESSO A QUESTI TASTI

PrtScn ->
Blocco scorrimento PrintScreen ->
Pausa ScrollLock -> Pausa
Maiusc sinistra Maiusc -> Maiusc Sinistra
destra Maiusc -> Maiusc destra
Sinistra Ctrl -> Contrl Sinistra
destra Ctrl -> ControlRight
Blocco maiuscole -> Tasto CapsLock
-> Scheda
Enter -> Enter
Enter sul numero tastierino numerico -> Tastierino
numerico - Bloc Num ->
Inserisci blocco numeri -> Inserisci
tastierino numerico -> Tastierino numerico0
Backspace -> Backspace
Del -> Elimina
F1 ... F12 -> Da F1 a F12
Esc
-> Esci da sinistra tasto Windows -> MetaLeft
destra Tasto Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (tipo di buggy, rileva ControlLeft e quindi AltRight,ma è davvero AltRight)
chiave dell'applicazione (menu di scelta rapida) -> ContextMenu

EDIT:
1 byte salvato su ;dopo aver chiamato la funzione
18 byte salvati grazie a Lil 'Bits e ETHproductions, hanno notato che ho dimenticato di abbreviare i nomi di funzioni e var.
32 byte salvati grazie a RogerSpielker, notò che stavo facendo codice risparmiato senza motivo; e ancora -2 byte: onkeydown-> onkeyup
1 byte salvato: nessuna necessità di barra finale
2 byte salvati grazie a CraigAyre: with()funzione
2 byte salvati grazie solo a ASCII: keyal posto di which
4 byte salvati, dato che abbiamo testo, non è necessario per '-'+(ogni identificatore è unico senza questo) 1 byte salvato grazie solo a ASCII (di nuovo): non più simboli di chiusura > 15 byte salvati grazie a apsiller, come detto all'inizio della mia risposta.

<body onkeyup=alert(event.code)


Aspetta ... come viene rilevato ... Blocco maiuscole ... Pensavo fosse impossibile ... Eh, vabbè. PrtScn e SysRq non funzionano per me, ma sono su un laptop con una piccola tastiera che utilizza Fn + End e Fn + Home per quei due tasti.
ETHproductions,

Mi piace questa risposta ma sembra che abbia dei problemi. Tab non segnala nulla per me quando lo collaudo su codepen.io/anon/pen/MoLPQM . Anche F12, PrtScn non segue questa regola "Non dovrebbe eseguire alcuna altra azione dalla pressione dei tasti che riceve e non dovrebbe produrre nulla a parte l'identificatore univoco."

@Lembik usando html, non è davvero possibile impedire al sistema di usare la chiave. È necessario forzarlo a non riconoscere gli input chiave con un linguaggio efficace della macchina (o del sistema) (come forse C). E per quanto riguarda la scheda, non so a quali condizioni funziona (voglio dire, a volte funziona e talvolta no, non so come la mia risposta tratta le chiavi percorribili.
V. Courtois

@Lembik Se visualizzi il codice in modo indipendente (non uno snippet o un violino o simile), pagina a schermo intero (ad es. Con F11), acquisisce le schede; il fatto che non acquisisca le schede è una funzione dello stato dell'ambiente browser più grande, non del codice in esecuzione sulla pagina. Per quanto riguarda la prevenzione dei comportamenti di default, <body onkeydown=return!!alert(event.code)>dovrebbe fare il trucco tornando falsesukeydown
apsillers il

8

Tcl / Tk, 22 caratteri

bind . <Key> {puts %K}

Esecuzione di esempio:

chiavi identificate da Tcl / Tk

Appunti:

  • Nessun tasto destro di Windows sulla mia tastiera ☹ ( designer intelligente ha messo l'interruttore della retroilluminazione al suo posto)
  • L'inserto del tastierino numerico genera un codice diverso in base allo stato di NumLock
  • La manopola del volume genera codici specifici per X.org, tutti gli altri sono solo normali palestre

6

Bash con X.org, 21 byte

xev|awk 'NR%2&&/\(k/'

Sfortunatamente, non posso provarlo dal momento che sono su MacBook su Linux: niente PrntScr, nessuna tastiera numerica e tutto il resto.

xevè uno strumento che genera eventi del mouse e della tastiera sotto X.org. Lo installo per awk, filtro anche le linee (poiché ogni tasto viene mostrato quando viene premuto il tasto, e poi quando viene rilasciato), e seleziono solo quelli che contengono (k- questa stringa è in ogni riga che descrive il tasto premuto.


Potresti aggiungere gli output di esempio elencati nella domanda per favore.

1
@Lembik tutto l'output appare dopo essere uscito.
enedil,

Ah. Questo non è ciò che le specifiche richiedono. Lo chiarirò ora.

Questo ora dà un errore di sintassi.

3
Nota che Linux non implica X11. ad esempio, questo non funzionerebbe su una console di testo (usa showkey -slì: P) o su un desktop con interfaccia grafica Wayland puro. Questa è davvero una risposta bash + Xorg.
Peter Cordes,

5

C e Win32, 240 224 216 205 202 194 191 byte

#include<d3d.h>
#include<stdio.h>
w[9];p(x,y,a,b){printf("%X",a^b);}main(){w[1]=p;w[9]=p;CreateWindow(RegisterClass(w),0,1<<28,0,0,0,0,0,0,0,0);for(;GetMessage(w,0,16,0);)DispatchMessage(w);}

Uscite

TAB: F0008C00F0008

PAUSE: 450012C0450012

ENTER: 1C000CC01C000C

NUMPAD-ENTER: 11C000CC11C000C

WINDOWS-LEFT: 15B005AC15B005A

WINDOWS-RIGHT: 15C005DC15C005D

INSERT: 152002CC152002C

NUMPAD-INSERT: 52002CC052002C

Spiegazione

#include <d3d.h> // shortest built-in header that includes windows.h
#include <stdio.h> // for printf

w[9]; // space for wndclass-data array

// function castable to the signature of WNDPROC
p(x,y,a,b)
{
    // key and state are encoded in the last two 4-byte arguments to wndproc
    printf("%X",a^b);
}

main(m)
{
    // set minimal window class equivalent data pointing to wndproc above
    w[1]=p;w[9]=p;

    // create the window using the class, with WS_VISIBLE flag
    CreateWindow(RegisterClass(w),0,1<<28,0,0,0,0,0,0,0,0)
    for(;GetMessage(w,0,16,0);) // filter messages 15 and lower, which fire without input
        DispatchMessage(w);
}

Le modifiche

-16 grazie a @ugoren

-8: modificato WNDCLASSin intarray poiché tutti e 10 i membri sono 4 byte

-11: inizializzazione parziale dell'array wndclass-data, ridotta a 9 elementi

-3: usa intdecl implicito per l'array wndclass-data

-8: rimuove la nuova riga dal formato di output (non richiesto nelle specifiche e stampa immediatamente senza di essa); passare RegisterClassad CreateWindowarg, usando restituito ATOM; imposta il nome wndclass su mcui è necessario solo un byte zero per essere una stringa valida.

-3: riutilizzare wvar per i MSGdati


Fare la stessa cosa con C ++ usando cout non sarebbe molto più breve?
onurcanbektas,

@Leth No. <iostream>+ std::cout<<a^b<<"\n"è più lungo. Inoltre, penso che dovresti aggiungere tipi restituiti ai decls di funzione e mnon potrebbe essere un implicito int.
MooseBoys,

Salva un for(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
personaggio

Inoltre, p(x,y,a,b)e (void*)pdovrebbe salvare alcuni.
ugoren,

3

Java (OpenJDK 8) , 369 byte

import java.awt.event.*;import javax.swing.*;class F{public static void main(String[] a){JFrame f=new JFrame();f.addKeyListener(new KeyListener(){public void keyPressed(KeyEvent e){System.out.print(e.getKeyCode()*8+e.getKeyLocation());}public void keyTyped(KeyEvent e){}public void keyReleased(KeyEvent e){}});f.setVisible(true);f.setFocusTraversalKeysEnabled(false);}}

Questo non può essere eseguito con TIO perché utilizza un'interfaccia grafica, ma funziona sul mio computer.

Pausa: 153
Immettere: 81
Inserisci su NumPad: 84
Tasto Super sinistro: 193 (Dopo aver disabilitato il collegamento Menu per il mio desktop)
Tasto Super destro: 201
Inserisci: 241
Inserisci su Numpad: 522948 (non ne ho uno, ma è quello che ottieni quando premi 5 con Bloc Num disattivato. Quando Bloc Num è attivo, ottieni 812.)

Ungolfed / Spiegazione:

import java.awt.event.*; // KeyListener, KeyEvent
import javax.swing.*; // JFrame

class F implements KeyListener {

    public static void main(String[] a) {
        JFrame f=new JFrame(); // creates a new GUI frame
        f.addKeyListener(new KeyListener() {  // puts a KeyListener in the frame with the following properties:

            // Method that runs whenever a key is pressed
            public void keyPressed(KeyEvent e) {
                // getKeyCode returns an integer that uniquely identifies the key,
                // but not the location (e.g. LShift and RShift have the same key code)
                // To fix this, I scale up the key code by 8 and add the location,
                // which is always 0-4 (Standard, Left, Right, NumPad, or Unknown)
                // I could have scaled by 5 instead but I wasn't really thinking
                System.out.print(e.getKeyCode() * 8 + e.getKeyLocation());
                // If you want nicer-looking output, just change "print" to "println"
            }

            // Method that runs whenever a printable character is typed (does nothing)
            public void keyTyped(KeyEvent e){}

            // Method that runs whenever a keyboard key is released (does nothing)
            public void keyReleased(KeyEvent e){}
        });

        f.setVisible(true); // the frame will only except key presses if it is visible
        f.setFocusTraversalKeysEnabled(false); // disables "focus traversal" keys (such as Tab) from actually traversing focus
    }
}

Non sembra funzionare con il tasto Tab?
Colpisci il

setFocusTraversalKeysEnabled(false);nella tua risposta risolverà questo.
Magic Octopus Urn

@MagicOctopusUrn Non so cosa faccia e non credo di volerlo fare: P
musicman523

Fa funzionare la tua risposta per la chiave TAB, poiché la risposta non è valida senza di essa.
Magic Octopus Urn

Ohhhhh capisco - Tab è una "chiave di attraversamento della messa a fuoco"
musicman523

3

Scala 2.10+, 279 caratteri, 279 byte

Questa è una risposta allo scala :) anche se mi sembra di fare Java. Comunque non possiamo provarlo su TIO.

import scala.swing._
import java.awt.event._
object M extends SimpleSwingApplication{def top=new MainFrame{this.peer.addKeyListener(new KeyListener(){def keyPressed(e:KeyEvent){print(e.getKeyCode+"-"+e.getKeyLocation)}
def keyReleased(e:KeyEvent){}
def keyTyped(e:KeyEvent){}})}}

È triste che dobbiamo dichiarare tutti i metodi ereditati anche se non li usiamo: posso rimuoverli dal conteggio dei byte, poiché alcuni flag del compilatore possono consentire di non dichiararli?

Questo stampa (come per la mia risposta html-js) il tasto premuto, "-" e quindi la sua "posizione".

Per esempio :

PrtScn -> non verificabile
Blocco scorrimento -> 145-1
Pausa -> 19-1
spostamento sinistro -> 16-2
spostamento destro -> 16-3
sinistro Ctrl -> 17-2
destro Ctrl -> 17-3
Blocco maiuscole -> 20-1
Tab -> non verificabile
Enter -> 10-1
Enter sul tastierino numerico -> 10-4
Bloc Num -> 144-4
Inserisci -> 96-1
Ins sul tastierino numerico -> 96-4
Backspace -> 8-1
Canc -> 127-1
F1 ... F12 -> 112-1 a 123-1
Esc -> 27-1
tasto Windows sinistro -> 524-2
tasto Windows destro -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (tipo di buggy, rileva 17-2 e quindi 18-3,ma è in effetti 18-3)
chiave dell'applicazione (menu di scelta rapida) -> 525-1

Anche se penso che dipenda dal computer: / Sono su un laptop azerty ora.


Se non si desidera contare le dichiarazioni non necessarie, potrebbe essere necessario includere la lunghezza dei flag del compilatore non standard. A meno che i vecchi compilatori non lo usassero di default? Le risposte C di solito devono essere compilate -std=c89dal momento che i compilatori moderni impostano di default su c99 o c11, ma non è necessario contarlo. Quindi non sono sicuro di quale sarebbe la sentenza dal meta-golf del meta.
Peter Cordes

3

TI-BASIC, 19 byte

PROGRAMMA: S

If Ans
Disp Ans
getKey
prgmS
  • Inserisci: 105,
  • Tasto sinistro: 24,
  • Tasto destro: 26,
  • Ins [ert] è un po 'diverso perché normalmente occorrerebbero due pressioni di tasti per arrivare a, ma quelle sarebbero 21 seguite da 23.

Ecco un'illustrazione del resto dei tasti:

inserisci qui la descrizione dell'immagine

Spiegazione:

PROGRAMMA: S L'editor visualizza il nome in alto a parte il codice; il nome è "S"

If Ans    // If the last input isn't zero
Disp Ans  // Display the last input
getKey    // Input a key press
prgmS     // Call the same program in a recursive fashion

Questo, sfortunatamente, non è possibile farlo in Arnold C, quindi ho dovuto attenermi a TI-BASIC.


1
Funziona per ogni chiave in quella foto? In caso contrario, per quali chiavi non funziona?

2
Sì, funziona per ogni tasto tranne il pulsante di accensione, riservato per uccidere il programma senza estrarre una batteria dalla calcolatrice.
bearacuda13,

@ bearacuda13: ho un calcolatore uguale che ho comprato 18 anni fa e non conoscevo i dettagli della chiave ON da anni. Lo
usavo

1

C #, 144 + 601 = 745 byte

È composto da due classi, non sono riuscito a combinarle con successo in una classe.

Classe principale:

namespace System.Windows.Forms{class P:Form{static void Main(){Application.Run(new P());}P(){new Reflection.M().U+=k=>Console.Write(k.f+k.v);}}}

Classe di aggancio:

namespace System.Reflection{using Runtime.InteropServices;public class M{public delegate void d(s s);event d u;public event d U{add{if(h<1){j=m;h=SetWindowsHookEx(13,j,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);}u+=value;}remove{u-=value;}}public struct s{public int v;public int c;public int f;}[DllImport("user32.dll")]static extern int SetWindowsHookEx(int idHook,p lpfn,IntPtr hMod,int dwThreadId);delegate int p(int c,int w,IntPtr l);p j;int h;int m(int c,int w,IntPtr l){if(c>=0&u!=null&(w==257|w==261))u.Invoke((s)Marshal.PtrToStructure(l,typeof(s)));return -1;}}}

Uscite:

  • Tab: 137
  • Pausa: 147
  • Accedere: 141
  • NumPad Enter: 142
  • Finestre a sinistra: 220
  • Finestre giuste: 221
  • Inserire: 174
  • Inserisci NumPad: 224

Posso ridurre un po 'i byte cambiando ||in |e altri golf simili ma il mio cervello ha bisogno di riposo dopo averlo fatto!
TheLethalCoder

Nella classe Hook, penso che public int v;public int c;public int f;potrebbe essere abbreviato inpublic int v,c,f;
Mark Marks

@QuestionMarks Una buona idea giocherà a golf quando torno a un computer
TheLethalCoder

1

Tasto di scelta automatica , 26 byte

loop{
input,x,L1M
send %x%
}

Impossibile eseguire il test (solo win), ma l' Mopzione dice

M: I tasti modificati come Control-A fino a Control-Z vengono riconosciuti e trascritti se corrispondono a caratteri ASCII reali.

Quindi dovrebbe andare bene.


1

WinApi C ( gcc ), 156 byte

#include <d3d.h>
#define b GetStdHandle(-10)
BYTE i[20];main(){SetConsoleMode(b,0);a:ReadConsoleInput(b,i,1,i+5);*i^1||*(i+4)||printf("%X\n",i[10]);goto a;}

Questo programma stampa il codice chiave virtuale di Windows associato a ciascun tasto di input della tastiera. Il \nnelprintf format-string è opzionale (ma rende uscita human-friendly) e può essere abbandonato per un punteggio totale di 154 byte . Un modo semplice per uccidere il programma (senza taskmgr) è con CTRL + PAUSE. Se hai una tastiera con un tasto Fn, questo programma non può prenderlo dal momento che non è nemmeno notato da Windows.

  • Ringraziamo la risposta di MooseBoys per il #include <d3d.h>trucco e l'ispirazione per l' BYTEarray.

Il programma con variabili locali, leggibilità e senza avvisi del compilatore è simile al seguente:

#include <windows.h>
#include <stdio.h>

int main(void)
{
    HANDLE conIn = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD ir;
    DWORD useless;

    SetConsoleMode(conIn, 0);

    for(;;)
    {
        ReadConsoleInput(conIn, &ir, 1, &useless);

        if(ir.EventType == KEY_EVENT && !ir.Event.KeyEvent.bKeyDown)
            printf("%X\n", ir.Event.KeyEvent.wVirtualKeyCode);
    }

    return 0;
}

1

C (gcc) + Win32, 94 95 98 105 107 110 byte

#import"d3d.h"
j;f(){for(;;)for(j=191;j--;)GetAsyncKeyState(j)&(j<16||j>18)?printf("%d",j):0;}

Il codice acquisisce i tasti anche dopo aver perso lo stato attivo.

I seguenti screenshot vengono registrati aggiungendo spazi tra le uscite ( printf("%d ",j);+1 byte) per una migliore leggibilità:

schermata chiave

Left-ctrl Left-win Left-alt Space Right-alt Right-win Right-menu Right-ctrl Left-shift Z X C Right-shift Left-shift 1 2 3 Num 1 Num 2 Num 3 Left-shift +/= (on the main part) Num + Left-alt PrtScn

Il codice utilizza GetAsyncKeyStateper interrogare lo stato della chiave senza controllare la coda dei messaggi, in genere più in tempo reale rispetto ad altri approcci in modalità utente (tranne DirectInput). Questo approccio è ampiamente utilizzato nei keylogger.

(j<16||j>18)filtra i normali Ctrl / Alt / Maiusc. 16/17/18 viene attivato ogni volta che si preme uno sinistro o destro, insieme al valore vkey specificato nella posizione.


1

PowerShell, 34 byte

$Host.UI.RawUI.ReadKey().Character

Output sulla stessa riga dell'input, che può essere un po 'confuso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.