मैंने इसे 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
बाइंड कीकोड प्राप्त करने के लिए उपयोग करें :
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$
बाइंड कीकोड 5 और उसके कमांड (जैसे रन /tmp/.a.out
) को ~ / .bashrc में डालें :
bind '"5":"/tmp/a.out\n"'
ध्यान दें कि प्रासंगिक कोडकोड को स्रोत कोड में भी बदलने की जरूरत है (हेक्स मूल्य sudo showkey -a
ऊपर से भी मिल सकता है):
int c = 0x35;
के साथ संकलन ( /tmp/a.out
मेरे उदाहरण में आउटपुट ):
cc filename.c -lcurses
प्रदर्शन:
Numpad 5, शॉर्ट प्रेस ओपन न्यू टैब, मीडियम प्रेस ओपन गेडिट और लॉन्ग प्रेस ओपन गनोम-टर्मिनल।
यह gnome डेस्कटॉप मैनेजर पर किसी भी विंडो में प्रत्यक्ष रूप से लागू नहीं है, लेकिन मुझे लगता है कि इसे लागू करने के लिए आपको (हार्ड) कुछ विचार देना चाहिए। यह वर्चुअल कंसोल (Ctrl + Alt + N) में भी काम करता है, और कुछ टर्मिनल एमुलेटर (जैसे konsole, gnome-terminal, xterm) में काम करता है।
p / s: मैं एसी प्रोग्रामर नहीं हूं, इसलिए मुझे क्षमा करें यदि यह कोड अनुकूलित नहीं है।
[अपडेट करें]
पिछला उत्तर केवल शेल और आवश्यक फोकस में काम करता है, इसलिए मुझे लगता है कि / X / dev / input / eventX पूरे एक्स सत्र में काम करने का समाधान है।
मैं पहिए को फिर से नहीं लगाना चाहता। मैं evtest
उपयोगिता के साथ खेलता हूं और अपने स्वयं के कोड के साथ evtest.c के निचले हिस्से को संशोधित करता हूं:
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;
}
}
}
}
}
}
ध्यान दें कि आपको उपयोगकर्ता नाम बदलना चाहिए ( xiaobai मेरा उपयोगकर्ता नाम है)। और यह भी if ( (ev[i].code == 76) ) {
मेरा Numpad 5 कीकोड है, आपको डबल पुष्टिकरण के लिए ev [i] .code को मैन्युअल रूप से प्रिंट करना होगा। और निश्चित रूप से आपको वीडियो पथ भी बदलना चाहिए :)
इसे संकलित करें और सीधे परीक्षण करें (सही पाने के लिए `` भाग है /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}')" ` &
ध्यान दें कि /by-id/
Fedora 24 में काम नहीं करता है, इसलिए मैं इसे / by-path / में बदल देता हूं। काली ऐसी कोई समस्या नहीं।
मेरा डेस्कटॉप मैनेजर gdm3 है:
$ cat /etc/X11/default-display-manager
/usr/sbin/gdm3
इसलिए, मैंने /etc/gdm3/PostLogin/Default
इस कमांड को gdm स्टार्टअप पर रूट के रूप में चलाने के लिए इस लाइन को डाला ( /etc/X11/Xsession.d/*
काम नहीं करता):
/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 &
अज्ञात कारण के लिए / etc/gdm/PostLogin/Default
फेडोरा 24 'जीडीएम पर काम नहीं करता है जो मुझे चेक लॉग के दौरान " अनुमति अस्वीकृत " देता है /tmp/l_gdmE
। हालांकि कोई समस्या नहीं मैन्युअल रूप से चलाएँ।
प्रदर्शन:
Numpad 5, झटपट-प्रेस (<= 0.2 सेकंड) नजरअंदाज कर दिया जाएगा, शॉर्ट-प्रेस (0.2 से 0.5 सेकंड) खुला nautilus
, मध्यम-प्रेस (0.5 से 1 सेकंड) vlc
वीडियो चलाने के लिए खुला , लंबे समय से प्रेस (1 से 2 सेकंड) खुला gnome-terminal
, और टाइमआउट-प्रेस (2 सेकंड) खुला gedit
।
मैंने यहां पूरा कोड (केवल एक फ़ाइल) अपलोड किया है ।
[फिर से अपडेट करें]
[१] कई कुंजियों को जोड़ा गया और notify-send
परिभाषित करने में विफल रहा DBUS_SESSION_BUS_ADDRESS
। [२] जोड़ा गया XDG_CURRENT_DESKTOP
और GNOME_DESKTOP_SESSION_ID
यह सुनिश्चित करने के लिए कोनोलास सूक्ति थीम गुई का उपयोग करें (इसे बदलें यदि आप सूक्ति का उपयोग नहीं कर रहे हैं)।
मैंने यहाँ अपना कोड अपडेट किया ।
ध्यान दें कि यह कोड संयोजन कुंजी प्रवाह, जैसे Ctrl+ के लिए संभाल नहीं करता है t।
अपडेट करें:
ऐसे कई उपकरण इंटरफ़ेस हैं, जो / dev / input / by-path / XXX-eventN प्रविष्टियों अनुक्रम यादृच्छिक है। इसलिए मैं /etc/gdm3/PostLogin/Default
नीचे के रूप में कमांड को बदलता हूं ( Chesen
यह मेरा कीबोर्ड नाम है, आपके मामले के लिए, आपको इसे grep Razer
इसके बजाय बदलना चाहिए ):
/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 &
आप इवेंट से निकालने की कोशिश कर सकते हैं 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
$
ऊपर इस उदाहरण में, केवल sudo cat /dev/input/event7
रेजर माउस पर 12 अंकों पर क्लिक करने पर विचित्र आउटपुट प्रिंट होगा, जिसमें grep -P '^(?=.*sysrq)(?=.*leds)'
ऊपर में उपयोग करने के लिए "sysrq kbd leds इवेंट 7" पैटर्न है (आपका पैटर्न भिन्न हो सकता है)। sudo cat /dev/input/event6
केवल मध्य अप / डाउन की को क्लिक करने पर विचित्र आउटपुट प्रिंट करेगा। जबकि sudo cat /dev/input/event5
विचित्र उत्पादन प्रिंट जब अपने माउस और पहिया स्क्रॉल पर आ जाएगा।
[अद्यतन: कार्यक्रम को फिर से लोड करने के लिए रिप्लेग कीबोर्ड कीबोर्ड का समर्थन करें]
निम्नलिखित स्व-स्पष्टीकरण होना चाहिए:
$ 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 &