diff --git a/examples/mouse.rs b/examples/mouse.rs
new file mode 100644
index 0000000000000000000000000000000000000000..9d8a5987622141c0e643a828f9ccde6dd62b35ae
--- /dev/null
+++ b/examples/mouse.rs
@@ -0,0 +1,41 @@
+extern crate termion;
+
+fn main() {
+    use termion::{TermRead, TermWrite, IntoRawMode, Key, Event, MouseEvent};
+    use std::io::{Write, stdout, stdin};
+
+    let stdin = stdin();
+    let mut stdout = stdout().into_raw_mode().unwrap().with_mouse().unwrap();
+
+    stdout.clear().unwrap();
+    stdout.goto(0, 0).unwrap();
+    stdout.write(b"q to exit. Type stuff, use alt, click around...").unwrap();
+    stdout.flush().unwrap();
+
+    let mut x = 0;
+    let mut y = 0;
+
+    for c in stdin.events() {
+        stdout.goto(5, 5).unwrap();
+        stdout.clear_line().unwrap();
+        let evt = c.unwrap();
+        match evt {
+            Event::Key(Key::Char('q')) => break,
+            Event::Mouse(me) => {
+                match me {
+                    MouseEvent::Press(_, a, b) |
+                    MouseEvent::Release(a, b) => {
+                        x = a;
+                        y = b;
+                    }
+                }
+            }
+            _ => {}
+        }
+        println!("{:?}", evt);
+        stdout.goto(x, y).unwrap();
+        stdout.flush().unwrap();
+    }
+
+    stdout.show_cursor().unwrap();
+}
diff --git a/examples/test.rs b/examples/test.rs
deleted file mode 100644
index 48ba1f5ccdd594991ed6345f1850617da157f1da..0000000000000000000000000000000000000000
--- a/examples/test.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-extern crate termion;
-
-fn main() {
-    use termion::{TermRead, TermWrite, IntoRawMode, Key, Event};
-    use std::io::{Write, stdout, stdin};
-
-    let stdin = stdin();
-    let mut stdout = stdout().into_raw_mode().unwrap();
-
-    stdout.clear().unwrap();
-    stdout.goto(0, 0).unwrap();
-    stdout.write(b"q to exit. Type stuff, use alt, click around...").unwrap();
-    stdout.flush().unwrap();
-
-    let mut x = 0;
-    let mut y = 0;
-
-    for c in stdin.events() {
-        stdout.goto(5, 5).unwrap();
-        stdout.clear_line().unwrap();
-        match c.unwrap() {
-            Event::KeyEvent(Key::Char('q')) => break,
-            Event::MouseEvent(val, a, b) => {
-                x = a;
-                y = b;
-                println!("{:?}", Event::MouseEvent(val, a, b));
-            },
-            val => println!("{:?}", val),
-        }
-        stdout.goto(x, y).unwrap();
-        stdout.flush().unwrap();
-    }
-
-    stdout.show_cursor().unwrap();
-}
diff --git a/src/event.rs b/src/event.rs
index cd98b3cdcc685d199028c28ed7a2969d49bc292c..852196e4af8c67816c2bc9f4e852089c4d71dbe9 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -6,20 +6,20 @@ use std::str;
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum Event {
     /// A key press.
-    KeyEvent(Key),
+    Key(Key),
     /// A mouse button press, release or wheel use at specific coordinates.
-    MouseEvent(Mouse, u16, u16),
+    Mouse(MouseEvent),
     /// An event that cannot currently be evaluated.
     Unsupported,
 }
 
 /// A mouse related event.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum Mouse {
+pub enum MouseEvent {
     /// A mouse button was pressed.
-    Press(MouseButton),
+    Press(MouseButton, u16, u16),
     /// A mouse button was released.
-    Release,
+    Release(u16, u16),
 }
 
 /// A mouse button.
@@ -86,6 +86,7 @@ pub enum Key {
     __IsNotComplete
 }
 
+/// Parse an Event from `item` and possibly subsequent bytes through `iter`.
 pub fn parse_event<I>(item: Result<u8, Error>, iter: &mut I) -> Result<Event, Error>
 where I: Iterator<Item = Result<u8, Error>>
 {
@@ -95,51 +96,47 @@ where I: Iterator<Item = Result<u8, Error>>
             Ok(match iter.next() {
                 Some(Ok(b'O')) => {
                     match iter.next() {
-                        Some(Ok(b'P')) => Event::KeyEvent(Key::F(1)),
-                        Some(Ok(b'Q')) => Event::KeyEvent(Key::F(2)),
-                        Some(Ok(b'R')) => Event::KeyEvent(Key::F(3)),
-                        Some(Ok(b'S')) => Event::KeyEvent(Key::F(4)),
+                        Some(Ok(val @ b'P' ... b'S')) => Event::Key(Key::F(1 + val - b'P')),
                         _ => return error,
                     }
                 }
                 Some(Ok(b'[')) => {
                     match iter.next() {
-                        Some(Ok(b'D')) => Event::KeyEvent(Key::Left),
-                        Some(Ok(b'C')) => Event::KeyEvent(Key::Right),
-                        Some(Ok(b'A')) => Event::KeyEvent(Key::Up),
-                        Some(Ok(b'B')) => Event::KeyEvent(Key::Down),
-                        Some(Ok(b'H')) => Event::KeyEvent(Key::Home),
-                        Some(Ok(b'F')) => Event::KeyEvent(Key::End),
+                        Some(Ok(b'D')) => Event::Key(Key::Left),
+                        Some(Ok(b'C')) => Event::Key(Key::Right),
+                        Some(Ok(b'A')) => Event::Key(Key::Up),
+                        Some(Ok(b'B')) => Event::Key(Key::Down),
+                        Some(Ok(b'H')) => Event::Key(Key::Home),
+                        Some(Ok(b'F')) => Event::Key(Key::End),
                         Some(Ok(b'M')) => {
-                            // X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only)
+                            // X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only).
                             let cb = iter.next().unwrap().unwrap() as i8 - 32;
-                            // (1, 1) are the coords for upper left
-                            let cx = (iter.next().unwrap().unwrap() as u8 - 1).saturating_sub(32);
-                            let cy = (iter.next().unwrap().unwrap() as u8 - 1).saturating_sub(32);
-                            Event::MouseEvent(match cb & 0b11 {
+                            // (1, 1) are the coords for upper left.
+                            let cx = (iter.next().unwrap().unwrap() as u8 - 1).saturating_sub(32) as u16;
+                            let cy = (iter.next().unwrap().unwrap() as u8 - 1).saturating_sub(32) as u16;
+                            Event::Mouse(match cb & 0b11 {
                                 0 => {
-                                    if cb & 64 != 0 {
-                                        Mouse::Press(MouseButton::WheelUp)
+                                    if cb & 0x40 != 0 {
+                                        MouseEvent::Press(MouseButton::WheelUp, cx, cy)
                                     } else {
-                                        Mouse::Press(MouseButton::Left)
+                                        MouseEvent::Press(MouseButton::Left, cx, cy)
                                     }
                                 }
                                 1 => {
-                                    if cb & 64 != 0 {
-                                        Mouse::Press(MouseButton::WheelDown)
+                                    if cb & 0x40 != 0 {
+                                        MouseEvent::Press(MouseButton::WheelDown, cx, cy)
                                     } else {
-                                        Mouse::Press(MouseButton::Middle)
+                                        MouseEvent::Press(MouseButton::Middle, cx, cy)
                                     }
                                 }
-                                2 => Mouse::Press(MouseButton::Right),
-                                3 => Mouse::Release,
+                                2 => MouseEvent::Press(MouseButton::Right, cx, cy),
+                                3 => MouseEvent::Release(cx, cy),
                                 _ => return error,
-                            },
-                            cx as u16,
-                            cy as u16)
+                            })
                         }
                         Some(Ok(b'<')) => {
-                            // xterm mouse encoding: ESC [ < Cb ; Cx ; Cy ; (M or m)
+                            // xterm mouse encoding:
+                            // ESC [ < Cb ; Cx ; Cy ; (M or m)
                             let mut buf = Vec::new();
                             let mut c = iter.next().unwrap().unwrap();
                                 while match c {
@@ -164,17 +161,15 @@ where I: Iterator<Item = Result<u8, Error>>
                                 65 => MouseButton::WheelDown,
                                 _ => return error,
                             };
-                            Event::MouseEvent(match c {
-                                b'M' => Mouse::Press(button),
-                                b'm' => Mouse::Release,
+                            Event::Mouse(match c {
+                                b'M' => MouseEvent::Press(button, cx, cy),
+                                b'm' => MouseEvent::Release(cx, cy),
                                 _ => return error,
 
-                            },
-                            cx,
-                            cy)
+                            })
                         }
                         Some(Ok(c @ b'0'...b'9')) => {
-                            // numbered escape code
+                            // Numbered escape code.
                             let mut buf = Vec::new();
                             buf.push(c);
                             let mut c = iter.next().unwrap().unwrap();
@@ -187,7 +182,8 @@ where I: Iterator<Item = Result<u8, Error>>
                             }
 
                             match c {
-                                // rxvt mouse encoding: ESC [ Cb ; Cx ; Cy ; M
+                                // rxvt mouse encoding:
+                                // ESC [ Cb ; Cx ; Cy ; M
                                 b'M' => {
                                     let str_buf = String::from_utf8(buf).unwrap();
                                     let ref mut nums = str_buf.split(';');
@@ -197,30 +193,30 @@ where I: Iterator<Item = Result<u8, Error>>
                                     let cy = nums.next().unwrap().parse::<u16>().unwrap() - 1;
 
                                     let event = match cb {
-                                        32 => Mouse::Press(MouseButton::Left),
-                                        33 => Mouse::Press(MouseButton::Middle),
-                                        34 => Mouse::Press(MouseButton::Right),
-                                        35 => Mouse::Release,
-                                        96 => Mouse::Press(MouseButton::WheelUp),
-                                        97 => Mouse::Press(MouseButton::WheelUp),
+                                        32 => MouseEvent::Press(MouseButton::Left, cx, cy),
+                                        33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
+                                        34 => MouseEvent::Press(MouseButton::Right, cx, cy),
+                                        35 => MouseEvent::Release(cx, cy),
+                                        96 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
+                                        97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
                                         _ => return error,
                                     };
 
-                                    Event::MouseEvent(event, cx, cy)
+                                    Event::Mouse(event)
                                 },
-                                // special key code
+                                // Special key code.
                                 b'~' => {
                                     let num: u8 = String::from_utf8(buf).unwrap().parse().unwrap();
                                     match num {
-                                        1 | 7 => Event::KeyEvent(Key::Home),
-                                        2 => Event::KeyEvent(Key::Insert),
-                                        3 => Event::KeyEvent(Key::Delete),
-                                        4 | 8 => Event::KeyEvent(Key::End),
-                                        5 => Event::KeyEvent(Key::PageUp),
-                                        6 => Event::KeyEvent(Key::PageDown),
-                                        v @ 11...15 => Event::KeyEvent(Key::F(v - 10)),
-                                        v @ 17...21 => Event::KeyEvent(Key::F(v - 11)),
-                                        v @ 23...24 => Event::KeyEvent(Key::F(v - 12)),
+                                        1 | 7 => Event::Key(Key::Home),
+                                        2 => Event::Key(Key::Insert),
+                                        3 => Event::Key(Key::Delete),
+                                        4 | 8 => Event::Key(Key::End),
+                                        5 => Event::Key(Key::PageUp),
+                                        6 => Event::Key(Key::PageDown),
+                                        v @ 11...15 => Event::Key(Key::F(v - 10)),
+                                        v @ 17...21 => Event::Key(Key::F(v - 11)),
+                                        v @ 23...24 => Event::Key(Key::F(v - 12)),
                                         _ => return error,
                                     }
                                 }
@@ -232,29 +228,30 @@ where I: Iterator<Item = Result<u8, Error>>
                 }
                 Some(Ok(c)) => {
                     let ch = parse_utf8_char(c, iter);
-                    Event::KeyEvent(Key::Alt(try!(ch)))
+                    Event::Key(Key::Alt(try!(ch)))
                 }
                 Some(Err(_)) | None => return error,
             })
         }
-        Ok(b'\n') | Ok(b'\r') => Ok(Event::KeyEvent(Key::Char('\n'))),
-        Ok(b'\t') => Ok(Event::KeyEvent(Key::Char('\t'))),
-        Ok(b'\x7F') => Ok(Event::KeyEvent(Key::Backspace)),
-        Ok(c @ b'\x01'...b'\x1A') => Ok(Event::KeyEvent(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
+        Ok(b'\n') | Ok(b'\r') => Ok(Event::Key(Key::Char('\n'))),
+        Ok(b'\t') => Ok(Event::Key(Key::Char('\t'))),
+        Ok(b'\x7F') => Ok(Event::Key(Key::Backspace)),
+        Ok(c @ b'\x01'...b'\x1A') => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
         Ok(c @ b'\x1C'...b'\x1F') => {
-            Ok(Event::KeyEvent(Key::Ctrl((c as u8 - 0x1C + b'4') as char)))
+            Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char)))
         }
-        Ok(b'\0') => Ok(Event::KeyEvent(Key::Null)),
+        Ok(b'\0') => Ok(Event::Key(Key::Null)),
         Ok(c) => {
             Ok({
                 let ch = parse_utf8_char(c, iter);
-                Event::KeyEvent(Key::Char(try!(ch)))
+                Event::Key(Key::Char(try!(ch)))
             })
         }
         Err(e) => Err(e),
     }
 }
 
+/// Parse `c` as either a single byte ASCII char or a variable size UTF-8 char.
 fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
 where I: Iterator<Item = Result<u8, Error>>
 {
diff --git a/src/input.rs b/src/input.rs
index 32c51ed207be336e40af238851395ba137f660c3..060226f80a4076e0600bff3682cad8d8242f3c36 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -15,7 +15,7 @@ impl<I: Iterator<Item = Result<u8, io::Error>>> Iterator for Keys<I> {
     fn next(&mut self) -> Option<Result<Key, io::Error>> {
         loop {
             match self.iter.next() {
-                Some(Ok(Event::KeyEvent(k))) => return Some(Ok(k)),
+                Some(Ok(Event::Key(k))) => return Some(Ok(k)),
                 Some(Ok(_)) => continue,
                 e @ Some(Err(_)) => e,
                 None => return None,
diff --git a/src/lib.rs b/src/lib.rs
index c1d84b3309ac156c09af1a2326f5e797624b9607..165cd158e1afbe9925f162ca172cb4aee676faec 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,10 +27,10 @@ mod input;
 pub use input::{TermRead, Events, Keys};
 
 mod event;
-pub use event::{Key, Mouse, MouseButton, Event};
+pub use event::{Key, MouseEvent, MouseButton, Event};
 
 mod raw;
-pub use raw::{IntoRawMode, RawTerminal};
+pub use raw::{IntoRawMode, RawTerminal, MouseTerminal};
 
 mod size;
 pub use size::terminal_size;
diff --git a/src/raw.rs b/src/raw.rs
index c861006809857aa5495a8dd3746153b00c449cac..ec836a1296ebe36822549a0f79c9d77acc3627b7 100644
--- a/src/raw.rs
+++ b/src/raw.rs
@@ -1,9 +1,6 @@
 use std::io::{self, Write};
 use std::ops::{Deref, DerefMut};
 
-const ENTER_MOUSE_SEQUENCE: &'static[u8] = b"\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h";
-const EXIT_MOUSE_SEQUENCE: &'static[u8] = b"\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l";
-
 /// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
 /// dropped.
 #[cfg(target_os = "redox")]
@@ -15,7 +12,6 @@ pub struct RawTerminal<W: Write> {
 impl<W: Write> Drop for RawTerminal<W> {
     fn drop(&mut self) {
         use control::TermWrite;
-        try!(self.write(EXIT_MOUSE_SEQUENCE));
         self.csi(b"R").unwrap();
     }
 }
@@ -30,11 +26,21 @@ pub struct RawTerminal<W: Write> {
     output: W,
 }
 
+#[cfg(not(target_os = "redox"))]
+impl<W> RawTerminal<W>
+where W: Write
+{
+    /// Enable mouse support.
+    pub fn with_mouse(mut self) -> io::Result<MouseTerminal<W>> {
+        try!(self.write(ENTER_MOUSE_SEQUENCE));
+        Ok(MouseTerminal { term: self })
+    }
+}
+
 #[cfg(not(target_os = "redox"))]
 impl<W: Write> Drop for RawTerminal<W> {
     fn drop(&mut self) {
         use termios::set_terminal_attr;
-        self.write(EXIT_MOUSE_SEQUENCE).unwrap();
         set_terminal_attr(&mut self.prev_ios as *mut _);
     }
 }
@@ -91,11 +97,10 @@ impl<W: Write> IntoRawMode for W {
         if set_terminal_attr(&mut ios as *mut _) != 0 {
             Err(io::Error::new(io::ErrorKind::Other, "Unable to set Termios attribute."))
         } else {
-            let mut res = RawTerminal {
+            let res = RawTerminal {
                 prev_ios: prev_ios,
                 output: self,
             };
-            try!(res.write(ENTER_MOUSE_SEQUENCE));
             Ok(res)
         }
     }
@@ -106,14 +111,63 @@ impl<W: Write> IntoRawMode for W {
 
         self.csi(b"r").map(|_| {
             let mut res = RawTerminal {
-            output: self,
+                output: self,
             };
-            try!(res.write(ENTER_MOUSE_SEQUENCE));
             res
         })
     }
 }
 
+/// A sequence of escape codes to enable terminal mouse support.
+const ENTER_MOUSE_SEQUENCE: &'static[u8] = b"\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h";
+
+/// A sequence of escape codes to disable terminal mouse support.
+const EXIT_MOUSE_SEQUENCE: &'static[u8] = b"\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l";
+
+/// A `RawTerminal` with added mouse support.
+///
+/// To get such a terminal handle use `RawTerminal`'s
+/// [`with_mouse()`](../termion/struct.RawTerminal.html#method.with_mouse) method.
+#[cfg(not(target_os = "redox"))]
+pub struct MouseTerminal<W: Write> {
+    term: RawTerminal<W>,
+}
+
+#[cfg(not(target_os = "redox"))]
+impl<W: Write> Drop for MouseTerminal<W> {
+    fn drop(&mut self) {
+        self.term.write(EXIT_MOUSE_SEQUENCE).unwrap();
+    }
+}
+
+#[cfg(not(target_os = "redox"))]
+impl<W: Write> Deref for MouseTerminal<W> {
+    type Target = W;
+
+    fn deref(&self) -> &W {
+        self.term.deref()
+    }
+}
+
+#[cfg(not(target_os = "redox"))]
+impl<W: Write> DerefMut for MouseTerminal<W> {
+    fn deref_mut(&mut self) -> &mut W {
+        self.term.deref_mut()
+    }
+}
+
+#[cfg(not(target_os = "redox"))]
+impl<W: Write> Write for MouseTerminal<W> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.term.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.term.flush()
+    }
+}
+
+
 #[cfg(test)]
 mod test {
     use super::*;