Compare commits

...

4 Commits

Author SHA1 Message Date
Alex Kotov 21080d2cbb
Disable WM check 2022-09-09 19:24:07 +04:00
Alex Kotov 1a356b10c5
Move XBase to Rust 2022-09-09 19:20:30 +04:00
Alex Kotov 392c60dc9b
Use Rust atoms in Rust Xbase 2022-09-09 19:08:00 +04:00
Alex Kotov b88b936ccf
Revert "Remove Xbase in Rust"
This reverts commit 333b3163d3.
2022-09-09 19:06:09 +04:00
6 changed files with 113 additions and 75 deletions

View File

@ -24,7 +24,8 @@ RUST_APIS = \
src/constraints.h \
src/geom.h \
src/helpers.h \
src/settings.h
src/settings.h \
src/xbase.h
MODULES_SRC = \
src/drw.c \
@ -35,8 +36,7 @@ MODULES_SRC = \
src/spawn.c \
src/state.c \
src/unit.c \
src/util.c \
src/xbase.c
src/util.c
DWM_SRC = \
src/dwm/bar.c \

View File

@ -2,3 +2,4 @@ mod atoms;
mod constraints;
mod geom;
mod settings;
mod xbase;

View File

@ -0,0 +1,23 @@
use crate::*;
use std::alloc::{alloc, dealloc, Layout};
use std::ffi::CStr;
use std::os::raw::*;
#[no_mangle]
unsafe extern "C" fn xbase_new(
program_title: *const c_char,
x_error_handler: xbase::ErrorHandler,
) -> *mut Xbase {
let program_title = CStr::from_ptr(program_title).to_str().unwrap();
let layout = Layout::new::<Xbase>();
let ptr = alloc(layout) as *mut Xbase;
*ptr = Xbase::new(program_title.to_string(), x_error_handler).unwrap();
ptr
}
#[no_mangle]
unsafe extern "C" fn xbase_delete(xbase: *mut Xbase) {
let layout = Layout::new::<Xbase>();
dealloc(xbase as *mut u8, layout);
}

View File

@ -1,6 +1,7 @@
mod api;
mod atoms;
mod constraints;
mod xbase;
pub mod geom;
pub mod settings;
@ -8,3 +9,4 @@ pub mod unit;
pub use atoms::Atoms;
pub use settings::Settings;
pub use xbase::Xbase;

View File

@ -0,0 +1,84 @@
use crate::geom;
use crate::Atoms;
use std::os::raw::*;
use std::ptr::null;
use x11::xlib::{self, Display};
pub type ErrorHandler =
unsafe extern "C" fn(*mut Display, *mut xlib::XErrorEvent) -> c_int;
pub struct Xbase {
program_title: String,
x_display: *mut Display,
x_screen: c_int,
x_root: c_ulong,
screen_sizes: geom::Sizes,
x_error: Option<ErrorHandler>,
atoms: Atoms,
}
impl Xbase {
pub fn new(
program_title: String,
x_error_handler: ErrorHandler,
) -> Result<Self, Box<dyn std::error::Error>> {
unsafe {
if xlib::XSupportsLocale() == 0 {
return Err("no locale support in X".into());
}
let x_display = xlib::XOpenDisplay(null());
if x_display.is_null() {
return Err("cannot open X display".into());
}
let x_screen = xlib::XDefaultScreen(x_display);
let x_root = xlib::XRootWindow(x_display, x_screen);
let screen_sizes = geom::Sizes::new(
xlib::XDisplayWidth(x_display, x_screen),
xlib::XDisplayHeight(x_display, x_screen),
);
let x_error = xlib::XSetErrorHandler(Some(x_error_wm_check));
xlib::XSelectInput(
x_display,
xlib::XDefaultRootWindow(x_display),
xlib::SubstructureRedirectMask,
);
xlib::XSync(x_display, xlib::False);
xlib::XSetErrorHandler(Some(x_error_handler));
xlib::XSync(x_display, xlib::False);
let atoms = Atoms::create(x_display);
Ok(Self {
program_title,
x_display,
x_screen,
x_root,
screen_sizes,
x_error,
atoms,
})
}
}
}
impl Drop for Xbase {
fn drop(&mut self) {
unsafe { xlib::XCloseDisplay(self.x_display) };
}
}
unsafe extern "C" fn x_error_wm_check(
_display: *mut Display,
_x_error_event: *mut xlib::XErrorEvent,
) -> c_int {
// FIXME:
// panic!("another window manager is already running");
0
}

View File

@ -1,72 +0,0 @@
#include "xbase.h"
#include "logger.h"
#include <stdlib.h>
#include <string.h>
/* Startup Error handler to check if another
* window manager is already running. */
static int x_error_wm_check(Display*, XErrorEvent*);
Xbase xbase_new(
const char *const program_title,
const XErrorHandler x_error_handler
) {
if (!XSupportsLocale()) warning("no locale support in X");
Xbase xbase = malloc(sizeof(struct Xbase));
if (!xbase) fatal_perror("cannot allocate xbase");
if (!(xbase->program_title = strdup(program_title))) {
fatal_perror("no program title is given");
}
if (!(xbase->x_display = XOpenDisplay(NULL))) {
fatal("cannot open X display");
}
xbase->x_screen = DefaultScreen(xbase->x_display);
xbase->x_root = RootWindow(xbase->x_display, xbase->x_screen);
xbase->screen_sizes = sizes_create_from_args(
DisplayWidth(xbase->x_display, xbase->x_screen),
DisplayHeight(xbase->x_display, xbase->x_screen)
);
if (!(xbase->x_error = XSetErrorHandler(x_error_wm_check))) {
fatal("no X error handler is given");
}
// This causes an error if some other window manager is running
XSelectInput(
xbase->x_display,
DefaultRootWindow(xbase->x_display),
SubstructureRedirectMask
);
XSync(xbase->x_display, False);
XSetErrorHandler(x_error_handler);
XSync(xbase->x_display, False);
if (!(xbase->atoms = atoms_create(xbase->x_display))) {
fatal("cannot create atoms");
}
return xbase;
}
void xbase_delete(const Xbase xbase)
{
// TODO: maybe we should assert here
if (xbase == NULL) return;
ATOMS_DELETE(xbase->atoms);
XCloseDisplay(xbase->x_display);
free(xbase);
}
int x_error_wm_check(
__attribute__((unused)) Display *const x_display,
__attribute__((unused)) XErrorEvent *const x_error_event
) {
fatal("another window manager is already running");
}