- list->dx += packet->dx;
- list->dy += packet->dy;
- list->dz += packet->dz;
- list->buttons = mousedev->buttons;
- list->ready = 1;
- kill_fasync(&list->fasync, SIGIO, POLL_IN);
+ spin_lock_irqsave(&list->packet_lock, flags);
+
+ p = &list->packets[list->head];
+ if (list->ready && p->buttons != mousedev->packet.buttons) {
+ unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN;
+ if (new_head != list->tail) {
+ p = &list->packets[list->head = new_head];
+ memset(p, 0, sizeof(struct mousedev_motion));
+ }
+ }
+
+ if (packet->abs_event) {
+ p->dx += packet->x - list->pos_x;
+ p->dy += packet->y - list->pos_y;
+ list->pos_x = packet->x;
+ list->pos_y = packet->y;
+ }
+
+ list->pos_x += packet->dx;
+ list->pos_x = list->pos_x < 0 ? 0 : (list->pos_x >= xres ? xres : list->pos_x);
+ list->pos_y += packet->dy;
+ list->pos_y = list->pos_y < 0 ? 0 : (list->pos_y >= yres ? yres : list->pos_y);
+
+ p->dx += packet->dx;
+ p->dy += packet->dy;
+ p->dz += packet->dz;
+ p->buttons = mousedev->packet.buttons;
+
+ if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons)
+ list->ready = 1;
+
+ spin_unlock_irqrestore(&list->packet_lock, flags);
+
+ if (list->ready) {
+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
+ wake_readers = 1;
+ }