Nowe posty

xx Debian 9 Stretch, linuxcnc i restart przy uruchamianiu (2)
2019-10-19, 21:54:36
xx Zakup sprzętu bez preinstalowanego windowsa (8)
2019-10-17, 16:50:51
xx Problem z pocztą Dovecot+Postfix+MySQL (3)
2019-10-16, 14:43:41
xx Instalacja Debian10 problem z instalacją GRUBa na RAID5 (5)
2019-10-15, 17:58:57
xx AMD Ryzen 5 3500U (11)
2019-10-14, 18:29:46
xx Konfiguracja directadmina (0)
2019-10-13, 03:18:36
xx Problem z instalacją sterowników TL-WN821N (4)
2019-10-11, 23:15:00
xx Sprzet z Linuxem (1)
2019-10-11, 10:06:24
xx nadpisanie partycji domowej (6)
2019-10-03, 03:27:28
xx Screen flickering Deepin (4)
2019-10-02, 20:32:56

Autor Wątek: Powtarzające się wciśnięcie klawisza  (Przeczytany 11941 razy)

Offline

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 14
    • Zobacz profil
Powtarzające się wciśnięcie klawisza
« dnia: 2010-03-12, 22:18:09 »
Piszę program z użyciem biblioteki GTK. Chciałbym żeby wykonywał pewną funkcję w momencie naciśnięcia klawisza na klawiaturze i inną w momencie zwolnienia go. Niestety GTK nie rozróżnia wciśnięcia klawisza od powtórzenia go, więc trzymając klawisz przez dłuższy czas cykl wciśnięcie-zwolnienie powtarza się wielokrotnie. Czy jest jakiś sposób na ominięcie tego problemu?
Wiem że klawiatura wysyła różne sygnały w zależności od tego czy klawisz był rzeczywiście w tym momencie wciśnięty czy tylko przytrzymany. Można to zaobserwować wykonując polecenie hexdump -x /dev/input/event1 (gdzie /dev/input/event1 to deskryptor klawiatury). Kiedy klawisz jest wciskany jedna z wyświetlanych wartości wynosi 1, kiedy jest zwalniany: 0, a kiedy przytrzymany: 2. Czy używając GTK można jakoś uzyskać dostęp do nieprzetworzonych danych wysyłanych przez klawiaturę w celu rozróżnienia tych przypadków?
Wiem też że można wysłać do układu elektronicznego klawiatury polecenie przełączające ją w tryb, w którym nie wysyła powtórzeń klawiszy (typematic repeat delay i typematic repeat rate), ale nie chciałbym korzystać z tego sposobu.

void klawisz_wcisniety(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie wciśnięcia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
 
printf("klawisz wcisnięty: %8hd,%8hd\\n", klawisz, klawisz_hardware);
/*tymczasowa funkcja wyświetlająca kody wciśniętego klawisza*/
}


void klawisz_zwolniony(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie zwolnienia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
 
printf("klawisz zwolniony: %8hd,%8hd\\n", klawisz, klawisz_hardware);
/*tymczasowa funkcja wyświetlająca kody zwolnionego klawisza*/
}

int main( int argc, char *argv[])
{
gtk_signal_connect(GTK_OBJECT(window),"key_press_event", G_CALLBACK(klawisz_wcisniety), NULL);
gtk_signal_connect(GTK_OBJECT(window),"key_release_event", G_CALLBACK(klawisz_zwolniony), NULL);
}

Offline

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 16
    • Zobacz profil
Powtarzające się wciśnięcie klawisza
« Odpowiedź #1 dnia: 2010-03-13, 18:06:08 »
Cytat: msuma
Piszę program z użyciem biblioteki GTK. Chciałbym żeby wykonywał pewną funkcję w momencie naciśnięcia klawisza na klawiaturze i inną w momencie zwolnienia go. Niestety GTK nie rozróżnia wciśnięcia klawisza od powtórzenia go, więc trzymając klawisz przez dłuższy czas cykl wciśnięcie-zwolnienie powtarza się wielokrotnie. Czy jest jakiś sposób na ominięcie tego problemu?
Wiem że klawiatura wysyła różne sygnały w zależności od tego czy klawisz był rzeczywiście w tym momencie wciśnięty czy tylko przytrzymany. Można to zaobserwować wykonując polecenie hexdump -x /dev/input/event1 (gdzie /dev/input/event1 to deskryptor klawiatury). Kiedy klawisz jest wciskany jedna z wyświetlanych wartości wynosi 1, kiedy jest zwalniany: 0, a kiedy przytrzymany: 2. Czy używając GTK można jakoś uzyskać dostęp do nieprzetworzonych danych wysyłanych przez klawiaturę w celu rozróżnienia tych przypadków?
Wiem też że można wysłać do układu elektronicznego klawiatury polecenie przełączające ją w tryb, w którym nie wysyła powtórzeń klawiszy (typematic repeat delay i typematic repeat rate), ale nie chciałbym korzystać z tego sposobu.
Masz rację z tym że na CentOs 5.4 i zapewnie na wszystkich redhat-ach klawiatura to /dev/input/event0

Rozwiązaniem będzie użycie:
GdkEventType type;
 the type of the event (GDK_KEY_PRESS or GDK_KEY_RELEASE)

Offline

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 14
    • Zobacz profil
Powtarzające się wciśnięcie klawisza
« Odpowiedź #2 dnia: 2010-03-13, 23:15:28 »
Z deskryptorem różnie bywa. Nawet na dwóch komputerach z tym samym systemem deskryptor się różnił. Porzuciłem to podejście bo program musiałem uruchamiać jako root.
Dopisałem zaproponowany przez Ciebie warunek, ale nic się nie zmienia. Problem w tym że klawiatura wysyła powtórzenie klawisza co kilkadziesiąt milisekund (typematic repeat rate), a GDK nie rozróżnia tych powtórzeń od prawdziwych zdarzeń naciśnięcia i zwolnienia klawisza. Pole hardware_keycode w strukturze GdkEventKey powinno zawierać cały kod klawisza generowany przez klawiaturę, ale jest on niestety identyczny dla wciśnięcia, zwolnienia i przytrzymania. Chodzi mi o tę jedną cyferkę rozróżniającą je (0, 1 lub 2). Jak się do niej dostać?
void klawisz_wcisniety(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie wciśnięcia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
  GdkEventType typ_zdarzenia;  
  typ_zdarzenia = ((GdkEventKey*)event)->type;
if (typ_zdarzenia == GDK_KEY_PRESS || typ_zdarzenia == GDK_KEY_RELEASE)
{printf("klawisz wcisnięty: %8hd,%8hd\\n", klawisz, klawisz_hardware);}
/*tymczasowa funkcja wyświetlająca kody wciśniętego klawisza*/
}


void klawisz_zwolniony(GtkWidget *widget,  GdkEventKey *event, gpointer  data)
{
/*funkcja wykonywana w momencie zwolnienia klawisza*/
  uint klawisz;
  uint klawisz_hardware;
 
  klawisz = ((GdkEventKey*)event)->keyval;
  klawisz_hardware = ((GdkEventKey*)event)->hardware_keycode;
  GdkEventType typ_zdarzenia;  
  typ_zdarzenia = ((GdkEventKey*)event)->type;
if (typ_zdarzenia == GDK_KEY_PRESS || typ_zdarzenia == GDK_KEY_RELEASE)
{printf("klawisz zwolniony: %8hd,%8hd\\n", klawisz, klawisz_hardware);}
/*tymczasowa funkcja wyświetlająca kody zwolnionego klawisza*/
}

int main( int argc, char *argv[])
{
gtk_signal_connect(GTK_OBJECT(window),"key_press_event", G_CALLBACK(klawisz_wcisniety), NULL);
gtk_signal_connect(GTK_OBJECT(window),"key_release_event", G_CALLBACK(klawisz_zwolniony), NULL);
}
Próbowałem wykluczać powtarzające się pary zdarzeń zwolnienie-naciśnięcie, które mają ten sam czas wystąpienia, ale nie jest to zbyt eleganckie rozwiązanie i nie daje zadowalających rezultatów. Poza ty sprawy bardzo się skomplikują kiedy będę naciskał i puszczał kilka klawiszy jednocześnie.
Znalazłem też w: System/Preferencje/Klawiatura opcję "Powtarzanie naciśnięcia klawisza przy jego przytrzymaniu" (w systemie Ubuntu 9.10). Czy dałoby się zrobić tak żeby była ona wyłączana w momencie uruchomienia programu i włączana z powrotem przy jego zamknięciu?

Offline

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 16
    • Zobacz profil
Powtarzające się wciśnięcie klawisza
« Odpowiedź #3 dnia: 2010-03-14, 00:42:46 »
Cześć,
Przypuszczam że nie sprecyzowałeś co chcesz.
Cytat: msuma
Piszę program z użyciem biblioteki GTK. Chciałbym żeby wykonywał pewną funkcję w momencie naciśnięcia klawisza na klawiaturze i inną w momencie zwolnienia go. Niestety GTK nie rozróżnia wciśnięcia klawisza od powtórzenia go, więc trzymając klawisz przez dłuższy czas cykl wciśnięcie-zwolnienie powtarza się wielokrotnie. Czy jest jakiś sposób na ominięcie tego problemu?
Wiem że klawiatura wysyła różne sygnały w zależności od tego czy klawisz był rzeczywiście w tym momencie wciśnięty czy tylko przytrzymany. Można to zaobserwować wykonując polecenie hexdump -x /dev/input/event1 (gdzie /dev/input/event1 to deskryptor klawiatury). Kiedy klawisz jest wciskany jedna z wyświetlanych wartości wynosi 1, kiedy jest zwalniany: 0, a kiedy przytrzymany: 2. Czy używając GTK można jakoś uzyskać dostęp do nieprzetworzonych danych wysyłanych przez klawiaturę w celu rozróżnienia tych przypadków?
Wiem też że można wysłać do układu elektronicznego klawiatury polecenie przełączające ją w tryb, w którym nie wysyła powtórzeń klawiszy (typematic repeat delay i typematic repeat rate), ale nie chciałbym korzystać z tego sposobu.
Jest kilka niekonsekwencji. Wiem, że tylko krowa nie zmienia poglądów ale ...

Cytat: msuma
Znalazłem też w: System/Preferencje/Klawiatura opcję "Powtarzanie naciśnięcia klawisza przy jego przytrzymaniu" (w systemie Ubuntu 9.10). Czy dałoby się zrobić tak żeby była ona wyłączana w momencie uruchomienia programu i włączana z powrotem przy jego zamknięciu?

Offline

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 14
    • Zobacz profil
Powtarzające się wciśnięcie klawisza
« Odpowiedź #4 dnia: 2010-03-14, 01:20:44 »
Nie chciałbym korzystać z tego sposobu, ale jeśli innego nie będzie to dobre i to. Najlepiej byłoby gdyby program miał bezpośredni dostęp do klawiatury, ale do tego musiałby być uruchamiany przez roota. Bardzo dobrze by było gdyby rozróżniał wciśnięcie, zwolnienie i przytrzymanie klawisza. Jeśli nie da się tego osiągnąć to zadowoliłbym się funkcją wyłączającą "Powtarzanie naciśnięcia klawisza przy jego przytrzymaniu" zaraz po uruchomieniu programu i włączającą z powrotem przed jego zamknięciem. Chyba jasno się wyraziłem.
Polecenie zmieniające częstotliwość i opóźnienie to sudo kbdrate -r 10 -d 250 (w tym przypadku 10 znaków na sekundę po 250 milisekundach od wciśnięcia klawisza). Co zrobić żeby program wykonywał je na początku i na końcu i jakie parametry wyłączają powtarzanie klawiszy całkowicie?
Czy ktoś miał kiedyś podobny problem?