| 15 | |
| 16 | impl Capturer { |
| 17 | pub fn new(display: Display) -> io::Result<Capturer> { |
| 18 | // Calculate dimensions. |
| 19 | |
| 20 | let pixel_width = 4; |
| 21 | let rect = display.rect(); |
| 22 | let size = (rect.w as usize) * (rect.h as usize) * pixel_width; |
| 23 | |
| 24 | // Create a shared memory segment. |
| 25 | |
| 26 | let shmid = unsafe { |
| 27 | libc::shmget( |
| 28 | libc::IPC_PRIVATE, |
| 29 | size, |
| 30 | // Everyone can do anything. |
| 31 | libc::IPC_CREAT | 0o777, |
| 32 | ) |
| 33 | }; |
| 34 | |
| 35 | if shmid == -1 { |
| 36 | return Err(io::Error::last_os_error()); |
| 37 | } |
| 38 | |
| 39 | // Attach the segment to a readable address. |
| 40 | |
| 41 | let buffer = unsafe { libc::shmat(shmid, ptr::null(), libc::SHM_RDONLY) } as *mut u8; |
| 42 | |
| 43 | if buffer as isize == -1 { |
| 44 | return Err(io::Error::last_os_error()); |
| 45 | } |
| 46 | |
| 47 | // Attach the segment to XCB. |
| 48 | |
| 49 | let server = display.server().raw(); |
| 50 | let xcbid = unsafe { xcb_generate_id(server) }; |
| 51 | unsafe { |
| 52 | xcb_shm_attach( |
| 53 | server, |
| 54 | xcbid, |
| 55 | shmid as u32, |
| 56 | 0, // False, i.e. not read-only. |
| 57 | ); |
| 58 | } |
| 59 | |
| 60 | let c = Capturer { |
| 61 | display, |
| 62 | shmid, |
| 63 | xcbid, |
| 64 | buffer, |
| 65 | size, |
| 66 | saved_raw_data: Vec::new(), |
| 67 | }; |
| 68 | Ok(c) |
| 69 | } |
| 70 | |
| 71 | pub fn display(&self) -> &Display { |
| 72 | &self.display |