diff --git a/Cargo.toml b/Cargo.toml
index 4f0f1190984dcf7c3b163e56bf0b9fe136b1ce93..aa8505ad1dd7f9efbfa381dcc8eae80bcd9d7d71 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,7 +5,3 @@ authors = ["Ticki <Ticki@users.noreply.github.com>"]
 
 [target.'cfg(not(target_os = "redox"))'.dependencies]
 libc = "0.2.8"
-
-[features]
-default = ["nightly"]
-nightly = []
diff --git a/README.md b/README.md
index 69560de7d307fb8826f9eae300d0e27af646dae4..cd8896d181a3082fbe060dd97a81253c54d4e02f 100644
--- a/README.md
+++ b/README.md
@@ -19,21 +19,11 @@ and this crate can generally be considered stable.
 
 ## Cargo.toml
 
-For nightly, add
-
 ```toml
 [dependencies.termion]
 git = "https://github.com/ticki/termion.git"
 ```
 
-For stable,
-
-```toml
-[dependencies.termion]
-git = "https://github.com/ticki/termion.git"
-default-features = false
-```
-
 ## Features
 
 - Raw mode.
@@ -51,6 +41,7 @@ default-features = false
 - Special keys events (modifiers, special keys, etc.).
 - Allocation-free.
 - Asynchronous key events.
+- Mouse input
 - Carefully tested.
 
 and much more.
@@ -92,10 +83,6 @@ For a more complete example, see [a minesweeper implementation](https://github.c
 <img src="image.png" width="200">
 
 
-## TODO
-
-- Mouse input
-
 ## License
 
 MIT/X11.
diff --git a/examples/keys.rs b/examples/keys.rs
index 55d2f831d6680a8c6c042c773588240ae7629768..4427d7f681824a13b63c4b8d7c5e5fc0f1650dfc 100644
--- a/examples/keys.rs
+++ b/examples/keys.rs
@@ -1,6 +1,5 @@
 extern crate termion;
 
-#[cfg(feature = "nightly")]
 fn main() {
     use termion::{TermRead, TermWrite, IntoRawMode, Key};
     use std::io::{Write, stdout, stdin};
@@ -27,7 +26,6 @@ fn main() {
             Key::Up => println!("↑"),
             Key::Down => println!("↓"),
             Key::Backspace => println!("×"),
-            Key::Invalid => println!("???"),
             _ => {},
         }
         stdout.flush().unwrap();
@@ -35,8 +33,3 @@ fn main() {
 
     stdout.show_cursor().unwrap();
 }
-
-#[cfg(not(feature = "nightly"))]
-fn main() {
-    println!("To run this example, you need to enable the `nightly` feature. Use Rust nightly and compile with `--features nightly`.")
-}
diff --git a/examples/test.rs b/examples/test.rs
new file mode 100644
index 0000000000000000000000000000000000000000..48ba1f5ccdd594991ed6345f1850617da157f1da
--- /dev/null
+++ b/examples/test.rs
@@ -0,0 +1,35 @@
+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
new file mode 100644
index 0000000000000000000000000000000000000000..cd98b3cdcc685d199028c28ed7a2969d49bc292c
--- /dev/null
+++ b/src/event.rs
@@ -0,0 +1,277 @@
+use std::io::{Error, ErrorKind};
+use std::ascii::AsciiExt;
+use std::str;
+
+/// An event reported by the terminal.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum Event {
+    /// A key press.
+    KeyEvent(Key),
+    /// A mouse button press, release or wheel use at specific coordinates.
+    MouseEvent(Mouse, u16, u16),
+    /// An event that cannot currently be evaluated.
+    Unsupported,
+}
+
+/// A mouse related event.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum Mouse {
+    /// A mouse button was pressed.
+    Press(MouseButton),
+    /// A mouse button was released.
+    Release,
+}
+
+/// A mouse button.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum MouseButton {
+    /// The left mouse button.
+    Left,
+    /// The right mouse button.
+    Right,
+    /// The middle mouse button.
+    Middle,
+    /// Mouse wheel is going up.
+    ///
+    /// This event is typically only used with Mouse::Press.
+    WheelUp,
+    /// Mouse wheel is going down.
+    ///
+    /// This event is typically only used with Mouse::Press.
+    WheelDown,
+}
+
+/// A key.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum Key {
+    /// Backspace.
+    Backspace,
+    /// Left arrow.
+    Left,
+    /// Right arrow.
+    Right,
+    /// Up arrow.
+    Up,
+    /// Down arrow.
+    Down,
+    /// Home key.
+    Home,
+    /// End key.
+    End,
+    /// Page Up key.
+    PageUp,
+    /// Page Down key.
+    PageDown,
+    /// Delete key.
+    Delete,
+    /// Insert key.
+    Insert,
+    /// Function keys.
+    ///
+    /// Only function keys 1 through 12 are supported.
+    F(u8),
+    /// Normal character.
+    Char(char),
+    /// Alt modified character.
+    Alt(char),
+    /// Ctrl modified character.
+    ///
+    /// Note that certain keys may not be modifiable with `ctrl`, due to limitations of terminals.
+    Ctrl(char),
+    /// Null byte.
+    Null,
+
+    #[allow(missing_docs)]
+    #[doc(hidden)]
+    __IsNotComplete
+}
+
+pub fn parse_event<I>(item: Result<u8, Error>, iter: &mut I) -> Result<Event, Error>
+where I: Iterator<Item = Result<u8, Error>>
+{
+    let error = Err(Error::new(ErrorKind::Other, "Could not parse an event"));
+    match item {
+        Ok(b'\x1B') => {
+            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)),
+                        _ => 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'M')) => {
+                            // 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 {
+                                0 => {
+                                    if cb & 64 != 0 {
+                                        Mouse::Press(MouseButton::WheelUp)
+                                    } else {
+                                        Mouse::Press(MouseButton::Left)
+                                    }
+                                }
+                                1 => {
+                                    if cb & 64 != 0 {
+                                        Mouse::Press(MouseButton::WheelDown)
+                                    } else {
+                                        Mouse::Press(MouseButton::Middle)
+                                    }
+                                }
+                                2 => Mouse::Press(MouseButton::Right),
+                                3 => Mouse::Release,
+                                _ => return error,
+                            },
+                            cx as u16,
+                            cy as u16)
+                        }
+                        Some(Ok(b'<')) => {
+                            // 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 {
+                                    b'm' | b'M' => false,
+                                    _ => true,
+                                } {
+                                    buf.push(c);
+                                    c = iter.next().unwrap().unwrap();
+                                }
+                            let str_buf = String::from_utf8(buf).unwrap();
+                            let ref mut nums = str_buf.split(';');
+
+                            let cb = nums.next().unwrap().parse::<u16>().unwrap();
+                            let cx = nums.next().unwrap().parse::<u16>().unwrap() - 1;
+                            let cy = nums.next().unwrap().parse::<u16>().unwrap() - 1;
+
+                            let button = match cb {
+                                0 => MouseButton::Left,
+                                1 => MouseButton::Middle,
+                                2 => MouseButton::Right,
+                                64 => MouseButton::WheelUp,
+                                65 => MouseButton::WheelDown,
+                                _ => return error,
+                            };
+                            Event::MouseEvent(match c {
+                                b'M' => Mouse::Press(button),
+                                b'm' => Mouse::Release,
+                                _ => return error,
+
+                            },
+                            cx,
+                            cy)
+                        }
+                        Some(Ok(c @ b'0'...b'9')) => {
+                            // numbered escape code
+                            let mut buf = Vec::new();
+                            buf.push(c);
+                            let mut c = iter.next().unwrap().unwrap();
+                            while match c {
+                                b'M' | b'~' => false,
+                                _ => true,
+                            } {
+                                buf.push(c);
+                                c = iter.next().unwrap().unwrap();
+                            }
+
+                            match c {
+                                // 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(';');
+
+                                    let cb = nums.next().unwrap().parse::<u16>().unwrap();
+                                    let cx = nums.next().unwrap().parse::<u16>().unwrap() - 1;
+                                    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),
+                                        _ => return error,
+                                    };
+
+                                    Event::MouseEvent(event, cx, cy)
+                                },
+                                // 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)),
+                                        _ => return error,
+                                    }
+                                }
+                                _ => return error,
+                            }
+                        }
+                        _ => return error,
+                    }
+                }
+                Some(Ok(c)) => {
+                    let ch = parse_utf8_char(c, iter);
+                    Event::KeyEvent(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(c @ b'\x1C'...b'\x1F') => {
+            Ok(Event::KeyEvent(Key::Ctrl((c as u8 - 0x1C + b'4') as char)))
+        }
+        Ok(b'\0') => Ok(Event::KeyEvent(Key::Null)),
+        Ok(c) => {
+            Ok({
+                let ch = parse_utf8_char(c, iter);
+                Event::KeyEvent(Key::Char(try!(ch)))
+            })
+        }
+        Err(e) => Err(e),
+    }
+}
+
+fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
+where I: Iterator<Item = Result<u8, Error>>
+{
+    let error = Err(Error::new(ErrorKind::Other, "Input character is not valid UTF-8"));
+    if c.is_ascii() {
+        Ok(c as char)
+    } else {
+        let ref mut bytes = Vec::new();
+        bytes.push(c);
+
+        loop {
+            bytes.push(iter.next().unwrap().unwrap());
+            match str::from_utf8(bytes) {
+                Ok(st) => return Ok(st.chars().next().unwrap()),
+                Err(_) => {},
+            }
+            if bytes.len() >= 4 { return error; }
+        }
+    }
+}
diff --git a/src/input.rs b/src/input.rs
index 824bb49d69570ff8003dd229c34528c314d4da07..32c51ed207be336e40af238851395ba137f660c3 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,126 +1,53 @@
 use std::io::{self, Read, Write};
+use event::{parse_event, Event, Key};
 
 use IntoRawMode;
 
-/// A key.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum Key {
-    /// Backspace.
-    Backspace,
-    /// Left arrow.
-    Left,
-    /// Right arrow.
-    Right,
-    /// Up arrow.
-    Up,
-    /// Down arrow.
-    Down,
-    /// Home key.
-    Home,
-    /// End key.
-    End,
-    /// Page Up key.
-    PageUp,
-    /// Page Down key.
-    PageDown,
-    /// Delete key.
-    Delete,
-    /// Insert key.
-    Insert,
-    /// Function keys.
-    ///
-    /// Only function keys 1 through 12 are supported.
-    F(u8),
-    /// Normal character.
-    Char(char),
-    /// Alt modified character.
-    Alt(char),
-    /// Ctrl modified character.
-    ///
-    /// Note that certain keys may not be modifiable with `ctrl`, due to limitations of terminals.
-    Ctrl(char),
-    /// Invalid character code.
-    Invalid,
-    /// Null byte.
-    Null,
 
+/// An iterator over input keys.
+pub struct Keys<I> {
+    iter: Events<I>,
+}
 
-    #[allow(missing_docs)]
-    #[doc(hidden)]
-    __IsNotComplete
+impl<I: Iterator<Item = Result<u8, io::Error>>> Iterator for Keys<I> {
+    type Item = Result<Key, io::Error>;
+
+    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(_)) => continue,
+                e @ Some(Err(_)) => e,
+                None => return None,
+            };
+        }
+    }
 }
 
-/// An iterator over input keys.
-#[cfg(feature = "nightly")]
-pub struct Keys<I> {
-    chars: I,
+/// An iterator over input events.
+pub struct Events<I> {
+    bytes: I,
 }
 
-#[cfg(feature = "nightly")]
-impl<I: Iterator<Item = Result<char, io::CharsError>>> Iterator for Keys<I> {
-    type Item = Result<Key, io::CharsError>;
-
-    fn next(&mut self) -> Option<Result<Key, io::CharsError>> {
-        Some(match self.chars.next() {
-            Some(Ok('\x1B')) => Ok(match self.chars.next() {
-                Some(Ok('O')) => match self.chars.next() {
-                    Some(Ok('P')) => Key::F(1),
-                    Some(Ok('Q')) => Key::F(2),
-                    Some(Ok('R')) => Key::F(3),
-                    Some(Ok('S')) => Key::F(4),
-                    _ => Key::Invalid,
-                },
-                Some(Ok('[')) => match self.chars.next() {
-                    Some(Ok('D')) => Key::Left,
-                    Some(Ok('C')) => Key::Right,
-                    Some(Ok('A')) => Key::Up,
-                    Some(Ok('B')) => Key::Down,
-                    Some(Ok('H')) => Key::Home,
-                    Some(Ok('F')) => Key::End,
-                    Some(Ok(c @ '1' ... '8')) => match self.chars.next() {
-                        Some(Ok('~')) => match c {
-                            '1' | '7' => Key::Home,
-                            '2'=> Key::Insert,
-                            '3' => Key::Delete,
-                            '4' | '8' => Key::End,
-                            '5' => Key::PageUp,
-                            '6' => Key::PageDown,
-                            _ => Key::Invalid,
-                        },
-                        Some(Ok(k @ '0' ... '9')) => match self.chars.next() {
-                            Some(Ok('~')) => match 10 * (c as u8 - b'0') + (k as u8 - b'0') {
-                                v @ 11 ... 15 => Key::F(v - 10),
-                                v @ 17 ... 21 => Key::F(v - 11),
-                                v @ 23 ... 24 => Key::F(v - 12),
-                                _ => Key::Invalid,
-                            },
-                            _ => Key::Invalid,
-                        },
-                        _ => Key::Invalid,
-                    },
-                    _ => Key::Invalid,
-                },
-                Some(Ok(c)) => Key::Alt(c),
-                Some(Err(_)) | None => Key::Invalid,
-            }),
-            Some(Ok('\n')) | Some(Ok('\r')) => Ok(Key::Char('\n')),
-            Some(Ok('\t')) => Ok(Key::Char('\t')),
-            Some(Ok('\x7F')) => Ok(Key::Backspace),
-            Some(Ok(c @ '\x01' ... '\x1A')) => Ok(Key::Ctrl((c as u8 - 0x1  + b'a') as char)),
-            Some(Ok(c @ '\x1C' ... '\x1F')) => Ok(Key::Ctrl((c as u8 - 0x1C + b'4') as char)),
-            Some(Ok('\0')) => Ok(Key::Null),
-            Some(Ok(c)) => Ok(Key::Char(c)),
-            Some(Err(e)) => Err(e),
-            None => return None,
-        })
+impl<I: Iterator<Item = Result<u8, io::Error>>> Iterator for Events<I> {
+    type Item = Result<Event, io::Error>;
+
+    fn next(&mut self) -> Option<Result<Event, io::Error>> {
+        let ref mut iter = self.bytes;
+        match iter.next() {
+            Some(item) => Some(parse_event(item, iter).or(Ok(Event::Unsupported))),
+            None => None,
+        }
     }
 }
 
 /// Extension to `Read` trait.
 pub trait TermRead {
+    /// An iterator over input events.
+    fn events(self) -> Events<io::Bytes<Self>> where Self: Sized;
+
     /// An iterator over key inputs.
-    #[cfg(feature = "nightly")]
-    fn keys(self) -> Keys<io::Chars<Self>> where Self: Sized;
+    fn keys(self) -> Keys<io::Bytes<Self>> where Self: Sized;
 
     /// Read a line.
     ///
@@ -140,10 +67,14 @@ pub trait TermRead {
 
 
 impl<R: Read> TermRead for R {
-    #[cfg(feature = "nightly")]
-    fn keys(self) -> Keys<io::Chars<R>> {
+    fn events(self) -> Events<io::Bytes<R>> {
+        Events {
+            bytes: self.bytes(),
+        }
+    }
+    fn keys(self) -> Keys<io::Bytes<R>> {
         Keys {
-            chars: self.chars(),
+            iter: self.events(),
         }
     }
 
@@ -170,7 +101,6 @@ mod test {
     use super::*;
     use std::io;
 
-    #[cfg(feature = "nightly")]
     #[test]
     fn test_keys() {
         let mut i = b"\x1Bayo\x7F\x1B[D".keys();
@@ -183,7 +113,6 @@ mod test {
         assert!(i.next().is_none());
     }
 
-    #[cfg(feature = "nightly")]
     #[test]
     fn test_function_keys() {
         let mut st = b"\x1BOP\x1BOQ\x1BOR\x1BOS".keys();
@@ -198,7 +127,6 @@ mod test {
         }
     }
 
-    #[cfg(feature = "nightly")]
     #[test]
     fn test_special_keys() {
         let mut st = b"\x1B[2~\x1B[H\x1B[7~\x1B[5~\x1B[3~\x1B[F\x1B[8~\x1B[6~".keys();
diff --git a/src/lib.rs b/src/lib.rs
index 8a789818131fa6fbb0ecc49afa9eb496ce905bbc..c1d84b3309ac156c09af1a2326f5e797624b9607 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,9 +11,6 @@
 //! For more information refer to the [README](https://github.com/ticki/termion).
 #![warn(missing_docs)]
 
-#![cfg_attr(feature = "nightly", feature(io))]
-
-
 #[cfg(not(target_os = "redox"))]
 extern crate libc;
 
@@ -27,9 +24,10 @@ mod async;
 pub use async::{AsyncReader, async_stdin};
 
 mod input;
-pub use input::{TermRead, Key};
-#[cfg(feature = "nightly")]
-pub use input::Keys;
+pub use input::{TermRead, Events, Keys};
+
+mod event;
+pub use event::{Key, Mouse, MouseButton, Event};
 
 mod raw;
 pub use raw::{IntoRawMode, RawTerminal};
diff --git a/src/raw.rs b/src/raw.rs
index ca5215dc6dbd45c77d0a54805f58414bdc19f081..c861006809857aa5495a8dd3746153b00c449cac 100644
--- a/src/raw.rs
+++ b/src/raw.rs
@@ -1,6 +1,9 @@
 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")]
@@ -12,6 +15,7 @@ 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,6 +34,7 @@ pub struct RawTerminal<W: Write> {
 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 _);
     }
 }
@@ -86,10 +91,12 @@ 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 {
-            Ok(RawTerminal {
+            let mut res = RawTerminal {
                 prev_ios: prev_ios,
                 output: self,
-            })
+            };
+            try!(res.write(ENTER_MOUSE_SEQUENCE));
+            Ok(res)
         }
     }
 
@@ -97,8 +104,12 @@ impl<W: Write> IntoRawMode for W {
     fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
         use control::TermWrite;
 
-        self.csi(b"r").map(|_| RawTerminal {
+        self.csi(b"r").map(|_| {
+            let mut res = RawTerminal {
             output: self,
+            };
+            try!(res.write(ENTER_MOUSE_SEQUENCE));
+            res
         })
     }
 }