Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/target
Cargo.lock

# CLion stuff
.idea/
13 changes: 10 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
[package]
name = "baseview"
version = "0.1.0"
authors = ["William Light <git@wrl.lhiaudio.com>"]
authors = [
"William Light <git@wrl.lhiaudio.com>",
"Charles Saracco <crsaracco@gmail.com>"
]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
[target.'cfg(target_os="linux")'.dependencies]
xcb = { version = "0.9", features = ["thread", "xlib_xcb", "dri2"] }

# [target.'cfg(target_os="windows")'.dependencies]

# [target.'cfg(target_os="macos")'.dependencies]
10 changes: 10 additions & 0 deletions examples/x11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview",
width: 512,
height: 512,
parent: baseview::Parent::None,
};

baseview::run(window_open_options);
}
10 changes: 8 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::ffi::c_void;

mod x11;

pub enum Parent {
None,
AsIfParented,
WithParent(*mut c_void)
WithParent(*mut c_void),
}

pub struct WindowOpenOptions<'a> {
Expand All @@ -12,5 +14,9 @@ pub struct WindowOpenOptions<'a> {
pub width: usize,
pub height: usize,

pub parent: Parent
pub parent: Parent,
}

pub fn run(options: WindowOpenOptions) {
x11::run(options);
}
110 changes: 110 additions & 0 deletions src/x11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// TODO: messy for now, will refactor when I have more of an idea of the API/architecture
// TODO: actually handle events
// TODO: set window title
// TODO: close window

use crate::Parent;
use crate::WindowOpenOptions;

struct X11Window {
xcb_connection: xcb::Connection,
}

impl X11Window {
pub fn run(options: WindowOpenOptions) -> Self {
// Convert the parent to a X11 window ID if we're given one
let parent = match options.parent {
Parent::None => None,
Parent::AsIfParented => None, // ???
Parent::WithParent(p) => Some(p as u32),
};

// Connect to the X server
let (conn, screen_num) = xcb::Connection::connect_with_xlib_display().unwrap();

// Figure out screen information
let setup = conn.get_setup();
let screen = setup.roots().nth(screen_num as usize).unwrap();

// Create window, connecting to the parent if we have one
let win = conn.generate_id();
let event_mask = &[
(xcb::CW_BACK_PIXEL, screen.black_pixel()),
(
xcb::CW_EVENT_MASK,
xcb::EVENT_MASK_EXPOSURE
| xcb::EVENT_MASK_BUTTON_PRESS
| xcb::EVENT_MASK_BUTTON_RELEASE
| xcb::EVENT_MASK_BUTTON_1_MOTION,
),
];
xcb::create_window(
// Connection
&conn,
// Depth
xcb::COPY_FROM_PARENT as u8,
// Window ID
win,
// Parent ID
if let Some(p) = parent {
p
} else {
screen.root()
},
// x
0,
// y
0,
// width
1024,
// height
1024,
// border width
0,
// class
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
// visual
screen.root_visual(),
// masks
event_mask,
);

// Change window title
let title = options.title;
xcb::change_property(
&conn,
xcb::PROP_MODE_REPLACE as u8,
win,
xcb::ATOM_WM_NAME,
xcb::ATOM_STRING,
8,
title.as_bytes(),
);

// Display the window
xcb::map_window(&conn, win);
conn.flush();

let x11_window = Self {
xcb_connection: conn,
};

x11_window.handle_events();

return x11_window;
}

// Event loop
fn handle_events(&self) {
loop {
let ev = self.xcb_connection.wait_for_event();
if let Some(event) = ev {
println!("{:?}", event.response_type());
}
}
}
}

pub fn run(options: WindowOpenOptions) {
X11Window::run(options);
}