mirror of
https://github.com/YaLTeR/niri.git
synced 2024-10-26 11:48:09 +03:00
Adds support for wlr_gamma_control_unstable_v1 protocol
This commit is contained in:
parent
f6ffe8b3ab
commit
89dfaa6cac
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2119,6 +2119,7 @@ dependencies = [
|
|||||||
"async-channel",
|
"async-channel",
|
||||||
"async-io 1.13.0",
|
"async-io 1.13.0",
|
||||||
"bitflags 2.4.2",
|
"bitflags 2.4.2",
|
||||||
|
"bytemuck",
|
||||||
"calloop 0.13.0",
|
"calloop 0.13.0",
|
||||||
"clap",
|
"clap",
|
||||||
"directories",
|
"directories",
|
||||||
|
@ -73,6 +73,7 @@ tracy-client.workspace = true
|
|||||||
url = { version = "2.5.0", optional = true }
|
url = { version = "2.5.0", optional = true }
|
||||||
xcursor = "0.3.5"
|
xcursor = "0.3.5"
|
||||||
zbus = { version = "~3.15.2", optional = true }
|
zbus = { version = "~3.15.2", optional = true }
|
||||||
|
bytemuck = "1.14.3"
|
||||||
|
|
||||||
[dependencies.smithay]
|
[dependencies.smithay]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
@ -8,7 +8,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{io, mem};
|
use std::{io, mem};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Context};
|
use anyhow::{anyhow, bail, ensure, Context};
|
||||||
use libc::dev_t;
|
use libc::dev_t;
|
||||||
use niri_config::Config;
|
use niri_config::Config;
|
||||||
use smithay::backend::allocator::dmabuf::Dmabuf;
|
use smithay::backend::allocator::dmabuf::Dmabuf;
|
||||||
@ -1244,6 +1244,65 @@ impl Tty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_gamma_length(&self, output: &Output) -> Option<u32> {
|
||||||
|
let tty_state = output.user_data().get::<TtyOutputState>().unwrap();
|
||||||
|
let device = self.devices.get(&tty_state.node)?;
|
||||||
|
let crtc_info = device.drm.get_crtc(tty_state.crtc.clone()).ok()?;
|
||||||
|
return Some(crtc_info.gamma_length());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_gamma(&self, output: &Output) -> Option<Vec<u16>> {
|
||||||
|
let tty_state = output.user_data().get::<TtyOutputState>().unwrap();
|
||||||
|
let device = self.devices.get(&tty_state.node)?;
|
||||||
|
let crtc_info = device.drm.get_crtc(tty_state.crtc.clone()).ok()?;
|
||||||
|
let crtc = tty_state.crtc.clone();
|
||||||
|
let gamma_length = crtc_info.gamma_length() as usize;
|
||||||
|
let mut red = vec![0; gamma_length];
|
||||||
|
let mut green = vec![0; gamma_length];
|
||||||
|
let mut blue = vec![0; gamma_length];
|
||||||
|
if let Err(err) = device.drm.get_gamma(crtc, &mut red, &mut green, &mut blue) {
|
||||||
|
warn!("error getting gamma for crtc {crtc:?}: {err:?}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
red.extend(green);
|
||||||
|
red.extend(blue);
|
||||||
|
return Some(red);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_gamma(
|
||||||
|
&self,
|
||||||
|
niri: &mut Niri,
|
||||||
|
output: &Output,
|
||||||
|
ramp: Vec<u16>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let tty_state = output.user_data().get::<TtyOutputState>().unwrap();
|
||||||
|
let device = self
|
||||||
|
.devices
|
||||||
|
.get(&tty_state.node)
|
||||||
|
.context("missing device")?;
|
||||||
|
|
||||||
|
let crtc_info = device.drm.get_crtc(tty_state.crtc.clone())?;
|
||||||
|
let crtc = tty_state.crtc.clone();
|
||||||
|
let gamma_length = crtc_info.gamma_length() as usize;
|
||||||
|
|
||||||
|
ensure!(ramp.len() == gamma_length * 3, "wrong gamma length");
|
||||||
|
let mut red = ramp.clone();
|
||||||
|
red.truncate(gamma_length);
|
||||||
|
let mut green = ramp.clone();
|
||||||
|
green.drain(0..gamma_length);
|
||||||
|
green.truncate(gamma_length);
|
||||||
|
let mut blue = ramp;
|
||||||
|
blue.drain(0..gamma_length * 2);
|
||||||
|
blue.truncate(gamma_length);
|
||||||
|
|
||||||
|
device
|
||||||
|
.drm
|
||||||
|
.set_gamma(crtc, &mut red, &mut green, &mut blue)
|
||||||
|
.context("error setting gamma")?;
|
||||||
|
niri.queue_redraw(output.clone());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn refresh_ipc_outputs(&self) {
|
fn refresh_ipc_outputs(&self) {
|
||||||
let _span = tracy_client::span!("Tty::refresh_ipc_outputs");
|
let _span = tracy_client::span!("Tty::refresh_ipc_outputs");
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use std::os::fd::OwnedFd;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use smithay::backend::allocator::dmabuf::Dmabuf;
|
use smithay::backend::allocator::dmabuf::Dmabuf;
|
||||||
use smithay::backend::drm::DrmNode;
|
use smithay::backend::drm::DrmNode;
|
||||||
use smithay::desktop::{PopupKind, PopupManager};
|
use smithay::desktop::{PopupKind, PopupManager};
|
||||||
@ -15,6 +16,7 @@ use smithay::input::pointer::{CursorIcon, CursorImageStatus, PointerHandle};
|
|||||||
use smithay::input::{keyboard, Seat, SeatHandler, SeatState};
|
use smithay::input::{keyboard, Seat, SeatHandler, SeatState};
|
||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||||
|
use smithay::reexports::wayland_server::backend::ObjectId;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource;
|
use smithay::reexports::wayland_server::protocol::wl_data_source::WlDataSource;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
|
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
|
||||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||||
@ -58,9 +60,10 @@ use crate::niri::{ClientState, State};
|
|||||||
use crate::protocols::foreign_toplevel::{
|
use crate::protocols::foreign_toplevel::{
|
||||||
self, ForeignToplevelHandler, ForeignToplevelManagerState,
|
self, ForeignToplevelHandler, ForeignToplevelManagerState,
|
||||||
};
|
};
|
||||||
|
use crate::protocols::gamma_control::{GammaControlHandler, GammaControlManagerState};
|
||||||
use crate::protocols::screencopy::{Screencopy, ScreencopyHandler};
|
use crate::protocols::screencopy::{Screencopy, ScreencopyHandler};
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
use crate::{delegate_foreign_toplevel, delegate_screencopy};
|
use crate::{delegate_foreign_toplevel, delegate_gamma_control, delegate_screencopy};
|
||||||
|
|
||||||
impl SeatHandler for State {
|
impl SeatHandler for State {
|
||||||
type KeyboardFocus = WlSurface;
|
type KeyboardFocus = WlSurface;
|
||||||
@ -440,3 +443,58 @@ impl DrmLeaseHandler for State {
|
|||||||
delegate_drm_lease!(State);
|
delegate_drm_lease!(State);
|
||||||
|
|
||||||
delegate_viewporter!(State);
|
delegate_viewporter!(State);
|
||||||
|
|
||||||
|
impl GammaControlHandler for State {
|
||||||
|
fn gamma_control_manager_state(&mut self) -> &mut GammaControlManagerState {
|
||||||
|
&mut self.niri.gamma_control_manager_state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gamma(
|
||||||
|
&mut self,
|
||||||
|
wl_output: &WlOutput,
|
||||||
|
ramp: Vec<u16>,
|
||||||
|
gamma_size: u32,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if ramp.len() != gamma_size as usize * 3 {
|
||||||
|
error!(
|
||||||
|
"gamma length wrong (expected {}, got {})",
|
||||||
|
gamma_size,
|
||||||
|
ramp.len()
|
||||||
|
);
|
||||||
|
return Err(anyhow!("Gamma length wrong"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(output) = Output::from_resource(wl_output) else {
|
||||||
|
return Err(anyhow!("No Output matching WlOutput"));
|
||||||
|
};
|
||||||
|
|
||||||
|
self.backend.tty().set_gamma(&mut self.niri, &output, ramp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_gamma(&mut self, wl_output: &WlOutput) -> Option<Vec<u16>> {
|
||||||
|
let output = Output::from_resource(wl_output)?;
|
||||||
|
|
||||||
|
let gamma_ramp = self.backend.tty().get_gamma(&output);
|
||||||
|
if gamma_ramp.is_none() {
|
||||||
|
warn!("Failed to get gamma ramp");
|
||||||
|
}
|
||||||
|
gamma_ramp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(&mut self, output_id: ObjectId) {
|
||||||
|
self.niri
|
||||||
|
.gamma_control_manager_state
|
||||||
|
.destroy_gamma_control(output_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_gamma_size(&mut self, wl_output: &WlOutput) -> Option<u32> {
|
||||||
|
let output = Output::from_resource(wl_output)?;
|
||||||
|
let gamma_size = self.backend.tty().get_gamma_length(&output);
|
||||||
|
if gamma_size.is_none() {
|
||||||
|
warn!("Failed to get gamma size");
|
||||||
|
}
|
||||||
|
gamma_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate_gamma_control!(State);
|
||||||
|
12
src/niri.rs
12
src/niri.rs
@ -101,6 +101,7 @@ use crate::input::{apply_libinput_settings, TabletData};
|
|||||||
use crate::ipc::server::IpcServer;
|
use crate::ipc::server::IpcServer;
|
||||||
use crate::layout::{Layout, MonitorRenderElement};
|
use crate::layout::{Layout, MonitorRenderElement};
|
||||||
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
|
||||||
|
use crate::protocols::gamma_control::GammaControlManagerState;
|
||||||
use crate::protocols::screencopy::{Screencopy, ScreencopyManagerState};
|
use crate::protocols::screencopy::{Screencopy, ScreencopyManagerState};
|
||||||
use crate::pw_utils::{Cast, PipeWire};
|
use crate::pw_utils::{Cast, PipeWire};
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
@ -187,6 +188,7 @@ pub struct Niri {
|
|||||||
pub popup_grab: Option<PopupGrabState>,
|
pub popup_grab: Option<PopupGrabState>,
|
||||||
pub presentation_state: PresentationState,
|
pub presentation_state: PresentationState,
|
||||||
pub security_context_state: SecurityContextState,
|
pub security_context_state: SecurityContextState,
|
||||||
|
pub gamma_control_manager_state: GammaControlManagerState,
|
||||||
|
|
||||||
pub seat: Seat<State>,
|
pub seat: Seat<State>,
|
||||||
/// Scancodes of the keys to suppress.
|
/// Scancodes of the keys to suppress.
|
||||||
@ -929,6 +931,15 @@ impl Niri {
|
|||||||
let viewporter_state = ViewporterState::new::<State>(&display_handle);
|
let viewporter_state = ViewporterState::new::<State>(&display_handle);
|
||||||
let xdg_foreign_state = XdgForeignState::new::<State>(&display_handle);
|
let xdg_foreign_state = XdgForeignState::new::<State>(&display_handle);
|
||||||
|
|
||||||
|
let gamma_control_manager_state = GammaControlManagerState::new::<State, _>(
|
||||||
|
&display_handle,
|
||||||
|
match backend {
|
||||||
|
Backend::Tty(_) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
|client| !client.get_data::<ClientState>().unwrap().restricted,
|
||||||
|
);
|
||||||
|
|
||||||
let mut seat: Seat<State> = seat_state.new_wl_seat(&display_handle, backend.seat_name());
|
let mut seat: Seat<State> = seat_state.new_wl_seat(&display_handle, backend.seat_name());
|
||||||
seat.add_keyboard(
|
seat.add_keyboard(
|
||||||
config_.input.keyboard.xkb.to_xkb_config(),
|
config_.input.keyboard.xkb.to_xkb_config(),
|
||||||
@ -1082,6 +1093,7 @@ impl Niri {
|
|||||||
suppressed_keys: HashSet::new(),
|
suppressed_keys: HashSet::new(),
|
||||||
presentation_state,
|
presentation_state,
|
||||||
security_context_state,
|
security_context_state,
|
||||||
|
gamma_control_manager_state,
|
||||||
|
|
||||||
seat,
|
seat,
|
||||||
keyboard_focus: None,
|
keyboard_focus: None,
|
||||||
|
238
src/protocols/gamma_control.rs
Normal file
238
src/protocols/gamma_control.rs
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use smithay::reexports::wayland_protocols_wlr;
|
||||||
|
use smithay::reexports::wayland_server::backend::{ClientId, ObjectId};
|
||||||
|
use smithay::reexports::wayland_server::protocol::wl_output::WlOutput;
|
||||||
|
use smithay::reexports::wayland_server::{
|
||||||
|
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
|
||||||
|
};
|
||||||
|
use wayland_protocols_wlr::gamma_control::v1::server::{
|
||||||
|
zwlr_gamma_control_manager_v1, zwlr_gamma_control_v1,
|
||||||
|
};
|
||||||
|
use zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1;
|
||||||
|
use zwlr_gamma_control_v1::ZwlrGammaControlV1;
|
||||||
|
|
||||||
|
const VERSION: u32 = 1;
|
||||||
|
|
||||||
|
pub struct GammaControlManagerState {
|
||||||
|
gamma_controls: HashMap<WlOutput, ZwlrGammaControlV1>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GammaControlManagerGlobalData {
|
||||||
|
filter: Box<dyn for<'c> Fn(&'c Client) -> bool + Send + Sync>,
|
||||||
|
can_view: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GammaControlHandler {
|
||||||
|
fn gamma_control_manager_state(&mut self) -> &mut GammaControlManagerState;
|
||||||
|
fn set_gamma(
|
||||||
|
&mut self,
|
||||||
|
output: &WlOutput,
|
||||||
|
ramp: Vec<u16>,
|
||||||
|
gamma_size: u32,
|
||||||
|
) -> anyhow::Result<()>;
|
||||||
|
fn get_gamma(&mut self, output: &WlOutput) -> Option<Vec<u16>>;
|
||||||
|
fn destroy(&mut self, output_id: ObjectId);
|
||||||
|
fn get_gamma_size(&mut self, output: &WlOutput) -> Option<u32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GammaControlState {
|
||||||
|
gamma_size: Option<u32>,
|
||||||
|
previous_gamma_ramp: Option<Vec<u16>>,
|
||||||
|
output: WlOutput,
|
||||||
|
failed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GammaControlManagerState {
|
||||||
|
pub fn new<D, F>(display: &DisplayHandle, can_view: bool, filter: F) -> Self
|
||||||
|
where
|
||||||
|
D: GlobalDispatch<ZwlrGammaControlManagerV1, GammaControlManagerGlobalData>,
|
||||||
|
D: Dispatch<ZwlrGammaControlManagerV1, ()>,
|
||||||
|
D: Dispatch<ZwlrGammaControlV1, GammaControlState>,
|
||||||
|
D: GammaControlHandler,
|
||||||
|
D: 'static,
|
||||||
|
F: for<'c> Fn(&'c Client) -> bool + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let global_data = GammaControlManagerGlobalData {
|
||||||
|
filter: Box::new(filter),
|
||||||
|
can_view,
|
||||||
|
};
|
||||||
|
display.create_global::<D, ZwlrGammaControlManagerV1, _>(VERSION, global_data);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
gamma_controls: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn destroy_gamma_control(&mut self, output_id: ObjectId) {
|
||||||
|
self.gamma_controls.remove(&output_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> GlobalDispatch<ZwlrGammaControlManagerV1, GammaControlManagerGlobalData, D>
|
||||||
|
for GammaControlManagerState
|
||||||
|
where
|
||||||
|
D: GlobalDispatch<ZwlrGammaControlManagerV1, GammaControlManagerGlobalData>,
|
||||||
|
D: Dispatch<ZwlrGammaControlManagerV1, ()>,
|
||||||
|
D: Dispatch<ZwlrGammaControlV1, GammaControlState>,
|
||||||
|
D: GammaControlHandler,
|
||||||
|
D: 'static,
|
||||||
|
{
|
||||||
|
fn bind(
|
||||||
|
_state: &mut D,
|
||||||
|
_handle: &DisplayHandle,
|
||||||
|
_client: &Client,
|
||||||
|
manager: New<ZwlrGammaControlManagerV1>,
|
||||||
|
_manager_state: &GammaControlManagerGlobalData,
|
||||||
|
data_init: &mut DataInit<'_, D>,
|
||||||
|
) {
|
||||||
|
data_init.init(manager, ());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_view(client: Client, global_data: &GammaControlManagerGlobalData) -> bool {
|
||||||
|
global_data.can_view && (global_data.filter)(&client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> Dispatch<ZwlrGammaControlManagerV1, (), D> for GammaControlManagerState
|
||||||
|
where
|
||||||
|
D: Dispatch<ZwlrGammaControlManagerV1, ()>,
|
||||||
|
D: Dispatch<ZwlrGammaControlV1, GammaControlState>,
|
||||||
|
D: GammaControlHandler,
|
||||||
|
D: 'static,
|
||||||
|
{
|
||||||
|
fn request(
|
||||||
|
state: &mut D,
|
||||||
|
_client: &Client,
|
||||||
|
_resource: &ZwlrGammaControlManagerV1,
|
||||||
|
request: <ZwlrGammaControlManagerV1 as Resource>::Request,
|
||||||
|
_data: &(),
|
||||||
|
_dhandle: &DisplayHandle,
|
||||||
|
data_init: &mut DataInit<'_, D>,
|
||||||
|
) {
|
||||||
|
match request {
|
||||||
|
zwlr_gamma_control_manager_v1::Request::GetGammaControl { id, output } => {
|
||||||
|
let gamma_size = state.get_gamma_size(&output);
|
||||||
|
let previous_gamma_ramp = state.get_gamma(&output);
|
||||||
|
|
||||||
|
if state
|
||||||
|
.gamma_control_manager_state()
|
||||||
|
.gamma_controls
|
||||||
|
.contains_key(&output)
|
||||||
|
|| gamma_size.is_none()
|
||||||
|
|| previous_gamma_ramp.is_none()
|
||||||
|
{
|
||||||
|
data_init
|
||||||
|
.init(
|
||||||
|
id,
|
||||||
|
GammaControlState {
|
||||||
|
gamma_size: gamma_size.clone(),
|
||||||
|
previous_gamma_ramp: None,
|
||||||
|
output: output.clone(),
|
||||||
|
failed: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let zwlr_gamma_control = data_init.init(
|
||||||
|
id,
|
||||||
|
GammaControlState {
|
||||||
|
gamma_size: gamma_size.clone(),
|
||||||
|
previous_gamma_ramp,
|
||||||
|
output: output.clone(),
|
||||||
|
failed: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
zwlr_gamma_control.gamma_size(gamma_size.unwrap());
|
||||||
|
state
|
||||||
|
.gamma_control_manager_state()
|
||||||
|
.gamma_controls
|
||||||
|
.insert(output, zwlr_gamma_control);
|
||||||
|
}
|
||||||
|
zwlr_gamma_control_manager_v1::Request::Destroy => (),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D> Dispatch<ZwlrGammaControlV1, GammaControlState, D> for GammaControlManagerState
|
||||||
|
where
|
||||||
|
D: Dispatch<ZwlrGammaControlV1, GammaControlState>,
|
||||||
|
D: GammaControlHandler,
|
||||||
|
D: 'static,
|
||||||
|
{
|
||||||
|
fn request(
|
||||||
|
state: &mut D,
|
||||||
|
_client: &Client,
|
||||||
|
resource: &ZwlrGammaControlV1,
|
||||||
|
request: <ZwlrGammaControlV1 as Resource>::Request,
|
||||||
|
data: &GammaControlState,
|
||||||
|
_dhandle: &DisplayHandle,
|
||||||
|
_data_init: &mut DataInit<'_, D>,
|
||||||
|
) {
|
||||||
|
match request {
|
||||||
|
zwlr_gamma_control_v1::Request::SetGamma { fd } => {
|
||||||
|
if data.failed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug!("setting gamma for output {:?}", data.output);
|
||||||
|
let buf = &mut Vec::new();
|
||||||
|
if File::from(fd).read_to_end(buf).is_err() {
|
||||||
|
warn!("failed to read gamma data for output {:?}", data.output);
|
||||||
|
resource.failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gamma = bytemuck::cast_slice(buf).to_vec();
|
||||||
|
let gamma_size = data.gamma_size.unwrap();
|
||||||
|
|
||||||
|
if let Err(err) = state.set_gamma(&data.output, gamma, gamma_size) {
|
||||||
|
warn!("error setting gamma: {err:?}");
|
||||||
|
resource.failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zwlr_gamma_control_v1::Request::Destroy => (),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroyed(
|
||||||
|
state: &mut D,
|
||||||
|
_client: ClientId,
|
||||||
|
_resource: &ZwlrGammaControlV1,
|
||||||
|
data: &GammaControlState,
|
||||||
|
) {
|
||||||
|
if data.failed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let ramp = data.previous_gamma_ramp.as_ref().unwrap();
|
||||||
|
|
||||||
|
if let Err(err) = state.set_gamma(&data.output, ramp.to_vec(), data.gamma_size.unwrap()) {
|
||||||
|
warn!("error resetting gamma: {err:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
state.destroy(data.output.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! delegate_gamma_control {
|
||||||
|
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
|
||||||
|
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||||
|
smithay::reexports::wayland_protocols_wlr::gamma_control::v1::server::zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1: $crate::protocols::gamma_control::GammaControlManagerGlobalData
|
||||||
|
] => $crate::protocols::gamma_control::GammaControlManagerState);
|
||||||
|
|
||||||
|
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||||
|
smithay::reexports::wayland_protocols_wlr::gamma_control::v1::server::zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1: ()
|
||||||
|
] => $crate::protocols::gamma_control::GammaControlManagerState);
|
||||||
|
|
||||||
|
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||||
|
smithay::reexports::wayland_protocols_wlr::gamma_control::v1::server::zwlr_gamma_control_v1::ZwlrGammaControlV1: $crate::protocols::gamma_control::GammaControlState
|
||||||
|
] => $crate::protocols::gamma_control::GammaControlManagerState);
|
||||||
|
};
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
pub mod foreign_toplevel;
|
pub mod foreign_toplevel;
|
||||||
|
pub mod gamma_control;
|
||||||
pub mod screencopy;
|
pub mod screencopy;
|
||||||
|
Loading…
Reference in New Issue
Block a user