Android 4.0 touch screen message (writing)

Source: Internet
Author: User

The word "message" first appeared in Yijing: "Daily, daily, and daily messages. "It means that when the sun arrives at noon, it will gradually turn to the west, and when the moon is full, it will gradually fall short. Things in the sky and the earth, or the abundance or weakness, will change with the passage of time and sometimes decrease, sometimes grow. It can be seen that in ancient China, the objective world changes, their occurrence, development, and outcome, it refers to the fact that they have changed in glory, accumulation, ups and downs, rise and fall, movements, and gains and losses as "messages". ---------- From du Niang.
Therefore, the message we want to learn here is also a process of generation, development, and termination. Generation means that when the hardware receives a human touch, the message is reported through interruption, so that we can get the message through the upper thread, specifically, how to deal with it will be done through calls within or between threads, and finally the message will be distributed out through the distribution thread for consumption by consumers.
Before learning deeply, we must consider the following questions:
1. How does the system get messages?
2. How is a message read and processed by the system?
3. How do application developers use messages?
1. In the kernel, we will use the following function to report events. (Linux/input. h)
Settings:
1227 unsigned long evbit [BITS_TO_LONGS (EV_CNT)];
1228 unsigned long keybit [BITS_TO_LONGS (KEY_CNT)];
1229 unsigned long relbit [BITS_TO_LONGS (REL_CNT)];
1230 unsigned long absbit [BITS_TO_LONGS (ABS_CNT)];
Report:
1474 static inline void input_report_key (struct input_dev * dev, unsigned int code, int value)
1475 {
1476 input_event (dev, EV_KEY, code ,!! Value );
1477}
1478
1479 static inline void input_report_rel (struct input_dev * dev, unsigned int code, int value)
1480 {
1481 input_event (dev, EV_REL, code, value );
1482}
1483
1484 static inline void input_report_abs (struct input_dev * dev, unsigned int code, int value)
1485 {
1486 input_event (dev, EV_ABS, code, value );
1487}
The input_event function is called as follows:
347 void input_event (struct input_dev * dev,
348 unsigned int type, unsigned int code, int value)
349 {
350 unsigned long flags;
351
352 if (is_event_supported (type, dev-> evbit, EV_MAX )){
353
354 spin_lock_irqsave (& dev-> event_lock, flags );
355 add_input_randomness (type, code, value );
356 input_handle_event (dev, type, code, value );
357 spin_unlock_irqrestore (& dev-> event_lock, flags );
358}
359}
360 EXPORT_SYMBOL (input_event );
Input_handle_event () will call the input_pass_event () function.
77 static void input_pass_event (struct input_dev * dev,
78 unsigned int type, unsigned int code, int value)
79 {
80 struct input_handler * handler;
81 struct input_handle * handle;
82
83 rcu_read_lock ();
84
85 handle = rcu_dereference (dev-> grab );
86 if (handle)
87 handle-> handler-> event (handle, type, code, value );
88 else {
89 bool filtered = false;
90
91 list_for_each_entry_rcu (handle, & dev-> h_list, d_node ){
92 if (! Handle-> open)
93 continue;
94
95 handler = handle-> handler;
96 if (! Handler-> filter ){
97 if (filtered)
98 break;
99
100 handler-> event (handle, type, code, value );
101
102} else if (handler-> filter (handle, type, code, value ))
103 filtered = true;
104}
105}
106
107 rcu_read_unlock ();
108}
The handler above is the evdev_handler () function (). Defined in the evdev. c file. In evdev_init (), the association between input_dev and evdev_handler is completed by calling input_register_handler (& ev_handler) registration. The evdev_event () function is called to store data in the buffer. The Code is as follows:
59 static void evdev_pass_event (struct evdev_client * client,
60 struct input_event * event)
61 {
62/* Interrupts are disabled, just acquire the lock .*/
63 spin_lock (& client-> buffer_lock );
64
65 wake_lock_timeout (& client-> wake_lock, 5 * HZ );
66 client-> buffer [client-> head ++] = * event;
67 client-> head & = client-> bufsize-1;
68
69 if (unlikely (client-> head = client-> tail )){
70 /*
71 * This extends tively "drops" all unconsumed events, leaving
72 * EV_SYN/SYN_DROPPED plus the newest event in the queue.
73 */
74 client-> tail = (client-> head-2) & (client-> bufsize-1 );
75
76 client-> buffer [client-> tail]. time = event-> time;
77 client-> buffer [client-> tail]. type = EV_SYN;
78 client-> buffer [client-> tail]. code = SYN_DROPPED;
79 client-> buffer [client-> tail]. value = 0;
80
81 client-> packet_head = client-> tail;
82}
83
84 if (event-> type = EV_SYN & event-> code = SYN_REPORT ){
85 client-> packet_head = client-> head;
86 kill_fasync (& client-> fasync, SIGIO, POLL_IN );
87}
88
89 spin_unlock (& client-> buffer_lock );
90}
The registration and allocation of underlying devices are basically completed. Now we need to consider how to read data. Read in the kernel section is not introduced at the moment.
In this way, we can complete the settings of the touch screen. These are described in the previous article.
2. Data Reading Process at the frameworks Layer
First, we need to know the most important link is EventHub. It is the central processing site for all events in the system. It manages input events of input devices that can be identified in all systems. In addition, when a device is added or deleted, EventHub generates an input event to the system. The following code opens the device in the getEvents function in the EventHub. cpp file. It mainly calls scanDevicesLocked ().

0569
If (mNeedToScanDevices ){
0570
MNeedToScanDevices = false;
0571
ScanDevicesLocked ();
0572
MNeedToSendFinishedDeviceScan = true;
0573
}
The code for the scanDevicesLocked () function is as follows:
Static const char * DEVICE_PATH = "/dev/input ";
0801
Void EventHub: scanDevicesLocked (){
0802
Status_t res = scanDirLocked (DEVICE_PATH );
0803
If (res <0 ){
0804
LOGE ("scan dir failed for % s \ n", DEVICE_PATH );
0805
}
0806
} Next, call:
1270
Status_t EventHub: scanDirLocked (const char * dirname)
1271
{
1272
Char devname [PATH_MAX];
1273
Char * filename;
1274
DIR * dir;
1275
Struct dirent * de;
1276
Dir = opendir (dirname );
1277
If (dir = NULL)
1278
Return-1;
1279
Strcpy (devname, dirname );
1280
Filename = devname + strlen (devname );
1281
* Filename ++ = '/';
1282
While (de = readdir (dir ))){
1283
If (de-> d_name [0] = '.'&&
1284
(De-> d_name [1] = '\ 0' |
1285
(De-> d_name [1] = '.' & de-> d_name [2] = '\ 0 ')))
1286
Continue;
1287
Strcpy (filename, de-> d_name );
1288
OpenDeviceLocked (devname );
1289
}
1290
Closedir (dir );
1291
Return 0;
1292
}



From Cao taiqiang's column

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.