1use libc::c_int;
2use std::str;
3use std::ffi::CStr;
4
5use get_error;
6
7pub mod ll {
8 #![allow(non_camel_case_types)]
9
10 use libc::{c_int, uint8_t, uint16_t, uint32_t};
11 use libc::types::os::arch::c95::c_schar;
12
13 pub type CDstatus = c_int;
14
15 pub const CD_TRAYEMPTY: CDstatus = 0;
16 pub const CD_STOPPED: CDstatus = 1;
17 pub const CD_PLAYING: CDstatus = 2;
18 pub const CD_PAUSED: CDstatus = 3;
19 pub const CD_ERROR: CDstatus = -1;
20
21 #[repr(C)]
22 #[derive(Copy, Clone)]
23 pub struct SDL_CDtrack {
24 pub id: uint8_t,
25 pub _type: uint8_t,
26 pub unused: uint16_t,
27 pub length: uint32_t,
28 pub offset: uint32_t
29 }
30
31 #[repr(C)]
32 #[derive(Copy)]
33 pub struct SDL_CD {
34 pub id: c_int,
35 pub status: CDstatus,
36 pub numtracks: c_int,
37 pub cur_track: c_int,
38 pub cur_frame: c_int,
39 pub track: [SDL_CDtrack; 100],
40 }
41
42 impl Clone for SDL_CD {
43 fn clone(&self) -> SDL_CD {
44 *self
45 }
46 }
47
48 extern "C" {
49 pub fn SDL_CDNumDrives() -> c_int;
50 pub fn SDL_CDName(drive: c_int) -> *const c_schar;
51 pub fn SDL_CDOpen(drive: c_int) -> *mut SDL_CD;
52 pub fn SDL_CDStatus(cdrom: *mut SDL_CD) -> CDstatus;
53 pub fn SDL_CDClose(cdrom: *mut SDL_CD);
54 pub fn SDL_CDStop(cdrom: *mut SDL_CD) -> c_int;
55 pub fn SDL_CDEject(cdrom: *mut SDL_CD) -> c_int;
56 pub fn SDL_CDResume(cdrom: *mut SDL_CD) -> c_int;
57 pub fn SDL_CDPlay(cdrom: *mut SDL_CD, start: c_int, length: c_int) -> c_int;
58 pub fn SDL_CDPlayTracks(cdrom: *mut SDL_CD,
59 start_track: c_int,
60 start_frame: c_int,
61 ntracks: c_int,
62 nframes: c_int) -> c_int;
63 pub fn SDL_CDPause(cdrom: *mut SDL_CD) -> c_int;
64 }
65}
66
67pub fn get_num_drives() -> isize {
68 unsafe { ll::SDL_CDNumDrives() as isize }
69}
70
71pub fn get_drive_name(index: isize) -> Result<String, String> {
72 unsafe {
73 let cstr = ll::SDL_CDName(index as c_int);
74
75 if cstr.is_null() {
76 Err(get_error())
77 } else {
78 Ok(str::from_utf8(CStr::from_ptr(cstr).to_bytes()).unwrap().to_string())
79 }
80 }
81}
82
83#[derive(PartialEq)]
84pub struct CD {
85 pub raw: *mut ll::SDL_CD
86}
87
88fn wrap_cd(raw: *mut ll::SDL_CD) -> CD {
89 CD { raw: raw }
90}
91
92#[derive(PartialEq, Eq, Copy, Clone)]
93pub enum Status {
94 TrayEmpty = ll::CD_TRAYEMPTY as isize,
95 Stopped = ll::CD_STOPPED as isize,
96 Playing = ll::CD_PLAYING as isize,
97 Paused = ll::CD_PAUSED as isize,
98 Error = ll::CD_ERROR as isize
99}
100
101impl CD {
102 pub fn open(index: isize) -> Result<CD, String> {
103 unsafe {
104 let raw = ll::SDL_CDOpen(index as c_int);
105
106 if raw.is_null() { Err(get_error()) }
107 else { Ok(wrap_cd(raw)) }
108 }
109 }
110
111 pub fn get_status(&self) -> Status {
112 unsafe {
113 match ll::SDL_CDStatus(self.raw) {
115 0 => Status::TrayEmpty,
116 1 => Status::Stopped,
117 2 => Status::Playing,
118 3 => Status::Paused,
119 -1 => Status::Error,
120 _ => Status::Error
121 }
122 }
123 }
124
125 pub fn play(&self, start: isize, len: isize) -> bool {
126 unsafe { ll::SDL_CDPlay(self.raw, start as c_int, len as c_int) == 0 }
127 }
128
129 pub fn play_tracks(&self, start_track: isize, start_frame: isize, ntracks: isize,
130 nframes: isize) -> bool {
131 unsafe {
132 ll::SDL_CDPlayTracks(self.raw, start_track as c_int, start_frame as c_int,
133 ntracks as c_int, nframes as c_int) == 0
134 }
135 }
136
137 pub fn pause(&self) -> bool {
138 unsafe { ll::SDL_CDPause(self.raw) == 0 }
139 }
140
141 pub fn resume(&self) -> bool {
142 unsafe { ll::SDL_CDResume(self.raw) == 0 }
143 }
144
145 pub fn stop(&self) -> bool {
146 unsafe { ll::SDL_CDStop(self.raw) == 0 }
147 }
148}
149
150impl Drop for CD {
151 fn drop(&mut self) {
152 unsafe { ll::SDL_CDClose(self.raw); }
153 }
154}