cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

clipboard.c (3325B)


      1#include "qemu/osdep.h"
      2#include "ui/clipboard.h"
      3
      4static NotifierList clipboard_notifiers =
      5    NOTIFIER_LIST_INITIALIZER(clipboard_notifiers);
      6
      7static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
      8
      9void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
     10{
     11    notifier_list_add(&clipboard_notifiers, &peer->update);
     12}
     13
     14void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer)
     15{
     16    int i;
     17
     18    for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
     19        qemu_clipboard_peer_release(peer, i);
     20    }
     21
     22    notifier_remove(&peer->update);
     23}
     24
     25bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer,
     26                              QemuClipboardSelection selection)
     27{
     28    QemuClipboardInfo *info = qemu_clipboard_info(selection);
     29
     30    return info && info->owner == peer;
     31}
     32
     33void qemu_clipboard_peer_release(QemuClipboardPeer *peer,
     34                                 QemuClipboardSelection selection)
     35{
     36    g_autoptr(QemuClipboardInfo) info = NULL;
     37
     38    if (qemu_clipboard_peer_owns(peer, selection)) {
     39        /* set empty clipboard info */
     40        info = qemu_clipboard_info_new(NULL, selection);
     41        qemu_clipboard_update(info);
     42    }
     43}
     44
     45void qemu_clipboard_update(QemuClipboardInfo *info)
     46{
     47    g_autoptr(QemuClipboardInfo) old = NULL;
     48    assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
     49
     50    notifier_list_notify(&clipboard_notifiers, info);
     51
     52    old = cbinfo[info->selection];
     53    cbinfo[info->selection] = qemu_clipboard_info_ref(info);
     54}
     55
     56QemuClipboardInfo *qemu_clipboard_info(QemuClipboardSelection selection)
     57{
     58    assert(selection < QEMU_CLIPBOARD_SELECTION__COUNT);
     59
     60    return cbinfo[selection];
     61}
     62
     63QemuClipboardInfo *qemu_clipboard_info_new(QemuClipboardPeer *owner,
     64                                           QemuClipboardSelection selection)
     65{
     66    QemuClipboardInfo *info = g_new0(QemuClipboardInfo, 1);
     67
     68    info->owner = owner;
     69    info->selection = selection;
     70    info->refcount = 1;
     71
     72    return info;
     73}
     74
     75QemuClipboardInfo *qemu_clipboard_info_ref(QemuClipboardInfo *info)
     76{
     77    info->refcount++;
     78    return info;
     79}
     80
     81void qemu_clipboard_info_unref(QemuClipboardInfo *info)
     82{
     83    uint32_t type;
     84
     85    if (!info) {
     86        return;
     87    }
     88
     89    info->refcount--;
     90    if (info->refcount > 0) {
     91        return;
     92    }
     93
     94    for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
     95        g_free(info->types[type].data);
     96    }
     97    g_free(info);
     98}
     99
    100void qemu_clipboard_request(QemuClipboardInfo *info,
    101                            QemuClipboardType type)
    102{
    103    if (info->types[type].data ||
    104        info->types[type].requested ||
    105        !info->types[type].available ||
    106        !info->owner)
    107        return;
    108
    109    info->types[type].requested = true;
    110    info->owner->request(info, type);
    111}
    112
    113void qemu_clipboard_set_data(QemuClipboardPeer *peer,
    114                             QemuClipboardInfo *info,
    115                             QemuClipboardType type,
    116                             uint32_t size,
    117                             const void *data,
    118                             bool update)
    119{
    120    if (!info ||
    121        info->owner != peer) {
    122        return;
    123    }
    124
    125    g_free(info->types[type].data);
    126    info->types[type].data = g_memdup(data, size);
    127    info->types[type].size = size;
    128    info->types[type].available = true;
    129
    130    if (update) {
    131        qemu_clipboard_update(info);
    132    }
    133}