wayland: implement scaling
This involves many subsystems:
- config:
- allow setting the connector scale
- allow setting the cursor size
- cursors:
- load server cursors for all requested sizes and scales
- wl_surface:
- track the output the surface belongs to
- send wl_surface.enter/leave
- wl_output:
- implement wl_output.scale
- text:
- pre-render texts for all used scales
- renderer:
- properly align scale textures and rectangles
- wp_fractional_scale:
- new interface for fractional scaling
This commit is contained in:
parent
16aec8f87e
commit
e52a60b3b6
41 changed files with 1417 additions and 364 deletions
90
src/utils/refcounted.rs
Normal file
90
src/utils/refcounted.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
use {
|
||||
crate::utils::ptr_ext::{MutPtrExt, PtrExt},
|
||||
std::{cell::UnsafeCell, mem, ops::Deref},
|
||||
};
|
||||
|
||||
pub struct RefCounted<T> {
|
||||
map: UnsafeCell<Vec<(T, usize)>>,
|
||||
}
|
||||
|
||||
impl<T> Default for RefCounted<T> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
map: UnsafeCell::new(vec![]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq> RefCounted<T> {
|
||||
pub fn add(&self, t: T) -> bool {
|
||||
unsafe {
|
||||
let map = self.map.get().deref_mut();
|
||||
for (k, v) in &mut *map {
|
||||
if k == &t {
|
||||
*v += 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
map.push((t, 1));
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&self, t: &T) -> bool {
|
||||
unsafe {
|
||||
let map = self.map.get().deref_mut();
|
||||
let idx = 'idx: {
|
||||
for (idx, (k, v)) in map.iter_mut().enumerate() {
|
||||
if k == t {
|
||||
*v -= 1;
|
||||
if *v > 0 {
|
||||
return false;
|
||||
} else {
|
||||
break 'idx idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
let _v = map.swap_remove(idx);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_vec(&self) -> Vec<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
unsafe { self.map.get().deref().iter().map(|k| k.0).collect() }
|
||||
}
|
||||
|
||||
pub fn lock(&self) -> Locked<T> {
|
||||
unsafe {
|
||||
Locked {
|
||||
vec: mem::take(self.map.get().deref_mut()),
|
||||
rc: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Locked<'a, T> {
|
||||
rc: &'a RefCounted<T>,
|
||||
vec: Vec<(T, usize)>,
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for Locked<'a, T> {
|
||||
type Target = [(T, usize)];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.vec
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for Locked<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
*self.rc.map.get() = mem::take(&mut self.vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue