mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-17 23:22:12 -06:00
Darwin-based host patches
- Remove various build warnings - Fix building with modules on macOS - Fix mouse/keyboard GUI interactions -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmIwjAMACgkQ4+MsLN6t wN6AhBAAm4GBwQ5FYeFtKk2CmlTbWJtwsc4eRVnRnxRV/83scI+oWAl/jHRiAqHp Z3eKVD911UDmHUlajWu3UXulnZQZeh1kOrAYCnDvP/wbRAiKjTLzPhoiu2qsKgg7 UT5bmm8/vY51DuCdEbbhqFSjp6X4L7E8UJLm3SlqADd5YXlNeX4D/58RPLbOgS1b QX7eDREc/6ITVvsNrDeYmIf/AN3O0Rt+Spz7nruvIQd31tiLIXqrOtR4VfWIWvKz HFvOGD7bOYByt7NJN+Q1sdR8twzaoENV8lqbHROGNo/6uBlz7ciCNRly76u3nd4u uoFmpgWi9VDhxZztzM1V0qiD0VjyN+NnemAuexqbYrbT8Ym7AJt5hwLeWRjUqf1z hCMR4Jc+3VCGoNI2yTyAnWdzIQvBUNRfKvFgLeLNzGZmP9fzNAWurFL/p8xD1m7i lgZ5LAecIFkdtpwpzNKUnllTsRKBJDMc5g7tkm3gBosU0B4IFQuBDnwUQYlHcAhb +lFVWU6H/gD/FRjfGVI64yZ940u91vShmE72K+04EqH+s0efMOwC/LPmXdF2MaQq W7KyeWnBLvAFKgyYA6oM9+EWFeZ9KCFs+CXpujPEogJh3RloJNNNAtETu0keI0HZ gGx0QCNekrZ4u2mZPi1S1xwoJTPeowThQHxUj/MEJghtvYaID/A= =PLdU -----END PGP SIGNATURE----- Merge tag 'darwin-20220315' of https://github.com/philmd/qemu into staging Darwin-based host patches - Remove various build warnings - Fix building with modules on macOS - Fix mouse/keyboard GUI interactions # gpg: Signature made Tue 15 Mar 2022 12:52:19 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'darwin-20220315' of https://github.com/philmd/qemu: (21 commits) MAINTAINERS: Volunteer to maintain Darwin-based hosts support ui/cocoa: add option to swap Option and Command ui/cocoa: capture all keys and combos when mouse is grabbed ui/cocoa: release mouse when user switches away from QEMU window ui/cocoa: add option to disable left-command forwarding to guest ui/cocoa: Constify qkeycode translation arrays configure: Pass filtered QEMU_OBJCFLAGS to meson meson: Log QEMU_CXXFLAGS content in summary meson: Resolve the entitlement.sh script once for good osdep: Avoid using Clang-specific __builtin_available() audio: Rename coreaudio extension to use Objective-C compiler coreaudio: Always return 0 in handle_voice_change audio: Log context for audio bug audio/dbus: Fix building with modules on macOS audio/coreaudio: Remove a deprecation warning on macOS 12 block/file-posix: Remove a deprecation warning on macOS 12 hvf: Remove deprecated hv_vcpu_flush() calls hvf: Make hvf_get_segments() / hvf_put_segments() local hvf: Use standard CR0 and CR4 register definitions tests/fp/berkeley-testfloat-3: Ignore ignored #pragma directives ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
22a3a45ade
20 changed files with 283 additions and 120 deletions
|
@ -548,6 +548,12 @@ F: include/*/*win32*
|
||||||
X: qga/*win32*
|
X: qga/*win32*
|
||||||
F: qemu.nsi
|
F: qemu.nsi
|
||||||
|
|
||||||
|
Darwin (macOS, iOS)
|
||||||
|
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||||
|
S: Odd Fixes
|
||||||
|
F: .gitlab-ci.d/cirrus/macos-*
|
||||||
|
F: */*.m
|
||||||
|
|
||||||
Alpha Machines
|
Alpha Machines
|
||||||
--------------
|
--------------
|
||||||
M: Richard Henderson <richard.henderson@linaro.org>
|
M: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
@ -2414,6 +2420,7 @@ F: audio/alsaaudio.c
|
||||||
|
|
||||||
Core Audio framework backend
|
Core Audio framework backend
|
||||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||||
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||||
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
|
@ -2671,6 +2678,7 @@ F: util/drm.c
|
||||||
|
|
||||||
Cocoa graphics
|
Cocoa graphics
|
||||||
M: Peter Maydell <peter.maydell@linaro.org>
|
M: Peter Maydell <peter.maydell@linaro.org>
|
||||||
|
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||||
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: ui/cocoa.m
|
F: ui/cocoa.m
|
||||||
|
|
|
@ -117,7 +117,6 @@ int audio_bug (const char *funcname, int cond)
|
||||||
AUD_log (NULL, "I am sorry\n");
|
AUD_log (NULL, "I am sorry\n");
|
||||||
}
|
}
|
||||||
AUD_log (NULL, "Context:\n");
|
AUD_log (NULL, "Context:\n");
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cond;
|
return cond;
|
||||||
|
@ -138,7 +137,7 @@ static inline int audio_bits_to_index (int bits)
|
||||||
default:
|
default:
|
||||||
audio_bug ("bits_to_index", 1);
|
audio_bug ("bits_to_index", 1);
|
||||||
AUD_log (NULL, "invalid bits %d\n", bits);
|
AUD_log (NULL, "invalid bits %d\n", bits);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +155,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)
|
||||||
AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
|
AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
|
||||||
funcname);
|
funcname);
|
||||||
AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
|
AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
|
||||||
return NULL;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_malloc0 (len);
|
return g_malloc0 (len);
|
||||||
|
@ -543,7 +542,7 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
|
||||||
size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
|
size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
|
||||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||||
dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
return live;
|
return live;
|
||||||
}
|
}
|
||||||
|
@ -581,7 +580,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
|
||||||
}
|
}
|
||||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||||
dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
|
rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
|
||||||
|
@ -656,7 +655,7 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
|
||||||
|
|
||||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
return live;
|
return live;
|
||||||
}
|
}
|
||||||
|
@ -706,7 +705,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||||
live = sw->total_hw_samples_mixed;
|
live = sw->total_hw_samples_mixed;
|
||||||
if (audio_bug(__func__, live > hwsamples)) {
|
if (audio_bug(__func__, live > hwsamples)) {
|
||||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples);
|
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (live == hwsamples) {
|
if (live == hwsamples) {
|
||||||
|
@ -998,7 +997,7 @@ static size_t audio_get_avail (SWVoiceIn *sw)
|
||||||
if (audio_bug(__func__, live > sw->hw->conv_buf->size)) {
|
if (audio_bug(__func__, live > sw->hw->conv_buf->size)) {
|
||||||
dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live,
|
dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live,
|
||||||
sw->hw->conv_buf->size);
|
sw->hw->conv_buf->size);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
ldebug (
|
ldebug (
|
||||||
|
@ -1028,7 +1027,7 @@ static size_t audio_get_free(SWVoiceOut *sw)
|
||||||
if (audio_bug(__func__, live > sw->hw->mix_buf->size)) {
|
if (audio_bug(__func__, live > sw->hw->mix_buf->size)) {
|
||||||
dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live,
|
dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live,
|
||||||
sw->hw->mix_buf->size);
|
sw->hw->mix_buf->size);
|
||||||
return 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
dead = sw->hw->mix_buf->size - live;
|
dead = sw->hw->mix_buf->size - live;
|
||||||
|
@ -1170,7 +1169,7 @@ static void audio_run_out (AudioState *s)
|
||||||
|
|
||||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||||
continue;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hw->pending_disable && !nb_live) {
|
if (hw->pending_disable && !nb_live) {
|
||||||
|
@ -1203,7 +1202,7 @@ static void audio_run_out (AudioState *s)
|
||||||
if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) {
|
if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) {
|
||||||
dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n",
|
dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n",
|
||||||
hw->mix_buf->pos, hw->mix_buf->size, played);
|
hw->mix_buf->pos, hw->mix_buf->size, played);
|
||||||
hw->mix_buf->pos = 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_OUT
|
#ifdef DEBUG_OUT
|
||||||
|
@ -1223,7 +1222,7 @@ static void audio_run_out (AudioState *s)
|
||||||
if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) {
|
if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) {
|
||||||
dolog("played=%zu sw->total_hw_samples_mixed=%zu\n",
|
dolog("played=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||||
played, sw->total_hw_samples_mixed);
|
played, sw->total_hw_samples_mixed);
|
||||||
played = sw->total_hw_samples_mixed;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
sw->total_hw_samples_mixed -= played;
|
sw->total_hw_samples_mixed -= played;
|
||||||
|
@ -1346,7 +1345,7 @@ static void audio_run_capture (AudioState *s)
|
||||||
if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) {
|
if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) {
|
||||||
dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n",
|
dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||||
captured, sw->total_hw_samples_mixed);
|
captured, sw->total_hw_samples_mixed);
|
||||||
captured = sw->total_hw_samples_mixed;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
sw->total_hw_samples_mixed -= captured;
|
sw->total_hw_samples_mixed -= captured;
|
||||||
|
|
|
@ -59,12 +59,13 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
|
||||||
if (audio_bug(__func__, !voice_size && max_voices)) {
|
if (audio_bug(__func__, !voice_size && max_voices)) {
|
||||||
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
|
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
|
||||||
drv->name, max_voices);
|
drv->name, max_voices);
|
||||||
glue (s->nb_hw_voices_, TYPE) = 0;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_bug(__func__, voice_size && !max_voices)) {
|
if (audio_bug(__func__, voice_size && !max_voices)) {
|
||||||
dolog ("drv=`%s' voice_size=%d max_voices=0\n",
|
dolog ("drv=`%s' voice_size=%d max_voices=0\n",
|
||||||
drv->name, voice_size);
|
drv->name, voice_size);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +82,7 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
|
||||||
size_t samples = hw->samples;
|
size_t samples = hw->samples;
|
||||||
if (audio_bug(__func__, samples == 0)) {
|
if (audio_bug(__func__, samples == 0)) {
|
||||||
dolog("Attempted to allocate empty buffer\n");
|
dolog("Attempted to allocate empty buffer\n");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
|
HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
|
||||||
|
@ -252,12 +254,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||||
|
|
||||||
if (audio_bug(__func__, !drv)) {
|
if (audio_bug(__func__, !drv)) {
|
||||||
dolog ("No host audio driver\n");
|
dolog ("No host audio driver\n");
|
||||||
return NULL;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_bug(__func__, !drv->pcm_ops)) {
|
if (audio_bug(__func__, !drv->pcm_ops)) {
|
||||||
dolog ("Host audio driver without pcm_ops\n");
|
dolog ("Host audio driver without pcm_ops\n");
|
||||||
return NULL;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
hw = audio_calloc(__func__, 1, glue(drv->voice_size_, TYPE));
|
hw = audio_calloc(__func__, 1, glue(drv->voice_size_, TYPE));
|
||||||
|
@ -275,12 +277,13 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||||
QLIST_INIT (&hw->cap_head);
|
QLIST_INIT (&hw->cap_head);
|
||||||
#endif
|
#endif
|
||||||
if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
|
if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
|
||||||
goto err0;
|
g_free(hw);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_bug(__func__, hw->samples <= 0)) {
|
if (audio_bug(__func__, hw->samples <= 0)) {
|
||||||
dolog("hw->samples=%zd\n", hw->samples);
|
dolog("hw->samples=%zd\n", hw->samples);
|
||||||
goto err1;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hw->info.is_float) {
|
if (hw->info.is_float) {
|
||||||
|
@ -309,12 +312,6 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||||
audio_attach_capture (hw);
|
audio_attach_capture (hw);
|
||||||
#endif
|
#endif
|
||||||
return hw;
|
return hw;
|
||||||
|
|
||||||
err1:
|
|
||||||
glue (hw->pcm_ops->fini_, TYPE) (hw);
|
|
||||||
err0:
|
|
||||||
g_free (hw);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||||
|
@ -435,7 +432,7 @@ void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
|
||||||
if (sw) {
|
if (sw) {
|
||||||
if (audio_bug(__func__, !card)) {
|
if (audio_bug(__func__, !card)) {
|
||||||
dolog ("card=%p\n", card);
|
dolog ("card=%p\n", card);
|
||||||
return;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
glue (audio_close_, TYPE) (sw);
|
glue (audio_close_, TYPE) (sw);
|
||||||
|
@ -457,7 +454,7 @@ SW *glue (AUD_open_, TYPE) (
|
||||||
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
|
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
|
||||||
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
|
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
|
||||||
card, name, callback_fn, as);
|
card, name, callback_fn, as);
|
||||||
goto fail;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
s = card->state;
|
s = card->state;
|
||||||
|
@ -468,12 +465,12 @@ SW *glue (AUD_open_, TYPE) (
|
||||||
|
|
||||||
if (audio_bug(__func__, audio_validate_settings(as))) {
|
if (audio_bug(__func__, audio_validate_settings(as))) {
|
||||||
audio_print_settings (as);
|
audio_print_settings (as);
|
||||||
goto fail;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_bug(__func__, !s->drv)) {
|
if (audio_bug(__func__, !s->drv)) {
|
||||||
dolog ("Can not open `%s' (no host audio driver)\n", name);
|
dolog ("Can not open `%s' (no host audio driver)\n", name);
|
||||||
goto fail;
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sw && audio_pcm_info_eq (&sw->info, as)) {
|
if (sw && audio_pcm_info_eq (&sw->info, as)) {
|
||||||
|
|
|
@ -44,10 +44,15 @@ typedef struct coreaudioVoiceOut {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
} coreaudioVoiceOut;
|
} coreaudioVoiceOut;
|
||||||
|
|
||||||
|
#if !defined(MAC_OS_VERSION_12_0) \
|
||||||
|
|| (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0)
|
||||||
|
#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster
|
||||||
|
#endif
|
||||||
|
|
||||||
static const AudioObjectPropertyAddress voice_addr = {
|
static const AudioObjectPropertyAddress voice_addr = {
|
||||||
kAudioHardwarePropertyDefaultOutputDevice,
|
kAudioHardwarePropertyDefaultOutputDevice,
|
||||||
kAudioObjectPropertyScopeGlobal,
|
kAudioObjectPropertyScopeGlobal,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
static OSStatus coreaudio_get_voice(AudioDeviceID *id)
|
static OSStatus coreaudio_get_voice(AudioDeviceID *id)
|
||||||
|
@ -69,7 +74,7 @@ static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
|
||||||
AudioObjectPropertyAddress addr = {
|
AudioObjectPropertyAddress addr = {
|
||||||
kAudioDevicePropertyBufferFrameSizeRange,
|
kAudioDevicePropertyBufferFrameSizeRange,
|
||||||
kAudioDevicePropertyScopeOutput,
|
kAudioDevicePropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
return AudioObjectGetPropertyData(id,
|
return AudioObjectGetPropertyData(id,
|
||||||
|
@ -86,7 +91,7 @@ static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
|
||||||
AudioObjectPropertyAddress addr = {
|
AudioObjectPropertyAddress addr = {
|
||||||
kAudioDevicePropertyBufferFrameSize,
|
kAudioDevicePropertyBufferFrameSize,
|
||||||
kAudioDevicePropertyScopeOutput,
|
kAudioDevicePropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
return AudioObjectGetPropertyData(id,
|
return AudioObjectGetPropertyData(id,
|
||||||
|
@ -103,7 +108,7 @@ static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
|
||||||
AudioObjectPropertyAddress addr = {
|
AudioObjectPropertyAddress addr = {
|
||||||
kAudioDevicePropertyBufferFrameSize,
|
kAudioDevicePropertyBufferFrameSize,
|
||||||
kAudioDevicePropertyScopeOutput,
|
kAudioDevicePropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
return AudioObjectSetPropertyData(id,
|
return AudioObjectSetPropertyData(id,
|
||||||
|
@ -121,7 +126,7 @@ static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
|
||||||
AudioObjectPropertyAddress addr = {
|
AudioObjectPropertyAddress addr = {
|
||||||
kAudioDevicePropertyStreamFormat,
|
kAudioDevicePropertyStreamFormat,
|
||||||
kAudioDevicePropertyScopeOutput,
|
kAudioDevicePropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
return AudioObjectSetPropertyData(id,
|
return AudioObjectSetPropertyData(id,
|
||||||
|
@ -138,7 +143,7 @@ static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
|
||||||
AudioObjectPropertyAddress addr = {
|
AudioObjectPropertyAddress addr = {
|
||||||
kAudioDevicePropertyDeviceIsRunning,
|
kAudioDevicePropertyDeviceIsRunning,
|
||||||
kAudioDevicePropertyScopeOutput,
|
kAudioDevicePropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMain
|
||||||
};
|
};
|
||||||
|
|
||||||
return AudioObjectGetPropertyData(id,
|
return AudioObjectGetPropertyData(id,
|
||||||
|
@ -540,7 +545,6 @@ static OSStatus handle_voice_change(
|
||||||
const AudioObjectPropertyAddress *in_addresses,
|
const AudioObjectPropertyAddress *in_addresses,
|
||||||
void *in_client_data)
|
void *in_client_data)
|
||||||
{
|
{
|
||||||
OSStatus status;
|
|
||||||
coreaudioVoiceOut *core = in_client_data;
|
coreaudioVoiceOut *core = in_client_data;
|
||||||
|
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
|
@ -549,13 +553,12 @@ static OSStatus handle_voice_change(
|
||||||
fini_out_device(core);
|
fini_out_device(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = init_out_device(core);
|
if (!init_out_device(core)) {
|
||||||
if (!status) {
|
|
||||||
update_device_playback_state(core);
|
update_device_playback_state(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
return status;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
|
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
|
|
@ -7,7 +7,7 @@ softmmu_ss.add(files(
|
||||||
'wavcapture.c',
|
'wavcapture.c',
|
||||||
))
|
))
|
||||||
|
|
||||||
softmmu_ss.add(when: coreaudio, if_true: files('coreaudio.c'))
|
softmmu_ss.add(when: coreaudio, if_true: files('coreaudio.m'))
|
||||||
softmmu_ss.add(when: dsound, if_true: files('dsoundaudio.c', 'audio_win_int.c'))
|
softmmu_ss.add(when: dsound, if_true: files('dsoundaudio.c', 'audio_win_int.c'))
|
||||||
|
|
||||||
audio_modules = {}
|
audio_modules = {}
|
||||||
|
@ -28,7 +28,7 @@ endforeach
|
||||||
|
|
||||||
if dbus_display
|
if dbus_display
|
||||||
module_ss = ss.source_set()
|
module_ss = ss.source_set()
|
||||||
module_ss.add(when: gio, if_true: files('dbusaudio.c'))
|
module_ss.add(when: [gio, pixman, opengl, 'CONFIG_GIO'], if_true: files('dbusaudio.c'))
|
||||||
audio_modules += {'dbus': module_ss}
|
audio_modules += {'dbus': module_ss}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -3320,17 +3320,23 @@ BlockDriver bdrv_file = {
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
|
static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
|
||||||
CFIndex maxPathSize, int flags);
|
CFIndex maxPathSize, int flags);
|
||||||
|
|
||||||
|
#if !defined(MAC_OS_VERSION_12_0) \
|
||||||
|
|| (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0)
|
||||||
|
#define IOMainPort IOMasterPort
|
||||||
|
#endif
|
||||||
|
|
||||||
static char *FindEjectableOpticalMedia(io_iterator_t *mediaIterator)
|
static char *FindEjectableOpticalMedia(io_iterator_t *mediaIterator)
|
||||||
{
|
{
|
||||||
kern_return_t kernResult = KERN_FAILURE;
|
kern_return_t kernResult = KERN_FAILURE;
|
||||||
mach_port_t masterPort;
|
mach_port_t mainPort;
|
||||||
CFMutableDictionaryRef classesToMatch;
|
CFMutableDictionaryRef classesToMatch;
|
||||||
const char *matching_array[] = {kIODVDMediaClass, kIOCDMediaClass};
|
const char *matching_array[] = {kIODVDMediaClass, kIOCDMediaClass};
|
||||||
char *mediaType = NULL;
|
char *mediaType = NULL;
|
||||||
|
|
||||||
kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
|
kernResult = IOMainPort(MACH_PORT_NULL, &mainPort);
|
||||||
if ( KERN_SUCCESS != kernResult ) {
|
if ( KERN_SUCCESS != kernResult ) {
|
||||||
printf( "IOMasterPort returned %d\n", kernResult );
|
printf("IOMainPort returned %d\n", kernResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
@ -3343,7 +3349,7 @@ static char *FindEjectableOpticalMedia(io_iterator_t *mediaIterator)
|
||||||
}
|
}
|
||||||
CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
|
CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
|
||||||
kCFBooleanTrue);
|
kCFBooleanTrue);
|
||||||
kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch,
|
kernResult = IOServiceGetMatchingServices(mainPort, classesToMatch,
|
||||||
mediaIterator);
|
mediaIterator);
|
||||||
if (kernResult != KERN_SUCCESS) {
|
if (kernResult != KERN_SUCCESS) {
|
||||||
error_report("Note: IOServiceGetMatchingServices returned %d",
|
error_report("Note: IOServiceGetMatchingServices returned %d",
|
||||||
|
|
31
configure
vendored
31
configure
vendored
|
@ -77,6 +77,7 @@ TMPB="qemu-conf"
|
||||||
TMPC="${TMPDIR1}/${TMPB}.c"
|
TMPC="${TMPDIR1}/${TMPB}.c"
|
||||||
TMPO="${TMPDIR1}/${TMPB}.o"
|
TMPO="${TMPDIR1}/${TMPB}.o"
|
||||||
TMPCXX="${TMPDIR1}/${TMPB}.cxx"
|
TMPCXX="${TMPDIR1}/${TMPB}.cxx"
|
||||||
|
TMPM="${TMPDIR1}/${TMPB}.m"
|
||||||
TMPE="${TMPDIR1}/${TMPB}.exe"
|
TMPE="${TMPDIR1}/${TMPB}.exe"
|
||||||
|
|
||||||
rm -f config.log
|
rm -f config.log
|
||||||
|
@ -148,6 +149,10 @@ do_cxx() {
|
||||||
do_compiler "$cxx" $CPU_CFLAGS "$@"
|
do_compiler "$cxx" $CPU_CFLAGS "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_objc() {
|
||||||
|
do_compiler "$objcc" $CPU_CFLAGS "$@"
|
||||||
|
}
|
||||||
|
|
||||||
# Append $2 to the variable named $1, with space separation
|
# Append $2 to the variable named $1, with space separation
|
||||||
add_to() {
|
add_to() {
|
||||||
eval $1=\${$1:+\"\$$1 \"}\$2
|
eval $1=\${$1:+\"\$$1 \"}\$2
|
||||||
|
@ -285,6 +290,7 @@ done
|
||||||
|
|
||||||
EXTRA_CFLAGS=""
|
EXTRA_CFLAGS=""
|
||||||
EXTRA_CXXFLAGS=""
|
EXTRA_CXXFLAGS=""
|
||||||
|
EXTRA_OBJCFLAGS=""
|
||||||
EXTRA_LDFLAGS=""
|
EXTRA_LDFLAGS=""
|
||||||
|
|
||||||
xen_ctrl_version="$default_feature"
|
xen_ctrl_version="$default_feature"
|
||||||
|
@ -366,9 +372,12 @@ for opt do
|
||||||
--extra-cflags=*)
|
--extra-cflags=*)
|
||||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $optarg"
|
EXTRA_CFLAGS="$EXTRA_CFLAGS $optarg"
|
||||||
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
||||||
|
EXTRA_OBJCFLAGS="$EXTRA_OBJCFLAGS $optarg"
|
||||||
;;
|
;;
|
||||||
--extra-cxxflags=*) EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
--extra-cxxflags=*) EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $optarg"
|
||||||
;;
|
;;
|
||||||
|
--extra-objcflags=*) EXTRA_OBJCFLAGS="$EXTRA_OBJCFLAGS $optarg"
|
||||||
|
;;
|
||||||
--extra-ldflags=*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS $optarg"
|
--extra-ldflags=*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS $optarg"
|
||||||
;;
|
;;
|
||||||
--enable-debug-info) debug_info="yes"
|
--enable-debug-info) debug_info="yes"
|
||||||
|
@ -748,6 +757,8 @@ for opt do
|
||||||
;;
|
;;
|
||||||
--extra-cxxflags=*)
|
--extra-cxxflags=*)
|
||||||
;;
|
;;
|
||||||
|
--extra-objcflags=*)
|
||||||
|
;;
|
||||||
--extra-ldflags=*)
|
--extra-ldflags=*)
|
||||||
;;
|
;;
|
||||||
--enable-debug-info)
|
--enable-debug-info)
|
||||||
|
@ -1172,6 +1183,7 @@ Advanced options (experts only):
|
||||||
--objcc=OBJCC use Objective-C compiler OBJCC [$objcc]
|
--objcc=OBJCC use Objective-C compiler OBJCC [$objcc]
|
||||||
--extra-cflags=CFLAGS append extra C compiler flags CFLAGS
|
--extra-cflags=CFLAGS append extra C compiler flags CFLAGS
|
||||||
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags CXXFLAGS
|
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags CXXFLAGS
|
||||||
|
--extra-objcflags=OBJCFLAGS append extra Objective C compiler flags OBJCFLAGS
|
||||||
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
|
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
|
||||||
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
|
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
|
||||||
--cross-cc-cflags-ARCH= use compiler flags when building ARCH guest tests
|
--cross-cc-cflags-ARCH= use compiler flags when building ARCH guest tests
|
||||||
|
@ -1438,10 +1450,27 @@ cc_has_warning_flag() {
|
||||||
compile_prog "-Werror $optflag" ""
|
compile_prog "-Werror $optflag" ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
objcc_has_warning_flag() {
|
||||||
|
cat > $TMPM <<EOF
|
||||||
|
int main(void) { return 0; }
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Use the positive sense of the flag when testing for -Wno-wombat
|
||||||
|
# support (gcc will happily accept the -Wno- form of unknown
|
||||||
|
# warning options).
|
||||||
|
optflag="$(echo $1 | sed -e 's/^-Wno-/-W/')"
|
||||||
|
do_objc -Werror $optflag \
|
||||||
|
$OBJCFLAGS $EXTRA_OBJCFLAGS $CONFIGURE_OBJCFLAGS $QEMU_OBJCFLAGS \
|
||||||
|
-o $TMPE $TMPM $QEMU_LDFLAGS
|
||||||
|
}
|
||||||
|
|
||||||
for flag in $gcc_flags; do
|
for flag in $gcc_flags; do
|
||||||
if cc_has_warning_flag $flag ; then
|
if cc_has_warning_flag $flag ; then
|
||||||
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
|
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
|
||||||
fi
|
fi
|
||||||
|
if objcc_has_warning_flag $flag ; then
|
||||||
|
QEMU_OBJCFLAGS="$QEMU_OBJCFLAGS $flag"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if test "$stack_protector" != "no"; then
|
if test "$stack_protector" != "no"; then
|
||||||
|
@ -2983,6 +3012,7 @@ echo "LD=$ld" >> $config_host_mak
|
||||||
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
|
echo "CFLAGS_NOPIE=$CFLAGS_NOPIE" >> $config_host_mak
|
||||||
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
|
echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
|
||||||
echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
|
echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
|
||||||
|
echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
|
||||||
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
|
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
|
||||||
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
|
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
|
||||||
echo "GLIB_VERSION=$(pkg-config --modversion glib-2.0)" >> $config_host_mak
|
echo "GLIB_VERSION=$(pkg-config --modversion glib-2.0)" >> $config_host_mak
|
||||||
|
@ -3137,6 +3167,7 @@ if test "$skip_meson" = no; then
|
||||||
echo "[built-in options]" >> $cross
|
echo "[built-in options]" >> $cross
|
||||||
echo "c_args = [$(meson_quote $CFLAGS $EXTRA_CFLAGS)]" >> $cross
|
echo "c_args = [$(meson_quote $CFLAGS $EXTRA_CFLAGS)]" >> $cross
|
||||||
echo "cpp_args = [$(meson_quote $CXXFLAGS $EXTRA_CXXFLAGS)]" >> $cross
|
echo "cpp_args = [$(meson_quote $CXXFLAGS $EXTRA_CXXFLAGS)]" >> $cross
|
||||||
|
test -n "$objcc" && echo "objc_args = [$(meson_quote $OBJCFLAGS $EXTRA_OBJCFLAGS)]" >> $cross
|
||||||
echo "c_link_args = [$(meson_quote $CFLAGS $LDFLAGS $EXTRA_CFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
echo "c_link_args = [$(meson_quote $CFLAGS $LDFLAGS $EXTRA_CFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
||||||
echo "cpp_link_args = [$(meson_quote $CXXFLAGS $LDFLAGS $EXTRA_CXXFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
echo "cpp_link_args = [$(meson_quote $CXXFLAGS $LDFLAGS $EXTRA_CXXFLAGS $EXTRA_LDFLAGS)]" >> $cross
|
||||||
echo "[binaries]" >> $cross
|
echo "[binaries]" >> $cross
|
||||||
|
|
|
@ -624,19 +624,15 @@ size_t qemu_get_host_physmem(void);
|
||||||
* for the current thread.
|
* for the current thread.
|
||||||
*/
|
*/
|
||||||
#if defined(MAC_OS_VERSION_11_0) && \
|
#if defined(MAC_OS_VERSION_11_0) && \
|
||||||
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
|
MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
|
||||||
static inline void qemu_thread_jit_execute(void)
|
static inline void qemu_thread_jit_execute(void)
|
||||||
{
|
{
|
||||||
if (__builtin_available(macOS 11.0, *)) {
|
|
||||||
pthread_jit_write_protect_np(true);
|
pthread_jit_write_protect_np(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void qemu_thread_jit_write(void)
|
static inline void qemu_thread_jit_write(void)
|
||||||
{
|
{
|
||||||
if (__builtin_available(macOS 11.0, *)) {
|
|
||||||
pthread_jit_write_protect_np(false);
|
pthread_jit_write_protect_np(false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void qemu_thread_jit_write(void) {}
|
static inline void qemu_thread_jit_write(void) {}
|
||||||
|
|
17
meson.build
17
meson.build
|
@ -173,11 +173,13 @@ endif
|
||||||
|
|
||||||
qemu_cflags = config_host['QEMU_CFLAGS'].split()
|
qemu_cflags = config_host['QEMU_CFLAGS'].split()
|
||||||
qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
|
qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
|
||||||
|
qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
|
||||||
qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
|
qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
|
||||||
|
|
||||||
if get_option('gprof')
|
if get_option('gprof')
|
||||||
qemu_cflags += ['-p']
|
qemu_cflags += ['-p']
|
||||||
qemu_cxxflags += ['-p']
|
qemu_cxxflags += ['-p']
|
||||||
|
qemu_objcflags += ['-p']
|
||||||
qemu_ldflags += ['-p']
|
qemu_ldflags += ['-p']
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -216,8 +218,9 @@ if get_option('fuzzing')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
add_global_arguments(qemu_cflags, native: false, language: ['c', 'objc'])
|
add_global_arguments(qemu_cflags, native: false, language: ['c'])
|
||||||
add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
|
add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
|
||||||
|
add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
|
||||||
add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
|
add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
|
||||||
|
|
||||||
if targetos == 'linux'
|
if targetos == 'linux'
|
||||||
|
@ -3076,6 +3079,10 @@ common_all = static_library('common',
|
||||||
|
|
||||||
feature_to_c = find_program('scripts/feature_to_c.sh')
|
feature_to_c = find_program('scripts/feature_to_c.sh')
|
||||||
|
|
||||||
|
if targetos == 'darwin'
|
||||||
|
entitlement = find_program('scripts/entitlement.sh')
|
||||||
|
endif
|
||||||
|
|
||||||
emulators = {}
|
emulators = {}
|
||||||
foreach target : target_dirs
|
foreach target : target_dirs
|
||||||
config_target = config_target_mak[target]
|
config_target = config_target_mak[target]
|
||||||
|
@ -3233,7 +3240,6 @@ foreach target : target_dirs
|
||||||
install_input += meson.current_source_dir() / entitlements
|
install_input += meson.current_source_dir() / entitlements
|
||||||
endif
|
endif
|
||||||
|
|
||||||
entitlement = find_program('scripts/entitlement.sh')
|
|
||||||
emulators += {exe['name'] : custom_target(exe['name'],
|
emulators += {exe['name'] : custom_target(exe['name'],
|
||||||
input: build_input,
|
input: build_input,
|
||||||
output: exe['name'],
|
output: exe['name'],
|
||||||
|
@ -3470,11 +3476,18 @@ if link_language == 'cpp'
|
||||||
+ ['-O' + get_option('optimization')]
|
+ ['-O' + get_option('optimization')]
|
||||||
+ (get_option('debug') ? ['-g'] : []))}
|
+ (get_option('debug') ? ['-g'] : []))}
|
||||||
endif
|
endif
|
||||||
|
if targetos == 'darwin'
|
||||||
|
summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
|
||||||
|
+ ['-O' + get_option('optimization')]
|
||||||
|
+ (get_option('debug') ? ['-g'] : []))}
|
||||||
|
endif
|
||||||
link_args = get_option(link_language + '_link_args')
|
link_args = get_option(link_language + '_link_args')
|
||||||
if link_args.length() > 0
|
if link_args.length() > 0
|
||||||
summary_info += {'LDFLAGS': ' '.join(link_args)}
|
summary_info += {'LDFLAGS': ' '.join(link_args)}
|
||||||
endif
|
endif
|
||||||
summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
|
summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
|
||||||
|
summary_info += {'QEMU_CXXFLAGS': config_host['QEMU_CXXFLAGS']}
|
||||||
|
summary_info += {'QEMU_OBJCFLAGS': config_host['QEMU_OBJCFLAGS']}
|
||||||
summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
|
summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
|
||||||
summary_info += {'profiler': get_option('profiler')}
|
summary_info += {'profiler': get_option('profiler')}
|
||||||
summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
|
summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
|
||||||
|
|
29
qapi/ui.json
29
qapi/ui.json
|
@ -1260,6 +1260,34 @@
|
||||||
{ 'struct' : 'DisplayCurses',
|
{ 'struct' : 'DisplayCurses',
|
||||||
'data' : { '*charset' : 'str' } }
|
'data' : { '*charset' : 'str' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @DisplayCocoa:
|
||||||
|
#
|
||||||
|
# Cocoa display options.
|
||||||
|
#
|
||||||
|
# @left-command-key: Enable/disable forwarding of left command key to
|
||||||
|
# guest. Allows command-tab window switching on the
|
||||||
|
# host without sending this key to the guest when
|
||||||
|
# "off". Defaults to "on"
|
||||||
|
#
|
||||||
|
# @full-grab: Capture all key presses, including system combos. This
|
||||||
|
# requires accessibility permissions, since it performs
|
||||||
|
# a global grab on key events. (default: off)
|
||||||
|
# See https://support.apple.com/en-in/guide/mac-help/mh32356/mac
|
||||||
|
#
|
||||||
|
# @swap-opt-cmd: Swap the Option and Command keys so that their key codes match
|
||||||
|
# their position on non-Mac keyboards and you can use Meta/Super
|
||||||
|
# and Alt where you expect them. (default: off)
|
||||||
|
#
|
||||||
|
# Since: 7.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'DisplayCocoa',
|
||||||
|
'data': {
|
||||||
|
'*left-command-key': 'bool',
|
||||||
|
'*full-grab': 'bool',
|
||||||
|
'*swap-opt-cmd': 'bool'
|
||||||
|
} }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @DisplayType:
|
# @DisplayType:
|
||||||
#
|
#
|
||||||
|
@ -1338,6 +1366,7 @@
|
||||||
'discriminator' : 'type',
|
'discriminator' : 'type',
|
||||||
'data' : {
|
'data' : {
|
||||||
'gtk': { 'type': 'DisplayGTK', 'if': 'CONFIG_GTK' },
|
'gtk': { 'type': 'DisplayGTK', 'if': 'CONFIG_GTK' },
|
||||||
|
'cocoa': { 'type': 'DisplayCocoa', 'if': 'CONFIG_COCOA' },
|
||||||
'curses': { 'type': 'DisplayCurses', 'if': 'CONFIG_CURSES' },
|
'curses': { 'type': 'DisplayCurses', 'if': 'CONFIG_CURSES' },
|
||||||
'egl-headless': { 'type': 'DisplayEGLHeadless',
|
'egl-headless': { 'type': 'DisplayEGLHeadless',
|
||||||
'if': { 'all': ['CONFIG_OPENGL', 'CONFIG_GBM'] } },
|
'if': { 'all': ['CONFIG_OPENGL', 'CONFIG_GBM'] } },
|
||||||
|
|
|
@ -1916,12 +1916,18 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
|
||||||
#if defined(CONFIG_CURSES)
|
#if defined(CONFIG_CURSES)
|
||||||
"-display curses[,charset=<encoding>]\n"
|
"-display curses[,charset=<encoding>]\n"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_COCOA)
|
||||||
|
"-display cocoa[,full-grab=on|off][,swap-opt-cmd=on|off]\n"
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_OPENGL)
|
#if defined(CONFIG_OPENGL)
|
||||||
"-display egl-headless[,rendernode=<file>]\n"
|
"-display egl-headless[,rendernode=<file>]\n"
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_DBUS_DISPLAY)
|
#if defined(CONFIG_DBUS_DISPLAY)
|
||||||
"-display dbus[,addr=<dbusaddr>]\n"
|
"-display dbus[,addr=<dbusaddr>]\n"
|
||||||
" [,gl=on|core|es|off][,rendernode=<file>]\n"
|
" [,gl=on|core|es|off][,rendernode=<file>]\n"
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_COCOA)
|
||||||
|
"-display cocoa[,show-cursor=on|off][,left-command-key=on|off]\n"
|
||||||
#endif
|
#endif
|
||||||
"-display none\n"
|
"-display none\n"
|
||||||
" select display backend type\n"
|
" select display backend type\n"
|
||||||
|
@ -2009,6 +2015,15 @@ SRST
|
||||||
``charset=CP850`` for IBM CP850 encoding. The default is
|
``charset=CP850`` for IBM CP850 encoding. The default is
|
||||||
``CP437``.
|
``CP437``.
|
||||||
|
|
||||||
|
``cocoa``
|
||||||
|
Display video output in a Cocoa window. Mac only. This interface
|
||||||
|
provides drop-down menus and other UI elements to configure and
|
||||||
|
control the VM during runtime. Valid parameters are:
|
||||||
|
|
||||||
|
``show-cursor=on|off`` : Force showing the mouse cursor
|
||||||
|
|
||||||
|
``left-command-key=on|off`` : Disable forwarding left command key to host
|
||||||
|
|
||||||
``egl-headless[,rendernode=<file>]``
|
``egl-headless[,rendernode=<file>]``
|
||||||
Offload all OpenGL operations to a local DRI device. For any
|
Offload all OpenGL operations to a local DRI device. For any
|
||||||
graphical display, this display needs to be paired with either
|
graphical display, this display needs to be paired with either
|
||||||
|
|
|
@ -124,10 +124,11 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
|
||||||
uint64_t efer = rvmcs(vcpu, VMCS_GUEST_IA32_EFER);
|
uint64_t efer = rvmcs(vcpu, VMCS_GUEST_IA32_EFER);
|
||||||
uint64_t old_cr0 = rvmcs(vcpu, VMCS_GUEST_CR0);
|
uint64_t old_cr0 = rvmcs(vcpu, VMCS_GUEST_CR0);
|
||||||
uint64_t changed_cr0 = old_cr0 ^ cr0;
|
uint64_t changed_cr0 = old_cr0 ^ cr0;
|
||||||
uint64_t mask = CR0_PG | CR0_CD | CR0_NW | CR0_NE | CR0_ET;
|
uint64_t mask = CR0_PG_MASK | CR0_CD_MASK | CR0_NW_MASK |
|
||||||
|
CR0_NE_MASK | CR0_ET_MASK;
|
||||||
uint64_t entry_ctls;
|
uint64_t entry_ctls;
|
||||||
|
|
||||||
if ((cr0 & CR0_PG) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE) &&
|
if ((cr0 & CR0_PG_MASK) && (rvmcs(vcpu, VMCS_GUEST_CR4) & CR4_PAE_MASK) &&
|
||||||
!(efer & MSR_EFER_LME)) {
|
!(efer & MSR_EFER_LME)) {
|
||||||
address_space_read(&address_space_memory,
|
address_space_read(&address_space_memory,
|
||||||
rvmcs(vcpu, VMCS_GUEST_CR3) & ~0x1f,
|
rvmcs(vcpu, VMCS_GUEST_CR3) & ~0x1f,
|
||||||
|
@ -142,8 +143,8 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
|
||||||
wvmcs(vcpu, VMCS_CR0_SHADOW, cr0);
|
wvmcs(vcpu, VMCS_CR0_SHADOW, cr0);
|
||||||
|
|
||||||
if (efer & MSR_EFER_LME) {
|
if (efer & MSR_EFER_LME) {
|
||||||
if (changed_cr0 & CR0_PG) {
|
if (changed_cr0 & CR0_PG_MASK) {
|
||||||
if (cr0 & CR0_PG) {
|
if (cr0 & CR0_PG_MASK) {
|
||||||
enter_long_mode(vcpu, cr0, efer);
|
enter_long_mode(vcpu, cr0, efer);
|
||||||
} else {
|
} else {
|
||||||
exit_long_mode(vcpu, cr0, efer);
|
exit_long_mode(vcpu, cr0, efer);
|
||||||
|
@ -155,23 +156,21 @@ static inline void macvm_set_cr0(hv_vcpuid_t vcpu, uint64_t cr0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter new CR0 after we are finished examining it above. */
|
/* Filter new CR0 after we are finished examining it above. */
|
||||||
cr0 = (cr0 & ~(mask & ~CR0_PG));
|
cr0 = (cr0 & ~(mask & ~CR0_PG_MASK));
|
||||||
wvmcs(vcpu, VMCS_GUEST_CR0, cr0 | CR0_NE | CR0_ET);
|
wvmcs(vcpu, VMCS_GUEST_CR0, cr0 | CR0_NE_MASK | CR0_ET_MASK);
|
||||||
|
|
||||||
hv_vcpu_invalidate_tlb(vcpu);
|
hv_vcpu_invalidate_tlb(vcpu);
|
||||||
hv_vcpu_flush(vcpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)
|
static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)
|
||||||
{
|
{
|
||||||
uint64_t guest_cr4 = cr4 | CR4_VMXE;
|
uint64_t guest_cr4 = cr4 | CR4_VMXE_MASK;
|
||||||
|
|
||||||
wvmcs(vcpu, VMCS_GUEST_CR4, guest_cr4);
|
wvmcs(vcpu, VMCS_GUEST_CR4, guest_cr4);
|
||||||
wvmcs(vcpu, VMCS_CR4_SHADOW, cr4);
|
wvmcs(vcpu, VMCS_CR4_SHADOW, cr4);
|
||||||
wvmcs(vcpu, VMCS_CR4_MASK, CR4_VMXE);
|
wvmcs(vcpu, VMCS_CR4_MASK, CR4_VMXE_MASK);
|
||||||
|
|
||||||
hv_vcpu_invalidate_tlb(vcpu);
|
hv_vcpu_invalidate_tlb(vcpu);
|
||||||
hv_vcpu_flush(vcpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
|
static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
|
||||||
|
|
|
@ -119,7 +119,7 @@ bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
|
||||||
bool x86_is_protected(struct CPUState *cpu)
|
bool x86_is_protected(struct CPUState *cpu)
|
||||||
{
|
{
|
||||||
uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
||||||
return cr0 & CR0_PE;
|
return cr0 & CR0_PE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool x86_is_real(struct CPUState *cpu)
|
bool x86_is_real(struct CPUState *cpu)
|
||||||
|
@ -150,13 +150,13 @@ bool x86_is_long64_mode(struct CPUState *cpu)
|
||||||
bool x86_is_paging_mode(struct CPUState *cpu)
|
bool x86_is_paging_mode(struct CPUState *cpu)
|
||||||
{
|
{
|
||||||
uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
||||||
return cr0 & CR0_PG;
|
return cr0 & CR0_PG_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool x86_is_pae_enabled(struct CPUState *cpu)
|
bool x86_is_pae_enabled(struct CPUState *cpu)
|
||||||
{
|
{
|
||||||
uint64_t cr4 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
|
uint64_t cr4 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
|
||||||
return cr4 & CR4_PAE;
|
return cr4 & CR4_PAE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong linear_addr(struct CPUState *cpu, target_ulong addr, X86Seg seg)
|
target_ulong linear_addr(struct CPUState *cpu, target_ulong addr, X86Seg seg)
|
||||||
|
|
|
@ -42,40 +42,6 @@ typedef struct x86_register {
|
||||||
};
|
};
|
||||||
} __attribute__ ((__packed__)) x86_register;
|
} __attribute__ ((__packed__)) x86_register;
|
||||||
|
|
||||||
typedef enum x86_reg_cr0 {
|
|
||||||
CR0_PE = (1L << 0),
|
|
||||||
CR0_MP = (1L << 1),
|
|
||||||
CR0_EM = (1L << 2),
|
|
||||||
CR0_TS = (1L << 3),
|
|
||||||
CR0_ET = (1L << 4),
|
|
||||||
CR0_NE = (1L << 5),
|
|
||||||
CR0_WP = (1L << 16),
|
|
||||||
CR0_AM = (1L << 18),
|
|
||||||
CR0_NW = (1L << 29),
|
|
||||||
CR0_CD = (1L << 30),
|
|
||||||
CR0_PG = (1L << 31),
|
|
||||||
} x86_reg_cr0;
|
|
||||||
|
|
||||||
typedef enum x86_reg_cr4 {
|
|
||||||
CR4_VME = (1L << 0),
|
|
||||||
CR4_PVI = (1L << 1),
|
|
||||||
CR4_TSD = (1L << 2),
|
|
||||||
CR4_DE = (1L << 3),
|
|
||||||
CR4_PSE = (1L << 4),
|
|
||||||
CR4_PAE = (1L << 5),
|
|
||||||
CR4_MSE = (1L << 6),
|
|
||||||
CR4_PGE = (1L << 7),
|
|
||||||
CR4_PCE = (1L << 8),
|
|
||||||
CR4_OSFXSR = (1L << 9),
|
|
||||||
CR4_OSXMMEXCPT = (1L << 10),
|
|
||||||
CR4_VMXE = (1L << 13),
|
|
||||||
CR4_SMXE = (1L << 14),
|
|
||||||
CR4_FSGSBASE = (1L << 16),
|
|
||||||
CR4_PCIDE = (1L << 17),
|
|
||||||
CR4_OSXSAVE = (1L << 18),
|
|
||||||
CR4_SMEP = (1L << 20),
|
|
||||||
} x86_reg_cr4;
|
|
||||||
|
|
||||||
/* 16 bit Task State Segment */
|
/* 16 bit Task State Segment */
|
||||||
typedef struct x86_tss_segment16 {
|
typedef struct x86_tss_segment16 {
|
||||||
uint16_t link;
|
uint16_t link;
|
||||||
|
|
|
@ -129,7 +129,7 @@ static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
|
||||||
|
|
||||||
uint32_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
uint32_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
|
||||||
/* check protection */
|
/* check protection */
|
||||||
if (cr0 & CR0_WP) {
|
if (cr0 & CR0_WP_MASK) {
|
||||||
if (pt->write_access && !pte_write_access(pte)) {
|
if (pt->write_access && !pte_write_access(pte)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,12 +174,12 @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea
|
||||||
//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
|
//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
|
||||||
VM_PANIC("task_switch_16");
|
VM_PANIC("task_switch_16");
|
||||||
|
|
||||||
macvm_set_cr0(cpu->hvf->fd, rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0) | CR0_TS);
|
macvm_set_cr0(cpu->hvf->fd, rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0) |
|
||||||
|
CR0_TS_MASK);
|
||||||
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
|
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
|
||||||
vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);
|
vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);
|
||||||
|
|
||||||
store_regs(cpu);
|
store_regs(cpu);
|
||||||
|
|
||||||
hv_vcpu_invalidate_tlb(cpu->hvf->fd);
|
hv_vcpu_invalidate_tlb(cpu->hvf->fd);
|
||||||
hv_vcpu_flush(cpu->hvf->fd);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ void hvf_put_xsave(CPUState *cpu_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hvf_put_segments(CPUState *cpu_state)
|
static void hvf_put_segments(CPUState *cpu_state)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &X86_CPU(cpu_state)->env;
|
CPUX86State *env = &X86_CPU(cpu_state)->env;
|
||||||
struct vmx_segment seg;
|
struct vmx_segment seg;
|
||||||
|
@ -125,8 +125,6 @@ void hvf_put_segments(CPUState *cpu_state)
|
||||||
|
|
||||||
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
|
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
|
||||||
vmx_write_segment_descriptor(cpu_state, &seg, R_LDTR);
|
vmx_write_segment_descriptor(cpu_state, &seg, R_LDTR);
|
||||||
|
|
||||||
hv_vcpu_flush(cpu_state->hvf->fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hvf_put_msrs(CPUState *cpu_state)
|
void hvf_put_msrs(CPUState *cpu_state)
|
||||||
|
@ -166,7 +164,7 @@ void hvf_get_xsave(CPUState *cpu_state)
|
||||||
x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hvf_get_segments(CPUState *cpu_state)
|
static void hvf_get_segments(CPUState *cpu_state)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &X86_CPU(cpu_state)->env;
|
CPUX86State *env = &X86_CPU(cpu_state)->env;
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,9 @@ void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
|
||||||
SegmentCache *qseg, bool is_tr);
|
SegmentCache *qseg, bool is_tr);
|
||||||
void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg);
|
void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg);
|
||||||
void hvf_put_xsave(CPUState *cpu_state);
|
void hvf_put_xsave(CPUState *cpu_state);
|
||||||
void hvf_put_segments(CPUState *cpu_state);
|
|
||||||
void hvf_put_msrs(CPUState *cpu_state);
|
void hvf_put_msrs(CPUState *cpu_state);
|
||||||
void hvf_get_xsave(CPUState *cpu_state);
|
void hvf_get_xsave(CPUState *cpu_state);
|
||||||
void hvf_get_msrs(CPUState *cpu_state);
|
void hvf_get_msrs(CPUState *cpu_state);
|
||||||
void vmx_clear_int_window_exiting(CPUState *cpu);
|
void vmx_clear_int_window_exiting(CPUState *cpu);
|
||||||
void hvf_get_segments(CPUState *cpu_state);
|
|
||||||
void vmx_update_tpr(CPUState *cpu);
|
void vmx_update_tpr(CPUState *cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,11 @@ tfcflags = [
|
||||||
'-Wno-error',
|
'-Wno-error',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if cc.get_id() == 'clang'
|
||||||
|
# Clang does not support '#pragma STDC FENV_ACCESS'
|
||||||
|
tfcflags += [ '-Wno-ignored-pragmas' ]
|
||||||
|
endif
|
||||||
|
|
||||||
tfgencases = [
|
tfgencases = [
|
||||||
tfdir / 'genCases_ui32.c',
|
tfdir / 'genCases_ui32.c',
|
||||||
tfdir / 'genCases_ui64.c',
|
tfdir / 'genCases_ui64.c',
|
||||||
|
|
106
ui/cocoa.m
106
ui/cocoa.m
|
@ -95,6 +95,8 @@ static DisplayChangeListener dcl = {
|
||||||
};
|
};
|
||||||
static int last_buttons;
|
static int last_buttons;
|
||||||
static int cursor_hide = 1;
|
static int cursor_hide = 1;
|
||||||
|
static int left_command_key_enabled = 1;
|
||||||
|
static bool swap_opt_cmd;
|
||||||
|
|
||||||
static int gArgc;
|
static int gArgc;
|
||||||
static char **gArgv;
|
static char **gArgv;
|
||||||
|
@ -308,11 +310,13 @@ static void handleAnyDeviceErrors(Error * err)
|
||||||
BOOL isMouseGrabbed;
|
BOOL isMouseGrabbed;
|
||||||
BOOL isFullscreen;
|
BOOL isFullscreen;
|
||||||
BOOL isAbsoluteEnabled;
|
BOOL isAbsoluteEnabled;
|
||||||
|
CFMachPortRef eventsTap;
|
||||||
}
|
}
|
||||||
- (void) switchSurface:(pixman_image_t *)image;
|
- (void) switchSurface:(pixman_image_t *)image;
|
||||||
- (void) grabMouse;
|
- (void) grabMouse;
|
||||||
- (void) ungrabMouse;
|
- (void) ungrabMouse;
|
||||||
- (void) toggleFullScreen:(id)sender;
|
- (void) toggleFullScreen:(id)sender;
|
||||||
|
- (void) setFullGrab:(id)sender;
|
||||||
- (void) handleMonitorInput:(NSEvent *)event;
|
- (void) handleMonitorInput:(NSEvent *)event;
|
||||||
- (bool) handleEvent:(NSEvent *)event;
|
- (bool) handleEvent:(NSEvent *)event;
|
||||||
- (bool) handleEventLocked:(NSEvent *)event;
|
- (bool) handleEventLocked:(NSEvent *)event;
|
||||||
|
@ -335,6 +339,19 @@ static void handleAnyDeviceErrors(Error * err)
|
||||||
|
|
||||||
QemuCocoaView *cocoaView;
|
QemuCocoaView *cocoaView;
|
||||||
|
|
||||||
|
static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEventRef cgEvent, void *userInfo)
|
||||||
|
{
|
||||||
|
QemuCocoaView *cocoaView = userInfo;
|
||||||
|
NSEvent *event = [NSEvent eventWithCGEvent:cgEvent];
|
||||||
|
if ([cocoaView isMouseGrabbed] && [cocoaView handleEvent:event]) {
|
||||||
|
COCOA_DEBUG("Global events tap: qemu handled the event, capturing!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
COCOA_DEBUG("Global events tap: qemu did not handle the event, letting it through...\n");
|
||||||
|
|
||||||
|
return cgEvent;
|
||||||
|
}
|
||||||
|
|
||||||
@implementation QemuCocoaView
|
@implementation QemuCocoaView
|
||||||
- (id)initWithFrame:(NSRect)frameRect
|
- (id)initWithFrame:(NSRect)frameRect
|
||||||
{
|
{
|
||||||
|
@ -360,6 +377,11 @@ QemuCocoaView *cocoaView;
|
||||||
}
|
}
|
||||||
|
|
||||||
qkbd_state_free(kbd);
|
qkbd_state_free(kbd);
|
||||||
|
|
||||||
|
if (eventsTap) {
|
||||||
|
CFRelease(eventsTap);
|
||||||
|
}
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,6 +676,36 @@ QemuCocoaView *cocoaView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setFullGrab:(id)sender
|
||||||
|
{
|
||||||
|
COCOA_DEBUG("QemuCocoaView: setFullGrab\n");
|
||||||
|
|
||||||
|
CGEventMask mask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged);
|
||||||
|
eventsTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
|
||||||
|
mask, handleTapEvent, self);
|
||||||
|
if (!eventsTap) {
|
||||||
|
warn_report("Could not create event tap, system key combos will not be captured.\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
COCOA_DEBUG("Global events tap created! Will capture system key combos.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
|
||||||
|
if (!runLoop) {
|
||||||
|
warn_report("Could not obtain current CF RunLoop, system key combos will not be captured.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRunLoopSourceRef tapEventsSrc = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventsTap, 0);
|
||||||
|
if (!tapEventsSrc ) {
|
||||||
|
warn_report("Could not obtain current CF RunLoop, system key combos will not be captured.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRunLoopAddSource(runLoop, tapEventsSrc, kCFRunLoopDefaultMode);
|
||||||
|
CFRelease(tapEventsSrc);
|
||||||
|
}
|
||||||
|
|
||||||
- (void) toggleKey: (int)keycode {
|
- (void) toggleKey: (int)keycode {
|
||||||
qkbd_state_key_event(kbd, keycode, !qkbd_state_key_get(kbd, keycode));
|
qkbd_state_key_event(kbd, keycode, !qkbd_state_key_get(kbd, keycode));
|
||||||
}
|
}
|
||||||
|
@ -671,7 +723,7 @@ QemuCocoaView *cocoaView;
|
||||||
|
|
||||||
/* translates Macintosh keycodes to QEMU's keysym */
|
/* translates Macintosh keycodes to QEMU's keysym */
|
||||||
|
|
||||||
int without_control_translation[] = {
|
static const int without_control_translation[] = {
|
||||||
[0 ... 0xff] = 0, // invalid key
|
[0 ... 0xff] = 0, // invalid key
|
||||||
|
|
||||||
[kVK_UpArrow] = QEMU_KEY_UP,
|
[kVK_UpArrow] = QEMU_KEY_UP,
|
||||||
|
@ -686,7 +738,7 @@ QemuCocoaView *cocoaView;
|
||||||
[kVK_Delete] = QEMU_KEY_BACKSPACE,
|
[kVK_Delete] = QEMU_KEY_BACKSPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
int with_control_translation[] = {
|
static const int with_control_translation[] = {
|
||||||
[0 ... 0xff] = 0, // invalid key
|
[0 ... 0xff] = 0, // invalid key
|
||||||
|
|
||||||
[kVK_UpArrow] = QEMU_KEY_CTRL_UP,
|
[kVK_UpArrow] = QEMU_KEY_CTRL_UP,
|
||||||
|
@ -803,13 +855,23 @@ QemuCocoaView *cocoaView;
|
||||||
qkbd_state_key_event(kbd, Q_KEY_CODE_CTRL_R, false);
|
qkbd_state_key_event(kbd, Q_KEY_CODE_CTRL_R, false);
|
||||||
}
|
}
|
||||||
if (!(modifiers & NSEventModifierFlagOption)) {
|
if (!(modifiers & NSEventModifierFlagOption)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false);
|
||||||
|
qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false);
|
||||||
|
} else {
|
||||||
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false);
|
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false);
|
||||||
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false);
|
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(modifiers & NSEventModifierFlagCommand)) {
|
if (!(modifiers & NSEventModifierFlagCommand)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT, false);
|
||||||
|
qkbd_state_key_event(kbd, Q_KEY_CODE_ALT_R, false);
|
||||||
|
} else {
|
||||||
qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false);
|
qkbd_state_key_event(kbd, Q_KEY_CODE_META_L, false);
|
||||||
qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false);
|
qkbd_state_key_event(kbd, Q_KEY_CODE_META_R, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch ([event type]) {
|
switch ([event type]) {
|
||||||
case NSEventTypeFlagsChanged:
|
case NSEventTypeFlagsChanged:
|
||||||
|
@ -840,29 +902,45 @@ QemuCocoaView *cocoaView;
|
||||||
|
|
||||||
case kVK_Option:
|
case kVK_Option:
|
||||||
if (!!(modifiers & NSEventModifierFlagOption)) {
|
if (!!(modifiers & NSEventModifierFlagOption)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
[self toggleKey:Q_KEY_CODE_META_L];
|
||||||
|
} else {
|
||||||
[self toggleKey:Q_KEY_CODE_ALT];
|
[self toggleKey:Q_KEY_CODE_ALT];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kVK_RightOption:
|
case kVK_RightOption:
|
||||||
if (!!(modifiers & NSEventModifierFlagOption)) {
|
if (!!(modifiers & NSEventModifierFlagOption)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
[self toggleKey:Q_KEY_CODE_META_R];
|
||||||
|
} else {
|
||||||
[self toggleKey:Q_KEY_CODE_ALT_R];
|
[self toggleKey:Q_KEY_CODE_ALT_R];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Don't pass command key changes to guest unless mouse is grabbed */
|
/* Don't pass command key changes to guest unless mouse is grabbed */
|
||||||
case kVK_Command:
|
case kVK_Command:
|
||||||
if (isMouseGrabbed &&
|
if (isMouseGrabbed &&
|
||||||
!!(modifiers & NSEventModifierFlagCommand)) {
|
!!(modifiers & NSEventModifierFlagCommand)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
[self toggleKey:Q_KEY_CODE_ALT];
|
||||||
|
} else {
|
||||||
[self toggleKey:Q_KEY_CODE_META_L];
|
[self toggleKey:Q_KEY_CODE_META_L];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kVK_RightCommand:
|
case kVK_RightCommand:
|
||||||
if (isMouseGrabbed &&
|
if (isMouseGrabbed &&
|
||||||
!!(modifiers & NSEventModifierFlagCommand)) {
|
!!(modifiers & NSEventModifierFlagCommand)) {
|
||||||
|
if (swap_opt_cmd) {
|
||||||
|
[self toggleKey:Q_KEY_CODE_ALT_R];
|
||||||
|
} else {
|
||||||
[self toggleKey:Q_KEY_CODE_META_R];
|
[self toggleKey:Q_KEY_CODE_META_R];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1259,6 +1337,7 @@ QemuCocoaView *cocoaView;
|
||||||
- (void) applicationWillResignActive: (NSNotification *)aNotification
|
- (void) applicationWillResignActive: (NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
|
COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
|
||||||
|
[cocoaView ungrabMouse];
|
||||||
[cocoaView raiseAllKeys];
|
[cocoaView raiseAllKeys];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1278,6 +1357,13 @@ QemuCocoaView *cocoaView;
|
||||||
[cocoaView toggleFullScreen:sender];
|
[cocoaView toggleFullScreen:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setFullGrab:(id)sender
|
||||||
|
{
|
||||||
|
COCOA_DEBUG("QemuCocoaAppController: setFullGrab\n");
|
||||||
|
|
||||||
|
[cocoaView setFullGrab:sender];
|
||||||
|
}
|
||||||
|
|
||||||
/* Tries to find then open the specified filename */
|
/* Tries to find then open the specified filename */
|
||||||
- (void) openDocumentation: (NSString *) filename
|
- (void) openDocumentation: (NSString *) filename
|
||||||
{
|
{
|
||||||
|
@ -1991,16 +2077,30 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
|
||||||
qemu_sem_wait(&app_started_sem);
|
qemu_sem_wait(&app_started_sem);
|
||||||
COCOA_DEBUG("cocoa_display_init: app start completed\n");
|
COCOA_DEBUG("cocoa_display_init: app start completed\n");
|
||||||
|
|
||||||
|
QemuCocoaAppController *controller = (QemuCocoaAppController *)[[NSApplication sharedApplication] delegate];
|
||||||
/* if fullscreen mode is to be used */
|
/* if fullscreen mode is to be used */
|
||||||
if (opts->has_full_screen && opts->full_screen) {
|
if (opts->has_full_screen && opts->full_screen) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[NSApp activateIgnoringOtherApps: YES];
|
[NSApp activateIgnoringOtherApps: YES];
|
||||||
[(QemuCocoaAppController *)[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
|
[controller toggleFullScreen: nil];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (opts->u.cocoa.has_full_grab && opts->u.cocoa.full_grab) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[controller setFullGrab: nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->has_show_cursor && opts->show_cursor) {
|
if (opts->has_show_cursor && opts->show_cursor) {
|
||||||
cursor_hide = 0;
|
cursor_hide = 0;
|
||||||
}
|
}
|
||||||
|
if (opts->u.cocoa.has_swap_opt_cmd) {
|
||||||
|
swap_opt_cmd = opts->u.cocoa.swap_opt_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts->u.cocoa.has_left_command_key && !opts->u.cocoa.left_command_key) {
|
||||||
|
left_command_key_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// register vga output callbacks
|
// register vga output callbacks
|
||||||
register_displaychangelistener(&dcl);
|
register_displaychangelistener(&dcl);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue