Linux input子系統分析 5 事件傳遞過程

2021-06-07 06:32:41 字數 4674 閱讀 8444

三. 事件傳遞過程(以s3c2410_ts為例)

1. 事件產生

當按下觸控螢幕時,進入觸控螢幕按下中斷,開始ad轉換,ad轉換完成進入ad完成中斷,在這個中斷中將事件傳送出去,呼叫input_report_abs(dev, abs_x, xp);

static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)

input_report_abs(dev, abs_y, yp); 這兩個函式呼叫了 input_event(dev, ev_abs, code, value)

所有的事件報告函式都呼叫這個函式。

2. 事件報告

(1) input_event函式分析,這個函式定義在input.c中

/**

* input_event() - report new input event

* @dev: device that generated the event

* @type: type of the event

* @code: event code

* @value: value of the event

** this function should be used by drivers implementing various input

* devices to report input events. see also input_inject_event().

** note: input_event() may be safely used right after input device was

* allocated with input_allocate_device(), even before it is registered

* with input_register_device(), but the event will not reach any of the

* input handlers. such early invocation of input_event() may be used

* to 'seed' initial state of a switch or initial position of absolute

* axis, etc.

*/void input_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

}export_symbol(input_event);

(2) input_handle_event函式分析,這個函式定義在input.c中.

static void input_handle_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

break;

case syn_mt_report:

dev->sync = 0;

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)

disposition = input_pass_to_handlers;

}break;

case ev_sw:

if (is_event_supported(code, dev->swbit, sw_max) &&

!!test_bit(code, dev->sw) != value)

break;

case ev_abs:

if (is_event_supported(code, dev->absbit, abs_max))

value = input_defuzz_abs_event(value,

dev->abs[code], dev->absfuzz[code]);

if (dev->abs[code] != value)

}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)

break;

case ev_snd:

if (is_event_supported(code, dev->sndbit, snd_max))

break;

case ev_rep:

if (code <= rep_max && value >= 0 && dev->rep[code] != value)

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);

}

函式主要是根據事件型別的不同,做相應的處理。

只關心ev_key型別,其他函式和事件傳遞關係不大,只要關心,disposition這個是事件處理的方式,預設的是input_ignore_event,忽略這個事件,如果是input_pass_to_handlers則是傳遞給事件處理器,如果是input_pass_to_device,則是傳遞給裝置處理,觸控螢幕驅動沒有定義這個。

下面分析input_pass_event函式。

/*

* pass event first through all filters and then, if event has not been

* filtered out, through all open handles. this function is called with

* dev->event_lock held and interrupts disabled.

*/static void input_pass_event(struct input_dev *dev,

unsigned int type, unsigned int code, int value)

else if (handler->filter(handle, type, code, value))

filtered = true;}}

rcu_read_unlock();

}

下面分析 evdev事件處理器的event函式:evdev_event()

/*

* pass incoming event to all connected clients.

*/static void evdev_event(struct input_handle *handle,

unsigned int type, unsigned int code, int value)

下面分析 evdev_pass_event()函式:

static void evdev_pass_event(struct evdev_client *client,

struct input_event *event)

看出, evdev_pass_event函式最終將事件傳遞給了使用者端的client結構中的input_event陣列中,只需將這個input_event陣列複製給使用者空間,程序就能收到觸控螢幕按下的資訊了。具體處理由具體的應用程式來完成。

Linux input子系統分析之一 軟體層次

標籤 input子系統 tslib linux驅動開發 linux軟體層次 linux輸入子系統 2015 08 23 10 49 2808人閱讀收藏 舉報 s5pv210 cortex a8 11 linux核心 驅動 17 輸入輸出是使用者和產品互動的手段,因此輸入驅動開發在linux驅動開發中...

framebuffer 子系統分析

fb info screen base dma alloc writecombine fbi dev,map size,map dma,gfp kernel fb info screen base 是framebuffer起始虛擬位址,也就是mmap後程式寫入fb的位址,該位址會直接寫入到fb in...

framebuffer 子系統分析

come from struct fb info ranges 0 apertures struct fb var screeninfo struct fb fix screeninfo 這兩個結構體分別記錄了顯示器可以修改和不可修改的資訊,這些資料成員需要在驅動程式中初始化。其中fix.visua...