Chatting with input devices in Linux (9) from generation to generation, where is the end

Source: Internet
Author: User

Here, we will analyze how to report events to our input subsystem by taking one row as an example.

Input_report_abs (data-> input_dev, abs_rx, rbuf [0]); Continue tracking:

 

Static inline void input_report_abs (struct input_dev * Dev, unsigned int code, int value)

{

Input_event (Dev, ev_abs, code, value );

}

As you can see, this function also calls only one input_event function. The Network Name "bin Laden's father" is about to swear: "Why does one line of code also implement a function? Isn't that a fool ?" Brother, you need to understand the good intentions of our Linux kernel code-writing buddies (you say you want to escape, but you're doomed to settle down, love is gone out, and there's nothing left to worry about, spring has gone through the flowers and fallen, but with a bitter heart but empty, How do I describe my pain, love your wrong hand in my life. Zhang Yu is a classic song. They hope that the same function can be called by multiple other functions at the same time to achieve code reuse. For example, input_event (Dev, ev_abs, code, value); perform different processing based on the second parameter. Next time, you have to deal with a button event. We can simply do this:
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{
        input_event(dev, EV_KEY, code, value);
}
Okay, let's talk a little bit about it. Keep tracking in:

Void input_event (struct input_dev * Dev,

Unsigned int type, unsigned int code, int value)

{

1 unsigned long flags;

 

2 If (is_event_supported (type, Dev-> evbit, ev_max )){

 

3Spin_lock_irqsave (& Dev-> event_lock, flags );

4 add_input_randomness (type, code, value );

5 input_handle_event (Dev, type, code, value );

6Spin_unlock_irqrestore (& Dev-> event_lock, flags );

}

}

Finally, we can see a function that looks like a function. There are at least six lines of code. Brother, you and I should all be very happy. Functions with hundreds of lines of code in the Linux kernel are everywhere.

One line defines an identifier and will be used later.

Two rows: Determine whether the ev_abs identifier is set in the evbit in our input device to support absolute value coordinates. Think back to set_bit (ev_abs, AKM-> input_dev-> evbit) in section 2. If there is no error, we have settings, so we can go down.

Lines 3 and 6 apply a spin lock to our critical code to prevent concurrent access. Careful friends may find that this is a little different from our usual spin locks. The general spin locks are paired with the spin lock () and the spin lock. How long is the tail here. Yes, some differences between men and women seem to be here. Sorry, my thoughts are no longer... Coming back, we have more demanding spin lock conditions. The general spin lock protects the code in the critical section from other CPU and CPU preemption processes. The two long-tailed buddies are even more cruel. They even refused to interrupt us. In a word, let us know that you don't even want to touch anything I possess, unless I release her. It's tough! Yes, men should be jealous of themselves. The flag defined above is used to save the interrupted state information that is rejected by us.

Four lines generate random factors for the kernel.

Five lines, the real savvy buddy should glance at these lines of code and find that this line is the true national treasure. Is this a so-called talent, you have to admire Nicolas Cage's sharpness. With such a little bit of information, you can find such a large treasure. But in real life, the probability of such a thing happening is like Zhang manyu suddenly broke up with her foreign boyfriend for you and then came to Chang 'an, In order to stay with you silently. Continue with input_handle_event (Dev, type, code, value ):

It is also a function from input core.

Static void input_handle_event (struct input_dev * Dev,

Unsigned int type, unsigned int code, int value)

{

Int disposition = input_ignore_event;

 

Switch (type ){

 

Case ev_syn:

Switch (CODE ){

Case syn_config:

Disposition = input_pass_to_all;

Break;

 

Case syn_report:

If (! Dev-> sync ){

Dev-> sync = 1;

Disposition = input_pass_to_handlers;

}

Break;

}

Break;

 

Case ev_key:

If (is_event_supported (Code, Dev-> keybit, key_max )&&

!! Test_bit (Code, Dev-> key )! = Value ){

 

If (value! = 2 ){

_ Change_bit (Code, Dev-> key );

If (value)

Input_start_autorepeat (Dev, Code );

}

 

Disposition = input_pass_to_handlers;

}

Break;

 

Case ev_sw:

If (is_event_supported (Code, Dev-> swbit, sw_max )&&

!! Test_bit (Code, Dev-> SW )! = Value ){

 

_ Change_bit (Code, Dev-> SW );

Disposition = input_pass_to_handlers;

}

Break;

 

CaseEv_abs:

1If (is_event_supported (Code, Dev-> absbit, abs_max ))

2 {

 

3 value = input_defuzz_abs_event (value,

4 Dev-> ABS [Code], Dev-> absfuzz [Code]);

5 If (Dev-> ABS [Code]! = Value)

6 {

Dev-> ABS [Code] = value;

7 Disposition = input_pass_to_handlers;

8}

9}

10 break;

 

Case ev_rel:

If (is_event_supported (Code, Dev-> relbit, rel_max) & value)

Disposition = input_pass_to_handlers;

 

Break;

 

Case ev_msc:

If (is_event_supported (Code, Dev-> mscbit, msc_max ))

Disposition = input_pass_to_all;

 

Break;

 

Case ev_led:

If (is_event_supported (Code, Dev-> ledbit, led_max )&&

!! Test_bit (Code, Dev-> led )! = Value ){

 

_ Change_bit (Code, Dev-> led );

Disposition = input_pass_to_all;

}

Break;

 

Case ev_snd:

If (is_event_supported (Code, Dev-> sndbit, snd_max )){

 

If (!! Test_bit (Code, Dev-> SND )! = !! Value)

_ Change_bit (Code, Dev-> SND );

Disposition = input_pass_to_all;

}

Break;

 

Case ev_rep:

If (Code <= rep_max & value> = 0 & Dev-> rep [Code]! = Value ){

Dev-> rep [Code] = value;

Disposition = input_pass_to_all;

}

Break;

 

Case ev_ff:

If (value> = 0)

Disposition = input_pass_to_all;

Break;

 

Case ev_pwr:

Disposition = input_pass_to_all;

Break;

}

 

If (Disposition! = Input_ignore_event & type! = Ev_syn)

Dev-> sync = 0;

 

If (Disposition & input_pass_to_device) & Dev-> event)

Dev-> event (Dev, type, code, value );

 

If (Disposition & input_pass_to_handlers)

Input_pass_event (Dev, type, code, value );

}

A brother is about to talk: "A long pile of code", yes, I admit, this is the longest function in my document so far. Those who have not learned a little C language in the university should not think that it is complicated. Otherwise, you will not be able to see Jiangdong's father without saying anything. I'm more sorry, brother tan haoqiang. The entire function has a switch first. Then different processing is performed based on different cases to obtain different disposition variable values. Then, it's up to the last six lines of code. Isn't it a simple B. The passed parameter is exactly ev_abs. So we only need to focus on the bold part of the code.

 

Line 1: Check whether abs_rx is set in the absbit in our input device. Obviously, we have already set a function that we didn't know before. I believe that your C language code reading capability is definitely above me. How can I identify you with just a few lines of code.

3-4 rows for error calibration. Here I set it to 0 during initialization. In fact, there is nothing to do. The stars are still the stars, the moon is the moon, and the value is also the value.

In lines 5-7, the value is paid to Dev-> ABS [Code], Dev-> ABS [Code] to record the last coordinate value. If this is the first time, it is obviously 0. So we finally get disposition = input_pass_to_handlers. After quietly doing so much preliminary work, we were able to get her. Now I finally got what I expected, and she began to wander across the world .....

Where did the waves go? Clever, you immediately discovered the last two lines of code. The sun is still shining, the Earth is still rotating, you still love her in your heart, the story is still going on, input_pass_event (Dev, type, code, value) is still passing values, where will he upload the type, code, and value we have collected? Do you want to know? For more information, see the next section.

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.