2012-04-25 11 views
11

मेरे पास एक एम्बेडेड डिवाइस है जो Linux/X11 चला रहा है जो एक डिवाइस से जुड़ा हुआ है जो यूएसबी कनेक्शन पर टच इवेंट प्रदान करता है। यह डिवाइस मानक सूचक/माउस इनपुट के किसी भी रूप के रूप में पहचाना नहीं गया है। मैं जो करने की कोशिश कर रहा हूं वह बाहरी घटनाओं की रिपोर्ट करता है जब एक्स 11 में माउस घटनाओं को "इंजेक्ट" करने का एक तरीका मिलता है।X11 इनपुट कतार में सिंथेटिक माउस ईवेंट कैसे सम्मिलित करें

ऐसा करने से जीटीके + कॉल के साथ नकली माउस प्रेस में मेरे आवेदन (जीटीके + का उपयोग कर सी में लिखा गया) की आवश्यकता को हटा दिया जाएगा।

यदि यह किया जा सकता है तो मेरे जीटीके + एप्लिकेशन को स्पर्श घटनाओं को उत्पन्न करने वाले डिवाइस के बारे में जानने या देखभाल करने की आवश्यकता नहीं होगी। यह सिर्फ मानक माउस घटनाओं के रूप में आवेदन के लिए दिखाई देगा।

कोई भी जानता है कि X11 में सिंथेटिक माउस ईवेंट डालने के बारे में कैसे जाना है?

अभी मैं निम्नलिखित काम कर रहा हूं जो काम करता है, लेकिन इष्टतम नहीं है।

GtkWidget *btnSpin;  /* sample button */ 

gboolean buttonPress_cb(void *btn); 
gboolean buttonDePress_cb(void *btn); 


/* make this call after the device library calls the TouchEvent_cb() callback 
    and the application has determined which, if any, button was touched 

    In this example we are assuming btnSpin was touched. 

    This function will, in 5ms, begin the process of causing the button to do it's 
    normal animation (button in, button out effects) and then send the actual 
    button_clicked event to the button. 
*/ 
g_timeout_add(5, (GSourceFunc) buttonPress_cb, (void *)btnSpin); 


/* this callback is fired 5ms after the g_timeout_add() function above. 
    It first sets the button state to ACTIVE to begin the animation cycle (pressed look) 
    And then 250ms later calls buttonDePress_cb which will make the button look un-pressed 
    and then send the button_clicked event. 
*/  
gboolean buttonPress_cb(void *btn) 
{ 

    gtk_widget_set_state((GtkWidget *)btn, GTK_STATE_ACTIVE); 
    g_timeout_add(250, (GSourceFunc) buttonDePress_cb, btn); 


    return(FALSE); 
} 

/* Sets button state back to NORMAL (not pressed look) 
    and sends the button_clicked event so that the registered signal handler for the 
    button can be activated 
*/ 
gboolean buttonDePress_cb(void *btn) 
{ 

    gtk_widget_set_state(btn, GTK_STATE_NORMAL); 
    gtk_button_clicked(GTK_BUTTON(btn)); 

    return(FALSE); 
} 

उत्तर

9

लिनक्स इनपुट सिस्टम में यूनपुट नामक इनपुट डिवाइस के उपयोगकर्ता-स्थान कार्यान्वयन की सुविधा होनी चाहिए। आप एक पृष्ठभूमि प्रोग्राम लिख सकते हैं जो कर्नेल में इनपुट इवेंट भेजने के लिए आपके डिवाइस की कॉलबैक लाइब्रेरी का उपयोग करता है। एक्स सर्वर (माना जाता है कि यह evdev इनपुट मॉड्यूल का उपयोग कर रहा है) तो यह किसी भी अन्य माउस घटना के रूप में प्रक्रिया करेगा।

libsuinput नामक एक लाइब्रेरी है जो इसे करने में काफी आसान बनाती है। इसमें example mouse input program भी शामिल है जिसे आप शायद मॉडल के रूप में उपयोग कर सकते हैं। हालांकि, चूंकि आपका डिवाइस एक टच-आधारित डिवाइस है, इसलिए यह शायद रिश्तेदार (REL_X, REL_Y) के बजाय पूर्ण अक्ष (ABS_X, ABS_Y) का उपयोग करेगा।

+0

उत्कृष्ट .. यह सिर्फ जवाब हो सकता है। मुझे यह देखने की आवश्यकता होगी कि मेरा एम्बेडेड लिनक्स डिवाइस 'यूनपूट' सिस्टम का समर्थन करता है या नहीं। धन्यवाद। – Chimera

9

कई विधियां हैं।

  1. XSendEvent का उपयोग करें। चेतावनी: कुछ अनुप्रयोग ढांचे XSendEvent के साथ भेजे गए कार्यक्रमों को अनदेखा करते हैं। मुझे लगता है कि जीटीके + नहीं है, लेकिन मैंने जांच नहीं की है।
  2. XTestFakeMotionEvent और XTestFakeButtonEvent का उपयोग करें। आपको अपने एक्स सर्वर पर एक्सटेस्ट एक्सटेंशन की आवश्यकता है।
  3. अपने डिवाइस के लिए कर्नेल ड्राइवर लिखें ताकि यह माउस/टचपैड के रूप में दिखाई दे।
+0

आपके उत्तर के लिए धन्यवाद। – Chimera

6

सबसे अच्छी बात कर्नेल के अंदर एक डिवाइस ड्राइवर को कार्यान्वित करना होगा जो /dev/input/eventX फ़ाइल बनाता है जो evdev प्रोटोकॉल बोलता है। यदि आप ऐसा करना चाहते हैं तो मैं आपको Linux Device Drivers नामक पुस्तक पढ़ने की सलाह देता हूं। पुस्तक वेब पर स्वतंत्र रूप से उपलब्ध है।

यदि आप इसे उपयोगकर्ता स्थान में करना चाहते हैं, तो मैं आपको Xlib (या XCB) का उपयोग करने का सुझाव देता हूं। सादे Xlib (सी भाषा) पर, आप X Test Extension या XSendEvent() का उपयोग कर सकते हैं।

xautomation पैकेज (डेबियन, sudo apt-get install xautomation और फिर man xte पर) से xte नामक एक बाइनरी भी है। xte का उपयोग करना बहुत आसान है, और आप एक्स टेस्ट एक्सटेंशन का उपयोग कैसे करें सीखने के लिए अपने स्रोत कोड को भी देख सकते हैं।

प्वाइंटर:

+0

विस्तृत उत्तर के लिए धन्यवाद। – Chimera

1

लगता है कि afte थोड़ा और अनुसंधान, जीटीके + एक जीडीके लाइब्रेरी का उपयोग करता है जो एक्स 11 कोडिंग में गहराई से डूबने या कर्नेल ड्राइवर लिखने के बिना जो भी कर सकता है वह कर सकता है। हालांकि, अगर मेरे पास समय था, तो मैं एक लिनक्स कर्नेल माउस ड्राइवर लिखना पसंद करूंगा।

उपयोग gtk_event_put() प्रकार GdkEventButton

संरचना का एक GdkEvent संलग्न करने के लिए एक GdkEventButton के लिए है::

GDK 2 Reference Manual का उपयोग करते हुए मुझे लगता है मैं निम्न कर सकते हैं पाया

इन क्षेत्रों में से
struct GdkEventButton { 
    GdkEventType type; 
    GdkWindow *window; 
    gint8 send_event; 
    guint32 time; 
    gdouble x; 
    gdouble y; 
    gdouble *axes; 
    guint state; 
    guint button; 
    GdkDevice *device; 
    gdouble x_root, y_root; 
}; 

अधिकांश अपवाद के साथ भरने के लिए तुच्छ होगा:

gdouble x; 
    the x coordinate of the pointer relative to the window. 

gdouble y; 
    the y coordinate of the pointer relative to the window. 

GdkDevice *device; 
    the device where the event originated. 

gdouble x_root; 
    the x coordinate of the pointer relative to the root of the screen. 

gdouble y_root; 
    the y coordinate of the pointer relative to the root of the screen. 

मुझे स्क्रीन रूट को कनवर्ट करने के लिए विंडो रिश्तेदार निर्देशांक को समन्वयित करने के तरीके की आवश्यकता होगी।

*device - मुझे यकीन नहीं है कि मुझे इस क्षेत्र का उपयोग करने की आवश्यकता है (NULL पर सेट करें) क्योंकि यह एक विस्तारित इनपुट डिवाइस के लिए है। हालांकि, अगर मुझे यहां एक वैध डिवाइस की आवश्यकता है तो मुझे gdk_devices_list()

संबंधित मुद्दे