diff options
Diffstat (limited to 'xinput_ivy.e')
-rw-r--r-- | xinput_ivy.e | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/xinput_ivy.e b/xinput_ivy.e new file mode 100644 index 0000000..15d0a54 --- /dev/null +++ b/xinput_ivy.e @@ -0,0 +1,431 @@ +class XINPUT_IVY + +inherit + GRAPHIC + +insert + ARGUMENTS + +creation {ANY} + make + +feature {} + + ivy_bus: STRING + + application_name: STRING + + device_id: STRING + + make is + local + ready: BOOLEAN + do + application_name := "wacom" + ivy_bus := ":3110" + device_id := "default" + screen := vision.root_window + ready := decode_options + if ready then + create ivy.make(application_name) + ivy.start(ivy_bus) + vision.loop_stack.add_job(ivy) + vision.start + end + end + + screen: ROOT_WINDOW + + decode_options: BOOLEAN is + local + i: INTEGER + option, value: STRING + equal_index: INTEGER + error: BOOLEAN + tmp_pointer: WACOM_POINTER + do + from + i := 1 + option := "" + value := "" + create tmp_pointer.make(Current) + until + i > argument_count or error + loop + option.copy(argument(i)) + equal_index := option.first_index_of('=') + if equal_index = 0 then + value.clear_count + else + value.copy(option) + value.remove_head(equal_index) + option.remove_tail(option.count - equal_index + 1) + end + inspect option + when "-help" then + print_help + when "-list_devices" then + list_devices + when "-pad" then + if init_pad(value) then + Result := True + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid pad name.%N") + end + when "-wacom_pointer" then + if init_wacom_pointer(tmp_pointer, value) then + Result := True + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid pointer name.%N") + end + when "-bus" then + ivy_bus.copy(value) + when "-b" then + if i < argument_count then + i := i + 1 + ivy_bus.copy(argument(i)) + else + error := True + std_error.put_string("Missing bus identifier after % + %-b option.%N") + end + when "-application" then + application_name.copy(value) + when "-identifier" then + device_id.copy(value) + when "-x_offset" then + if value.is_integer then + tmp_pointer.set_x_offset(value.to_integer) + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid x_offset (an integer is needed).%N") + end + when "-y_offset" then + if value.is_integer then + tmp_pointer.set_y_offset(value.to_integer) + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid y_offset (an integer is needed).%N") + end + when "-prediction" then + if value.is_real then + tmp_pointer.set_prediction(value.to_real) + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid time (a real number is needed).%N") + end + when "-ignore" then + if value.is_integer then + tmp_pointer.set_ignore_rate(value.to_integer) + else + error := True + std_error.put_character('"') + std_error.put_string(value) + std_error.put_string("%" is not a valid ignore rate (an integer is needed).%N") + end + else + error := True + std_error.put_string("Unknown option ") + std_error.put_string(argument(i)) + std_error.put_new_line + print_help + end + i := i + 1 + end + if error then + Result := False + end + if argument_count =0 then + print_help + end + end + + init_pad(pad_name: STRING): BOOLEAN is + local + pad: X_INPUT_DEVICE + message_header: STRING + do + pad := subscribe_input(pad_name) + if pad /= Void then + Result := True + message_header := "slider_event device_id=" + message_header.append(device_id) + message_header.append(once " value=") + pad.when_moved(screen, agent slider_event(message_header, ?)) + pad.when_proximity_out(screen, agent left_slider_out(message_header, ?)) + + message_header := "pad_event device_id=" + message_header.append(device_id) + message_header.append(once " button=") + pad.when_button_pressed(screen, agent pad_button_pressed(message_header, ?)) + pad.when_button_released(screen, agent pad_button_released(message_header, ?)) + end + end + + init_wacom_pointer(wacom_pointer_model: WACOM_POINTER; pointer_name: STRING): BOOLEAN is + local + pointer: X_INPUT_DEVICE + message_header: STRING + wacom_pointer: WACOM_POINTER + do + pointer := subscribe_input(pointer_name) + if pointer /= Void then + Result := True + wacom_pointer := wacom_pointer_model.twin + message_header := "_event device_id=" + message_header.append(device_id) + wacom_pointer.set_message_header(message_header) + pointer.when_moved(screen, agent wacom_pointer.move) + pointer.when_button_pressed(screen, agent wacom_pointer.button(True, ?)) + pointer.when_button_released(screen, agent wacom_pointer.button(False, ?)) + pointer.when_proximity_in(screen, agent wacom_pointer.proximity(True, ?)) + pointer.when_proximity_out(screen, agent wacom_pointer.proximity(False, ?)) + end + end + + print_help is + do + io.put_string("[ + This tool get data from wacom pen screen and is + able to send them to applications using ivy bus. + + Options: + -help: print this help. + + -list_devices: all available devices are listed. + + -pad=name: report pad data from the pad device with this name. + + -wacom_pointer=name: report pointer data from the pointer device with + this name. Ex: stylus. + + -bus=[address]:port: specify the ivy bus (default is :3110). + + -b [address]:port: specify the ivy bus (default is :3110) (added for + compatibility with other ivy tools). + + -application=name: specify the application name on the ivy bus + (default is wacom). + + -identifier=id: this identifier will be used in ivy messages + device_id value (default is "default"). + + -x_offset=n: specify the x-offset for the wacom device + for the display configuration (default is 0). + + -y_offset=n: specify the y-offset for the wacom device + for the display configuration (default is 0). + + -prediction=t: change the prediction time for the physical position. + (default is 25ms). + + -ignore=n: number of messages to ignore before sending a new + position message (this reduces message frequency). + (default is 0 => ~120message/s). + + Options are considered in the order they appear in the command line. A new + value overrides the previous one. "wacom_pointer" and "pad" are created where they + appear, with known information. + + Messages: + slider_event device_id=radar_wacom value=4 side=left time=4523271 + device_id: identifier (see options). + value: new slider value (0 when the + finger leaves the slider). + side: left or right. + time: event time (ms), X server reference. + + pad_event device_id=radar_wacom button=12 status=left time=4523271 + device_id: identifier (see options). + button: button identifier. + status: up or down. + time: event time (ms), X server reference. + + button_event device_id=radar_wacom button=2 status=up x=1290 y=325 + presure=307 tilt_x=-20 tilt_y=15 wheel=0 predicted_x=1272 predicted_y=322 + type=123 serial_number=429389 time=4523271 hires_x=0.827 hires_y=0.231 + proximity=unchanged + pointer_event device_id=radar_wacom x=1290 y=325 + presure=307 tilt_x=-20 tilt_y=15 wheel=0 predicted_x=1272 predicted_y=322 + type=123 serial_number=429389 time=4523271 hires_x=0.827 hires_y=0.231 + proximity=unchanged + device_id: identifier (see options). + button: button identifier. + status: up or down. + x: pointer position (display coordinates). + y: pointer position (display coordinates). + presure: presure value ([0, 1023] for intuos 3). + tilt_x: device tilt in degrees. + tilt_y: device tilt in degrees. + wheel: rotation value (device type dependent value). + predicted_x: predicted position. It is expected to be + the current position of the real device. + predicted_y: predicted position. It is expected to be + the current position of the real device. + type: the type of the device (pen, eraser, mouse, + cursor, airbrush...). + serial_number: the serial number of the device. + time: event time (ms), X server reference. + hires_x: pointer position (device coordinates, in range [0,1]). + hires_y: pointer position (device coordinates, in range [0,1]). + proximity: unchanged, in, out + + ]") + --*** calibration? + --*** filtrage? + --*** bouton du stylo? + --*** distance du stylo? + --*** message pour demander la configuration? + --*** suppression du curseur souris + --*** display + --*** + --*** Ajouter le message pour modifier la prédiction + end + + x11: X11 + + subscribe_input(name: STRING): X_INPUT_DEVICE is + local + i: INTEGER + devices: FAST_ARRAY[X_INPUT_DEVICE] + do + if not x11.has_x_input_extension then + std_error.put_line("XInputExtension is not available.") + else + from + devices := x11.x_input_extension.devices + i := devices.lower + until + i > devices.upper or else Result /= Void + loop + if devices.item(i).name.is_equal(name) then + Result := devices.item(i) + if Result.is_available_extension then + Result.connect + else + Result := Void + end + end + i := i + 1 + end + end + end + + left_pad_position: INTEGER + right_pad_position: INTEGER + + slider_event(message_header: STRING; pad: X_INPUT_DEVICE) is + local + new_pad_position: INTEGER + message: STRING + do + message := once "" + new_pad_position := pad.motion_axis_data(4) + if new_pad_position /= left_pad_position then + message.copy(message_header) + new_pad_position.append_in(message) + message.append(once " side=left time=") + pad.event_time.append_in(message) + ivy.send_message(message) + left_pad_position := new_pad_position + end + + new_pad_position := pad.motion_axis_data(5) + if new_pad_position /= right_pad_position then + message.copy(message_header) + new_pad_position.append_in(message) + message.append(once " side=right time=") + pad.event_time.append_in(message) + ivy.send_message(message) + right_pad_position := new_pad_position + end + end + + left_slider_out(message_header: STRING; pad: X_INPUT_DEVICE) is + local + message: STRING + do + message := once "" + message.copy(message_header) + message.extend('0') + message.append(once " side=left time=") + pad.event_time.append_in(message) + ivy.send_message(message) + left_pad_position := 0 + end + + pad_button_pressed(message_header: STRING; pad: X_INPUT_DEVICE) is + local + message: STRING + do + message := once "" + message.copy(message_header) + pad.button_number.append_in(message) + message.append(once " status=down time=") + pad.event_time.append_in(message) + ivy.send_message(message) + end + + pad_button_released(message_header: STRING; pad: X_INPUT_DEVICE) is + local + message: STRING + do + message := once "" + message.copy(message_header) + pad.button_number.append_in(message) + message.append(once " status=up time=") + pad.event_time.append_in(message) + ivy.send_message(message) + end + + list_devices is + local + i: INTEGER + devices: FAST_ARRAY[X_INPUT_DEVICE] + device: X_INPUT_DEVICE + do + if not x11.has_x_input_extension then + std_error.put_line("XInputExtension is not available.") + else + from + devices := x11.x_input_extension.devices + i := devices.lower + until + i > devices.upper + loop + device := devices.item(i) + std_output.put_string(device.name) + std_output.put_string(once " (Type: ") + if device.type = Void then + std_output.put_character('?') + else + std_output.put_string(device.type) + end + std_output.put_string(once " Status: ") + if device.is_available_extension then + std_output.put_line(once " available)") + else + std_output.put_line(once " unavailable)") + end + i := i + 1 + end + end + end + +feature {WACOM_POINTER} + ivy: IVY + + +end |