Mercurial > tablet-emu
annotate src/main.rs @ 3:72e63d6a3f8a
Simplify state handling into a single struct.
| author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
|---|---|
| date | Fri, 09 Oct 2020 15:03:55 +0200 |
| parents | 39f87ef69b2a |
| children | 2e074d185151 |
| rev | line source |
|---|---|
| 0 | 1 use gio::prelude::*; |
| 2 use gtk::prelude::*; | |
| 3 | |
| 4 use std::env::args; | |
| 5 use std::fs::{File, OpenOptions}; | |
| 6 use std::io::ErrorKind; | |
| 7 use std::sync::{Arc, Mutex}; | |
| 8 | |
| 9 use input_linux::{ | |
| 10 sys::input_event, sys::timeval, AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, | |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
11 InputId, InputProperty, Key, MiscKind, SynchronizeKind, UInputHandle, |
| 0 | 12 }; |
| 13 | |
| 14 const WIDTH: i32 = 320; | |
| 15 const HEIGHT: i32 = 180; | |
| 16 | |
| 17 const MAX_X: i32 = 69920; | |
| 18 const MAX_Y: i32 = 39980; | |
| 19 | |
| 20 fn create_uinput_device() -> std::io::Result<UInputHandle<File>> { | |
| 21 let file = OpenOptions::new().write(true).open("/dev/uinput")?; | |
| 22 let dev = UInputHandle::new(file); | |
| 23 | |
| 24 dev.set_evbit(EventKind::Synchronize)?; | |
| 25 dev.set_evbit(EventKind::Key)?; | |
| 26 dev.set_evbit(EventKind::Absolute)?; | |
| 27 dev.set_evbit(EventKind::Misc)?; | |
| 28 dev.set_keybit(Key::ButtonToolPen)?; | |
| 29 dev.set_keybit(Key::ButtonToolRubber)?; | |
| 30 dev.set_keybit(Key::ButtonToolBrush)?; | |
| 31 dev.set_keybit(Key::ButtonToolPencil)?; | |
| 32 dev.set_keybit(Key::ButtonToolAirbrush)?; | |
| 33 dev.set_keybit(Key::ButtonTouch)?; | |
| 34 dev.set_keybit(Key::ButtonStylus)?; | |
| 35 dev.set_keybit(Key::ButtonStylus2)?; | |
| 36 dev.set_keybit(Key::ButtonStylus3)?; | |
| 37 dev.set_mscbit(MiscKind::Serial)?; | |
| 38 dev.set_propbit(InputProperty::Direct)?; | |
| 39 | |
| 40 dev.set_absbit(AbsoluteAxis::X)?; | |
| 41 dev.set_absbit(AbsoluteAxis::Y)?; | |
| 42 dev.set_absbit(AbsoluteAxis::Z)?; | |
| 43 dev.set_absbit(AbsoluteAxis::Wheel)?; | |
| 44 dev.set_absbit(AbsoluteAxis::Pressure)?; | |
| 45 dev.set_absbit(AbsoluteAxis::Distance)?; | |
| 46 dev.set_absbit(AbsoluteAxis::TiltX)?; | |
| 47 dev.set_absbit(AbsoluteAxis::TiltY)?; | |
| 48 dev.set_absbit(AbsoluteAxis::Misc)?; | |
| 49 | |
| 50 let id = InputId { | |
| 51 bustype: 3, | |
| 52 vendor: 0x56a, | |
| 53 product: 0x350, | |
| 54 version: 0xb, | |
| 55 }; | |
| 56 | |
| 57 let x = AbsoluteInfoSetup { | |
| 58 axis: AbsoluteAxis::X, | |
| 59 info: AbsoluteInfo { | |
| 60 value: 0, | |
| 61 minimum: 0, | |
| 62 maximum: MAX_X, | |
| 63 fuzz: 0, | |
| 64 flat: 0, | |
| 65 resolution: 200, | |
| 66 }, | |
| 67 }; | |
| 68 let y = AbsoluteInfoSetup { | |
| 69 axis: AbsoluteAxis::Y, | |
| 70 info: AbsoluteInfo { | |
| 71 value: 0, | |
| 72 minimum: 0, | |
| 73 maximum: MAX_Y, | |
| 74 fuzz: 0, | |
| 75 flat: 0, | |
| 76 resolution: 200, | |
| 77 }, | |
| 78 }; | |
| 79 let z = AbsoluteInfoSetup { | |
| 80 axis: AbsoluteAxis::Z, | |
| 81 info: AbsoluteInfo { | |
| 82 value: 0, | |
| 83 minimum: -900, | |
| 84 maximum: 899, | |
| 85 fuzz: 0, | |
| 86 flat: 0, | |
| 87 resolution: 287, | |
| 88 }, | |
| 89 }; | |
| 90 let wheel = AbsoluteInfoSetup { | |
| 91 axis: AbsoluteAxis::Wheel, | |
| 92 info: AbsoluteInfo { | |
| 93 value: 0, | |
| 94 minimum: 0, | |
| 95 maximum: 2047, | |
| 96 fuzz: 0, | |
| 97 flat: 0, | |
| 98 resolution: 0, | |
| 99 }, | |
| 100 }; | |
| 101 let pressure = AbsoluteInfoSetup { | |
| 102 axis: AbsoluteAxis::Pressure, | |
| 103 info: AbsoluteInfo { | |
| 104 value: 0, | |
| 105 minimum: 0, | |
| 106 maximum: 8196, | |
| 107 fuzz: 0, | |
| 108 flat: 0, | |
| 109 resolution: 0, | |
| 110 }, | |
| 111 }; | |
| 112 let distance = AbsoluteInfoSetup { | |
| 113 axis: AbsoluteAxis::Distance, | |
| 114 info: AbsoluteInfo { | |
| 115 value: 0, | |
| 116 minimum: 0, | |
| 117 maximum: 63, | |
| 118 fuzz: 0, | |
| 119 flat: 0, | |
| 120 resolution: 0, | |
| 121 }, | |
| 122 }; | |
| 123 let tilt_x = AbsoluteInfoSetup { | |
| 124 axis: AbsoluteAxis::TiltX, | |
| 125 info: AbsoluteInfo { | |
| 126 value: 0, | |
| 127 minimum: -64, | |
| 128 maximum: 63, | |
| 129 fuzz: 0, | |
| 130 flat: 0, | |
| 131 resolution: 57, | |
| 132 }, | |
| 133 }; | |
| 134 let tilt_y = AbsoluteInfoSetup { | |
| 135 axis: AbsoluteAxis::TiltY, | |
| 136 info: AbsoluteInfo { | |
| 137 value: 0, | |
| 138 minimum: -64, | |
| 139 maximum: 63, | |
| 140 fuzz: 0, | |
| 141 flat: 0, | |
| 142 resolution: 57, | |
| 143 }, | |
| 144 }; | |
| 145 let misc = AbsoluteInfoSetup { | |
| 146 axis: AbsoluteAxis::Misc, | |
| 147 info: AbsoluteInfo { | |
| 148 value: 0, | |
| 149 minimum: 0, | |
| 150 maximum: 0, | |
| 151 fuzz: 0, | |
| 152 flat: 0, | |
| 153 resolution: 0, | |
| 154 }, | |
| 155 }; | |
| 156 | |
| 157 dev.create( | |
| 158 &id, | |
| 159 b"TabletEmu", | |
| 160 0, | |
| 161 &[x, y, z, wheel, pressure, distance, tilt_x, tilt_y, misc], | |
| 162 )?; | |
| 163 Ok(dev) | |
| 164 } | |
| 165 | |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
166 fn input_event_new(type_: EventKind, code: u16, value: i32) -> input_event { |
| 0 | 167 input_event { |
| 168 time: timeval { | |
| 169 tv_sec: 0, | |
| 170 tv_usec: 0, | |
| 171 }, | |
| 172 type_: type_ as u16, | |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
173 code, |
| 0 | 174 value, |
| 175 } | |
| 176 } | |
| 177 | |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
178 fn input_axis_new(code: AbsoluteAxis, value: i32) -> input_event { |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
179 input_event_new(EventKind::Absolute, code as u16, value) |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
180 } |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
181 |
|
2
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
182 fn input_key_new(code: Key, value: i32) -> input_event { |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
183 input_event_new(EventKind::Key, code as u16, value) |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
184 } |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
185 |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
186 fn input_misc_new(code: MiscKind, value: i32) -> input_event { |
|
2
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
187 input_event_new(EventKind::Misc, code as u16, value) |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
188 } |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
189 |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
190 fn input_synchronize_new(code: SynchronizeKind, value: i32) -> input_event { |
|
2
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
191 input_event_new(EventKind::Synchronize, code as u16, value) |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
192 } |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
193 |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
194 struct State { |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
195 dev: UInputHandle<File>, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
196 width: f64, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
197 height: f64, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
198 selected_tool: Key, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
199 pressed: bool, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
200 } |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
201 |
| 0 | 202 fn build_ui(application: >k::Application) { |
| 203 let dev = match create_uinput_device() { | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
204 Ok(dev) => dev, |
| 0 | 205 Err(err) => { |
| 206 match err.kind() { | |
| 207 ErrorKind::NotFound => { | |
| 208 eprintln!("Couldn’t find /dev/uinput: {}", err); | |
| 209 eprintln!("Maybe you forgot to `modprobe uinput`?"); | |
| 210 } | |
| 211 ErrorKind::PermissionDenied => { | |
| 212 eprintln!("Couldn’t open /dev/uinput for writing: {}", err); | |
| 213 eprintln!("Maybe you aren’t allowed to create input devices?"); | |
| 214 } | |
| 215 _ => eprintln!("Couldn’t open /dev/uinput for writing: {}", err), | |
| 216 } | |
| 217 return; | |
| 218 } | |
| 219 }; | |
| 220 println!( | |
| 221 "New device at {:?} ({:?})", | |
| 222 dev.evdev_path().unwrap(), | |
| 223 dev.sys_path().unwrap() | |
| 224 ); | |
| 225 | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
226 let state = Arc::new(Mutex::new(State { |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
227 dev, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
228 width: WIDTH as f64, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
229 height: HEIGHT as f64, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
230 selected_tool: Key::ButtonToolPen, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
231 pressed: false, |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
232 })); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
233 |
| 0 | 234 let window = gtk::ApplicationWindow::new(application); |
| 235 | |
| 236 window.set_title("tablet-emu"); | |
| 237 window.set_position(gtk::WindowPosition::Center); | |
| 238 | |
| 239 let hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0); | |
| 240 let tools_box = gtk::Box::new(gtk::Orientation::Vertical, 0); | |
| 241 | |
| 242 let tool1 = gtk::Button::with_label("Pen"); | |
| 243 let tool2 = gtk::Button::with_label("Rubber"); | |
| 244 let tool3 = gtk::Button::with_label("Brush"); | |
| 245 let tool4 = gtk::Button::with_label("Pencil"); | |
| 246 let tool5 = gtk::Button::with_label("Airbrush"); | |
| 247 | |
| 248 macro_rules! impl_tool_signal { | |
| 249 ($tool:ident) => { | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
250 let state_weak = Arc::downgrade(&state); |
| 0 | 251 $tool.connect_clicked(move |b| { |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
252 let state = state_weak.upgrade().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
253 let mut state = state.lock().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
254 state.selected_tool = match b.get_label().unwrap().as_str() { |
|
2
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
255 "Pen" => Key::ButtonToolPen, |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
256 "Rubber" => Key::ButtonToolRubber, |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
257 "Brush" => Key::ButtonToolBrush, |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
258 "Pencil" => Key::ButtonToolPencil, |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
259 "Airbrush" => Key::ButtonToolAirbrush, |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
260 _ => unreachable!(), |
|
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
261 }; |
| 0 | 262 }); |
| 263 }; | |
| 264 }; | |
| 265 impl_tool_signal!(tool1); | |
| 266 impl_tool_signal!(tool2); | |
| 267 impl_tool_signal!(tool3); | |
| 268 impl_tool_signal!(tool4); | |
| 269 impl_tool_signal!(tool5); | |
| 270 | |
| 271 tools_box.add(&tool1); | |
| 272 tools_box.add(&tool2); | |
| 273 tools_box.add(&tool3); | |
| 274 tools_box.add(&tool4); | |
| 275 tools_box.add(&tool5); | |
| 276 | |
| 277 let drawing_area = gtk::DrawingArea::new(); | |
| 278 drawing_area.set_size_request(WIDTH, HEIGHT); | |
| 279 drawing_area.set_hexpand(true); | |
| 280 drawing_area.set_events( | |
| 281 gdk::EventMask::BUTTON_PRESS_MASK | |
| 282 | gdk::EventMask::BUTTON_RELEASE_MASK | |
| 283 | gdk::EventMask::POINTER_MOTION_MASK, | |
| 284 ); | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
285 let state_weak = Arc::downgrade(&state); |
| 0 | 286 drawing_area.connect_configure_event(move |_, event| { |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
287 let state = state_weak.upgrade().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
288 let mut state = state.lock().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
289 match event.get_size() { |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
290 (width, height) => { |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
291 state.width = width as f64; |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
292 state.height = height as f64; |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
293 } |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
294 } |
| 0 | 295 true |
| 296 }); | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
297 let state_weak = Arc::downgrade(&state); |
| 0 | 298 drawing_area.connect_button_press_event(move |_, event| { |
| 299 if event.get_button() != 1 { | |
| 300 return Inhibit(false); | |
| 301 } | |
| 302 | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
303 let state = state_weak.upgrade().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
304 let mut state = state.lock().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
305 state.pressed = true; |
| 0 | 306 let (x, y) = event.get_position(); |
|
2
39f87ef69b2a
Add support for selecting tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
307 //println!("press tool {} at {}, {}", current_tool.lock().unwrap(), x, y); |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
308 state.dev.write(&[ |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
309 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
310 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
311 input_axis_new(AbsoluteAxis::Z, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
312 input_axis_new(AbsoluteAxis::Wheel, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
313 input_axis_new(AbsoluteAxis::Pressure, 1024), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
314 input_axis_new(AbsoluteAxis::Distance, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
315 input_axis_new(AbsoluteAxis::TiltX, 16), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
316 input_axis_new(AbsoluteAxis::TiltY, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
317 input_misc_new(MiscKind::Serial, 0), |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
318 input_key_new(state.selected_tool, 1), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
319 input_synchronize_new(SynchronizeKind::Report, 0), |
| 0 | 320 ]) |
| 321 .unwrap(); | |
| 322 Inhibit(false) | |
| 323 }); | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
324 let state_weak = Arc::downgrade(&state); |
| 0 | 325 drawing_area.connect_button_release_event(move |_, event| { |
| 326 if event.get_button() != 1 { | |
| 327 return Inhibit(false); | |
| 328 } | |
| 329 | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
330 let state = state_weak.upgrade().unwrap(); |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
331 let mut state = state.lock().unwrap(); |
| 0 | 332 let (x, y) = event.get_position(); |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
333 state.pressed = false; |
| 0 | 334 //println!("release {}, {}", x, y); |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
335 state.dev.write(&[ |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
336 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
337 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
338 input_axis_new(AbsoluteAxis::Z, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
339 input_axis_new(AbsoluteAxis::Wheel, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
340 input_axis_new(AbsoluteAxis::Pressure, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
341 input_axis_new(AbsoluteAxis::Distance, 16), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
342 input_axis_new(AbsoluteAxis::TiltX, 16), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
343 input_axis_new(AbsoluteAxis::TiltY, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
344 input_misc_new(MiscKind::Serial, 0), |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
345 input_key_new(state.selected_tool, 1), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
346 input_synchronize_new(SynchronizeKind::Report, 0), |
| 0 | 347 ]) |
| 348 .unwrap(); | |
| 349 Inhibit(false) | |
| 350 }); | |
| 351 drawing_area.connect_motion_notify_event(move |_, event| { | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
352 let state = state.lock().unwrap(); |
| 0 | 353 let (x, y) = event.get_position(); |
| 354 //println!("motion {}, {}", x, y); | |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
355 state.dev.write(&[ |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
356 input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / state.width) as i32), |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
357 input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / state.height) as i32), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
358 input_axis_new(AbsoluteAxis::Z, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
359 input_axis_new(AbsoluteAxis::Wheel, 0), |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
360 input_axis_new(AbsoluteAxis::Pressure, if state.pressed { 2048 } else { 0 }), |
|
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
361 input_axis_new(AbsoluteAxis::Distance, if state.pressed { 0 } else { 32 }), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
362 input_axis_new(AbsoluteAxis::TiltX, 16), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
363 input_axis_new(AbsoluteAxis::TiltY, 0), |
|
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
364 input_misc_new(MiscKind::Serial, 0), |
|
3
72e63d6a3f8a
Simplify state handling into a single struct.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
365 input_key_new(state.selected_tool, 1), |
|
1
6dbe2bbeef70
Improve input event types with helper functions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
366 input_synchronize_new(SynchronizeKind::Report, 0), |
| 0 | 367 ]) |
| 368 .unwrap(); | |
| 369 Inhibit(false) | |
| 370 }); | |
| 371 drawing_area.connect_draw(move |_, ctx| { | |
| 372 //println!("drawing {}", drawing_area); | |
| 373 ctx.set_source_rgb(1., 0., 0.); | |
| 374 ctx.set_operator(cairo::Operator::Screen); | |
| 375 ctx.paint(); | |
| 376 Inhibit(false) | |
| 377 }); | |
| 378 | |
| 379 hbox.add(&tools_box); | |
| 380 hbox.add(&drawing_area); | |
| 381 | |
| 382 window.add(&hbox); | |
| 383 | |
| 384 window.show_all(); | |
| 385 } | |
| 386 | |
| 387 fn main() { | |
| 388 let application = gtk::Application::new( | |
| 389 Some("fr.linkmauve.TabletEmu"), | |
| 390 gio::ApplicationFlags::empty(), | |
| 391 ) | |
| 392 .expect("Initialisation failed…"); | |
| 393 application.connect_activate(build_ui); | |
| 394 application.run(&args().collect::<Vec<_>>()); | |
| 395 } |
