亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? hid.c

?? Linux內核源代碼 為壓縮文件 是<<Linux內核>>一書中的源代碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
	for (i = 0; i < HID_REPORT_TYPES; i++) {		struct hid_report_enum *report_enum = device->report_enum + i;		for (j = 0; j < 256; j++) {			struct hid_report *report = report_enum->report_id_hash[j];			if (report) hid_free_report(report);		}	}	if (device->rdesc) kfree(device->rdesc);}/* * Fetch a report description item from the data stream. We support long * items, though they are not used yet. */static __u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item){	if ((end - start) > 0) {		__u8 b = *start++;		item->type = (b >> 2) & 3;		item->tag  = (b >> 4) & 15;		if (item->tag == HID_ITEM_TAG_LONG) {			item->format = HID_ITEM_FORMAT_LONG;			if ((end - start) >= 2) {				item->size = *start++;				item->tag  = *start++;				if ((end - start) >= item->size) {					item->data.longdata = start;					start += item->size;					return start;				}			}		} else {			item->format = HID_ITEM_FORMAT_SHORT;			item->size = b & 3;			switch (item->size) {				case 0:					return start;				case 1: 					if ((end - start) >= 1) {						item->data.u8 = *start++;						return start;					}					break;				case 2: 					if ((end - start) >= 2) {						item->data.u16 = le16_to_cpu( get_unaligned(((__u16*)start)++));						return start;					}				case 3: 					item->size++;					if ((end - start) >= 4) {						item->data.u32 = le32_to_cpu( get_unaligned(((__u32*)start)++));						return start;					}			}		}	}	return NULL;}/* * Parse a report description into a hid_device structure. Reports are * enumerated, fields are attached to these reports. */static struct hid_device *hid_parse_report(__u8 *start, unsigned size){	struct hid_device *device;	struct hid_parser *parser;	struct hid_item    item;	__u8 *end;	unsigned i;	static int (*dispatch_type[])(struct hid_parser *parser,				      struct hid_item *item) = {		hid_parser_main,		hid_parser_global,		hid_parser_local,		hid_parser_reserved	};	if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL)))		return NULL;	memset(device, 0, sizeof(struct hid_device));	for (i = 0; i < HID_REPORT_TYPES; i++)		INIT_LIST_HEAD(&device->report_enum[i].report_list);	if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) {		kfree(device);		return NULL;	}	memcpy(device->rdesc, start, size);	if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) {		kfree(device->rdesc);		kfree(device);		return NULL;	}	memset(parser, 0, sizeof(struct hid_parser));	parser->device = device;		end = start + size;	while ((start = fetch_item(start, end, &item)) != 0) {		if (item.format != HID_ITEM_FORMAT_SHORT) {			dbg("unexpected long global item");			hid_free_device(device);			kfree(parser);			return NULL;		}		if (dispatch_type[item.type](parser, &item)) {			dbg("item %u %u %u %u parsing failed\n",				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);			hid_free_device(device);			kfree(parser);			return NULL;		}		if (start == end) {			if (parser->collection_stack_ptr) {				dbg("unbalanced collection at end of report description");				hid_free_device(device);				kfree(parser);				return NULL;			}			if (parser->local.delimiter_depth) {				dbg("unbalanced delimiter at end of report description");				hid_free_device(device);				kfree(parser);				return NULL;			}			kfree(parser);			return device;		}	}	dbg("item fetching failed at offset %d\n", (int)(end - start));	hid_free_device(device);	kfree(parser);	return NULL;}/* * Convert a signed n-bit integer to signed 32-bit integer. Common * cases are done through the compiler, the screwed things has to be * done by hand. */static __inline__ __s32 snto32(__u32 value, unsigned n){	switch (n) {		case 8:  return ((__s8)value);		case 16: return ((__s16)value);		case 32: return ((__s32)value);	}	return value & (1 << (n - 1)) ? value | (-1 << n) : value;}/* * Convert a signed 32-bit integer to a signed n-bit integer.  */static __inline__ __u32 s32ton(__s32 value, unsigned n){	__s32 a = value >> (n - 1);	if (a && a != -1) return value > 0 ? 1 << (n - 1) : (1 << n) - 1;	return value & ((1 << n) - 1);}/* * Extract/implement a data field from/to a report. We use 64-bit unsigned, * 32-bit aligned, so that we can possibly have alignment problems on some * odd architectures. */static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n){	report += (offset >> 5) << 2; offset &= 31;	return (le64_to_cpu(get_unaligned((__u64*)report)) >> offset) & ((1 << n) - 1);}static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value){	report += (offset >> 5) << 2; offset &= 31;	*(__u64*)report &= cpu_to_le64(~((((__u64) 1 << n) - 1) << offset));	*(__u64*)report |= cpu_to_le64((__u64)value << offset);}static void hid_configure_usage(struct hid_device *device, struct hid_field *field, struct hid_usage *usage){	struct input_dev *input = &device->input;	int max;	unsigned long *bit;	switch (usage->hid & HID_USAGE_PAGE) {		case HID_UP_KEYBOARD:			set_bit(EV_REP, input->evbit);			usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;			if ((usage->hid & HID_USAGE) < 256) {				if (!(usage->code = hid_keyboard[usage->hid & HID_USAGE]))					return;				clear_bit(usage->code, bit);			} else				usage->code = KEY_UNKNOWN;			break; 		case HID_UP_BUTTON:			usage->code = ((usage->hid - 1) & 0xf) + 0x100;			usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;						switch (device->application) {				case HID_GD_GAMEPAD:  usage->code += 0x10;				case HID_GD_JOYSTICK: usage->code += 0x10;				case HID_GD_MOUSE:    usage->code += 0x10; break;				default:					if (field->physical == HID_GD_POINTER)						usage->code += 0x10;					break;			}			break;		case HID_UP_GENDESK:			if ((usage->hid & 0xf0) == 0x80) {	/* SystemControl */				switch (usage->hid & 0xf) {					case 0x1: usage->code = KEY_POWER;  break;					case 0x2: usage->code = KEY_SLEEP;  break;					case 0x3: usage->code = KEY_WAKEUP; break;					default: usage->code = KEY_UNKNOWN; break;				}				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;				break;			}			usage->code = usage->hid & 0xf;			if (field->report_size == 1) {				usage->code = BTN_MISC;				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;				break;			}			if (field->flags & HID_MAIN_ITEM_RELATIVE) {				usage->type = EV_REL; bit = input->relbit; max = REL_MAX;				break;			} 			usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;			if (usage->hid == HID_GD_HATSWITCH) {				usage->code = ABS_HAT0X;				usage->hat = 1 + (field->logical_maximum == 4);			}			break;		case HID_UP_LED:			usage->code = (usage->hid - 1) & 0xf;			usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; 			break;		case HID_UP_DIGITIZER:			switch (usage->hid & 0xff) {				case 0x30: /* TipPressure */					if (!test_bit(BTN_TOUCH, input->keybit)) {						device->quirks |= HID_QUIRK_NOTOUCH;						set_bit(EV_KEY, input->evbit);						set_bit(BTN_TOUCH, input->keybit);					}					usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; 					usage->code = ABS_PRESSURE;					clear_bit(usage->code, bit);					break;				case 0x32: /* InRange */					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;					switch (field->physical & 0xff) {							case 0x21: usage->code = BTN_TOOL_MOUSE; break;						case 0x22: usage->code = BTN_TOOL_FINGER; break;						default: usage->code = BTN_TOOL_PEN; break;					}					break;				case 0x3c: /* Invert */					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;					usage->code = BTN_TOOL_RUBBER;					clear_bit(usage->code, bit);					break;				case 0x33: /* Touch */				case 0x42: /* TipSwitch */				case 0x43: /* TipSwitch2 */					device->quirks &= ~HID_QUIRK_NOTOUCH;					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;					usage->code = BTN_TOUCH;					clear_bit(usage->code, bit);					break;				case 0x44: /* BarrelSwitch */					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;					usage->code = BTN_STYLUS;					clear_bit(usage->code, bit);					break;				default:  goto unknown;			}			break;		case HID_UP_CONSUMER:	/* USB HUT v1.1, pages 56-62 */						switch (usage->hid & HID_USAGE) {				case 0x000: usage->code = 0; break; 				case 0x034: usage->code = KEY_SLEEP;		break;				case 0x036: usage->code = BTN_MISC;		break;				case 0x08a: usage->code = KEY_WWW;		break;				case 0x095: usage->code = KEY_HELP;		break;				case 0x0b4: usage->code = KEY_REWIND;		break;				case 0x0b5: usage->code = KEY_NEXTSONG;		break;				case 0x0b6: usage->code = KEY_PREVIOUSSONG;	break;				case 0x0b7: usage->code = KEY_STOPCD;		break;				case 0x0b8: usage->code = KEY_EJECTCD;		break;				case 0x0cd: usage->code = KEY_PLAYPAUSE;	break;				case 0x0e2: usage->code = KEY_MUTE;		break;				case 0x0e9: usage->code = KEY_VOLUMEUP;		break;				case 0x0ea: usage->code = KEY_VOLUMEDOWN;	break;				case 0x183: usage->code = KEY_CONFIG;		break;				case 0x18a: usage->code = KEY_MAIL;		break;				case 0x192: usage->code = KEY_CALC;		break;				case 0x194: usage->code = KEY_FILE;		break;				case 0x21a: usage->code = KEY_UNDO;		break;				case 0x21b: usage->code = KEY_COPY;		break;				case 0x21c: usage->code = KEY_CUT;		break;				case 0x21d: usage->code = KEY_PASTE;		break;				case 0x221: usage->code = KEY_FIND;		break;				case 0x223: usage->code = KEY_HOMEPAGE;		break;				case 0x224: usage->code = KEY_BACK;		break;				case 0x225: usage->code = KEY_FORWARD;		break;				case 0x226: usage->code = KEY_STOP;		break;				case 0x227: usage->code = KEY_REFRESH;		break;				case 0x22a: usage->code = KEY_BOOKMARKS;	break;				default:    usage->code = KEY_UNKNOWN;		break;			}					usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;			break;		default:		unknown:			if (field->report_size == 1) {				usage->code = BTN_MISC;				usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;				break;			}			if (field->flags & HID_MAIN_ITEM_RELATIVE) {				usage->code = REL_MISC;				usage->type = EV_REL; bit = input->relbit; max = REL_MAX;				break;			}			usage->code = ABS_MISC;			usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;			break;	}	set_bit(usage->type, input->evbit);	while (usage->code <= max && test_and_set_bit(usage->code, bit)) {		usage->code = find_next_zero_bit(bit, max + 1, usage->code);	}	if (usage->code > max) return;	if (usage->type == EV_ABS) {		int a = field->logical_minimum;		int b = field->logical_maximum;		input->absmin[usage->code] = a; 		input->absmax[usage->code] = b;		input->absfuzz[usage->code] = (b - a) >> 8;		input->absflat[usage->code] = (b - a) >> 4;	}	if (usage->hat) {		int i;		for (i = usage->code; i < usage->code + 2 && i <= max; i++) {			input->absmax[i] = 1;			input->absmin[i] = -1;			input->absfuzz[i] = 0;			input->absflat[i] = 0;		}		set_bit(usage->code + 1, input->absbit);	}}static void hid_process_event(struct input_dev *input, int *quirks, struct hid_field *field, struct hid_usage *usage, __s32 value){	hid_dump_input(usage, value);	if (usage->hat) {		if (usage->hat == 2) value = value * 2;		if (value > 8) value = 8;		input_event(input, usage->type, usage->code    , hid_hat_to_axis[value].x);		input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[value].y);		return;	}	if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */		*quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);		return;	}	if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */		if (value) {			input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);			return;		}		input_event(input, usage->type, usage->code, 0);		input_event(input, usage->type, BTN_TOOL_RUBBER, 0);		return;	}	if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */		int a = field->logical_minimum;		int b = field->logical_maximum;		input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));	}	if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UKNOWN */		return;	input_event(input, usage->type, usage->code, value);	if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))		input_event(input, usage->type, usage->code, 0);}/* * Search an array for a value. */static __inline__ int search(__s32 *array, __s32 value, unsigned n){	while (n--) if (*array++ == value) return 0;	return -1;}/* * Analyse a received field, and fetch the data from it. The field * content is stored for next report processing (we do differential * reporting to the layer). */static void hid_input_field(struct hid_device *dev, struct hid_field *field, __u8 *data){	unsigned n;	unsigned count = field->report_count;	unsigned offset = field->report_offset;	unsigned size = field->report_size;	__s32 min = field->logical_minimum;	__s32 max = field->logical_maximum;	__s32 value[count]; /* WARNING: gcc specific */   	for (n = 0; n < count; n++)			value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : 						    extract(data, offset + n * size, size);	for (n = 0; n < count; n++) {		if (HID_MAIN_ITEM_VARIABLE & field->flags) {			if (field->flags & HID_MAIN_ITEM_RELATIVE) {				if (!value[n]) continue;			} else {				if (value[n] == field->value[n]) continue;			}			hid_process_event(&dev->input, &dev->quirks, field, &field->usage[n], value[n]);		} else {			if (field->value[n] >= min && field->value[n] <= max			/* non-NULL value */				&& field->usage[field->value[n] - min].hid			/* nonzero usage */				&& search(value, field->value[n], count))					hid_process_event(&dev->input, &dev->quirks, field,						&field->usage[field->value[n] - min], 0);			if (value[n] >= min && value[n] <= max					/* non-NULL value */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91国偷自产一区二区开放时间| 欧美精品一区二区三区蜜臀| 国产欧美一区二区精品性色| 国产欧美视频一区二区| 久久久高清一区二区三区| 色欧美日韩亚洲| 欧美激情一区二区三区四区| 全部av―极品视觉盛宴亚洲| 欧美剧情电影在线观看完整版免费励志电影 | 在线播放中文一区| 一本到高清视频免费精品| 高清不卡一区二区在线| 欧美日韩国产免费一区二区| 日本一区二区三区四区| 欧美日韩成人综合| 国产日韩av一区| 久久久国产一区二区三区四区小说 | 视频一区二区三区入口| 成人黄色av网站在线| 亚洲美女视频在线观看| 欧美视频精品在线观看| 欧美一区中文字幕| 欧美三级韩国三级日本三斤| 亚洲另类在线制服丝袜| 亚洲欧美日韩久久精品| 全部av―极品视觉盛宴亚洲| 99re成人在线| 国产酒店精品激情| 成人动漫精品一区二区| 97久久超碰精品国产| 欧美三级韩国三级日本一级| 久久久综合精品| 久久丁香综合五月国产三级网站| 99国产精品国产精品毛片| 成人激情免费网站| 91精品国产一区二区三区香蕉 | 国产精品毛片久久久久久| 国产精品亚洲综合一区在线观看| 欧美精品一区二区高清在线观看| 偷拍一区二区三区四区| 亚洲国产精品av| 欧美一级片免费看| 成人自拍视频在线观看| 欧洲av一区二区嗯嗯嗯啊| 韩国欧美国产一区| 一区二区在线观看av| 99久精品国产| 日韩精品亚洲一区| 1000部国产精品成人观看| 国产美女精品一区二区三区| 欧美经典一区二区三区| 精品久久国产老人久久综合| 色94色欧美sute亚洲线路二| 日韩精品一区二区三区在线| 蜜桃精品在线观看| 亚洲最大色网站| 久久精品国产亚洲一区二区三区| 国产嫩草影院久久久久| 久久99热这里只有精品| 日韩午夜激情免费电影| 日本欧美大码aⅴ在线播放| 国产伦精品一区二区三区视频青涩| 欧美影院一区二区三区| 狠狠色综合播放一区二区| 中文字幕字幕中文在线中不卡视频| 日韩视频不卡中文| 欧美国产激情二区三区| 久久精品国产99国产精品| 7777精品伊人久久久大香线蕉经典版下载 | 欧美系列一区二区| 亚洲桃色在线一区| 欧美日韩国产欧美日美国产精品| 欧美日韩一二区| 欧美一级免费大片| 久久久久国色av免费看影院| 中文字幕一区免费在线观看| 亚洲精品一区二区三区在线观看| 亚洲第一电影网| 4438x亚洲最大成人网| 欧美日韩精品二区第二页| 亚洲影院免费观看| 亚洲男人的天堂在线观看| 亚洲国产成人精品视频| 视频一区免费在线观看| 色av成人天堂桃色av| 日韩精品亚洲一区| 国产亚洲精品7777| 色偷偷88欧美精品久久久 | 中文字幕在线观看一区二区| 成人动漫在线一区| 欧美中文字幕一二三区视频| 91视频精品在这里| 色哟哟精品一区| 欧美午夜影院一区| 国产精品传媒入口麻豆| 色系网站成人免费| 成人精品gif动图一区| 亚洲最大色网站| 亚洲欧美日韩一区二区| 久久精品无码一区二区三区| 久久中文娱乐网| 在线精品视频小说1| 天天做天天摸天天爽国产一区| 久久综合成人精品亚洲另类欧美| 一本久久a久久精品亚洲| 韩国成人精品a∨在线观看| 日本欧美在线观看| 日韩avvvv在线播放| 图片区小说区国产精品视频| 亚洲欧美欧美一区二区三区| 国产视频一区二区在线观看| wwwwww.欧美系列| 亚洲视频中文字幕| 六月丁香婷婷色狠狠久久| 亚洲人成小说网站色在线| 欧美中文字幕久久| 亚洲精品免费在线观看| 欧美视频在线观看一区| 欧美综合一区二区三区| 国产精品国产三级国产| 亚洲.国产.中文慕字在线| 三级欧美韩日大片在线看| 99在线精品一区二区三区| 在线观看视频91| 国产日韩成人精品| 91精品视频网| 国产欧美中文在线| 国产在线视频精品一区| 日韩精品一区二区三区视频 | 欧美裸体bbwbbwbbw| 欧美丰满美乳xxx高潮www| 欧美色图第一页| 国产精品美女久久久久aⅴ| 欧美无乱码久久久免费午夜一区| 欧美国产97人人爽人人喊| 久久久一区二区| 亚洲电影第三页| 午夜精品在线视频一区| 午夜久久久久久| 欧美bbbbb| 成人精品免费看| 日韩欧美高清dvd碟片| 亚洲综合久久av| 欧美日韩在线精品一区二区三区激情 | 国产传媒久久文化传媒| 日韩精品1区2区3区| 久久成人久久爱| 欧美猛男男办公室激情| 亚洲成人一区二区在线观看| 欧美色电影在线| 亚洲精品中文字幕在线观看| 国产成人精品综合在线观看| 日韩一二三四区| 亚洲国产成人自拍| 欧美一级艳片视频免费观看| 日韩精品一区二区三区蜜臀| 中文字幕一区av| 精品少妇一区二区| 国产精品的网站| 欧美日韩国产高清一区二区三区 | 国产三级三级三级精品8ⅰ区| 日韩一级片网址| 国产99久久久精品| 偷拍自拍另类欧美| 亚洲美女一区二区三区| 男人操女人的视频在线观看欧美| a级精品国产片在线观看| 日韩中文字幕亚洲一区二区va在线| 成人免费视频网站在线观看| 国产精品麻豆久久久| 日韩三级视频在线观看| 中文字幕一区二区不卡| 在线观看日韩毛片| 国产麻豆精品一区二区| 亚洲精品在线电影| 欧美高清激情brazzers| 91在线视频18| 国产精品久久久久久久久搜平片| 欧美一级精品在线| 午夜av一区二区| 1024国产精品| 国产精品女同一区二区三区| 日韩视频在线观看一区二区| 性感美女久久精品| 久久视频一区二区| 91麻豆精品国产无毒不卡在线观看| 午夜精品久久久久| 欧美日韩激情一区二区| 国产精选一区二区三区| 午夜精彩视频在线观看不卡| 精品国产三级电影在线观看| 国产成人午夜精品影院观看视频 | 欧美视频自拍偷拍| 成人黄色综合网站| 欧美日韩视频在线观看一区二区三区| 亚洲免费观看高清完整版在线观看| 久久久久久久久久久电影| 亚洲欧洲精品天堂一级| 欧美精品粉嫩高潮一区二区| 成人午夜激情片|