summaryrefslogtreecommitdiff
path: root/xinput_ivy.e
diff options
context:
space:
mode:
Diffstat (limited to 'xinput_ivy.e')
-rw-r--r--xinput_ivy.e431
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