Skip to content

Commit

Permalink
Merge pull request #288 from mahkoh/jorth/data-control
Browse files Browse the repository at this point in the history
ipc: implement ext-data-control
  • Loading branch information
mahkoh authored Oct 25, 2024
2 parents 1ca5d43 + 4abbe94 commit 163bb2c
Show file tree
Hide file tree
Showing 33 changed files with 1,440 additions and 766 deletions.
1 change: 1 addition & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ Jay supports the following wayland protocols:

| Global | Version | Privileged |
|------------------------------------------------------|:----------------|---------------|
| ext_data_control_manager_v1 | 1 | Yes |
| ext_foreign_toplevel_image_capture_source_manager_v1 | 1 | |
| ext_foreign_toplevel_list_v1 | 1 | Yes |
| ext_idle_notifier_v1 | 1 | Yes |
Expand Down
2 changes: 2 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Add support fo ext-data-control-v1.

# 1.7.0 (2024-10-25)

- Various bugfixes.
Expand Down
11 changes: 9 additions & 2 deletions src/client/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use {
ext_image_capture_source_v1::ExtImageCaptureSourceV1,
ext_image_copy::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1,
ipc::{
wl_data_source::WlDataSource, zwlr_data_control_source_v1::ZwlrDataControlSourceV1,
data_control::{
ext_data_control_source_v1::ExtDataControlSourceV1,
zwlr_data_control_source_v1::ZwlrDataControlSourceV1,
},
wl_data_source::WlDataSource,
zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1,
},
jay_output::JayOutput,
Expand Down Expand Up @@ -34,7 +38,7 @@ use {
copyhashmap::{CopyHashMap, Locked},
},
wire::{
ExtForeignToplevelHandleV1Id, ExtImageCaptureSourceV1Id,
ExtDataControlSourceV1Id, ExtForeignToplevelHandleV1Id, ExtImageCaptureSourceV1Id,
ExtImageCopyCaptureSessionV1Id, JayOutputId, JayScreencastId, JayToplevelId,
JayWorkspaceId, WlBufferId, WlDataSourceId, WlOutputId, WlPointerId, WlRegionId,
WlRegistryId, WlSeatId, WlSurfaceId, WpDrmLeaseConnectorV1Id,
Expand Down Expand Up @@ -77,6 +81,7 @@ pub struct Objects {
CopyHashMap<ExtForeignToplevelHandleV1Id, Rc<ExtForeignToplevelHandleV1>>,
pub ext_copy_sessions:
CopyHashMap<ExtImageCopyCaptureSessionV1Id, Rc<ExtImageCopyCaptureSessionV1>>,
pub ext_data_sources: CopyHashMap<ExtDataControlSourceV1Id, Rc<ExtDataControlSourceV1>>,
ids: RefCell<Vec<usize>>,
}

Expand Down Expand Up @@ -113,6 +118,7 @@ impl Objects {
image_capture_sources: Default::default(),
foreign_toplevel_handles: Default::default(),
ext_copy_sessions: Default::default(),
ext_data_sources: Default::default(),
ids: RefCell::new(vec![]),
}
}
Expand Down Expand Up @@ -153,6 +159,7 @@ impl Objects {
self.image_capture_sources.clear();
self.foreign_toplevel_handles.clear();
self.ext_copy_sessions.clear();
self.ext_data_sources.clear();
}

pub fn id<T>(&self, client_data: &Client) -> Result<T, ClientError>
Expand Down
1 change: 1 addition & 0 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ fn start_compositor2(
toplevels: Default::default(),
const_40hz_latch: Default::default(),
tray_item_ids: Default::default(),
data_control_device_ids: Default::default(),
});
state.tracker.register(ClientId::from_raw(0));
create_dummy_output(&state);
Expand Down
6 changes: 5 additions & 1 deletion src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ use {
ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1Global,
ext_session_lock_manager_v1::ExtSessionLockManagerV1Global,
ipc::{
data_control::{
ext_data_control_manager_v1::ExtDataControlManagerV1Global,
zwlr_data_control_manager_v1::ZwlrDataControlManagerV1Global,
},
wl_data_device_manager::WlDataDeviceManagerGlobal,
zwlr_data_control_manager_v1::ZwlrDataControlManagerV1Global,
zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1Global,
},
jay_compositor::JayCompositorGlobal,
Expand Down Expand Up @@ -207,6 +210,7 @@ impl Globals {
add_singleton!(ExtImageCopyCaptureManagerV1Global);
add_singleton!(WpFifoManagerV1Global);
add_singleton!(WpCommitTimingManagerV1Global);
add_singleton!(ExtDataControlManagerV1Global);
}

pub fn add_backend_singletons(&self, backend: &Rc<dyn Backend>) {
Expand Down
47 changes: 12 additions & 35 deletions src/ifs/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ use {
crate::{
client::{Client, ClientError, ClientId},
fixed::Fixed,
ifs::{
ipc::{
x_data_device::XIpcDevice, zwlr_data_control_device_v1::ZwlrDataControlDeviceV1,
},
wl_seat::{WlSeatError, WlSeatGlobal},
},
ifs::{ipc::x_data_device::XIpcDevice, wl_seat::WlSeatGlobal},
utils::{
bitflags::BitflagsExt, cell_ext::CellExt, clonecell::CloneCell, numcell::NumCell,
smallmap::SmallMap,
Expand All @@ -26,17 +21,14 @@ use {
uapi::OwnedFd,
};

pub mod data_control;
pub mod wl_data_device;
pub mod wl_data_device_manager;
pub mod wl_data_offer;
pub mod wl_data_source;
pub mod x_data_device;
pub mod x_data_offer;
pub mod x_data_source;
pub mod zwlr_data_control_device_v1;
pub mod zwlr_data_control_manager_v1;
pub mod zwlr_data_control_offer_v1;
pub mod zwlr_data_control_source_v1;
pub mod zwp_primary_selection_device_manager_v1;
pub mod zwp_primary_selection_device_v1;
pub mod zwp_primary_selection_offer_v1;
Expand Down Expand Up @@ -64,9 +56,7 @@ pub trait DataSource: DynDataSource {
pub trait DynDataSource: 'static {
fn source_data(&self) -> &SourceData;
fn send_send(&self, mime_type: &str, fd: Rc<OwnedFd>);
fn offer_to_regular_client(self: Rc<Self>, client: &Rc<Client>);
fn offer_to_x(self: Rc<Self>, dd: &Rc<XIpcDevice>);
fn offer_to_wlr_device(self: Rc<Self>, dd: &Rc<ZwlrDataControlDeviceV1>);
fn detach_seat(&self, seat: &Rc<WlSeatGlobal>);
fn cancel_unprivileged_offers(&self);

Expand Down Expand Up @@ -139,24 +129,13 @@ pub trait IterableIpcVtable: IpcVtable {
C: FnMut(&Rc<Self::Device>);
}

pub trait WlrIpcVtable: IpcVtable<Device = ZwlrDataControlDeviceV1> {
fn for_each_device<C>(seat: &WlSeatGlobal, f: C)
where
C: FnMut(&Rc<Self::Device>);
}

pub trait IpcVtable: Sized {
type Device;
type Source: DataSource;
type Offer: DataOffer<Device = Self::Device>;

fn get_device_data(dd: &Self::Device) -> &DeviceData<Self::Offer>;
fn get_device_seat(dd: &Self::Device) -> Rc<WlSeatGlobal>;
fn set_seat_selection(
seat: &Rc<WlSeatGlobal>,
source: &Rc<Self::Source>,
serial: Option<u64>,
) -> Result<(), WlSeatError>;
fn create_offer(
dd: &Rc<Self::Device>,
data: OfferData<Self::Device>,
Expand Down Expand Up @@ -320,8 +299,8 @@ pub fn detach_seat<S: DataSource>(src: &S, seat: &Rc<WlSeatGlobal>) {
// data.client.flush();
}

fn offer_source_to_device<T: IpcVtable, S: DynDataSource>(
src: &Rc<S>,
fn offer_source_to_device<T: IpcVtable>(
src: &Rc<dyn DynDataSource>,
dd: &Rc<T::Device>,
data: &SourceData,
shared: Rc<SharedState>,
Expand Down Expand Up @@ -356,31 +335,29 @@ fn offer_source_to_device<T: IpcVtable, S: DynDataSource>(
}
}

fn offer_source_to_x<T, S>(src: &Rc<S>, dd: &Rc<XIpcDevice>)
fn offer_source_to_x<T>(src: Rc<dyn DynDataSource>, dd: &Rc<XIpcDevice>)
where
T: IpcVtable<Device = XIpcDevice>,
S: DynDataSource,
{
let data = src.source_data();
src.cancel_unprivileged_offers();
let shared = data.shared.get();
shared.role.set(data.role.get());
offer_source_to_device::<T, S>(src, dd, data, shared);
offer_source_to_device::<T>(&src, dd, data, shared);
}

pub fn offer_source_to_wlr_device<T, S>(src: &Rc<S>, dd: &Rc<T::Device>)
pub fn offer_source_to_data_control_device<T>(src: Rc<dyn DynDataSource>, dd: &Rc<T::Device>)
where
T: IpcVtable<Device = ZwlrDataControlDeviceV1>,
S: DynDataSource,
T: IpcVtable,
{
let data = src.source_data();
let shared = data.shared.get();
shared.role.set(data.role.get());
offer_source_to_device::<T, _>(src, dd, data, shared);
offer_source_to_device::<T>(&src, dd, data, shared);
}

fn offer_source_to_regular_client<T: IterableIpcVtable, S: DynDataSource>(
src: &Rc<S>,
pub fn offer_source_to_regular_client<T: IterableIpcVtable>(
src: Rc<dyn DynDataSource>,
client: &Rc<Client>,
) {
let data = src.source_data();
Expand All @@ -395,7 +372,7 @@ fn offer_source_to_regular_client<T: IterableIpcVtable, S: DynDataSource>(
let shared = data.shared.get();
shared.role.set(data.role.get());
T::for_each_device(&seat, client.id, |dd| {
offer_source_to_device::<T, S>(src, dd, data, shared.clone());
offer_source_to_device::<T>(&src, dd, data, shared.clone());
});
}

Expand Down
26 changes: 26 additions & 0 deletions src/ifs/ipc/data_control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use {
crate::ifs::ipc::{DynDataSource, IpcLocation},
std::rc::Rc,
};

pub mod ext_data_control_device_v1;
pub mod ext_data_control_manager_v1;
pub mod ext_data_control_offer_v1;
pub mod ext_data_control_source_v1;
mod private;
pub mod zwlr_data_control_device_v1;
pub mod zwlr_data_control_manager_v1;
pub mod zwlr_data_control_offer_v1;
pub mod zwlr_data_control_source_v1;

linear_ids!(DataControlDeviceIds, DataControlDeviceId, u64);

pub trait DynDataControlDevice {
fn id(&self) -> DataControlDeviceId;

fn handle_new_source(
self: Rc<Self>,
location: IpcLocation,
source: Option<Rc<dyn DynDataSource>>,
);
}
Loading

0 comments on commit 163bb2c

Please sign in to comment.