outputs: Handle removal
Currrently, Squeekboard doesn't do anything with this information. It still expects one output to be present, or it will crash.
This commit is contained in:
@ -11,7 +11,8 @@ struct squeek_output_handle {
|
|||||||
|
|
||||||
struct squeek_outputs *squeek_outputs_new(void);
|
struct squeek_outputs *squeek_outputs_new(void);
|
||||||
void squeek_outputs_free(struct squeek_outputs*);
|
void squeek_outputs_free(struct squeek_outputs*);
|
||||||
void squeek_outputs_register(struct squeek_outputs*, struct wl_output *output);
|
void squeek_outputs_register(struct squeek_outputs*, struct wl_output *output, uint32_t id);
|
||||||
|
struct wl_output *squeek_outputs_try_unregister(struct squeek_outputs*, uint32_t id);
|
||||||
struct squeek_output_handle squeek_outputs_get_current(struct squeek_outputs*);
|
struct squeek_output_handle squeek_outputs_get_current(struct squeek_outputs*);
|
||||||
int32_t squeek_outputs_get_perceptual_width(struct squeek_outputs*, struct wl_output *output);
|
int32_t squeek_outputs_get_perceptual_width(struct squeek_outputs*, struct wl_output *output);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -16,6 +16,7 @@ pub mod c {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::os::raw::{ c_char, c_void };
|
use std::os::raw::{ c_char, c_void };
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use ::util::c::{COpaquePtr, Wrapped};
|
use ::util::c::{COpaquePtr, Wrapped};
|
||||||
|
|
||||||
@ -25,6 +26,12 @@ pub mod c {
|
|||||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||||
pub struct WlOutput(*const c_void);
|
pub struct WlOutput(*const c_void);
|
||||||
|
|
||||||
|
impl WlOutput {
|
||||||
|
fn null() -> Self {
|
||||||
|
Self(ptr::null())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct WlOutputListener<T: COpaquePtr> {
|
struct WlOutputListener<T: COpaquePtr> {
|
||||||
geometry: extern fn(
|
geometry: extern fn(
|
||||||
@ -257,14 +264,17 @@ pub mod c {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_outputs_register(raw_collection: COutputs, output: WlOutput) {
|
fn squeek_outputs_register(raw_collection: COutputs, output: WlOutput, id: u32) {
|
||||||
let collection = raw_collection.clone_ref();
|
let collection = raw_collection.clone_ref();
|
||||||
let mut collection = collection.borrow_mut();
|
let mut collection = collection.borrow_mut();
|
||||||
collection.outputs.push(Output {
|
collection.outputs.push((
|
||||||
output: output.clone(),
|
Output {
|
||||||
pending: OutputState::uninitialized(),
|
output: output.clone(),
|
||||||
current: OutputState::uninitialized(),
|
pending: OutputState::uninitialized(),
|
||||||
});
|
current: OutputState::uninitialized(),
|
||||||
|
},
|
||||||
|
id,
|
||||||
|
));
|
||||||
|
|
||||||
unsafe { squeek_output_add_listener(
|
unsafe { squeek_output_add_listener(
|
||||||
output,
|
output,
|
||||||
@ -277,14 +287,29 @@ pub mod c {
|
|||||||
raw_collection,
|
raw_collection,
|
||||||
)};
|
)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This will try to unregister the output, if the id matches a registered one.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_outputs_try_unregister(raw_collection: COutputs, id: u32) -> WlOutput {
|
||||||
|
let collection = raw_collection.clone_ref();
|
||||||
|
let mut collection = collection.borrow_mut();
|
||||||
|
collection.remove_output_by_global(id)
|
||||||
|
.map_err(|e| log_print!(
|
||||||
|
logging::Level::Debug,
|
||||||
|
"Tried to remove global {:x} but it is not registered as an output: {:?}",
|
||||||
|
id, e,
|
||||||
|
))
|
||||||
|
.unwrap_or(WlOutput::null())
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_outputs_get_current(raw_collection: COutputs) -> OutputHandle {
|
fn squeek_outputs_get_current(raw_collection: COutputs) -> OutputHandle {
|
||||||
let collection = raw_collection.clone_ref();
|
let collection = raw_collection.clone_ref();
|
||||||
let collection = collection.borrow();
|
let collection = collection.borrow();
|
||||||
OutputHandle {
|
OutputHandle {
|
||||||
wl_output: collection.outputs[0].output.clone(),
|
wl_output: collection.outputs[0].0.output.clone(),
|
||||||
outputs: raw_collection.clone(),
|
outputs: raw_collection.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,8 +396,13 @@ struct Output {
|
|||||||
current: OutputState,
|
current: OutputState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NotFound;
|
||||||
|
|
||||||
|
type GlobalId = u32;
|
||||||
|
|
||||||
pub struct Outputs {
|
pub struct Outputs {
|
||||||
outputs: Vec<Output>,
|
outputs: Vec<(Output, GlobalId)>,
|
||||||
sender: event_loop::driver::Threaded,
|
sender: event_loop::driver::Threaded,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,10 +418,27 @@ impl Outputs {
|
|||||||
self.sender.send(event.into()).unwrap()
|
self.sender.send(event.into()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_output_by_global(&mut self, id: GlobalId)
|
||||||
|
-> Result<c::WlOutput, NotFound>
|
||||||
|
{
|
||||||
|
let index = self.outputs.iter()
|
||||||
|
.position(|(_o, global_id)| *global_id == id);
|
||||||
|
if let Some(index) = index {
|
||||||
|
let (output, _id) = self.outputs.remove(index);
|
||||||
|
self.send_event(Event {
|
||||||
|
change: ChangeType::Removed,
|
||||||
|
output: OutputId(output.output),
|
||||||
|
});
|
||||||
|
Ok(output.output)
|
||||||
|
} else {
|
||||||
|
Err(NotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn find_output(&self, wl_output: c::WlOutput) -> Option<&Output> {
|
fn find_output(&self, wl_output: c::WlOutput) -> Option<&Output> {
|
||||||
self.outputs
|
self.outputs
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|o|
|
.find_map(|(o, _global)|
|
||||||
if o.output == wl_output { Some(o) } else { None }
|
if o.output == wl_output { Some(o) } else { None }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -401,7 +448,7 @@ impl Outputs {
|
|||||||
{
|
{
|
||||||
self.outputs
|
self.outputs
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find_map(|o|
|
.find_map(|(o, _global)|
|
||||||
if o.output == wl_output { Some(o) } else { None }
|
if o.output == wl_output { Some(o) } else { None }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,7 +126,7 @@ registry_handle_global (void *data,
|
|||||||
} else if (!strcmp (interface, "wl_output")) {
|
} else if (!strcmp (interface, "wl_output")) {
|
||||||
struct wl_output *output = wl_registry_bind (registry, name,
|
struct wl_output *output = wl_registry_bind (registry, name,
|
||||||
&wl_output_interface, 2);
|
&wl_output_interface, 2);
|
||||||
squeek_outputs_register(wayland->outputs, output);
|
squeek_outputs_register(wayland->outputs, output, name);
|
||||||
} else if (!strcmp(interface, "wl_seat")) {
|
} else if (!strcmp(interface, "wl_seat")) {
|
||||||
wayland->seat = wl_registry_bind(registry, name,
|
wayland->seat = wl_registry_bind(registry, name,
|
||||||
&wl_seat_interface, 1);
|
&wl_seat_interface, 1);
|
||||||
@ -138,7 +138,12 @@ registry_handle_global_remove (void *data,
|
|||||||
struct wl_registry *registry,
|
struct wl_registry *registry,
|
||||||
uint32_t name)
|
uint32_t name)
|
||||||
{
|
{
|
||||||
// TODO: outputs
|
(void)registry;
|
||||||
|
struct squeek_wayland *wayland = data;
|
||||||
|
struct wl_output *output = squeek_outputs_try_unregister(wayland->outputs, name);
|
||||||
|
if (output) {
|
||||||
|
wl_output_destroy(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_registry_listener registry_listener = {
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
|||||||
Reference in New Issue
Block a user