xref: /openbmc/qemu/ui/clipboard.c (revision 660e8d0f0be4e87da937ce797973874bb282d498)
1*660e8d0fSGerd Hoffmann #include "qemu/osdep.h"
2*660e8d0fSGerd Hoffmann #include "ui/clipboard.h"
3*660e8d0fSGerd Hoffmann 
4*660e8d0fSGerd Hoffmann static NotifierList clipboard_notifiers =
5*660e8d0fSGerd Hoffmann     NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
6*660e8d0fSGerd Hoffmann 
7*660e8d0fSGerd Hoffmann void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
8*660e8d0fSGerd Hoffmann {
9*660e8d0fSGerd Hoffmann     notifier_list_add(&clipboard_notifiers, &peer->update);
10*660e8d0fSGerd Hoffmann }
11*660e8d0fSGerd Hoffmann 
12*660e8d0fSGerd Hoffmann void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
13*660e8d0fSGerd Hoffmann {
14*660e8d0fSGerd Hoffmann     notifier_remove(&peer->update);
15*660e8d0fSGerd Hoffmann }
16*660e8d0fSGerd Hoffmann 
17*660e8d0fSGerd Hoffmann void qemu_clipboard_update(QemuClipboardInfo *info)
18*660e8d0fSGerd Hoffmann {
19*660e8d0fSGerd Hoffmann     notifier_list_notify(&clipboard_notifiers, info);
20*660e8d0fSGerd Hoffmann }
21*660e8d0fSGerd Hoffmann 
22*660e8d0fSGerd Hoffmann QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
23*660e8d0fSGerd Hoffmann                                            QemuClipboardSelection selection)
24*660e8d0fSGerd Hoffmann {
25*660e8d0fSGerd Hoffmann     QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1);
26*660e8d0fSGerd Hoffmann 
27*660e8d0fSGerd Hoffmann     info->owner = owner;
28*660e8d0fSGerd Hoffmann     info->selection = selection;
29*660e8d0fSGerd Hoffmann     info->refcount = 1;
30*660e8d0fSGerd Hoffmann 
31*660e8d0fSGerd Hoffmann     return info;
32*660e8d0fSGerd Hoffmann }
33*660e8d0fSGerd Hoffmann 
34*660e8d0fSGerd Hoffmann QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
35*660e8d0fSGerd Hoffmann {
36*660e8d0fSGerd Hoffmann     info->refcount++;
37*660e8d0fSGerd Hoffmann     return info;
38*660e8d0fSGerd Hoffmann }
39*660e8d0fSGerd Hoffmann 
40*660e8d0fSGerd Hoffmann void qemu_clipboard_info_unref(QemuClipboardInfo *info)
41*660e8d0fSGerd Hoffmann {
42*660e8d0fSGerd Hoffmann     uint32_t type;
43*660e8d0fSGerd Hoffmann 
44*660e8d0fSGerd Hoffmann     if (!info) {
45*660e8d0fSGerd Hoffmann         return;
46*660e8d0fSGerd Hoffmann     }
47*660e8d0fSGerd Hoffmann 
48*660e8d0fSGerd Hoffmann     info->refcount--;
49*660e8d0fSGerd Hoffmann     if (info->refcount > 0) {
50*660e8d0fSGerd Hoffmann         return;
51*660e8d0fSGerd Hoffmann     }
52*660e8d0fSGerd Hoffmann 
53*660e8d0fSGerd Hoffmann     for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
54*660e8d0fSGerd Hoffmann         g_free(info->types[type].data);
55*660e8d0fSGerd Hoffmann     }
56*660e8d0fSGerd Hoffmann     g_free(info);
57*660e8d0fSGerd Hoffmann }
58*660e8d0fSGerd Hoffmann 
59*660e8d0fSGerd Hoffmann void qemu_clipboard_request(QemuClipboardInfo *info,
60*660e8d0fSGerd Hoffmann                             QemuClipboardType type)
61*660e8d0fSGerd Hoffmann {
62*660e8d0fSGerd Hoffmann     if (info->types[type].data ||
63*660e8d0fSGerd Hoffmann         info->types[type].requested ||
64*660e8d0fSGerd Hoffmann         !info->types[type].available ||
65*660e8d0fSGerd Hoffmann         !info->owner)
66*660e8d0fSGerd Hoffmann         return;
67*660e8d0fSGerd Hoffmann 
68*660e8d0fSGerd Hoffmann     info->types[type].requested = true;
69*660e8d0fSGerd Hoffmann     info->owner->request(info, type);
70*660e8d0fSGerd Hoffmann }
71*660e8d0fSGerd Hoffmann 
72*660e8d0fSGerd Hoffmann void qemu_clipboard_set_data(QemuClipboardPeer *peer,
73*660e8d0fSGerd Hoffmann                              QemuClipboardInfo *info,
74*660e8d0fSGerd Hoffmann                              QemuClipboardType type,
75*660e8d0fSGerd Hoffmann                              uint32_t size,
76*660e8d0fSGerd Hoffmann                              void *data,
77*660e8d0fSGerd Hoffmann                              bool update)
78*660e8d0fSGerd Hoffmann {
79*660e8d0fSGerd Hoffmann     if (!info ||
80*660e8d0fSGerd Hoffmann         info->owner != peer) {
81*660e8d0fSGerd Hoffmann         return;
82*660e8d0fSGerd Hoffmann     }
83*660e8d0fSGerd Hoffmann 
84*660e8d0fSGerd Hoffmann     g_free(info->types[type].data);
85*660e8d0fSGerd Hoffmann     info->types[type].data = g_memdup(data, size);
86*660e8d0fSGerd Hoffmann     info->types[type].size = size;
87*660e8d0fSGerd Hoffmann     info->types[type].available = true;
88*660e8d0fSGerd Hoffmann 
89*660e8d0fSGerd Hoffmann     if (update) {
90*660e8d0fSGerd Hoffmann         qemu_clipboard_update(info);
91*660e8d0fSGerd Hoffmann     }
92*660e8d0fSGerd Hoffmann }
93