mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 05:12:40 +03:00
add xgfx::Connection, store atoms inside it
This commit is contained in:
parent
ec3c8f04ba
commit
f879447d59
26
src/main.rs
26
src/main.rs
@ -36,9 +36,9 @@ mod xwin;
|
||||
use xwin::TerminalWindow;
|
||||
|
||||
fn dispatch_gui(
|
||||
conn: &xgfx::Connection,
|
||||
event: xcb::GenericEvent,
|
||||
window: &mut TerminalWindow,
|
||||
atom_delete: xcb::Atom,
|
||||
) -> Result<(), Error> {
|
||||
let r = event.response_type() & 0x7f;
|
||||
match r {
|
||||
@ -62,7 +62,7 @@ fn dispatch_gui(
|
||||
xcb::CLIENT_MESSAGE => {
|
||||
let msg: &xcb::ClientMessageEvent = unsafe { xcb::cast_event(&event) };
|
||||
println!("CLIENT_MESSAGE {:?}", msg.data().data32());
|
||||
if msg.data().data32()[0] == atom_delete {
|
||||
if msg.data().data32()[0] == conn.atom_delete() {
|
||||
// TODO: cleaner exit handling
|
||||
bail!("window close requested!");
|
||||
}
|
||||
@ -74,7 +74,7 @@ fn dispatch_gui(
|
||||
|
||||
fn run() -> Result<(), Error> {
|
||||
let poll = Poll::new()?;
|
||||
let (conn, screen_num) = xcb::Connection::connect(None)?;
|
||||
let conn = xgfx::Connection::new()?;
|
||||
|
||||
let waiter = sigchld::ChildWaiter::new()?;
|
||||
|
||||
@ -134,7 +134,6 @@ fn run() -> Result<(), Error> {
|
||||
|
||||
let mut window = TerminalWindow::new(
|
||||
&conn,
|
||||
screen_num,
|
||||
initial_pixel_width,
|
||||
initial_pixel_height,
|
||||
terminal,
|
||||
@ -142,21 +141,6 @@ fn run() -> Result<(), Error> {
|
||||
child,
|
||||
font,
|
||||
)?;
|
||||
let atom_protocols = xcb::intern_atom(&conn, false, "WM_PROTOCOLS")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
let atom_delete = xcb::intern_atom(&conn, false, "WM_DELETE_WINDOW")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
xcb::change_property(
|
||||
&conn,
|
||||
xcb::PROP_MODE_REPLACE as u8,
|
||||
window.window_id(),
|
||||
atom_protocols,
|
||||
4,
|
||||
32,
|
||||
&[atom_delete],
|
||||
);
|
||||
|
||||
window.show();
|
||||
|
||||
@ -190,12 +174,12 @@ fn run() -> Result<(), Error> {
|
||||
// will effectively hang without updating all the state.
|
||||
match conn.poll_for_event() {
|
||||
Some(event) => {
|
||||
dispatch_gui(event, &mut window, atom_delete)?;
|
||||
dispatch_gui(&conn, event, &mut window)?;
|
||||
// Since we read one event from the connection, we must
|
||||
// now eagerly consume the rest of the queued events.
|
||||
loop {
|
||||
match conn.poll_for_queued_event() {
|
||||
Some(event) => dispatch_gui(event, &mut window, atom_delete)?,
|
||||
Some(event) => dispatch_gui(&conn, event, &mut window)?,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
|
109
src/xgfx.rs
109
src/xgfx.rs
@ -1,5 +1,6 @@
|
||||
use resize;
|
||||
use std::convert::From;
|
||||
use std::ops::Deref;
|
||||
use std::result;
|
||||
use xcb;
|
||||
use xcb_util;
|
||||
@ -9,17 +10,63 @@ pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
use super::term::color::RgbColor;
|
||||
|
||||
pub struct Connection {
|
||||
conn: xcb::Connection,
|
||||
screen_num: i32,
|
||||
atom_protocols: xcb::Atom,
|
||||
atom_delete: xcb::Atom,
|
||||
}
|
||||
|
||||
impl Deref for Connection {
|
||||
type Target = xcb::Connection;
|
||||
|
||||
fn deref(&self) -> &xcb::Connection {
|
||||
&self.conn
|
||||
}
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
pub fn new() -> Result<Connection> {
|
||||
let (conn, screen_num) = xcb::Connection::connect(None)?;
|
||||
let atom_protocols = xcb::intern_atom(&conn, false, "WM_PROTOCOLS")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
let atom_delete = xcb::intern_atom(&conn, false, "WM_DELETE_WINDOW")
|
||||
.get_reply()?
|
||||
.atom();
|
||||
|
||||
Ok(Connection {
|
||||
conn,
|
||||
screen_num,
|
||||
atom_protocols,
|
||||
atom_delete,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn conn(&self) -> &xcb::Connection {
|
||||
&self.conn
|
||||
}
|
||||
|
||||
pub fn screen_num(&self) -> i32 {
|
||||
self.screen_num
|
||||
}
|
||||
|
||||
pub fn atom_delete(&self) -> xcb::Atom {
|
||||
self.atom_delete
|
||||
}
|
||||
}
|
||||
|
||||
/// The X protocol allows referencing a number of drawable
|
||||
/// objects. This trait marks those objects here in code.
|
||||
pub trait Drawable {
|
||||
fn as_drawable(&self) -> xcb::xproto::Drawable;
|
||||
fn get_conn(&self) -> &xcb::Connection;
|
||||
fn get_conn(&self) -> &Connection;
|
||||
}
|
||||
|
||||
/// A Window!
|
||||
pub struct Window<'a> {
|
||||
window_id: xcb::xproto::Window,
|
||||
conn: &'a xcb::Connection,
|
||||
conn: &'a Connection,
|
||||
}
|
||||
|
||||
impl<'a> Drawable for Window<'a> {
|
||||
@ -27,23 +74,21 @@ impl<'a> Drawable for Window<'a> {
|
||||
self.window_id
|
||||
}
|
||||
|
||||
fn get_conn(&self) -> &xcb::Connection {
|
||||
fn get_conn(&self) -> &Connection {
|
||||
self.conn
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Window<'a> {
|
||||
/// Create a new window on the specified screen with the specified dimensions
|
||||
pub fn new(conn: &xcb::Connection, screen_num: i32, width: u16, height: u16) -> Result<Window> {
|
||||
let setup = conn.get_setup();
|
||||
let screen = setup.roots().nth(screen_num as usize).ok_or(
|
||||
failure::err_msg(
|
||||
"no screen?",
|
||||
),
|
||||
pub fn new(conn: &Connection, width: u16, height: u16) -> Result<Window> {
|
||||
let setup = conn.conn().get_setup();
|
||||
let screen = setup.roots().nth(conn.screen_num() as usize).ok_or(
|
||||
failure::err_msg("no screen?"),
|
||||
)?;
|
||||
let window_id = conn.generate_id();
|
||||
let window_id = conn.conn().generate_id();
|
||||
xcb::create_window_checked(
|
||||
&conn,
|
||||
conn.conn(),
|
||||
xcb::COPY_FROM_PARENT as u8,
|
||||
window_id,
|
||||
screen.root(),
|
||||
@ -64,29 +109,41 @@ impl<'a> Window<'a> {
|
||||
),
|
||||
],
|
||||
).request_check()?;
|
||||
|
||||
xcb::change_property(
|
||||
conn,
|
||||
xcb::PROP_MODE_REPLACE as u8,
|
||||
window_id,
|
||||
conn.atom_protocols,
|
||||
4,
|
||||
32,
|
||||
&[conn.atom_delete],
|
||||
);
|
||||
|
||||
|
||||
Ok(Window { conn, window_id })
|
||||
}
|
||||
|
||||
/// Change the title for the window manager
|
||||
pub fn set_title(&self, title: &str) {
|
||||
xcb_util::icccm::set_wm_name(&self.conn, self.window_id, title);
|
||||
xcb_util::icccm::set_wm_name(self.conn.conn(), self.window_id, title);
|
||||
}
|
||||
|
||||
/// Display the window
|
||||
pub fn show(&self) {
|
||||
xcb::map_window(self.conn, self.window_id);
|
||||
xcb::map_window(self.conn.conn(), self.window_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for Window<'a> {
|
||||
fn drop(&mut self) {
|
||||
xcb::destroy_window(self.conn, self.window_id);
|
||||
xcb::destroy_window(self.conn.conn(), self.window_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pixmap<'a> {
|
||||
pixmap_id: xcb::xproto::Pixmap,
|
||||
conn: &'a xcb::Connection,
|
||||
conn: &'a Connection,
|
||||
}
|
||||
|
||||
impl<'a> Drawable for Pixmap<'a> {
|
||||
@ -94,7 +151,7 @@ impl<'a> Drawable for Pixmap<'a> {
|
||||
self.pixmap_id
|
||||
}
|
||||
|
||||
fn get_conn(&self) -> &xcb::Connection {
|
||||
fn get_conn(&self) -> &Connection {
|
||||
self.conn
|
||||
}
|
||||
}
|
||||
@ -102,9 +159,9 @@ impl<'a> Drawable for Pixmap<'a> {
|
||||
impl<'a> Pixmap<'a> {
|
||||
pub fn new(drawable: &Drawable, depth: u8, width: u16, height: u16) -> Result<Pixmap> {
|
||||
let conn = drawable.get_conn();
|
||||
let pixmap_id = conn.generate_id();
|
||||
let pixmap_id = conn.conn().generate_id();
|
||||
xcb::create_pixmap(
|
||||
&conn,
|
||||
conn.conn(),
|
||||
depth,
|
||||
pixmap_id,
|
||||
drawable.as_drawable(),
|
||||
@ -117,21 +174,21 @@ impl<'a> Pixmap<'a> {
|
||||
|
||||
impl<'a> Drop for Pixmap<'a> {
|
||||
fn drop(&mut self) {
|
||||
xcb::free_pixmap(self.conn, self.pixmap_id);
|
||||
xcb::free_pixmap(self.conn.conn(), self.pixmap_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context<'a> {
|
||||
gc_id: xcb::xproto::Gcontext,
|
||||
conn: &'a xcb::Connection,
|
||||
conn: &'a Connection,
|
||||
drawable: xcb::xproto::Drawable,
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
pub fn new(conn: &'a xcb::Connection, d: &Drawable) -> Context<'a> {
|
||||
let gc_id = conn.generate_id();
|
||||
pub fn new(conn: &'a Connection, d: &Drawable) -> Context<'a> {
|
||||
let gc_id = conn.conn().generate_id();
|
||||
let drawable = d.as_drawable();
|
||||
xcb::create_gc(&conn, gc_id, drawable, &[]);
|
||||
xcb::create_gc(conn.conn(), gc_id, drawable, &[]);
|
||||
Context {
|
||||
gc_id,
|
||||
conn,
|
||||
@ -153,7 +210,7 @@ impl<'a> Context<'a> {
|
||||
height: u16,
|
||||
) -> xcb::VoidCookie {
|
||||
xcb::copy_area(
|
||||
self.conn,
|
||||
self.conn.conn(),
|
||||
src.as_drawable(),
|
||||
dest.as_drawable(),
|
||||
self.gc_id,
|
||||
@ -177,7 +234,7 @@ impl<'a> Context<'a> {
|
||||
im.height
|
||||
);
|
||||
xcb::put_image(
|
||||
self.conn,
|
||||
self.conn.conn(),
|
||||
xcb::xproto::IMAGE_FORMAT_Z_PIXMAP as u8,
|
||||
self.drawable,
|
||||
self.gc_id,
|
||||
@ -194,7 +251,7 @@ impl<'a> Context<'a> {
|
||||
|
||||
impl<'a> Drop for Context<'a> {
|
||||
fn drop(&mut self) {
|
||||
xcb::free_gc(self.conn, self.gc_id);
|
||||
xcb::free_gc(self.conn.conn(), self.gc_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
11
src/xwin.rs
11
src/xwin.rs
@ -1,4 +1,3 @@
|
||||
|
||||
use failure::Error;
|
||||
use font::{Font, ftwrap};
|
||||
use pty::MasterPty;
|
||||
@ -7,12 +6,11 @@ use std::mem;
|
||||
use std::process::Child;
|
||||
use std::slice;
|
||||
use term;
|
||||
use xcb;
|
||||
use xgfx::{self, Drawable};
|
||||
use xgfx::{self, Connection, Drawable};
|
||||
|
||||
pub struct TerminalWindow<'a> {
|
||||
window: xgfx::Window<'a>,
|
||||
conn: &'a xcb::Connection,
|
||||
conn: &'a Connection,
|
||||
width: u16,
|
||||
height: u16,
|
||||
font: Font,
|
||||
@ -29,8 +27,7 @@ pub struct TerminalWindow<'a> {
|
||||
|
||||
impl<'a> TerminalWindow<'a> {
|
||||
pub fn new(
|
||||
conn: &xcb::Connection,
|
||||
screen_num: i32,
|
||||
conn: &Connection,
|
||||
width: u16,
|
||||
height: u16,
|
||||
terminal: term::Terminal,
|
||||
@ -40,7 +37,7 @@ impl<'a> TerminalWindow<'a> {
|
||||
) -> Result<TerminalWindow, Error> {
|
||||
let (cell_height, cell_width, descender) = font.get_metrics()?;
|
||||
|
||||
let window = xgfx::Window::new(&conn, screen_num, width, height)?;
|
||||
let window = xgfx::Window::new(&conn, width, height)?;
|
||||
window.set_title("wterm");
|
||||
let window_context = xgfx::Context::new(conn, &window);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user