Compare commits
4 Commits
41211e3f93
...
21080d2cbb
Author | SHA1 | Date |
---|---|---|
Alex Kotov | 21080d2cbb | |
Alex Kotov | 1a356b10c5 | |
Alex Kotov | 392c60dc9b | |
Alex Kotov | b88b936ccf |
6
Makefile
6
Makefile
|
@ -24,7 +24,8 @@ RUST_APIS = \
|
||||||
src/constraints.h \
|
src/constraints.h \
|
||||||
src/geom.h \
|
src/geom.h \
|
||||||
src/helpers.h \
|
src/helpers.h \
|
||||||
src/settings.h
|
src/settings.h \
|
||||||
|
src/xbase.h
|
||||||
|
|
||||||
MODULES_SRC = \
|
MODULES_SRC = \
|
||||||
src/drw.c \
|
src/drw.c \
|
||||||
|
@ -35,8 +36,7 @@ MODULES_SRC = \
|
||||||
src/spawn.c \
|
src/spawn.c \
|
||||||
src/state.c \
|
src/state.c \
|
||||||
src/unit.c \
|
src/unit.c \
|
||||||
src/util.c \
|
src/util.c
|
||||||
src/xbase.c
|
|
||||||
|
|
||||||
DWM_SRC = \
|
DWM_SRC = \
|
||||||
src/dwm/bar.c \
|
src/dwm/bar.c \
|
||||||
|
|
|
@ -2,3 +2,4 @@ mod atoms;
|
||||||
mod constraints;
|
mod constraints;
|
||||||
mod geom;
|
mod geom;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
mod xbase;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
mod api;
|
mod api;
|
||||||
mod atoms;
|
mod atoms;
|
||||||
mod constraints;
|
mod constraints;
|
||||||
|
mod xbase;
|
||||||
|
|
||||||
pub mod geom;
|
pub mod geom;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
@ -8,3 +9,4 @@ pub mod unit;
|
||||||
|
|
||||||
pub use atoms::Atoms;
|
pub use atoms::Atoms;
|
||||||
pub use settings::Settings;
|
pub use settings::Settings;
|
||||||
|
pub use xbase::Xbase;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
72
src/xbase.c
72
src/xbase.c
|
@ -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");
|
|
||||||
}
|
|
Loading…
Reference in New Issue