代码之家  ›  专栏  ›  技术社区  ›  user.dz

使用Gnome-libs(GDK)获取键盘修饰符状态仅获取初始状态

  •  3
  • user.dz  · 技术社区  · 9 年前

    我正在尝试通过gnomeGDK或GTK库获取当前的键盘修饰符状态,以实现一个显示该状态的可访问性gnomeshell扩展。

    我知道如何使用xlib获取其状态,但gnome gjs没有完全绑定。

    下面的代码只获取初始状态。它不会更新状态。

    /*
     * 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 回复  |  直到 9 年前
        1
  •  2
  •   andlabs    9 年前

    您需要运行GTK+事件循环才能使其工作。事件循环是GLib的一部分 主回路,主回路 。当你打电话时 gtk_main() ,此主循环运行。我不知道它是否轮询事件或是否有事件推送到它,但它不会像你试图做的那样,快速询问键盘状态。

    设置GDK的最简单方法是通过GTK+使用 gtk_init() gtk_main() 。您可以单独使用GDK,但我不知道如何使用。你似乎已经想通了,这是可行的。

    而不是打电话 g_usleep() ,这只会阻塞程序,您可以将周期性超时挂接到主循环中。这是用完成的 g_timeout_add() 。传递给的函数 g_timeout_add() 返回一个布尔值,该值决定计时器是否应该停止,因此您不必担心重新安排函数,因为GLib会为您执行此操作。

        2
  •  2
  •   user.dz    9 年前
    • 事实上,我需要一个事件循环,正如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);    
      }
      

    参考文献: