1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#[cfg(target_os = "linux")]
use usb;

#[cfg(not(target_os = "linux"))]
use hid;

use {Result as Res, Controller};
use {VENDOR_ID, PRODUCT_ID, ENDPOINT, INDEX};

/// Controller manager.
pub struct Manager {
	#[cfg(target_os = "linux")]
	usb: usb::Context,

	#[cfg(not(target_os = "linux"))]
	hid: hid::Manager,
}

impl Manager {
	/// Create a new controller manager.
	#[cfg(target_os = "linux")]
	pub fn new() -> Res<Manager> {
		Ok(Manager {
			usb: try!(usb::Context::new()),
		})
	}

	#[cfg(not(target_os = "linux"))]
	pub fn new() -> Res<Manager> {
		Ok(Manager {
			hid: try!(hid::init()),
		})
	}

	/// Open a controller.
	#[cfg(target_os = "linux")]
	pub fn open(&mut self) -> Res<Controller> {
		let devices = try!(self.usb.devices());

		for mut device in devices.iter() {
			let descriptor = try!(device.device_descriptor());

			if descriptor.vendor_id() != VENDOR_ID {
				continue;
			}

			for (&product, (&endpoint, &index)) in PRODUCT_ID.iter().zip(ENDPOINT.iter().zip(INDEX.iter())) {
				if descriptor.product_id() != product {
					continue;
				}
				
				let handle = try!(device.open());

				return Controller::new(device, handle, product, endpoint, index);
			}
		}

		return Err(usb::Error::NoDevice.into());
	}

	#[cfg(not(target_os = "linux"))]
	pub fn open(&self) -> Res<Controller> {
		for &product in &PRODUCT_ID {
			for device in self.hid.find(Some(VENDOR_ID), Some(product)) {
				if let Ok(handle) = device.open() {
					return Controller::new(handle, product);
				}
			}
		}

		return Err(hid::Error::NotFound.into());
	}
}