2015-08-05 6 views
1

Я пытаюсь получить текущее состояние модификаторов клавиатуры через gnome GDK или GTK-библиотеку, чтобы реализовать расширение оболочки gnome доступности, которое показывает это состояние.Получение состояния модификаторов клавиатуры с использованием Gnome libs (GDK) только для исходного состояния

Я знаю, как получить его состояние с помощью xlib, но нет полного связывания для gns gns.

Код ниже получает только начальное состояние. Он не обновляет состояние.

/* 
* compiling: gcc `pkg-config --cflags gdk-3.0` -o gdk_mod gdk_mod.c `pkg-config --libs gdk-3.0` 
*/ 

#include <gdk/gdk.h> 

int main (int argc, char **argv) { 

    gdk_init(&argc, &argv); 

    GdkDisplay * disp; 
    disp = gdk_display_open(NULL); 
    if (disp!=NULL) g_printf("display connected!\n"); 

    GdkKeymap * kmap; 
    kmap = gdk_keymap_get_for_display(disp); 

    guint state; 
    state = gdk_keymap_get_modifier_state(kmap); 
    g_printf("mod state: %x\n", state); 

    while (1) { 
     g_usleep(1000000); 
     //kmap = gdk_keymap_get_for_display(disp); 
     state = gdk_keymap_get_modifier_state(kmap); 
     g_printf("mod state: %x\n", state); 
    } 

} 

Вот пример вывод с CAPS зафиксировался активными затем неактивные, но никаких изменений:

$ ./gdk_mod 
display found! 
mod state: 2 
mod state: 2 
mod state: 2 
mod state: 2 
mod state: 2 
^C 

В настоящее время с помощью Kubuntu 15.04.

Что случилось с моим кодом?

+2

Для этого вам, вероятно, понадобится запустить цикл событий GTK +. Попробуйте изменить цикл 'g_usleep()' на [g_timeout_add()] на основе [loop] (https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#G- SOURCE-CONTINUE: CAPS), используя 'gtk_init()' вместо 'gdk_init()' и запуская 'gtk_main()'. – andlabs

+0

@andlabs, вы отлично работаете. Не могли бы вы отправить ответ. Я буду ждать немного дольше, чтобы принять его, потому что я предполагаю, что некоторые функции уровня gdk, вызванные циклом gtk_main', вытягивают/обновляют события из X в очередь событий gdk. Если эти функции существуют, я могу исправить свой исходный код и сохранить его с помощью чистого GDK. –

+0

@andlabs, вы заслуживаете заслуги и репутации ответа. Я написал один для документирования моего решения. Если вы скопируете этот комментарий в качестве ответа, я его приму. –

ответ

2

Вы будете нуждаться, чтобы запустить цикл обработки событий GTK + для этой работы. Цикл событий является частью основного цикла GLib . Когда вы вызываете gtk_main(), этот основной цикл запускается. Я не знаю, опросит ли он события или события, нажатые на него, но он не будет запрашивать состояние клавиатуры на лету, как вы пытались сделать.

Самый простой способ настроить GDK - это сделать через GTK +, используя gtk_init() и gtk_main(). Вы можете использовать GDK самостоятельно, но я не знаю, как это сделать. Казалось, вы это поняли, и это работает.

И вместо вызова g_usleep(), который просто блокирует вашу программу, вы можете подключить периодический таймаут в основной цикл. Это делается с помощью g_timeout_add(). Функция, которую вы передаете в g_timeout_add(), возвращает логическое значение, которое решает, следует ли остановить таймер или нет, поэтому вам не нужно беспокоиться о перенастройке вашей функции, поскольку GLib сделает это за вас.

1
  • Действительно, мне нужен цикл событий, как сказал в своем комментарии andlabs. Его предложение использовать GTK gtk_init() & gtk_main() работает отлично.

    /* 
    * compiling: gcc `pkg-config --cflags gtk+-3.0` -o gtk_xkbmod3 gtk_xkbmod3.c `pkg-config --libs gtk+-3.0` 
    */ 
    
    #include <gtk/gtk.h> 
    
    static void update(GdkKeymap * kmap) { 
        guint state; 
        state = gdk_keymap_get_modifier_state(kmap); 
        g_printf("%i\n", state); 
    } 
    
    int main (int argc, char **argv) { 
    
        gtk_init(&argc, &argv); 
    
        GdkKeymap * kmap; 
        kmap = gdk_keymap_get_default(); 
    
        g_timeout_add_seconds(1, (GSourceFunc) update, kmap); 
    
        gtk_main(); 
    
    } 
    
  • Я также могу использовать GDK с GLib GMainLoop.

    /* 
    * compiling: gcc `pkg-config --cflags gdk-3.0` -o gdk_xkbmod4 gdk_xkbmod4.c `pkg-config --libs gdk-3.0` 
    */ 
    
    #include <gdk/gdk.h> 
    
    GMainLoop *mainloop; 
    
    static void update(GdkKeymap * kmap) { 
        guint state; 
        state = gdk_keymap_get_modifier_state(kmap); 
        g_printf("%i\n", state); 
    } 
    
    int main (int argc, char **argv) {  
    
        gdk_init(&argc, &argv); 
    
        GdkKeymap * kmap; 
        kmap = gdk_keymap_get_default(); 
    
        g_timeout_add_seconds(1, (GSourceFunc) update, kmap); 
    
        mainloop = g_main_loop_new(g_main_context_default(), FALSE); 
        g_main_loop_run(mainloop);  
    } 
    

Ссылки: