/* * Timers documentation: * http://www.x.org/releases/X11R7.7/doc/xorg-server/Xserver-spec.html#id2536042 * * This function indirectly may call itself recursively using timer to guarantee correct * event delivery time. Ususally recursion ends after first recursive call. */ static CARD32 check_resolve_delayed(OsTimerPtr timer, CARD32 time, void *arg){ LocalDevicePtr local = arg; struct MTouch *mt = local->private; mstime_t delta_millis; struct timeval delta; // If it was to early to trigger delayed button, next timer will be set, // but when called by timer such situation shouldn't take place. switch (mtouch_delayed(mt)){ case 1: if(mt->is_timer_installed != 1){ TimerCancel(mt->timer); mt->is_timer_installed = 1; timersub(&mt->gs.button_delayed_time, &mt->gs.time, &delta); delta_millis = timertoms(&delta); mt->timer = TimerSet(mt->timer, 0, delta_millis, check_resolve_delayed, local); } break; case 2: TimerCancel(mt->timer); mt->is_timer_installed = 0; handle_gestures(local, &mt->gs); break; case 3: TimerCancel(mt->timer); handle_gestures(local, &mt->gs); mt->is_timer_installed = 2; /* Install coasting timer */ coasting_delayed(mt->timer, -1, arg); break; case 0: break; } return 0; }
/* called for each full received packet from the touchpad */ static void read_input(LocalDevicePtr local) { struct MTouch *mt = local->private; while (mtouch_read(mt) > 0) handle_gestures(local, &mt->gs); if (mtouch_delayed(mt)) handle_gestures(local, &mt->gs); }
void handle_usb_tablet_event (struct input_event *ev, int slot) { static int pen_inrange=0; struct input_event new_ev; new_ev.time = ev->time; new_ev.type = ev->type; new_ev.code = ev->code; new_ev.value = ev->value; struct tablet_scaling_params* t = &(tscale[slot]); if (new_ev.type == EV_ABS) { if (!pen_inrange || (t->subtype!=SUBTYPE_MONOTOUCH)) { if ((new_ev.code == ABS_X) || (new_ev.code == ABS_MT_POSITION_X)) new_ev.value = floor ( (new_ev.value - t->x_offs) * t->x_mult); else if ((new_ev.code == ABS_Y) || (new_ev.code == ABS_MT_POSITION_Y)) new_ev.value = floor ( (new_ev.value - t->y_offs) * t->y_mult); } else return; } else if (new_ev.type == EV_KEY) { /* Translate tablet codes into mouse codes, so it can be understood by drivers */ switch (new_ev.code) { case BTN_TOOL_PEN: if (new_ev.value) t->tool = BTN_LEFT; pen_inrange=new_ev.value; break; case BTN_TOOL_FINGER: if (new_ev.value) t->tool = BTN_TOOL_FINGER; break; case BTN_TOOL_RUBBER: if (new_ev.value) t->tool = BTN_RIGHT; pen_inrange=new_ev.value; break; case BTN_TOUCH: if (t->tool == BTN_TOOL_FINGER) { if (new_ev.value) { if ((t->btnleft==0) && (!pen_inrange)) t->btnleft=btnleft_newlypressed; break; } else if (t->btnleft) { new_ev.code=BTN_LEFT; t->btnleft=0; } else break; } else new_ev.code = t->tool; break; case BTN_STYLUS: new_ev.code = BTN_MIDDLE; break; } } if (new_ev.type == EV_SYN && new_ev.code == SYN_REPORT) { if (t->btnleft==btnleft_newlypressed) { t->btnleft=1; check_and_inject_event (&new_ev, slot, HID_TYPE_TABLET); set_and_inject_event(slot, &new_ev, EV_KEY, BTN_LEFT,1); set_and_inject_event(slot, &new_ev, EV_SYN, SYN_REPORT,0); return; } } // Check for SYN_DROPPED. Indicates buffer overrun, so no point forwarding any more of packet until next syn_report // Note that as any packets before the syn_dropped have already been transmitted, syn_dropped must still be transmitted // so that client knows to ignore them. if (new_ev.type == EV_SYN && new_ev.code == SYN_DROPPED) { ignore_events[slot] = 1; info ("Ignoring events from event%d until next packet begins", slot); } else if (ignore_events[slot]) { if (new_ev.type == EV_SYN && new_ev.code == SYN_REPORT) { ignore_events[slot] = 0; info ("End of dropped packet from event%d", slot); } else return; } if ((new_ev.type == EV_KEY) && (new_ev.code != ev->code)) { /* we want to send bot the mouse version and pen version */ check_and_inject_event (ev, slot, HID_TYPE_TABLET); } if (handle_gestures (&new_ev)) check_and_inject_event (&new_ev, slot, HID_TYPE_TABLET); }