Ben sadece C :
#include <stdio.h>
#include <curses.h>
#include <time.h> //time(0)
#include <sys/time.h> // gettimeofday()
#include <stdlib.h>
void waitFor (unsigned int secs) {
//credit: http://stackoverflow.com/a/3930477/1074998
unsigned int retTime = time(0) + secs; // Get finishing time.
while (time(0) < retTime); // Loop until it arrives.
}
int
main(void) {
struct timeval t0, t1, t2, t3;
double elapsedTime;
clock_t elapsed_t = 0;
int c = 0x35;
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
halfdelay(5); //increae the number if not working //adjust below `if (elapsedTime <= 0.n)` if this changed
printf("\nSTART again\n");
elapsed_t = 0;
gettimeofday(&t0, NULL);
float diff;
int first = 1;
int atleast_one = 0;
while( getch() == c) { //while repeating same char, else(ffff ffff in my system) break
int atleast_one = 1;
if (first == 1) {
gettimeofday(&t1, NULL);
first = 0;
}
//printf("DEBUG 1 %x!\n", c);
gettimeofday(&t2, NULL);
elapsedTime = (t2.tv_sec - t1.tv_sec) + ((t2.tv_usec - t1.tv_usec)/1000000.0);
if (elapsedTime > 1) { //hit max time
printf("Hit Max, quit now. %f\n", elapsedTime);
system("gnome-terminal");
//waitFor(4);
int cdd;
while ((cdd = getch()) != '\n' && cdd != EOF);
endwin();
exit(0);
}
if(halfdelay(1) == ERR) { //increae the number if not working
//printf("DEBUG 2\n");
//waitFor(4);
break;
}
else {
//printf("DEBUG 3\n");
}
}
if (atleast_one == 0) {
//gettimeofday(&t1, NULL);
t1 = t0;
}
gettimeofday(&t3, NULL);
elapsedTime = (t3.tv_sec - t1.tv_sec) + ((t3.tv_usec - t1.tv_usec)/1000000.0);
printf("Normal quit %f\n", elapsedTime);
if (elapsedTime > 0.6) { //this number based on halfdelay above
system("gedit &");
//system("xdotool key shift+left &");
//system("mplayer -vo caca -quiet 'video.mp4' &");
//waitFor(4);
}
else if (elapsedTime <= 0.6) {
system("xdotool key ctrl+shift+t &");
//waitFor(4);
}
int cdd;
while ( (cdd = getch() ) != '\n' && cdd != EOF);
endwin();
return 0;
}
showkey -a
Bağlama anahtar kodunu almak için kullanın :
xb@dnxb:/tmp$ sudo showkey -a
Press any keys - Ctrl-D will terminate this program
^[[24~ 27 0033 0x1b #pressed F12
91 0133 0x5b
50 0062 0x32
52 0064 0x34
126 0176 0x7e
5 53 0065 0x35 #pressed Numpad 5, 5 is the keycode used in `bind`
^C 3 0003 0x03
^D 4 0004 0x04
xb@dnxb:/tmp$
Bind anahtar kodunu 5 ve komutunu (örn. Run /tmp/.a.out
) ~ / .bashrc dizinine koyun :
bind '"5":"/tmp/a.out\n"'
İlgili anahtar kodunun kaynak kodda da değiştirilmesi gerektiğini unutmayın (onaltılık değer sudo showkey -a
yukarıdan da alabilir ):
int c = 0x35;
Derleme (örneğimde çıktı /tmp/a.out
):
cc filename.c -lcurses
gösteri:
Numpad 5, kısa basış açık yeni sekme, orta basış açık gedit ve uzun basış açık gnome terminali.
Bu doğrudan gnome masaüstü yöneticisi herhangi bir pencerede uygulanabilir değildir, ama ben bunu (zor) nasıl uygulamak için bazı fikir vermek gerektiğini düşünüyorum. Sanal Konsolda (Ctrl + Alt + N) de çalışır ve bazı terminal emülatörlerinde (örn. Konsole, gnome-terminal, xterm) çalışır.
p / s: Ben ac programcı değilim, bu yüzden bu kod optimize değilse beni affet.
[GÜNCELLEME]
Önceki cevap sadece kabuk ve gerekli odak çalışması, bu yüzden / dev / input / eventX ayrıştırma tüm X oturumu çalışmak için çözüm olduğunu düşünüyorum.
Tekerleği yeniden icat etmek istemiyorum. Ben evtest
yardımcı programı ile oynamak ve kendi kodu ile evtest.c alt kısmını değiştirdi :
int onHold = 0;
struct timeval t0;
double elapsedTime;
int hitMax = 0;
while (1) {
rd = read(fd, ev, sizeof(struct input_event) * 64);
if (rd < (int) sizeof(struct input_event)) {
perror("\nevtest: error reading");
return 1;
}
system("echo 'running' >/tmp/l_is_running 2>/tmp/l_isrunning_E &");
for (i = 0; i < rd / sizeof(struct input_event); i++) {
//system("date >/tmp/l_date 2>/tmp/l_dateE &");
if (ev[i].type == EV_KEY) {
if ( (ev[i].code == 76) ) {
if (!onHold) {
onHold = 1;
t0 = ev[i].time;
hitMax = 0;
}
if (!hitMax) { //to avoid hitMax still do the time checking instruction, you can remove hitMax checking if you think it's overkill, but still hitMax itself is necessary to avoid every (max) 2 seconds will repeatly system();
elapsedTime = (ev[i].time.tv_sec - t0.tv_sec) + ((ev[i].time.tv_usec - t0.tv_usec)/1000000.0);
printf("elapsedTime: %f\n", elapsedTime);
if (elapsedTime > 2) {
hitMax = 1;
printf("perform max time action\n");
system("su - xiaobai -c 'export DISPLAY=:0; gedit &'");
}
}
if (ev[i].value == 0) {
printf("reseted ...... %d\n", ev[i].value);
onHold = 0;
if (!hitMax) {
if (elapsedTime > 1) { //just ensure lower than max 2 seconds
system("su - xiaobai -c 'export DISPLAY=:0; gnome-terminal &'");
} else if (elapsedTime > 0.5) {
system("su - xiaobai -c \"export DISPLAY=:0; vlc '/home/xiaobai/Downloads/videos/test/Pokémon Red_Blue_Yellow Gym Leader Battle Theme Remix-CbJTkx7QUJU.mp4' &\"");
} else if (elapsedTime > 0.2) {
system("su - xiaobai -c 'export DISPLAY=:0; nautilus &'");
}
} else { //else's max system() already perform
hitMax = 0;
}
}
}
}
}
}
Kullanıcı adı ( xiaobai benim kullanıcı adımdır ) bölümünü değiştirmeniz gerektiğini unutmayın . Ve aynı zamanda if ( (ev[i].code == 76) ) {
benim Numpad 5 anahtar kodumdur, çift onaylamak için ev [i]. Kodunu manuel olarak yazdırmanız gerekebilir. Ve elbette video yolunu da değiştirmelisiniz :)
Doğrudan derleyin ve test edin (`` doğru olanı almak için kısımdır /dev/input/eventN
):
$ gcc /home/put_your_path/my_long_press.c -o /home/put_your_path/my_long_press; sudo /home/put_your_path/my_long_press `ls -la /dev/input/by-path/* | grep kbd | echo "/dev/input/""$(awk -F'/' '{print $NF}')" ` &
Bu /by-id/
Fedora 24 çalışmıyor, bu yüzden / by-path / olarak değiştirin. Kali böyle bir sorun yok.
Masaüstü yöneticim gdm3:
$ cat /etc/X11/default-display-manager
/usr/sbin/gdm3
Yani, ben bu satırı /etc/gdm3/PostLogin/Default
gdm başlangıçta root olarak bu komutu çalıştırmak için koymak ( /etc/X11/Xsession.d/*
çalışmıyor):
/home/put_your_path/my_long_press `ls -la /dev/input/by-id/* | grep kbd | echo "/dev/input/""$(awk -F'/' '{print $NF}')" 2>/tmp/l_gdm` 2>/tmp/l_gdmE &
Bilinmeyen bir nedenden dolayı / onay günlüğünde etc/gdm/PostLogin/Default
bana " İzin reddedildi " veren Fedora 24 'gdm'de çalışmıyor /tmp/l_gdmE
. El ile olsa sorun çalıştırın.
gösteri:
Numpad 5, anında basma (<= 0,2 saniye) yok sayılır, kısa basma (0,2 ila 0,5 saniye) açık nautilus
, orta basma (0,5 ila 1 saniye) vlc
videoyu oynatmak için uzun basın (1 ila 2 saniye) açın gnome-terminal
ve zaman aşımı düğmesine basın (2 saniye) gedit
.
Tam kodu buraya yükledim (sadece bir dosya) .
[Tekrar GÜNCELLEME]
[1] Birden fazla tuş akışı eklendi ve notify-send
tanımlanamadı DBUS_SESSION_BUS_ADDRESS
. [2] Eklendi XDG_CURRENT_DESKTOP
ve GNOME_DESKTOP_SESSION_ID
konsole gnome tema gui kullanın sağlamak için (gnome kullanmıyorsanız değiştirin).
Kodumu burada güncelledim .
Bu kodun, örneğin Ctrl+ gibi birleşik tuş akışı için işlemediğini unutmayın t.
GÜNCELLEME:
/ Dev / input / by-path / XXX-eventN girişleri sırasının rasgele olduğu birden çok aygıt arabirimi vardır. Bu yüzden komutu /etc/gdm3/PostLogin/Default
aşağıdaki gibi değiştiriyorum ( Chesen
benim klavye adım, sizin durumunuz için grep Razer
bunun yerine değiştirmelisiniz ):
/your_path/my_long_press "$(cat /proc/bus/input/devices | grep -i Chesen -A 4 | grep -P '^(?=.*sysrq)(?=.*leds)' | tr ' ' '\n' | ls /dev/input/`grep event`)" 2>/tmp/l_gdmE &
EventN ayıklamasını aşağıdakilerden deneyebilirsiniz cat /proc/bus/input/devices | grep -i Razer -A 4
:
$ cat /proc/bus/input/devices | grep -i Razer -A 4
N: Name="Razer Razer Naga Chroma"
P: Phys=usb-0000:00:14.0-1.3/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.3/3-1.3:1.0/0003:1532:0053.0003/input/input6
U: Uniq=
H: Handlers=mouse2 event5
--
N: Name="Razer Razer Naga Chroma"
P: Phys=usb-0000:00:14.0-1.3/input1
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.3/3-1.3:1.1/0003:1532:0053.0004/input/input7
U: Uniq=
H: Handlers=sysrq kbd event6
--
N: Name="Razer Razer Naga Chroma"
P: Phys=usb-0000:00:14.0-1.3/input2
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1.3/3-1.3:1.2/0003:1532:0053.0005/input/input8
U: Uniq=
H: Handlers=sysrq kbd leds event7
$
Yukarıdaki bu örnekte, yalnızca yukarıda sudo cat /dev/input/event7
kullanmak üzere "sysrq kbd leds event7" desenine sahip Razer fare üzerindeki 12 hane tıklandığında tuhaf çıktılar yazdırılacaktır grep -P '^(?=.*sysrq)(?=.*leds)'
(deseniniz değişebilir). sudo cat /dev/input/event6
tuhaf çıktıyı yalnızca orta yukarı / aşağı tuşuna tıkladığında yazdıracaktır. Süre sudo cat /dev/input/event5
farenizi hareket ettirdiğinizde ve tekerleği kaydırdığınızda tuhaf çıktılar basacaktır.
[Güncelleme: Programı yeniden yüklemek için klavye kablosunu yeniden destekleyin]
Aşağıdakiler kendi kendini açıklama olmalıdır:
$ lsusb #to know my keyboard is idVendor 0a81 and idProduct 0101
...
Bus 001 Device 003: ID 0a81:0101 Chesen Electronics Corp. Keyboard
$ cat /etc/udev/rules.d/52-hole-keyboard.rules #add this line with your idVendor and idProduct above in custom udev rules file
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0a81", ATTR{idProduct}=="0101", MODE="0666", GROUP="plugdev", RUN+="/bin/bash -c 'echo 1 > /tmp/chesen_plugged'"
$ cat /usr/local/bin/inotifyChesenPlugged #A long run listener script to listen for modification of /tmp/chesen_plugged #Ensures `inotifywait` has been installed first.
touch /tmp/chesen_plugged
while inotifywait -q -e modify /tmp/chesen_plugged >/dev/null; do
killall -9 my_long_press
/usr/local/bin/startLongPress &
done
$ cat /usr/local/bin/startLongPress #the executable script run the long press executable #Change with your pattern as explained above.
#!/bin/bash
<YOUR_DIR>/my_long_press "$(cat /proc/bus/input/devices | grep -i Chesen -A 4 | grep -P '^(?=.*sysrq)(?=.*leds)' | tr ' ' '\n' | ls /dev/input/`grep event`)" 2>/tmp/l_gdmE) & disown
$ cat /etc/gdm3/PostLogin/Default #the executable startup script run listener and long press script
/usr/local/bin/inotifyChesenPlugged &
/usr/local/bin/startLongPress &