diff options
author | guez | 2008-04-08 13:43:01 +0000 |
---|---|---|
committer | guez | 2008-04-08 13:43:01 +0000 |
commit | 8f1e0435cca1d97caba2da1e306432ace45d0bbd (patch) | |
tree | 55a65c1ccd8c1f8401f6bb204b656f451fcf97e8 /wacom_pointer.e | |
download | xinput-ivy-8f1e0435cca1d97caba2da1e306432ace45d0bbd.zip xinput-ivy-8f1e0435cca1d97caba2da1e306432ace45d0bbd.tar.gz xinput-ivy-8f1e0435cca1d97caba2da1e306432ace45d0bbd.tar.bz2 xinput-ivy-8f1e0435cca1d97caba2da1e306432ace45d0bbd.tar.xz |
Version 1.1 de xinput-ivy, auteur Philippe Ribet
Diffstat (limited to 'wacom_pointer.e')
-rw-r--r-- | wacom_pointer.e | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/wacom_pointer.e b/wacom_pointer.e new file mode 100644 index 0000000..1325625 --- /dev/null +++ b/wacom_pointer.e @@ -0,0 +1,426 @@ +class WACOM_POINTER + +create {XINPUT_IVY} + make, make_self_test + +feature {} + make(a_xinput_ivy: XINPUT_IVY) is + require + a_xinput_ivy /= Void + do + xinput_ivy := a_xinput_ivy + prediction_time := 25 + end + + make_self_test is + local + angle: REAL + x, y: REAL + mc: MATH_CONSTANTS + i: INTEGER + do + from + angle := 80 + prediction_time := 10 + until + i > 36 + loop + x := (angle * mc.Pi / 180).cos * 1000 + y := (angle * mc.Pi / 180).sin * 1000 + if i > 2 then + --io.put_string(once "Real position: x=") + io.put_real(x) + --io.put_string(once ", y=") + io.put_character(' ') + io.put_real(y) + io.put_new_line + end + update_predicted_position(x, y, angle) + if i >= 2 then + --io.put_string(once "Predicted position: x=") + io.put_real(predicted_x) + --io.put_string(once ", y=") + io.put_character(' ') + io.put_real(predicted_y) + io.put_character(' ') + --io.put_new_line + end + angle := angle + prediction_time + i := i + 1 + end + end + + xinput_ivy: XINPUT_IVY + + x_offset, y_offset: INTEGER + + prediction_time: REAL + + ignore_rate, ignored_counter: INTEGER + + pointer_message_header, button_message_header: STRING + + old_presure: INTEGER + + type_to_name(type_id: INTEGER): STRING is + do + inspect type_id + when 2066 then Result := once "pen_2066" -- 0x812 + when 2049 then Result := once "pen_2049" -- 0x801 + -- 0x012 + when 2082 then Result := once "pen_2082" -- 0x822 + -- 0x842 + -- 0x852 + when 2083 then Result := once "grip_pen_2083" -- 0x823 + when 2067 then Result := once "classic_pen_2067" -- 0x813 + when 2181 then Result := once "marker_pen_2181" -- 0x885 + -- 0x022 + when 2098 then Result := once "stroke_pen_2098" -- 0x832 + -- 0x032 + when 3346 then Result := once "airbrush_3346" -- 0xd12 + -- 0x912 + -- 0x112 + when 2323 then Result := once "airbrush_2323" -- 0x913 + when 2090 then Result := once "eraser_2090" -- 0x82a + -- 0x85a + -- 0x91a + -- 0xd1a + -- 0x0fa + when 2091 then Result := once "grip_pen_eraser_2091" -- 0x82b + when 2075 then Result := once "classic_pen_eraser_2075" -- 0x81b + when 2331 then Result := once "airbrush_eraser_2331" -- 0x91b + else + Result := once "" + Result.clear_count + type_id.append_in(Result) + end + end + +feature {XINPUT_IVY} + set_x_offset(offset: INTEGER) is + do + x_offset := offset + end + + set_y_offset(offset: INTEGER) is + do + y_offset := offset + end + + set_prediction(milliseconds: REAL) is + do + prediction_time := milliseconds + end + + set_ignore_rate(n: INTEGER) is + do + ignore_rate := n + end + + set_message_header(header: STRING) is + local + history_size: INTEGER + do + pointer_message_header := "pointer" + pointer_message_header.append(header) + button_message_header := "button" + button_message_header.append(header) + history_size := 1 + create x_history.make(0, history_size) + create y_history.make(0, history_size) + create time_history.make(0, history_size) + end + + device_to_screen_x(x: INTEGER): INTEGER is + do + Result := (x / 86400 * 1600 + x_offset).force_to_integer_32 -- **** geometrie paramétrable + end + + device_to_screen_y(y: INTEGER): INTEGER is + do + Result := (y / 65000 * 1200 + y_offset).force_to_integer_32 -- **** geometrie paramétrable + end + + x_history, y_history, time_history: RING_ARRAY[INTEGER] + + mean(history: RING_ARRAY[INTEGER]): REAL is + require + history.count > 0 + local + sum: INTEGER_64 + i: INTEGER + do + from + i := history.lower + until + i > history.upper + loop + sum := sum + history.item(i) + i := i + 1 + end + Result := sum / history.count + end + + move(pointer: X_INPUT_DEVICE) is + local + x, y, presure: INTEGER + t3: REAL_64 + message: STRING + do + x := pointer.motion_axis_data(1) + y := pointer.motion_axis_data(2) + --update_predicted_position(x, y, pointer.event_time) + x_history.remove_first + x_history.add_last(x) + y_history.remove_first + y_history.add_last(y) + time_history.remove_first + time_history.add_last(pointer.event_time) + t3 := mean(time_history) + if t3 /= t2 then + update_predicted_position(mean(x_history), mean(y_history), t3) + end + presure := pointer.motion_axis_data(3) + if ignored_counter < ignore_rate and then ((old_presure = 0) = (presure = 0)) then + ignored_counter := ignored_counter + 1 + else + ignored_counter := 0 + message := once "" + message.copy(pointer_message_header) + print_data_in(message, x, y, presure, pointer.motion_axis_data(4), + pointer.motion_axis_data(5), + pointer.motion_axis_data(6), pointer.event_time, + once "unchanged") + xinput_ivy.ivy.send_message(message) + end + old_presure := presure + end + + + print_data_in(message: STRING; x, y, presure, v4, v5, v6, time: INTEGER; proximity_description: STRING) is + do + message.append(once " x=") + device_to_screen_x(x).append_in(message) + message.append(once " y=") + device_to_screen_y(y).append_in(message) + message.append(once " presure=") + presure.append_in(message) + message.append(once " tilt_x=") + v4.low_16.append_in(message) + message.append(once " tilt_y=") + v5.low_16.append_in(message) + message.append(once " wheel=") + v6.low_16.append_in(message) + message.append(once " predicted_x=") + device_to_screen_x(predicted_x).append_in(message) + message.append(once " predicted_y=") + device_to_screen_y(predicted_y).append_in(message) + message.append(once " type=") + message.append(type_to_name(v4.high_16)) + message.append(once " serial_number=") + (v5.high_16.to_integer_32 |<< 16).bit_or(v6.high_16).append_in(message) + message.append(once " time=") + time.append_in(message) + message.append(once " hires_x=") + (x/86400).append_in(message) -- **** geometrie paramétrable + message.append(once " hires_y=") + (y/65000).append_in(message) -- **** geometrie paramétrable + message.append(once " proximity=") + message.append(proximity_description) + end + + button(pressed: BOOLEAN; pointer: X_INPUT_DEVICE) is + local + x, y, presure: INTEGER + t3: REAL_64 + message: STRING + do + x := pointer.motion_axis_data(1) + y := pointer.motion_axis_data(2) + --update_predicted_position(x, y, pointer.event_time) + x_history.remove_first + x_history.add_last(x) + y_history.remove_first + y_history.add_last(y) + time_history.remove_first + time_history.add_last(pointer.event_time) + t3 := mean(time_history) + if t3 /= t2 then + update_predicted_position(mean(x_history), mean(y_history), t3) + end + message := once "" + message.copy(button_message_header) + message.append(once " button=") + pointer.button_number.append_in(message) + message.append(once " status=") + if pressed then + message.append(once "down") + else + message.append(once "up") + end + presure := pointer.motion_axis_data(3) + print_data_in(message, x, y, presure, pointer.motion_axis_data(4), + pointer.motion_axis_data(5), + pointer.motion_axis_data(6), pointer.event_time, + once "unchanged") + xinput_ivy.ivy.send_message(message) + end + + proximity(in: BOOLEAN; pointer: X_INPUT_DEVICE) is + local + x, y: INTEGER + t3: REAL_64 + message, proximity_status: STRING + do + x := pointer.proximity_axis_data(1) + y := pointer.proximity_axis_data(2) + --update_predicted_position(x, y, pointer.event_time) + --*** exploiter le cas proximity in=True pour vider l'historique + x_history.remove_first + x_history.add_last(x) + y_history.remove_first + y_history.add_last(y) + time_history.remove_first + time_history.add_last(pointer.event_time) + t3 := mean(time_history) + if t3 /= t2 then + update_predicted_position(mean(x_history), mean(y_history), t3) + end + if in then + proximity_status := once "In" + else + proximity_status := once "Out" + end + message := once "" + message.copy(pointer_message_header) + print_data_in(message, x, y, pointer.proximity_axis_data(3), + pointer.proximity_axis_data(4), + pointer.proximity_axis_data(5), + pointer.proximity_axis_data(6), + pointer.event_time, proximity_status) + xinput_ivy.ivy.send_message(message) + end + + predicted_x, predicted_y: INTEGER + + int_update_predicted_position(x3, y3, t3: INTEGER) is + local + dt: REAL -- delta time, temporary value + s3x, s3y, s3: REAL -- speed beetween P2 and P3 + s3xn, s3yn: REAL -- normalized speed between point P2 and P3 + a3x, a3y: REAL -- acceleration at point P2 (needs P3!) + a3xm, a3ym: REAL -- a3 value in mobile coordinates (s2 vector) + a4x, a4y: REAL -- a3 value rotated by (s2 vector, s3 vector) angle + do + dt := t3 - t2 + --s3x := (x3 - x2).to_real_64 / dt + --s3y := (y3 - y2).to_real_64 / dt + s3 := (s3x * s3x + s3y * s3y).sqrt + s3xn := s3x / s3 + s3yn := s3y / s3 + + dt := (t3 - t1) / 2 + a3x := (s3x - s2x) / dt + a3y := (s3y - s2y) / dt + a3xm := a3x * s2xn + a3y * s2yn + a3ym := -a3x * s2yn + a3y * s2xn + a4x := s3xn * a3xm - s3yn * a3ym + a4y := s3yn * a3xm + s3xn * a3ym + + dt := (t3 - t2 + prediction_time) / 2 + predicted_x := x3 + (prediction_time * (s3x + a4x * dt)).force_to_integer_32 + predicted_y := y3 + (prediction_time * (s3y + a4y * dt)).force_to_integer_32 + + if (prediction_time * (s3y + a4y * dt)).abs > 5300 then + io.put_string(once "x2=" + x2.to_string + once " y2=" + y2.to_string) + io.put_string(once " x3=" + x3.to_string + once " y3=" + y3.to_string) + io.put_string(once " s3x=" + s3x.to_string + once " s3y=" + s3y.to_string) + io.put_string(once " a3x=" + a3x.to_string + once " a3y=" + a3y.to_string) + io.put_string(once " a3xm=" + a3xm.to_string + once " a3ym=" + a3ym.to_string) + io.put_string(once " a4x=" + a4x.to_string + once " a4y=" + a4y.to_string) + io.put_string(once " dt=" + dt.to_string) + io.put_string(once " ****") + io.put_new_line + end + -- Shift values + x2 := x3; y2 := y3 + s2x := s3x; s2y := s3y + s2xn := s3xn; s2yn := s3yn + t1 := t2; t2 := t3 + end + + update_predicted_position(x3, y3, t3: REAL) is + require + t2 /= t3 + local + dt: REAL -- delta time, temporary value + s3x, s3y, s3: REAL -- speed beetween P2 and P3 + s3xn, s3yn: REAL -- normalized speed between point P2 and P3 + a3x, a3y: REAL -- acceleration at point P2 (needs P3!) + a3xm, a3ym: REAL -- a3 value in mobile coordinates (s2 vector) + a4x, a4y: REAL -- a3 value rotated by (s2 vector, s3 vector) angle + do + dt := t3 - t2 + s3x := (x3 - x2) / dt + s3y := (y3 - y2) / dt + s3 := (s3x * s3x + s3y * s3y).sqrt + if s3 /= 0 then + s3xn := s3x / s3 + s3yn := s3y / s3 + end + + dt := (t3 - t1) / 2 + a3x := (s3x - s2x) / dt + a3y := (s3y - s2y) / dt + a3xm := a3x * s2xn + a3y * s2yn + a3ym := -a3x * s2yn + a3y * s2xn + a4x := s3xn * a3xm - s3yn * a3ym + a4y := s3yn * a3xm + s3xn * a3ym + + --dt := (t3 - t2 + prediction_time) / 2 + -- acceleration is constant + -- predicted_x := (x3 + prediction_time * (s3x + a3x * dt)).force_to_integer_32 + -- predicted_y := (y3 + prediction_time * (s3y + a3y * dt)).force_to_integer_32 + + -- acceleration is constant in mobile coordinates + -- predicted_x := (x3 + prediction_time * (s3x + a4x * dt)).force_to_integer_32 + -- predicted_y := (y3 + prediction_time * (s3y + a4y * dt)).force_to_integer_32 + + -- acceleration variation is constant + -- a4x := a3x + (a3x - a2x) * (prediction_time + t2 - t1) / (t3 + t1 - t2 - t0) + -- a4y := a3y + (a3y - a2y) * (prediction_time + t2 - t1) / (t3 + t1 - t2 - t0) + -- predicted_x := (x3 + prediction_time * (s3x + a4x * dt)).force_to_integer_32 + -- predicted_y := (y3 + prediction_time * (s3y + a4y * dt)).force_to_integer_32 + + -- half constant in mobile coordinates, half constant variation + dt := (prediction_time + t2 - t1) / (t3 + t1 - t2 - t0) + a4x := (a4x + a3x + (a3x - a2x) * dt) / 2 + a4y := (a4y + a3y + (a3y - a2y) * dt) / 2 + + dt := (t3 - t2 + prediction_time) / 2 + predicted_x := (x3 + prediction_time * (s3x + a4x * dt)).force_to_integer_32 + predicted_y := (y3 + prediction_time * (s3y + a4y * dt)).force_to_integer_32 + + -- Shift values + x2 := x3; y2 := y3 + s2x := s3x; s2y := s3y + s2xn := s3xn; s2yn := s3yn + a2x := a3x; a2y := a3y + t0 := t1; t1 := t2; t2 := t3 + end + + a2x, a2y: REAL + + t0: REAL + + --x2, y2: INTEGER -- point P2 coordinates + x2, y2: REAL -- point P2 coordinates + + s2x, s2y: REAL -- speed beetween P1 and P2 + + s2xn, s2yn: REAL -- normalized speed between P1 and P2 + + --t1, t2: INTEGER -- timestamp for points P1 and P2 + t1, t2: REAL -- timestamp for points P1 and P2 + +end |