1
0
Fork 0

barebones x11 window

This commit is contained in:
Charles Saracco 2020-05-25 15:35:33 -04:00
parent 7f299cf69b
commit 741318b7f6
5 changed files with 129 additions and 5 deletions

3
.gitignore vendored
View file

@ -1,2 +1,5 @@
/target /target
Cargo.lock Cargo.lock
# CLion stuff
.idea/

View file

@ -1,9 +1,16 @@
[package] [package]
name = "baseview" name = "baseview"
version = "0.1.0" 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" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [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
examples/x11.rs Normal file
View file

@ -0,0 +1,10 @@
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview",
width: 1024,
height: 1024,
parent: baseview::Parent::None,
};
baseview::run(window_open_options);
}

View file

@ -1,9 +1,11 @@
use std::ffi::c_void; use std::ffi::c_void;
mod x11;
pub enum Parent { pub enum Parent {
None, None,
AsIfParented, AsIfParented,
WithParent(*mut c_void) WithParent(*mut c_void),
} }
pub struct WindowOpenOptions<'a> { pub struct WindowOpenOptions<'a> {
@ -12,5 +14,9 @@ pub struct WindowOpenOptions<'a> {
pub width: usize, pub width: usize,
pub height: usize, pub height: usize,
pub parent: Parent pub parent: Parent,
}
pub fn run(options: WindowOpenOptions) {
x11::run(options);
} }

98
src/x11.rs Normal file
View file

@ -0,0 +1,98 @@
// 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,
);
// 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);
}