commit
f045c99cbf
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
|
# CLion stuff
|
||||||
|
.idea/
|
||||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -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
10
examples/x11.rs
Normal file
|
@ -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
src/lib.rs
10
src/lib.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
110
src/x11.rs
Normal file
110
src/x11.rs
Normal file
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in a new issue