2022-12-17 10:02:37 +00:00
|
|
|
Based on a reversion of upstream 7e3e20d89129614f4a7b2451fe321cc6ccca3b76,
|
|
|
|
adapted for 7.2.0
|
2022-04-27 09:35:20 +00:00
|
|
|
|
|
|
|
diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
|
|
|
|
index ce76aa451f..c4e1dc4ff4 100644
|
|
|
|
--- a/include/ui/clipboard.h
|
|
|
|
+++ b/include/ui/clipboard.h
|
|
|
|
@@ -269,7 +269,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
|
|
|
QemuClipboardInfo *info,
|
|
|
|
QemuClipboardType type,
|
|
|
|
uint32_t size,
|
|
|
|
- const void *data,
|
|
|
|
+ void *data,
|
|
|
|
bool update);
|
|
|
|
|
|
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuClipboardInfo, qemu_clipboard_info_unref)
|
|
|
|
diff --git a/ui/clipboard.c b/ui/clipboard.c
|
2022-12-17 10:02:37 +00:00
|
|
|
index 3d14bffaf8..2c3f4c3ba0 100644
|
2022-04-27 09:35:20 +00:00
|
|
|
--- a/ui/clipboard.c
|
|
|
|
+++ b/ui/clipboard.c
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -154,7 +154,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
2022-04-27 09:35:20 +00:00
|
|
|
QemuClipboardInfo *info,
|
|
|
|
QemuClipboardType type,
|
|
|
|
uint32_t size,
|
|
|
|
- const void *data,
|
|
|
|
+ void *data,
|
|
|
|
bool update)
|
|
|
|
{
|
|
|
|
if (!info ||
|
|
|
|
diff --git a/ui/cocoa.m b/ui/cocoa.m
|
2022-12-17 10:02:37 +00:00
|
|
|
index 660d3e0935..0e6760c360 100644
|
2022-04-27 09:35:20 +00:00
|
|
|
--- a/ui/cocoa.m
|
|
|
|
+++ b/ui/cocoa.m
|
2022-09-09 14:08:57 +00:00
|
|
|
@@ -29,7 +29,6 @@
|
2022-04-27 09:35:20 +00:00
|
|
|
|
2022-09-09 14:08:57 +00:00
|
|
|
#include "qemu/help-texts.h"
|
|
|
|
#include "qemu-main.h"
|
2022-04-27 09:35:20 +00:00
|
|
|
-#include "ui/clipboard.h"
|
|
|
|
#include "ui/console.h"
|
|
|
|
#include "ui/input.h"
|
|
|
|
#include "ui/kbd-state.h"
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -105,10 +104,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
|
|
|
|
|
2022-04-27 09:35:20 +00:00
|
|
|
static bool allow_events;
|
|
|
|
|
|
|
|
-static NSInteger cbchangecount = -1;
|
|
|
|
-static QemuClipboardInfo *cbinfo;
|
|
|
|
-static QemuEvent cbevent;
|
|
|
|
-
|
|
|
|
// Utility functions to run specified code block with iothread lock held
|
|
|
|
typedef void (^CodeBlock)(void);
|
|
|
|
typedef bool (^BoolCodeBlock)(void);
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -1799,107 +1794,6 @@ static void addRemovableDevicesMenuItems(void)
|
2022-04-27 09:35:20 +00:00
|
|
|
qapi_free_BlockInfoList(pointerToFree);
|
|
|
|
}
|
|
|
|
|
|
|
|
-@interface QemuCocoaPasteboardTypeOwner : NSObject<NSPasteboardTypeOwner>
|
|
|
|
-@end
|
|
|
|
-
|
|
|
|
-@implementation QemuCocoaPasteboardTypeOwner
|
|
|
|
-
|
|
|
|
-- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSPasteboardType)type
|
|
|
|
-{
|
|
|
|
- if (type != NSPasteboardTypeString) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- with_iothread_lock(^{
|
|
|
|
- QemuClipboardInfo *info = qemu_clipboard_info_ref(cbinfo);
|
|
|
|
- qemu_event_reset(&cbevent);
|
|
|
|
- qemu_clipboard_request(info, QEMU_CLIPBOARD_TYPE_TEXT);
|
|
|
|
-
|
|
|
|
- while (info == cbinfo &&
|
|
|
|
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].available &&
|
|
|
|
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].data == NULL) {
|
|
|
|
- qemu_mutex_unlock_iothread();
|
|
|
|
- qemu_event_wait(&cbevent);
|
|
|
|
- qemu_mutex_lock_iothread();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (info == cbinfo) {
|
|
|
|
- NSData *data = [[NSData alloc] initWithBytes:info->types[QEMU_CLIPBOARD_TYPE_TEXT].data
|
|
|
|
- length:info->types[QEMU_CLIPBOARD_TYPE_TEXT].size];
|
|
|
|
- [sender setData:data forType:NSPasteboardTypeString];
|
|
|
|
- [data release];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- qemu_clipboard_info_unref(info);
|
|
|
|
- });
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-@end
|
|
|
|
-
|
|
|
|
-static QemuCocoaPasteboardTypeOwner *cbowner;
|
|
|
|
-
|
|
|
|
-static void cocoa_clipboard_notify(Notifier *notifier, void *data);
|
|
|
|
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
|
|
|
- QemuClipboardType type);
|
|
|
|
-
|
|
|
|
-static QemuClipboardPeer cbpeer = {
|
|
|
|
- .name = "cocoa",
|
|
|
|
- .notifier = { .notify = cocoa_clipboard_notify },
|
|
|
|
- .request = cocoa_clipboard_request
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static void cocoa_clipboard_update_info(QemuClipboardInfo *info)
|
|
|
|
-{
|
|
|
|
- if (info->owner == &cbpeer || info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (info != cbinfo) {
|
|
|
|
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
- qemu_clipboard_info_unref(cbinfo);
|
|
|
|
- cbinfo = qemu_clipboard_info_ref(info);
|
|
|
|
- cbchangecount = [[NSPasteboard generalPasteboard] declareTypes:@[NSPasteboardTypeString] owner:cbowner];
|
|
|
|
- [pool release];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- qemu_event_set(&cbevent);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
|
|
|
-{
|
|
|
|
- QemuClipboardNotify *notify = data;
|
|
|
|
-
|
|
|
|
- switch (notify->type) {
|
|
|
|
- case QEMU_CLIPBOARD_UPDATE_INFO:
|
|
|
|
- cocoa_clipboard_update_info(notify->info);
|
|
|
|
- return;
|
|
|
|
- case QEMU_CLIPBOARD_RESET_SERIAL:
|
|
|
|
- /* ignore */
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
|
|
|
- QemuClipboardType type)
|
|
|
|
-{
|
2022-09-09 14:08:57 +00:00
|
|
|
- NSAutoreleasePool *pool;
|
2022-04-27 09:35:20 +00:00
|
|
|
- NSData *text;
|
|
|
|
-
|
|
|
|
- switch (type) {
|
|
|
|
- case QEMU_CLIPBOARD_TYPE_TEXT:
|
2022-09-09 14:08:57 +00:00
|
|
|
- pool = [[NSAutoreleasePool alloc] init];
|
2022-04-27 09:35:20 +00:00
|
|
|
- text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
|
|
|
|
- if (text) {
|
|
|
|
- qemu_clipboard_set_data(&cbpeer, info, type,
|
|
|
|
- [text length], [text bytes], true);
|
|
|
|
- }
|
2022-09-09 14:08:57 +00:00
|
|
|
- [pool release];
|
2022-04-27 09:35:20 +00:00
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
|
|
* The startup process for the OSX/Cocoa UI is complicated, because
|
|
|
|
* OSX insists that the UI runs on the initial main thread, and so we
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -1922,7 +1816,6 @@ static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
|
|
|
status = qemu_default_main();
|
|
|
|
qemu_mutex_unlock_iothread();
|
|
|
|
COCOA_DEBUG("Second thread: qemu_default_main() returned, exiting\n");
|
2022-04-27 09:35:20 +00:00
|
|
|
- [cbowner release];
|
|
|
|
exit(status);
|
|
|
|
}
|
|
|
|
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -2003,18 +1896,6 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
|
2022-04-27 09:35:20 +00:00
|
|
|
[cocoaView setAbsoluteEnabled:YES];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
-
|
|
|
|
- if (cbchangecount != [[NSPasteboard generalPasteboard] changeCount]) {
|
|
|
|
- qemu_clipboard_info_unref(cbinfo);
|
|
|
|
- cbinfo = qemu_clipboard_info_new(&cbpeer, QEMU_CLIPBOARD_SELECTION_CLIPBOARD);
|
|
|
|
- if ([[NSPasteboard generalPasteboard] availableTypeFromArray:@[NSPasteboardTypeString]]) {
|
|
|
|
- cbinfo->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
|
|
|
|
- }
|
|
|
|
- qemu_clipboard_update(cbinfo);
|
|
|
|
- cbchangecount = [[NSPasteboard generalPasteboard] changeCount];
|
|
|
|
- qemu_event_set(&cbevent);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
[pool release];
|
|
|
|
}
|
|
|
|
|
2022-12-17 10:02:37 +00:00
|
|
|
@@ -2071,12 +1952,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
|
2022-04-27 09:35:20 +00:00
|
|
|
|
|
|
|
// register vga output callbacks
|
|
|
|
register_displaychangelistener(&dcl);
|
|
|
|
-
|
|
|
|
- qemu_event_init(&cbevent, false);
|
|
|
|
- cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
|
|
|
|
- qemu_clipboard_peer_register(&cbpeer);
|
2022-12-17 10:02:37 +00:00
|
|
|
-
|
|
|
|
- [pool release];
|
2022-04-27 09:35:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static QemuDisplay qemu_display_cocoa = {
|