1
0
Fork 0
forked from wry/wry

wayland: implement xdg-activation

This commit is contained in:
Julian Orth 2024-02-14 17:42:59 +01:00
parent 0628a9d393
commit 41d7531cd5
26 changed files with 667 additions and 50 deletions

View file

@ -0,0 +1,28 @@
use {
crate::utils::opaque::{opaque, Opaque, OpaqueError},
std::{
fmt::{Display, Formatter},
str::FromStr,
},
};
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub struct ActivationToken(Opaque);
pub fn activation_token() -> ActivationToken {
ActivationToken(opaque())
}
impl Display for ActivationToken {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl FromStr for ActivationToken {
type Err = OpaqueError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.parse()?))
}
}

66
src/utils/opaque.rs Normal file
View file

@ -0,0 +1,66 @@
use {
rand::{thread_rng, Rng},
std::{
fmt::{Debug, Display, Formatter},
num::ParseIntError,
str::FromStr,
},
thiserror::Error,
};
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Opaque {
lo: u64,
hi: u64,
}
pub fn opaque() -> Opaque {
let mut rng = thread_rng();
Opaque {
lo: rng.gen(),
hi: rng.gen(),
}
}
impl Display for Opaque {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:016x}", self.hi)?;
write!(f, "{:016x}", self.lo)?;
Ok(())
}
}
impl Debug for Opaque {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(self, f)
}
}
impl FromStr for Opaque {
type Err = OpaqueError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() != LEN {
return Err(OpaqueError::InvalidLength);
}
if !s.is_char_boundary(LEN / 2) {
return Err(OpaqueError::NotAscii);
}
let (hi, lo) = s.split_at(LEN / 2);
let hi = u64::from_str_radix(hi, 16).map_err(OpaqueError::Parse)?;
let lo = u64::from_str_radix(lo, 16).map_err(OpaqueError::Parse)?;
Ok(Self { lo, hi })
}
}
const LEN: usize = 32;
#[derive(Debug, Error)]
pub enum OpaqueError {
#[error("The string is not exactly 32 bytes long")]
InvalidLength,
#[error("The string is not ascii")]
NotAscii,
#[error("Could not parse the string as a hex number")]
Parse(ParseIntError),
}

View file

@ -0,0 +1,28 @@
use crate::utils::numcell::NumCell;
#[derive(Default)]
pub struct ThresholdCounter {
counter: NumCell<usize>,
}
impl ThresholdCounter {
pub fn inc(&self) -> bool {
self.counter.fetch_add(1) == 0
}
pub fn dec(&self) -> bool {
self.counter.fetch_sub(1) == 1
}
pub fn adj(&self, inc: bool) -> bool {
if inc {
self.inc()
} else {
self.dec()
}
}
pub fn active(&self) -> bool {
self.counter.get() > 0
}
}