wacom_wac.c
来自「linux 内核源代码」· C语言 代码 · 共 711 行 · 第 1/2 页
C
711 行
/* * drivers/input/tablet/wacom_wac.c * * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code * *//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include "wacom.h"#include "wacom_wac.h"static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo){ unsigned char *data = wacom->data; switch (data[0]) { case 1: if (data[5] & 0x80) { wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; wacom_report_key(wcombo, wacom->tool[0], 1); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -127)); wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); } else { wacom_report_key(wcombo, wacom->tool[0], 0); wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */ wacom_report_abs(wcombo, ABS_PRESSURE, -1); wacom_report_key(wcombo, BTN_TOUCH, 0); } break; case 2: wacom_report_key(wcombo, BTN_TOOL_PEN, 1); wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127); wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40)); break; default: printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]); return 0; } return 1;}static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo){ unsigned char *data = wacom->data; int prox, id, pressure; if (data[0] != 2) { dbg("wacom_pl_irq: received unknown report #%d", data[0]); return 0; } prox = data[1] & 0x40; id = ERASER_DEVICE_ID; if (prox) { pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); if (wacom->features->pressure_max > 255) pressure = (pressure << 1) | ((data[4] >> 6) & 1); pressure += (wacom->features->pressure_max + 1) / 2; /* * if going from out of proximity into proximity select between the eraser * and the pen based on the state of the stylus2 button, choose eraser if * pressed else choose pen. if not a proximity change from out to in, send * an out of proximity for previous tool then a in for new tool. */ if (!wacom->tool[0]) { /* Eraser bit set for DTF */ if (data[1] & 0x10) wacom->tool[1] = BTN_TOOL_RUBBER; else /* Going into proximity select tool */ wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; } else { /* was entered with stylus2 pressed */ if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { /* report out proximity for previous tool */ wacom_report_key(wcombo, wacom->tool[1], 0); wacom_input_sync(wcombo); wacom->tool[1] = BTN_TOOL_PEN; return 0; } } if (wacom->tool[1] != BTN_TOOL_RUBBER) { /* Unknown tool selected default to pen tool */ wacom->tool[1] = BTN_TOOL_PEN; id = STYLUS_DEVICE_ID; } wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */ wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); wacom_report_abs(wcombo, ABS_PRESSURE, pressure); wacom_report_key(wcombo, BTN_TOUCH, data[4] & 0x08); wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10); /* Only allow the stylus2 button to be reported for the pen tool. */ wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); } else { /* report proximity-out of a (valid) tool */ if (wacom->tool[1] != BTN_TOOL_RUBBER) { /* Unknown tool selected default to pen tool */ wacom->tool[1] = BTN_TOOL_PEN; } wacom_report_key(wcombo, wacom->tool[1], prox); } wacom->tool[0] = prox; /* Save proximity state */ return 1;}static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo){ unsigned char *data = wacom->data; int id; if (data[0] != 2) { printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); return 0; } if (data[1] & 0x04) { wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08); id = ERASER_DEVICE_ID; } else { wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); id = STYLUS_DEVICE_ID; } wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); return 1;}static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo){ unsigned char *data = wacom->data; int x, y, id, rw; if (data[0] != 2) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); return 0; } id = STYLUS_DEVICE_ID; if (data[1] & 0x80) { /* in prox */ switch ((data[1] >> 5) & 3) { case 0: /* Pen */ wacom->tool[0] = BTN_TOOL_PEN; break; case 1: /* Rubber */ wacom->tool[0] = BTN_TOOL_RUBBER; id = ERASER_DEVICE_ID; break; case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); if (wacom->features->type == WACOM_G4 || wacom->features->type == WACOM_MO) { rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); wacom_report_rel(wcombo, REL_WHEEL, -rw); } else wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ wacom->tool[0] = BTN_TOOL_MOUSE; id = CURSOR_DEVICE_ID; wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); if (wacom->features->type == WACOM_G4 || wacom->features->type == WACOM_MO) wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); else wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); break; } x = wacom_le16_to_cpu(&data[2]); y = wacom_le16_to_cpu(&data[4]); wacom_report_abs(wcombo, ABS_X, x); wacom_report_abs(wcombo, ABS_Y, y); if (wacom->tool[0] != BTN_TOOL_MOUSE) { wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); } wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ wacom_report_key(wcombo, wacom->tool[0], 1); } else if (!(data[1] & 0x90)) { wacom_report_abs(wcombo, ABS_X, 0); wacom_report_abs(wcombo, ABS_Y, 0); if (wacom->tool[0] == BTN_TOOL_MOUSE) { wacom_report_key(wcombo, BTN_LEFT, 0); wacom_report_key(wcombo, BTN_RIGHT, 0); wacom_report_abs(wcombo, ABS_DISTANCE, 0); } else { wacom_report_abs(wcombo, ABS_PRESSURE, 0); wacom_report_key(wcombo, BTN_TOUCH, 0); wacom_report_key(wcombo, BTN_STYLUS, 0); wacom_report_key(wcombo, BTN_STYLUS2, 0); } wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ wacom_report_key(wcombo, wacom->tool[0], 0); } /* send pad data */ switch (wacom->features->type) { case WACOM_G4: if (data[7] & 0xf8) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 1; wacom->serial[1] = (data[7] & 0xf8); wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); wacom_report_rel(wcombo, REL_WHEEL, rw); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } else if (wacom->id[1]) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 0; wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); wacom_report_abs(wcombo, ABS_MISC, 0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } break; case WACOM_MO: if ((data[7] & 0xf8) || (data[8] & 0x80)) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 1; wacom->serial[1] = (data[7] & 0xf8); wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } else if (wacom->id[1]) { wacom_input_sync(wcombo); /* sync last event */ wacom->id[1] = 0; wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); wacom_report_abs(wcombo, ABS_MISC, 0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } break; } return 1;}static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo){ unsigned char *data = wacom->data; int idx; /* tool number */ idx = data[1] & 0x01; /* Enter report */ if ((data[1] & 0xfc) == 0xc0) { /* serial number of the tool */ wacom->serial[idx] = ((data[3] & 0x0f) << 28) + (data[4] << 20) + (data[5] << 12) + (data[6] << 4) + (data[7] >> 4); wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); switch (wacom->id[idx]) { case 0x812: /* Inking pen */ case 0x801: /* Intuos3 Inking pen */ case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL; break; case 0x822: /* Pen */ case 0x842: case 0x852: case 0x823: /* Intuos3 Grip Pen */ case 0x813: /* Intuos3 Classic Pen */ case 0x885: /* Intuos3 Marker Pen */ case 0x022: wacom->tool[idx] = BTN_TOOL_PEN; break; case 0x832: /* Stroke pen */ case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH; break; case 0x007: /* Mouse 4D and 2D */ case 0x09c: case 0x094: case 0x017: /* Intuos3 2D Mouse */ wacom->tool[idx] = BTN_TOOL_MOUSE; break; case 0x096: /* Lens cursor */ case 0x097: /* Intuos3 Lens cursor */ wacom->tool[idx] = BTN_TOOL_LENS; break; case 0x82a: /* Eraser */ case 0x85a: case 0x91a: case 0xd1a: case 0x0fa: case 0x82b: /* Intuos3 Grip Pen Eraser */ case 0x81b: /* Intuos3 Classic Pen Eraser */ case 0x91b: /* Intuos3 Airbrush Eraser */ wacom->tool[idx] = BTN_TOOL_RUBBER; break; case 0xd12: case 0x912: case 0x112: case 0x913: /* Intuos3 Airbrush */ wacom->tool[idx] = BTN_TOOL_AIRBRUSH; break; default: /* Unknown tool */ wacom->tool[idx] = BTN_TOOL_PEN; } return 1; } /* Exit report */ if ((data[1] & 0xfe) == 0x80) { wacom_report_abs(wcombo, ABS_X, 0); wacom_report_abs(wcombo, ABS_Y, 0); wacom_report_abs(wcombo, ABS_DISTANCE, 0); if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?