1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
//! Wayland proxy objects and helpers.
//!
//! Proxies represent objects in the wayland protocol. Libwayland uses `wl_proxy` pointers
//! to represent proxies and `wl-client` provides safe types to handle them.
//!
//! # Proxy types
//!
//! There are four different types of proxies across two dimensions:
//!
//! - In libwayland:
//! - A *wrapper* `wl_proxy` is a proxy that was created by calling the
//! `wl_proxy_create_wrapper` function.
//! - A *plain* `wl_proxy` is any other proxy.
//! - In `wl-client`:
//! - An *owned* proxy is a proxy that will destroy the underlying `wl_proxy` when it is
//! dropped.
//! - A *borrowed* proxy is a proxy that only references a `wl_proxy` and will never be
//! used to destroy it.
//!
//! Therefore, each proxy is
//!
//! - an owned wrapper proxy,
//! - an owned plain proxy,
//! - a borrowed wrapper proxy, or
//! - a borrowed plain proxy.
//!
//! # Owned proxies
//!
//! Owned proxies are proxies created by `wl-client`. They have a [`Queue`], also created by
//! `wl-client`, which can be accessed by calling [`queue`].
//!
//! When an owned proxy is used to create a new wayland object, the function returns a new
//! owned proxy that is assigned to the same queue as its parent.
//!
//! An owned proxy can be used to destroy the proxy by sending a destructor request or by
//! using the [`destroy`] function. Owned proxies are implicitly destroyed with the
//! [`destroy`] function in the following situations:
//!
//! - When the last reference to the owned proxy is dropped.
//! - When the [`QueueOwner`] owning the proxy's queue is dropped. This is explained in
//! detail in the documentation of [`Queue`].
//!
//! # Borrowed proxies
//!
//! Borrowed proxies might or might not have been created by `wl-client`. Each owned proxy
//! derefs to a borrowed proxy but a borrowed proxy can also be created from raw
//! `wl_proxy` pointers.
//!
//! Since the ownership of these proxies is unknown, they cannot be used to to destroy the
//! proxy.
//!
//! If a request is sent on a borrowed proxy that creates a new wayland object, the caller
//! must also pass in a [`Queue`]. The returned owned proxy will be assigned to this
//! queue.
//!
//! # Creating wrapper proxies
//!
//! When working with wayland objects created by foreign code, the foreign code usually
//! shares raw `wl_proxy` pointers. Given a [`Queue`], it is possible to create a new
//! owned wrapper proxy by calling [`Queue::wrap_wl_proxy`].
//!
//! # Setting proxy event handlers
//!
//! Event handlers can be attached to owned plain proxies by using one of the following
//! functions:
//!
//! - [`set_event_handler`] - for `Send + 'static` event handlers
//! - [`set_event_handler_local`] - for `'static` event handlers
//! - [`set_event_handler_no_op`]
//! - [`Scope::set_event_handler`] - for `Send + 'scope` event handlers
//! - [`Scope::set_event_handler_local`] - for `'scope` event handlers
//!
//! The `_local` variant allows setting event handlers that do not implement `Send`. The
//! `_no_op` variant can be used to destroy compositor-created resources if
//! the application is not otherwise interested in events.
//!
//! Event handlers cannot be set on owned wrapper proxies.
//!
//! For each proxy, the event handler can only be set once and once set it cannot be
//! unset.
use crateScope;
pub use crateBorrowedProxyLock;
use crate::;
use ;
/// An owned proxy.
///
/// This type is usually implemented by bindings that are automatically generated with the
/// `wl-client-builder` crate.
///
/// # Safety
///
/// - `WL_INTERFACE` must refer to a valid interface specification.
/// - It must be safe to transmute this type from an [`UntypedOwnedProxy`] that has an
/// interface that is compatible with `WL_INTERFACE`.
/// - The interface of the contained proxy must be compatible with `WL_INTERFACE`.
/// - The [`EventHandler::mutable_type`] of the [`OwnedProxy::NoOpEventHandler`] must be
/// `None` or the type ID of `()`.
pub unsafe
/// A borrowed proxy.
///
/// This type is usually implemented by bindings that are automatically generated with the
/// `wl-client-builder` crate.
///
/// # Safety
///
/// - It must be safe to transmute this type from a [`UntypedBorrowedProxy`] that has an
/// interface that is compatible with `Owned::WL_INTERFACE`.
/// - The interface of the contained proxy must be compatible with `Owned::WL_INTERFACE`.
pub unsafe
pub
pub
/// Destroys a proxy without sending a wayland message.
///
/// This function only destroys the proxy in libwayland without sending a message to the
/// compositor. You might use this function in the following situations:
///
/// - The type does not provide a destructor request.
/// - In an event handler that destroys the object, e.g. `wl_callback.done`.
/// - You want to deliberately leak the wayland object without leaking memory.
///
/// This function does nothing if the proxy is already destroyed.
///
/// # Panic
///
/// This function might panic if the proxy is attached to a local queue and the current
/// thread is not the thread in which the queue was created.
///
/// # Example
///
/// ```
/// # use std::ptr;
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_callback::{WlCallback, WlCallbackEventHandler, WlCallbackRef};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
///
/// let sync = display.sync();
/// let sync2 = sync.clone();
/// proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
/// proxy::destroy(&sync2);
/// }));
///
/// queue.dispatch_roundtrip_blocking().unwrap();
/// assert!(proxy::wl_proxy(&*sync).is_none());
/// ```
/// Sets the event handler of the proxy.
///
/// This function can only be called once for each proxy. This function cannot be called
/// on wrappers.
///
/// The event handler must implement [`Send`]. Use [`set_event_handler_local`] if your
/// event handler does not implement `Send`.
///
/// # Panic
///
/// This function panics if
///
/// - the proxy has already been destroyed,
/// - the proxy is a wrapper,
/// - the proxy is attached to a local queue and the current thread is not the thread in
/// which the queue was created,
/// - the proxy already has an event handler, or
/// - the event handler accepts a `&mut T`, `T != ()`, and the queue that the proxy
/// is attached to was not created with this data type.
///
/// This function also panics if the interface of the created handler is not the same as
/// the interface of the proxy. However, this cannot happen if you're using the bindings
/// generated by `wl-client-builder`.
///
/// # Example
///
/// ```
/// # use std::sync::Arc;
/// # use std::sync::atomic::AtomicBool;
/// # use std::sync::atomic::Ordering::Relaxed;
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_callback::{WlCallback, WlCallbackEventHandler, WlCallbackRef};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
/// let sync = display.sync();
/// let done = Arc::new(AtomicBool::new(false));
///
/// // Attach the event handler.
/// let done2 = done.clone();
/// proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
/// done2.store(true, Relaxed);
/// }));
///
/// // Wait for the compositor to send the `done` message.
/// queue.dispatch_roundtrip_blocking().unwrap();
///
/// // The event handler sets the value to `true`.
/// assert!(done.load(Relaxed));
/// ```
/// Sets the `!Send` event handler of the proxy.
///
/// This function is the same as [`set_event_handler`] except that the event handler does
/// not have to implement [`Send`] and the queue of the proxy must be a
/// [local queue](Connection::create_local_queue).
///
/// # Panic
///
/// This function panics whenever [`set_event_handler`] panics and also if the queue of
/// the proxy is not a local queue.
///
/// # Example
///
/// ```
/// # use std::cell::Cell;
/// # use std::rc::Rc;
/// # use std::sync::atomic::Ordering::Relaxed;
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_callback::{WlCallback, WlCallbackEventHandler, WlCallbackRef};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_local_queue(c"");
/// let display: WlDisplay = queue.display();
/// let sync = display.sync();
/// let done = Rc::new(Cell::new(false));
///
/// // Attach the event handler.
/// let done2 = done.clone();
/// proxy::set_event_handler_local(&sync, WlCallback::on_done(move |_, _| {
/// done2.set(true);
/// }));
///
/// // Wait for the compositor to send the `done` message.
/// queue.dispatch_roundtrip_blocking().unwrap();
///
/// // The event handler sets the value to `true`.
/// assert!(done.get());
/// ```
/// Sets the event handler of the proxy to ignore all events.
///
/// This can be used in the following situation:
///
/// - The application is not interested in events from this proxy.
/// - But the interface has events that contain file descriptors or create new proxies.
///
/// Not setting any event handler would cause the file descriptors and new proxies to be
/// leaked. Using this function will ensure that all resources are released.
///
/// # Example
///
/// ```
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"queue name");
/// let display: WlDisplay = queue.display();
///
/// let sync = display.sync();
/// proxy::set_event_handler_no_op(&sync);
/// ```
/// Locks the proxy for concurrent destruction.
///
/// If the proxy is not already destroyed, holding this lock will prevent other threads
/// from destroying it.
///
/// Trying to destroy the proxy from this thread while holding this lock will deadlock.
///
/// This lock only locks out concurrent destruction. Multiple threads can acquire this
/// lock at the same time.
///
/// # Example
///
/// ```
/// # use std::{ptr, thread};
/// # use std::sync::{Arc, Barrier};
/// # use std::time::Duration;
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
///
/// // Create a wl_callback that we will destroy in another thread.
/// let sync1 = display.sync();
/// let sync2 = sync1.clone();
///
/// // Lock the proxy to prevent the other thread from destroying it.
/// let lock = proxy::lock(&*sync1);
///
/// // Create a barrier to synchronize with the other thread.
/// let barrier1 = Arc::new(Barrier::new(2));
/// let barrier2 = barrier1.clone();
///
/// thread::spawn(move || {
/// // This will block until the main thread has released the lock.
/// proxy::destroy(&sync2);
/// barrier2.wait();
/// });
///
/// // Sleep for a second to demonstrate that the proxy::destroy does in fact not proceed.
/// thread::sleep(Duration::from_secs(1));
///
/// // The other spawned thread has not yet destroyed the proxy.
/// assert!(lock.wl_proxy().is_some());
/// // Drop the lock to let the other thread proceed.
/// drop(lock);
///
/// // Wait for the other thread to run to completion.
/// barrier1.wait();
///
/// // The proxy is now destroyed.
/// assert!(proxy::wl_proxy(&*sync1).is_none());
/// ```
/// Returns the `wl_proxy` pointer of a proxy.
///
/// This function returns a null pointer if the proxy has already been destroyed.
///
/// If this function returns a non-null pointer, the proxy might still get invalidated at
/// any time when another thread destroys the proxy. Consider using [`lock`] instead.
///
/// # Example
///
/// ```
/// # use std::ptr;
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
/// assert!(proxy::wl_proxy(&*display).is_some());
/// ```
/// Returns the wayland object ID of a proxy.
///
/// If the proxy has already been destroyed, this function returns either the original
/// ID or 0.
///
/// # Example
///
/// ```
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
///
/// let display: WlDisplay = queue.display();
/// assert_eq!(proxy::id(&*display), 1);
/// ```
/// Returns the version of this proxy object.
///
/// The version of the display object is always 0.
///
/// # Panic
///
/// Panics if the proxy is already destroyed.
///
/// # Example
///
/// ```
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
///
/// let display: WlDisplay = queue.display();
/// assert_eq!(proxy::version(&*display), 0);
/// ```
/// Returns the queue of a proxy.
///
/// # Example
///
/// ```
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
///
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
/// assert_eq!(proxy::queue(&display), &*queue);
/// ```
/// Returns whether this proxy is destroyed.
///
/// The proxy being destroyed and the wayland object being destroyed are two separate
/// properties. A proxy can be destroyed even if the wayland object is not yet destroyed
/// and vice versa.
///
/// In a multi-threaded application, a proxy might get destroyed immediately after this
/// function returns `false`. You can use [`lock`] to keep a proxy alive for a while.
///
/// # Example
///
/// ```
/// # use wl_client::{proxy, Libwayland};
/// # use wl_client::test_protocols::core::wl_display::WlDisplay;
/// #
/// let lib = Libwayland::open().unwrap();
/// let con = lib.connect_to_default_display().unwrap();
/// let queue = con.create_queue(c"");
/// let display: WlDisplay = queue.display();
///
/// let sync = display.sync();
/// assert!(proxy::is_not_destroyed(&*sync));
///
/// proxy::destroy(&sync);
/// assert!(proxy::is_destroyed(&*sync));
/// ```
/// Returns whether this proxy is not destroyed.
///
/// This is the same as `!is_destroyed(proxy)`.