mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-30 02:42:59 +00:00
qemu: 9.0.2 -> 9.1.0
The macOS deployment target has been set to 12.0, and the collection of patches and reverts to keep older macOS versions working has been dropped, as maintaining what is effectively a fork of QEMU solely for the sake of versions no longer supported by Apple has become untenable. It may or may not still work on older macOS versions, potentially with reduced functionality. Upstream only officially supports the latest two versions of macOS, so this is still extending support further back than QEMU will support. To continue supporting back to macOS 10.12, at least the following upstream commits would have to be reverted, and possibly more: * <2d27c91e2b
> * <e9c9d8dc3b
> * <7b60b971cc
> However, if you want to do that, you should be prepared to take up the burden of maintaining the monotonically‐increasing set of patches that will be required to keep this working in future. Fixes: CVE-2024-7409 Co-authored-by: Emily <vcs@emily.moe>
This commit is contained in:
parent
f0010d7d7e
commit
8ce7f9f78b
@ -1,10 +1,10 @@
|
||||
{ lib, stdenv, fetchurl, fetchpatch, python3Packages, zlib, pkg-config, glib, buildPackages
|
||||
{ lib, stdenv, fetchurl, fetchpatch, python3Packages, zlib, pkg-config, glib, overrideSDK, buildPackages
|
||||
, pixman, vde2, alsa-lib, flex, pcre2
|
||||
, bison, lzo, snappy, libaio, libtasn1, gnutls, nettle, curl, dtc, ninja, meson
|
||||
, sigtool
|
||||
, makeWrapper, removeReferencesTo
|
||||
, attr, libcap, libcap_ng, socat, libslirp
|
||||
, CoreServices, Cocoa, Hypervisor, rez, setfile, vmnet
|
||||
, CoreServices, Cocoa, Hypervisor, Kernel, rez, setfile, vmnet
|
||||
, guestAgentSupport ? (with stdenv.hostPlatform; isLinux || isNetBSD || isOpenBSD || isSunOS || isWindows) && !minimal
|
||||
, numaSupport ? stdenv.isLinux && !stdenv.isAarch32 && !minimal, numactl
|
||||
, seccompSupport ? stdenv.isLinux && !minimal, libseccomp
|
||||
@ -52,6 +52,16 @@
|
||||
|
||||
let
|
||||
hexagonSupport = hostCpuTargets == null || lib.elem "hexagon" hostCpuTargets;
|
||||
|
||||
buildPlatformStdenv =
|
||||
if stdenv.buildPlatform.isDarwin then
|
||||
overrideSDK buildPackages.stdenv {
|
||||
# Keep these values in sync with `all-packages.nix`.
|
||||
darwinSdkVersion = "12.3";
|
||||
darwinMinVersion = "12.0";
|
||||
}
|
||||
else
|
||||
buildPackages.stdenv;
|
||||
in
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
@ -61,14 +71,14 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
+ lib.optionalString nixosTestRunner "-for-vm-tests"
|
||||
+ lib.optionalString toolsOnly "-utils"
|
||||
+ lib.optionalString userOnly "-user";
|
||||
version = "9.0.2";
|
||||
version = "9.1.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://download.qemu.org/qemu-${finalAttrs.version}.tar.xz";
|
||||
hash = "sha256-qMP1lq7Olto7AMr7dLqvoNFFFer7jtHuP39cLQ6/ArY=";
|
||||
hash = "sha256-gWtwIqi6fCrDDi4M+XPoJva8yFBTOWAyEsXt6OlNeDQ=";
|
||||
};
|
||||
|
||||
depsBuildBuild = [ buildPackages.stdenv.cc ]
|
||||
depsBuildBuild = [ buildPlatformStdenv.cc ]
|
||||
++ lib.optionals hexagonSupport [ pkg-config ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
@ -82,16 +92,14 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
++ lib.optionals enableDocs [ python3Packages.sphinx python3Packages.sphinx-rtd-theme ]
|
||||
++ lib.optionals hexagonSupport [ glib ]
|
||||
++ lib.optionals stdenv.isDarwin [ sigtool ]
|
||||
++ lib.optionals (!userOnly) [ dtc ]
|
||||
# workaround, remove once this patch lands: https://lore.kernel.org/qemu-devel/20240805104921.4035256-1-hi@alyssa.is/
|
||||
++ lib.optionals (hexagonSupport && stdenv.hostPlatform.isStatic) [ pcre2 ];
|
||||
++ lib.optionals (!userOnly) [ dtc ];
|
||||
|
||||
buildInputs = [ zlib glib pixman
|
||||
vde2 lzo snappy libtasn1
|
||||
gnutls nettle curl libslirp
|
||||
]
|
||||
++ lib.optionals ncursesSupport [ ncurses ]
|
||||
++ lib.optionals stdenv.isDarwin [ CoreServices Cocoa Hypervisor rez setfile vmnet ]
|
||||
++ lib.optionals stdenv.isDarwin [ CoreServices Cocoa Hypervisor Kernel rez setfile vmnet ]
|
||||
++ lib.optionals seccompSupport [ libseccomp ]
|
||||
++ lib.optionals numaSupport [ numactl ]
|
||||
++ lib.optionals alsaSupport [ alsa-lib ]
|
||||
@ -129,17 +137,6 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
patches = [
|
||||
./fix-qemu-ga.patch
|
||||
|
||||
# QEMU upstream does not demand compatibility to pre-10.13, so 9p-darwin
|
||||
# support on nix requires utimensat fallback. The patch adding this fallback
|
||||
# set was removed during the process of upstreaming this functionality, and
|
||||
# will still be needed in nix until the macOS SDK reaches 10.13+.
|
||||
./provide-fallback-for-utimensat.patch
|
||||
# Cocoa clipboard support only works on macOS 10.14+
|
||||
./revert-ui-cocoa-add-clipboard-support.patch
|
||||
# Standard about panel requires AppKit and macOS 10.13+
|
||||
./revert-ui-cocoa-use-the-standard-about-panel.patch
|
||||
# Safe area insets require macOS 11+
|
||||
./remove-ui-cocoa-use-safe-area-insets.patch
|
||||
# Workaround for upstream issue with nested virtualisation: https://gitlab.com/qemu-project/qemu/-/issues/1008
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.com/qemu-project/qemu/-/commit/3e4546d5bd38a1e98d4bd2de48631abf0398a3a2.diff";
|
||||
|
@ -1,36 +1,45 @@
|
||||
diff --git i/qga/commands-posix.c w/qga/commands-posix.c
|
||||
index 954efed01b..39c4b916ce 100644
|
||||
--- i/qga/commands-posix.c
|
||||
+++ w/qga/commands-posix.c
|
||||
@@ -123,6 +123,8 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
|
||||
execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y",
|
||||
"hypervisor initiated shutdown", (char *)NULL);
|
||||
#else
|
||||
+ execl("/run/current-system/sw/bin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
|
||||
+ "hypervisor initiated shutdown", (char *)NULL);
|
||||
execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
|
||||
"hypervisor initiated shutdown", (char *)NULL);
|
||||
#endif
|
||||
@@ -158,11 +160,13 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
pid_t pid;
|
||||
Error *local_err = NULL;
|
||||
struct timeval tv;
|
||||
+ static const char hwclock_path_nix[] = "/run/current-system/sw/bin/hwclock";
|
||||
static const char hwclock_path[] = "/sbin/hwclock";
|
||||
static int hwclock_available = -1;
|
||||
|
||||
if (hwclock_available < 0) {
|
||||
- hwclock_available = (access(hwclock_path, X_OK) == 0);
|
||||
+ hwclock_available = (access(hwclock_path_nix, X_OK) == 0) ||
|
||||
+ (access(hwclock_path, X_OK) == 0);
|
||||
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
|
||||
index c2bd0b4316..47cee1c351 100644
|
||||
--- a/qga/commands-posix.c
|
||||
+++ b/qga/commands-posix.c
|
||||
@@ -246,7 +246,7 @@ void qmp_guest_shutdown(const char *mode, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hwclock_available) {
|
||||
@@ -208,6 +212,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
- const char *argv[] = {"/sbin/shutdown",
|
||||
+ const char *argv[] = {"/run/current-system/sw/bin/shutdown",
|
||||
#ifdef CONFIG_SOLARIS
|
||||
shutdown_flag, "-g0", "-y",
|
||||
#elif defined(CONFIG_BSD)
|
||||
@@ -257,6 +257,10 @@ void qmp_guest_shutdown(const char *mode, Error **errp)
|
||||
"hypervisor initiated shutdown", (char *) NULL};
|
||||
|
||||
/* Use '/sbin/hwclock -w' to set RTC from the system time,
|
||||
* or '/sbin/hwclock -s' to set the system time from RTC. */
|
||||
+ execl(hwclock_path_nix, "hwclock", has_time ? "-w" : "-s", NULL);
|
||||
execl(hwclock_path, "hwclock", has_time ? "-w" : "-s", NULL);
|
||||
_exit(EXIT_FAILURE);
|
||||
} else if (pid < 0) {
|
||||
ga_run_command(argv, NULL, "shutdown", &local_err);
|
||||
+ if (local_err) {
|
||||
+ argv[0] = "/sbin/shutdown";
|
||||
+ ga_run_command(argv, NULL, "shutdown", &local_err);
|
||||
+ }
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
@@ -270,7 +274,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
struct timeval tv;
|
||||
- const char *argv[] = {"/sbin/hwclock", has_time ? "-w" : "-s", NULL};
|
||||
+ const char *argv[] = {"/run/current-system/sw/bin/hwclock", has_time ? "-w" : "-s", NULL};
|
||||
|
||||
/* If user has passed a time, validate and set it. */
|
||||
if (has_time) {
|
||||
@@ -303,6 +307,11 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
|
||||
* hardware clock (RTC). */
|
||||
ga_run_command(argv, NULL, "set hardware clock to system time",
|
||||
&local_err);
|
||||
+ if (local_err) {
|
||||
+ argv[0] = "/sbin/hwclock";
|
||||
+ ga_run_command(argv, NULL, "set hardware clock to system time",
|
||||
+ &local_err);
|
||||
+ }
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
|
@ -1,189 +0,0 @@
|
||||
From 2ec149ea3f0046fa83e3be74aca192649a60be47 Mon Sep 17 00:00:00 2001
|
||||
From: Keno Fischer <keno@juliacomputing.com>
|
||||
Date: Sat, 16 Jun 2018 20:56:54 -0400
|
||||
Subject: [PATCH] 9p: darwin: Provide fallback impl for utimensat
|
||||
|
||||
This function is new in Mac OS 10.13. Provide a fallback implementation
|
||||
when building against older SDKs. The complication in the definition comes
|
||||
having to separately handle the used SDK version and the target OS version.
|
||||
|
||||
- If the SDK version is too low (__MAC_10_13 not defined), utimensat is not
|
||||
defined in the header, so we must not try to use it (doing so would error).
|
||||
- Otherwise, if the targetted OS version is at least 10.13, we know this
|
||||
function is available, so we can unconditionally call it.
|
||||
- Lastly, we check for the availability of the __builtin_available macro to
|
||||
potentially insert a dynamic check for this OS version. However, __builtin_available
|
||||
is only available with sufficiently recent versions of clang and while all
|
||||
Apple clang versions that ship with Xcode versions that support the 10.13
|
||||
SDK support with builtin, we want to allow building with compilers other
|
||||
than Apple clang that may not support this builtin.
|
||||
|
||||
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
|
||||
Signed-off-by: Michael Roitzsch <reactorcontrol@icloud.com>
|
||||
Signed-off-by: Will Cohen <wwcohen@gmail.com>
|
||||
---
|
||||
hw/9pfs/9p-local.c | 2 +-
|
||||
hw/9pfs/9p-util-darwin.c | 96 ++++++++++++++++++++++++++++++++++++++++
|
||||
hw/9pfs/9p-util-linux.c | 6 +++
|
||||
hw/9pfs/9p-util.h | 8 ++++
|
||||
4 files changed, 111 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
|
||||
index 9d07620235..9c77a431d5 100644
|
||||
--- a/hw/9pfs/9p-local.c
|
||||
+++ b/hw/9pfs/9p-local.c
|
||||
@@ -1081,7 +1081,7 @@ static int local_utimensat(FsContext *s, V9fsPath *fs_path,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- ret = qemu_utimensat(dirfd, name, buf, AT_SYMLINK_NOFOLLOW);
|
||||
+ ret = utimensat_nofollow(dirfd, name, buf);
|
||||
close_preserve_errno(dirfd);
|
||||
out:
|
||||
g_free(dirpath);
|
||||
diff --git a/hw/9pfs/9p-util-darwin.c b/hw/9pfs/9p-util-darwin.c
|
||||
index 95146e7354..74ab2a7f99 100644
|
||||
--- a/hw/9pfs/9p-util-darwin.c
|
||||
+++ b/hw/9pfs/9p-util-darwin.c
|
||||
@@ -145,3 +145,99 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
|
||||
}
|
||||
|
||||
#endif
|
||||
+
|
||||
+#ifndef __has_builtin
|
||||
+#define __has_builtin(x) 0
|
||||
+#endif
|
||||
+
|
||||
+static int update_times_from_stat(int fd, struct timespec times[2],
|
||||
+ int update0, int update1)
|
||||
+{
|
||||
+ struct stat buf;
|
||||
+ int ret = fstat(fd, &buf);
|
||||
+ if (ret == -1) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (update0) {
|
||||
+ times[0] = buf.st_atimespec;
|
||||
+ }
|
||||
+ if (update1) {
|
||||
+ times[1] = buf.st_mtimespec;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int utimensat_nofollow(int dirfd, const char *filename,
|
||||
+ const struct timespec times_in[2])
|
||||
+{
|
||||
+ int ret, fd;
|
||||
+ int special0, special1;
|
||||
+ struct timeval futimes_buf[2];
|
||||
+ struct timespec times[2];
|
||||
+ memcpy(times, times_in, 2 * sizeof(struct timespec));
|
||||
+
|
||||
+/* Check whether we have an SDK version that defines utimensat */
|
||||
+#if defined(__MAC_10_13)
|
||||
+# if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
|
||||
+# define UTIMENSAT_AVAILABLE 1
|
||||
+# elif __has_builtin(__builtin_available)
|
||||
+# define UTIMENSAT_AVAILABLE __builtin_available(macos 10.13, *)
|
||||
+# else
|
||||
+# define UTIMENSAT_AVAILABLE 0
|
||||
+# endif
|
||||
+ if (UTIMENSAT_AVAILABLE) {
|
||||
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* utimensat not available. Use futimes. */
|
||||
+ fd = openat_file(dirfd, filename, O_PATH_9P_UTIL | O_NOFOLLOW, 0);
|
||||
+ if (fd == -1) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ special0 = times[0].tv_nsec == UTIME_OMIT;
|
||||
+ special1 = times[1].tv_nsec == UTIME_OMIT;
|
||||
+ if (special0 || special1) {
|
||||
+ /* If both are set, nothing to do */
|
||||
+ if (special0 && special1) {
|
||||
+ ret = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = update_times_from_stat(fd, times, special0, special1);
|
||||
+ if (ret < 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ special0 = times[0].tv_nsec == UTIME_NOW;
|
||||
+ special1 = times[1].tv_nsec == UTIME_NOW;
|
||||
+ if (special0 || special1) {
|
||||
+ ret = futimes(fd, NULL);
|
||||
+ if (ret < 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* If both are set, we are done */
|
||||
+ if (special0 && special1) {
|
||||
+ ret = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = update_times_from_stat(fd, times, special0, special1);
|
||||
+ if (ret < 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ futimes_buf[0].tv_sec = times[0].tv_sec;
|
||||
+ futimes_buf[0].tv_usec = times[0].tv_nsec / 1000;
|
||||
+ futimes_buf[1].tv_sec = times[1].tv_sec;
|
||||
+ futimes_buf[1].tv_usec = times[1].tv_nsec / 1000;
|
||||
+ ret = futimes(fd, futimes_buf);
|
||||
+
|
||||
+done:
|
||||
+ close_preserve_errno(fd);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/hw/9pfs/9p-util-linux.c b/hw/9pfs/9p-util-linux.c
|
||||
index db451b0784..320697f347 100644
|
||||
--- a/hw/9pfs/9p-util-linux.c
|
||||
+++ b/hw/9pfs/9p-util-linux.c
|
||||
@@ -68,3 +68,9 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
|
||||
{
|
||||
return mknodat(dirfd, filename, mode, dev);
|
||||
}
|
||||
+
|
||||
+int utimensat_nofollow(int dirfd, const char *filename,
|
||||
+ const struct timespec times[2])
|
||||
+{
|
||||
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
|
||||
+}
|
||||
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
|
||||
index c314cf381d..12d57f3398 100644
|
||||
--- a/hw/9pfs/9p-util.h
|
||||
+++ b/hw/9pfs/9p-util.h
|
||||
@@ -101,6 +101,12 @@ static inline int errno_to_dotl(int err) {
|
||||
#define qemu_utimensat utimensat
|
||||
#define qemu_unlinkat unlinkat
|
||||
|
||||
+/* Compatibility with old SDK Versions for Darwin */
|
||||
+#if defined(CONFIG_DARWIN) && !defined(UTIME_NOW)
|
||||
+#define UTIME_NOW -1
|
||||
+#define UTIME_OMIT -2
|
||||
+#endif
|
||||
+
|
||||
static inline void close_preserve_errno(int fd)
|
||||
{
|
||||
int serrno = errno;
|
||||
@@ -163,6 +169,8 @@ ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
|
||||
char *list, size_t size);
|
||||
ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
|
||||
const char *name);
|
||||
+int utimensat_nofollow(int dirfd, const char *filename,
|
||||
+ const struct timespec times[2]);
|
||||
|
||||
/*
|
||||
* Darwin has d_seekoff, which appears to function similarly to d_off.
|
||||
--
|
||||
2.39.2
|
@ -1,14 +0,0 @@
|
||||
diff --git a/ui/cocoa.m b/ui/cocoa.m
|
||||
index 25e0db9dd0..7ce889d798 100644
|
||||
--- a/ui/cocoa.m
|
||||
+++ b/ui/cocoa.m
|
||||
@@ -539,9 +539,6 @@ - (NSSize)fixAspectRatio:(NSSize)max
|
||||
- (NSSize) screenSafeAreaSize
|
||||
{
|
||||
NSSize size = [[[self window] screen] frame].size;
|
||||
- NSEdgeInsets insets = [[[self window] screen] safeAreaInsets];
|
||||
- size.width -= insets.left + insets.right;
|
||||
- size.height -= insets.top + insets.bottom;
|
||||
return size;
|
||||
}
|
||||
|
@ -1,200 +0,0 @@
|
||||
Based on a reversion of upstream 7e3e20d89129614f4a7b2451fe321cc6ccca3b76,
|
||||
adapted for 7.2.0
|
||||
|
||||
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
|
||||
index 3d14bffaf8..2c3f4c3ba0 100644
|
||||
--- a/ui/clipboard.c
|
||||
+++ b/ui/clipboard.c
|
||||
@@ -154,7 +154,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
||||
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
|
||||
index 660d3e0935..0e6760c360 100644
|
||||
--- a/ui/cocoa.m
|
||||
+++ b/ui/cocoa.m
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "qemu/help-texts.h"
|
||||
#include "qemu-main.h"
|
||||
-#include "ui/clipboard.h"
|
||||
#include "ui/console.h"
|
||||
#include "ui/input.h"
|
||||
#include "ui/kbd-state.h"
|
||||
@@ -105,10 +104,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
|
||||
|
||||
static bool allow_events;
|
||||
|
||||
-static NSInteger cbchangecount = -1;
|
||||
-static QemuClipboardInfo *cbinfo;
|
||||
-static QemuEvent cbevent;
|
||||
-
|
||||
// Utility functions to run specified code block with the BQL held
|
||||
typedef void (^CodeBlock)(void);
|
||||
typedef bool (^BoolCodeBlock)(void);
|
||||
@@ -1799,107 +1794,6 @@ static void addRemovableDevicesMenuItems(void)
|
||||
qapi_free_BlockInfoList(pointerToFree);
|
||||
}
|
||||
|
||||
-@interface QemuCocoaPasteboardTypeOwner : NSObject<NSPasteboardTypeOwner>
|
||||
-@end
|
||||
-
|
||||
-@implementation QemuCocoaPasteboardTypeOwner
|
||||
-
|
||||
-- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSPasteboardType)type
|
||||
-{
|
||||
- if (type != NSPasteboardTypeString) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- with_bql(^{
|
||||
- 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) {
|
||||
- bql_unlock();
|
||||
- qemu_event_wait(&cbevent);
|
||||
- bql_lock();
|
||||
- }
|
||||
-
|
||||
- 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)
|
||||
-{
|
||||
- NSAutoreleasePool *pool;
|
||||
- NSData *text;
|
||||
-
|
||||
- switch (type) {
|
||||
- case QEMU_CLIPBOARD_TYPE_TEXT:
|
||||
- pool = [[NSAutoreleasePool alloc] init];
|
||||
- text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
|
||||
- if (text) {
|
||||
- qemu_clipboard_set_data(&cbpeer, info, type,
|
||||
- [text length], [text bytes], true);
|
||||
- }
|
||||
- [pool release];
|
||||
- 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
|
||||
@@ -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");
|
||||
- [cbowner release];
|
||||
exit(status);
|
||||
}
|
||||
|
||||
@@ -2003,18 +1896,6 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
|
||||
[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];
|
||||
}
|
||||
|
||||
@@ -2071,12 +1952,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
|
||||
// register vga output callbacks
|
||||
register_displaychangelistener(&dcl);
|
||||
[cocoaView updateUIInfo];
|
||||
-
|
||||
- qemu_event_init(&cbevent, false);
|
||||
- cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
|
||||
- qemu_clipboard_peer_register(&cbpeer);
|
||||
-
|
||||
- [pool release];
|
||||
}
|
||||
|
||||
static QemuDisplay qemu_display_cocoa = {
|
@ -1,145 +0,0 @@
|
||||
diff --git a/ui/cocoa.m b/ui/cocoa.m
|
||||
index 25e0db9dd0..4af0712036 100644
|
||||
--- a/ui/cocoa.m
|
||||
+++ b/ui/cocoa.m
|
||||
@@ -93,6 +93,7 @@ static void cocoa_switch(DisplayChangeListener *dcl,
|
||||
|
||||
static void cocoa_refresh(DisplayChangeListener *dcl);
|
||||
|
||||
+static NSWindow *about_window;
|
||||
static const DisplayChangeListenerOps dcl_ops = {
|
||||
.dpy_name = "cocoa",
|
||||
.dpy_gfx_update = cocoa_update,
|
||||
@@ -1180,6 +1181,7 @@ - (void)changeDeviceMedia:(id)sender;
|
||||
- (BOOL)verifyQuit;
|
||||
- (void)openDocumentation:(NSString *)filename;
|
||||
- (IBAction) do_about_menu_item: (id) sender;
|
||||
+- (void)make_about_window;
|
||||
- (void)adjustSpeed:(id)sender;
|
||||
@end
|
||||
|
||||
@@ -1227,6 +1229,8 @@ - (id) init
|
||||
[pauseLabel setFont: [NSFont fontWithName: @"Helvetica" size: 90]];
|
||||
[pauseLabel setTextColor: [NSColor blackColor]];
|
||||
[pauseLabel sizeToFit];
|
||||
+
|
||||
+ [self make_about_window];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -1549,29 +1553,92 @@ - (BOOL)verifyQuit
|
||||
/* The action method for the About menu item */
|
||||
- (IBAction) do_about_menu_item: (id) sender
|
||||
{
|
||||
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
- char *icon_path_c = get_relocated_path(CONFIG_QEMU_ICONDIR "/hicolor/512x512/apps/qemu.png");
|
||||
- NSString *icon_path = [NSString stringWithUTF8String:icon_path_c];
|
||||
- g_free(icon_path_c);
|
||||
- NSImage *icon = [[NSImage alloc] initWithContentsOfFile:icon_path];
|
||||
- NSString *version = @"QEMU emulator version " QEMU_FULL_VERSION;
|
||||
- NSString *copyright = @QEMU_COPYRIGHT;
|
||||
- NSDictionary *options;
|
||||
- if (icon) {
|
||||
- options = @{
|
||||
- NSAboutPanelOptionApplicationIcon : icon,
|
||||
- NSAboutPanelOptionApplicationVersion : version,
|
||||
- @"Copyright" : copyright,
|
||||
- };
|
||||
- [icon release];
|
||||
- } else {
|
||||
- options = @{
|
||||
- NSAboutPanelOptionApplicationVersion : version,
|
||||
- @"Copyright" : copyright,
|
||||
- };
|
||||
- }
|
||||
- [NSApp orderFrontStandardAboutPanelWithOptions:options];
|
||||
- [pool release];
|
||||
+ [about_window makeKeyAndOrderFront: nil];
|
||||
+}
|
||||
+
|
||||
+/* Create and display the about dialog */
|
||||
+- (void)make_about_window
|
||||
+{
|
||||
+ /* Make the window */
|
||||
+ int x = 0, y = 0, about_width = 400, about_height = 200;
|
||||
+ NSRect window_rect = NSMakeRect(x, y, about_width, about_height);
|
||||
+ about_window = [[NSWindow alloc] initWithContentRect:window_rect
|
||||
+ styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
|
||||
+ NSWindowStyleMaskMiniaturizable
|
||||
+ backing:NSBackingStoreBuffered
|
||||
+ defer:NO];
|
||||
+ [about_window setTitle: @"About"];
|
||||
+ [about_window setReleasedWhenClosed: NO];
|
||||
+ [about_window center];
|
||||
+ NSView *superView = [about_window contentView];
|
||||
+
|
||||
+ /* Create the dimensions of the picture */
|
||||
+ int picture_width = 80, picture_height = 80;
|
||||
+ x = (about_width - picture_width)/2;
|
||||
+ y = about_height - picture_height - 10;
|
||||
+ NSRect picture_rect = NSMakeRect(x, y, picture_width, picture_height);
|
||||
+
|
||||
+ /* Make the picture of QEMU */
|
||||
+ NSImageView *picture_view = [[NSImageView alloc] initWithFrame:
|
||||
+ picture_rect];
|
||||
+ char *qemu_image_path_c = get_relocated_path(CONFIG_QEMU_ICONDIR "/hicolor/512x512/apps/qemu.png");
|
||||
+ NSString *qemu_image_path = [NSString stringWithUTF8String:qemu_image_path_c];
|
||||
+ g_free(qemu_image_path_c);
|
||||
+ NSImage *qemu_image = [[NSImage alloc] initWithContentsOfFile:qemu_image_path];
|
||||
+ [picture_view setImage: qemu_image];
|
||||
+ [picture_view setImageScaling: NSImageScaleProportionallyUpOrDown];
|
||||
+ [superView addSubview: picture_view];
|
||||
+
|
||||
+ /* Make the name label */
|
||||
+ NSBundle *bundle = [NSBundle mainBundle];
|
||||
+ if (bundle) {
|
||||
+ x = 0;
|
||||
+ y = y - 25;
|
||||
+ int name_width = about_width, name_height = 20;
|
||||
+ NSRect name_rect = NSMakeRect(x, y, name_width, name_height);
|
||||
+ NSTextField *name_label = [[NSTextField alloc] initWithFrame: name_rect];
|
||||
+ [name_label setEditable: NO];
|
||||
+ [name_label setBezeled: NO];
|
||||
+ [name_label setDrawsBackground: NO];
|
||||
+ [name_label setAlignment: NSTextAlignmentCenter];
|
||||
+ NSString *qemu_name = [[bundle executablePath] lastPathComponent];
|
||||
+ [name_label setStringValue: qemu_name];
|
||||
+ [superView addSubview: name_label];
|
||||
+ }
|
||||
+
|
||||
+ /* Set the version label's attributes */
|
||||
+ x = 0;
|
||||
+ y = 50;
|
||||
+ int version_width = about_width, version_height = 20;
|
||||
+ NSRect version_rect = NSMakeRect(x, y, version_width, version_height);
|
||||
+ NSTextField *version_label = [[NSTextField alloc] initWithFrame:
|
||||
+ version_rect];
|
||||
+ [version_label setEditable: NO];
|
||||
+ [version_label setBezeled: NO];
|
||||
+ [version_label setAlignment: NSTextAlignmentCenter];
|
||||
+ [version_label setDrawsBackground: NO];
|
||||
+
|
||||
+ /* Create the version string*/
|
||||
+ NSString *version_string;
|
||||
+ version_string = [[NSString alloc] initWithFormat:
|
||||
+ @"QEMU emulator version %s", QEMU_FULL_VERSION];
|
||||
+ [version_label setStringValue: version_string];
|
||||
+ [superView addSubview: version_label];
|
||||
+
|
||||
+ /* Make copyright label */
|
||||
+ x = 0;
|
||||
+ y = 35;
|
||||
+ int copyright_width = about_width, copyright_height = 20;
|
||||
+ NSRect copyright_rect = NSMakeRect(x, y, copyright_width, copyright_height);
|
||||
+ NSTextField *copyright_label = [[NSTextField alloc] initWithFrame:
|
||||
+ copyright_rect];
|
||||
+ [copyright_label setEditable: NO];
|
||||
+ [copyright_label setBezeled: NO];
|
||||
+ [copyright_label setDrawsBackground: NO];
|
||||
+ [copyright_label setAlignment: NSTextAlignmentCenter];
|
||||
+ [copyright_label setStringValue: [NSString stringWithFormat: @"%s",
|
||||
+ QEMU_COPYRIGHT]];
|
||||
+ [superView addSubview: copyright_label];
|
||||
}
|
||||
|
||||
/* Used by the Speed menu items */
|
@ -32823,9 +32823,17 @@ with pkgs;
|
||||
eiskaltdcpp = libsForQt5.callPackage ../applications/networking/p2p/eiskaltdcpp { };
|
||||
|
||||
qemu = callPackage ../applications/virtualization/qemu {
|
||||
inherit (darwin.apple_sdk.frameworks) CoreServices Cocoa Hypervisor vmnet;
|
||||
inherit (darwin.apple_sdk_12_3.frameworks) CoreServices Cocoa Hypervisor Kernel vmnet;
|
||||
inherit (darwin.stubs) rez setfile;
|
||||
inherit (darwin) sigtool;
|
||||
stdenv =
|
||||
if stdenv.hostPlatform.isDarwin then
|
||||
overrideSDK stdenv {
|
||||
darwinSdkVersion = "12.3";
|
||||
darwinMinVersion = "12.0";
|
||||
}
|
||||
else
|
||||
stdenv;
|
||||
};
|
||||
|
||||
qemu-python-utils = python3Packages.toPythonApplication (
|
||||
|
Loading…
Reference in New Issue
Block a user