use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::System::DataExchange::{
EmptyClipboard, GetClipboardOwner, GetClipboardSequenceNumber,
};
use windows_sys::Win32::System::Ole::CF_DIB;
use super::State;
use super::data::{Open, offer};
use crate::clipboard::ClipboardCommand;
impl State {
pub(super) fn set(&mut self, hwnd: HWND, command: ClipboardCommand) {
let Some(open) = Open::clipboard(hwnd) else {
return;
};
if unsafe { EmptyClipboard() } == 0 {
return;
}
self.lazy.clear();
let ClipboardCommand::Set {
generation,
items,
lazy,
} = command;
self.generation = Some(generation);
let mut eager = Vec::new();
for item in items {
if let Some(format) = self.formats.format(&item.mime) {
if self.formats.write(format, &item.data) {
eager.push(format);
if item.mime == a7n_core::clipboard::IMAGE_PNG
&& self.formats.write(u32::from(CF_DIB), &item.data)
{
eager.push(u32::from(CF_DIB));
}
}
}
}
for item in lazy {
if item.size > a7n_core::clipboard::limit_for(&item.mime) as u64 {
continue;
}
if let Some(format) = self.formats.format(&item.mime) {
if !eager.contains(&format)
&& !self.lazy.iter().any(|(existing, _)| *existing == format)
{
offer(format);
if item.mime == a7n_core::clipboard::IMAGE_PNG {
offer(u32::from(CF_DIB));
self.lazy.push((u32::from(CF_DIB), item.clone()));
}
self.lazy.push((format, item));
}
}
}
self.sequence = Some(unsafe { GetClipboardSequenceNumber() });
drop(open);
}
pub(super) fn render(&mut self, format: u32) {
let Some(index) = self.lazy.iter().position(|(offered, _)| *offered == format) else {
return;
};
let Some(generation) = self.generation else {
return;
};
let item = &self.lazy[index].1;
let Some(bytes) = crate::clipboard::fetch::fetch(generation, item.item_index, &self.pastes)
else {
return;
};
if bytes.len() as u64 == item.size && self.formats.write(format, &bytes) {
self.lazy.swap_remove(index);
}
}
pub(super) fn render_all(&mut self, hwnd: HWND) {
let Some(_open) = Open::clipboard(hwnd) else {
return;
};
if unsafe { GetClipboardOwner() } != hwnd {
return;
}
let formats: Vec<_> = self.lazy.iter().map(|(format, _)| *format).collect();
for format in formats {
self.render(format);
}
}
}