📄 wacom.c
字号:
if (retval) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval);}static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs){ struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; int x, y, id, rw; int retval; switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } if (data[0] != 2) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); goto exit; } input_regs(dev, regs); id = STYLUS_DEVICE_ID; if (data[1] & 0x10) { /* 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 */ input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); if (wacom->features->type == G4) { rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); input_report_rel(dev, REL_WHEEL, rw); } else input_report_rel(dev, REL_WHEEL, (signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ wacom->tool[0] = BTN_TOOL_MOUSE; id = CURSOR_DEVICE_ID; input_report_key(dev, BTN_LEFT, data[1] & 0x01); input_report_key(dev, BTN_RIGHT, data[1] & 0x02); if (wacom->features->type == G4) input_report_abs(dev, ABS_DISTANCE, data[6]); else input_report_abs(dev, ABS_DISTANCE, data[7]); break; } } if (data[1] & 0x90) { x = le16_to_cpu(*(__le16 *) &data[2]); y = le16_to_cpu(*(__le16 *) &data[4]); input_report_abs(dev, ABS_X, x); input_report_abs(dev, ABS_Y, y); if (wacom->tool[0] != BTN_TOOL_MOUSE) { input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8)); input_report_key(dev, BTN_TOUCH, data[1] & 0x01); input_report_key(dev, BTN_STYLUS, data[1] & 0x02); input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); } } input_report_key(dev, wacom->tool[0], (data[1] & 0x10) ? id : 0); input_sync(dev); /* send pad data */ if (wacom->features->type == G4) { /* fist time sending pad data */ if (wacom->tool[1] != BTN_TOOL_FINGER) { wacom->id[1] = 0; wacom->serial[1] = (data[7] & 0x38) >> 2; } if (data[7] & 0xf8) { input_report_key(dev, BTN_0, (data[7] & 0x40)); input_report_key(dev, BTN_4, (data[7] & 0x80)); if (((data[7] & 0x38) >> 2) == (wacom->serial[1] & 0x0e)) /* alter REL_WHEEL value so X apps can get it */ wacom->serial[1] += (wacom->serial[1] & 0x01) ? -1 : 1; else wacom->serial[1] = (data[7] & 0x38 ) >> 2; /* don't alter the value when there is no wheel event */ if (wacom->serial[1] == 1) wacom->serial[1] = 0; rw = wacom->serial[1]; rw = (rw & 0x08) ? -(rw & 0x07) : (rw & 0x07); input_report_rel(dev, REL_WHEEL, rw); wacom->tool[1] = BTN_TOOL_FINGER; wacom->id[1] = data[7] & 0xf8; input_report_key(dev, wacom->tool[1], 0xf0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } else if (wacom->id[1]) { wacom->id[1] = 0; wacom->serial[1] = 0; input_report_key(dev, wacom->tool[1], 0); input_event(dev, EV_MSC, MSC_SERIAL, 0xf0); } input_sync(dev); } exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval);}static int wacom_intuos_inout(struct urb *urb){ struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; 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; } input_report_key(dev, wacom->tool[idx], wacom->id[idx]); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); return 1; } /* Exit report */ if ((data[1] & 0xfe) == 0x80) { input_report_key(dev, wacom->tool[idx], 0); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); return 1; } return 0;}static void wacom_intuos_general(struct urb *urb){ struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; unsigned int t; /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); input_report_abs(dev, ABS_PRESSURE, t); input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); input_report_key(dev, BTN_STYLUS, data[1] & 2); input_report_key(dev, BTN_STYLUS2, data[1] & 4); input_report_key(dev, BTN_TOUCH, t > 10); } /* airbrush second packet */ if ((data[1] & 0xbc) == 0xb4) { input_report_abs(dev, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); } return;}static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs){ struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = wacom->dev; unsigned int t; int idx; int retval; switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { dbg("wacom_intuos_irq: received unknown report #%d", data[0]); goto exit; } input_regs(dev, regs); /* tool number */ idx = data[1] & 0x01; /* pad packets. Works as a second tool and is always in prox */ if (data[0] == 12) { /* initiate the pad as a device */ if (wacom->tool[1] != BTN_TOOL_FINGER) { wacom->tool[1] = BTN_TOOL_FINGER; input_report_key(dev, wacom->tool[1], 1); } input_report_key(dev, BTN_0, (data[5] & 0x01)); input_report_key(dev, BTN_1, (data[5] & 0x02)); input_report_key(dev, BTN_2, (data[5] & 0x04)); input_report_key(dev, BTN_3, (data[5] & 0x08)); input_report_key(dev, BTN_4, (data[6] & 0x01)); input_report_key(dev, BTN_5, (data[6] & 0x02)); input_report_key(dev, BTN_6, (data[6] & 0x04)); input_report_key(dev, BTN_7, (data[6] & 0x08)); input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff); input_sync(dev); goto exit; } /* process in/out prox events */ if (wacom_intuos_inout(urb)) goto exit; /* Cintiq doesn't send data when RDY bit isn't set */ if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) goto exit; if (wacom->features->type >= INTUOS3) { input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); } else { input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2])); input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4])); input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); } /* process general packets */ wacom_intuos_general(urb); /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { if (data[1] & 0x02) { /* Rotation packet */ if (wacom->features->type >= INTUOS3) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -