use std::{fmt::Debug, os::fd::AsFd};
use serde_repr::Deserialize_repr;
use zbus::zvariant::{Fd, Type};
use crate::{Error, Pid, error::PortalError, proxy::Proxy};
#[cfg_attr(feature = "glib", derive(glib::Enum))]
#[cfg_attr(feature = "glib", enum_type(name = "AshpdGameModeStatus"))]
#[derive(Deserialize_repr, PartialEq, Eq, Debug, Clone, Copy, Type)]
#[repr(i32)]
pub enum Status {
Inactive = 0,
Active = 1,
Registered = 2,
Rejected = -1,
}
#[derive(Deserialize_repr, PartialEq, Eq, Debug, Type)]
#[repr(i32)]
enum RegisterStatus {
Success = 0,
Rejected = -1,
}
#[derive(Debug)]
#[doc(alias = "org.freedesktop.portal.GameMode")]
pub struct GameMode(Proxy<'static>);
impl GameMode {
pub async fn new() -> Result<Self, Error> {
let proxy = Proxy::new_desktop("org.freedesktop.portal.GameMode").await?;
Ok(Self(proxy))
}
pub async fn with_connection(connection: zbus::Connection) -> Result<Self, Error> {
let proxy =
Proxy::new_desktop_with_connection(connection, "org.freedesktop.portal.GameMode")
.await?;
Ok(Self(proxy))
}
pub fn version(&self) -> u32 {
self.0.version()
}
#[doc(alias = "QueryStatus")]
pub async fn query_status(&self, pid: Pid) -> Result<Status, Error> {
self.0.call("QueryStatus", &(pid as i32)).await
}
#[doc(alias = "QueryStatusByPIDFd")]
pub async fn query_status_by_pidfd(
&self,
target: &impl AsFd,
requester: &impl AsFd,
) -> Result<Status, Error> {
self.0
.call(
"QueryStatusByPIDFd",
&(Fd::from(target), Fd::from(requester)),
)
.await
}
#[doc(alias = "QueryStatusByPid")]
pub async fn query_status_by_pid(&self, target: Pid, requester: Pid) -> Result<Status, Error> {
self.0
.call("QueryStatusByPid", &(target as i32, requester as i32))
.await
}
#[doc(alias = "RegisterGame")]
pub async fn register(&self, pid: Pid) -> Result<(), Error> {
let status = self.0.call("RegisterGame", &(pid as i32)).await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(format!(
"Failed to register game for `{pid}`"
)))),
}
}
#[doc(alias = "RegisterGameByPIDFd")]
pub async fn register_by_pidfd(
&self,
target: &impl AsFd,
requester: &impl AsFd,
) -> Result<(), Error> {
let status = self
.0
.call(
"RegisterGameByPIDFd",
&(Fd::from(target), Fd::from(requester)),
)
.await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(
"Failed to register by pidfd".to_string(),
))),
}
}
#[doc(alias = "RegisterGameByPid")]
pub async fn register_by_pid(&self, target: Pid, requester: Pid) -> Result<(), Error> {
let status = self
.0
.call("RegisterGameByPid", &(target as i32, requester as i32))
.await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(format!(
"Failed to register by pid for target=`{target}` requester=`{requester}`"
)))),
}
}
#[doc(alias = "UnregisterGame")]
pub async fn unregister(&self, pid: Pid) -> Result<(), Error> {
let status = self.0.call("UnregisterGame", &(pid as i32)).await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(format!(
"Failed to unregister for `{pid}`"
)))),
}
}
#[doc(alias = "UnregisterGameByPIDFd")]
pub async fn unregister_by_pidfd(
&self,
target: &impl AsFd,
requester: &impl AsFd,
) -> Result<(), Error> {
let status = self
.0
.call(
"UnregisterGameByPIDFd",
&(Fd::from(target), Fd::from(requester)),
)
.await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(
"Failed to unregister by pidfd`".to_string(),
))),
}
}
#[doc(alias = "UnregisterGameByPid")]
pub async fn unregister_by_pid(&self, target: Pid, requester: Pid) -> Result<(), Error> {
let status = self
.0
.call("UnregisterGameByPid", &(target as i32, requester as i32))
.await?;
match status {
RegisterStatus::Success => Ok(()),
RegisterStatus::Rejected => Err(Error::Portal(PortalError::Failed(format!(
"Failed to unregister by pid for target=`{target}` requester=`{requester}`"
)))),
}
}
#[doc(alias = "Active")]
pub async fn is_active(&self) -> Result<bool, Error> {
let is_active = self.0.property("Active").await?;
Ok(is_active)
}
}
impl std::ops::Deref for GameMode {
type Target = zbus::Proxy<'static>;
fn deref(&self) -> &Self::Target {
&self.0
}
}