2012-01-14 12 views
5

में Xorg ईवेंट हैंडिंग को जोड़ने के लिए मेरे पास a lightweight application है जो Xorg और dbus ईवेंट को पकड़ता है। ऐसा करने के लिए मैं dbus पाश प्रारंभ और g_main_loop शुरू कर दिया है, लेकिन मैं एक प्राकृतिक तरीके में से निपटने Xorg घटना जोड़ने के लिए पता नहीं कैसे:g_main_loop

GMainLoop * mainloop = NULL; 
mainloop = g_main_loop_new(NULL,FALSE); 
dbus_g_thread_init(); 
dbus_init(); 
// <<<<<<<<<<<<<<<<<<<<<<<<< 
//1 way using timeout 
//g_timeout_add(100, kbdd_default_iter, mainloop); 
//2nd way using pthread 
//GThread * t = g_thread_create(kbdd_default_loop, NULL, FALSE, NULL); 
//>>>>>>>>>>>>>>>>>>>>>>>>>>> 
g_main_loop_run(mainloop); 

डिफ़ॉल्ट आईटीईआर में मैं जाँच कर रहा हूँ अगर वहाँ एक्स इंतजार कर घटना और उन्हें संभाल लें।

दोनों तरीके खराब दिखते हैं, पहले क्योंकि मेरे पास ईवेंट की जांच के लिए अनियंत्रित कॉल हैं, दूसरा क्योंकि मैं अतिरिक्त थ्रेड करता हूं और अतिरिक्त ताले बनाना पड़ता हूं।

पीएस मुझे पता है कि मैं gtk lib का उपयोग कर सकता हूं, लेकिन मैं किसी टूलकिट पर निर्भरता नहीं रखना चाहता हूं।

उत्तर

4

यदि आप टाइमआउट का उपयोग किये बिना मुख्य लूप में एक्सओआर इवेंट हैंडलिंग जोड़ना चाहते हैं (जैसा कि आप राज्य कचरा है), तो आपको एक्स कनेक्शन का चुनाव करने वाला एक स्रोत जोड़ना होगा। इसके लिए, अंतर्निहित एक्स कनेक्शन फ़ाइल डिस्क्रिप्टर प्राप्त करने के लिए आपको Xlib abstraction परत से नीचे जाना होगा। यही वह पूरा कार्यक्रम है जो नीचे करता है। मतदान के लिए ग्लिब मुख्य लूप का उपयोग करने के लिए यह C. Tronche's excellent X11 tutorial का अनुकूलन है। मैंने एंड्रयू क्रूस द्वारा "जीटीके + विकास की नींव" से भी आकर्षित किया।

यदि यह बहुत "प्राकृतिक" प्रतीत नहीं होता है, तो ऐसा इसलिए है क्योंकि मुझे संदेह है कि ऐसा करने के लिए एक बहुत ही "प्राकृतिक" तरीका है - आप वास्तव में यहां जीडीके का मुख्य भाग पुनः कार्यान्वित कर रहे हैं।

/* needed to break into 'Display' struct internals. */ 
#define XLIB_ILLEGAL_ACCESS 

#include <X11/Xlib.h> // Every Xlib program must include this 
#include <assert.h> // I include this to test return values the lazy way 
#include <glib.h> 

typedef struct _x11_source { 
    GSource source; 
    Display *dpy; 
    Window w; 
} x11_source_t; 

static gboolean 
x11_fd_prepare(GSource *source, 
      gint *timeout) 
{ 
    *timeout = -1; 
    return FALSE; 
} 

static gboolean 
x11_fd_check (GSource *source) 
{ 
    return TRUE; 
} 

static gboolean 
x11_fd_dispatch(GSource* source, GSourceFunc callback, gpointer user_data) 
{ 
    static gint counter = 0; 

    Display *dpy = ((x11_source_t*)source)->dpy; 
    Window window = ((x11_source_t*)source)->w; 

    XEvent e; 

    while (XCheckWindowEvent(dpy, 
       window, 
       EnterWindowMask, 
       &e)) 
    { 
     if (e.type == EnterNotify) 
    g_print("We're in!!! (%d)\n", ++counter); 
    } 

    return TRUE; 
} 

static gboolean 
msg_beacon(gpointer data) 
{ 
    static gint counter = 0; 
    g_print("Beacon %d\n", ++counter); 
    return TRUE; 
} 

int 
main() 
{ 
     Display *dpy = XOpenDisplay(NULL); 
     assert(dpy); 

     int blackColor = BlackPixel(dpy, DefaultScreen(dpy)); 
     int whiteColor = WhitePixel(dpy, DefaultScreen(dpy)); 

     Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 
        200, 100, 0, blackColor, blackColor); 

     XSelectInput(dpy, w, StructureNotifyMask | EnterWindowMask); 
     XMapWindow(dpy, w); 

     for (;;) { 
    XEvent e; 
    XNextEvent(dpy, &e); 
    if (e.type == MapNotify) 
     break; 
     } 

     GMainLoop *mainloop = NULL; 
     mainloop = g_main_loop_new(NULL, FALSE); 

     /* beacon to demonstrate we're not blocked. */ 
     g_timeout_add(300, msg_beacon, mainloop); 

     GPollFD dpy_pollfd = {dpy->fd, 
       G_IO_IN | G_IO_HUP | G_IO_ERR, 
       0}; 

     GSourceFuncs x11_source_funcs = { 
    x11_fd_prepare, 
    x11_fd_check, 
    x11_fd_dispatch, 
    NULL, /* finalize */ 
    NULL, /* closure_callback */ 
    NULL /* closure_marshal */ 
     }; 

     GSource *x11_source = 
    g_source_new(&x11_source_funcs, sizeof(x11_source_t)); 
     ((x11_source_t*)x11_source)->dpy = dpy; 
     ((x11_source_t*)x11_source)->w = w; 
     g_source_add_poll(x11_source, &dpy_pollfd); 
     g_source_attach(x11_source, NULL); 

     g_main_loop_run(mainloop); 

     return 0; 

}