From patchwork Thu Feb 14 10:28:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041980 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="xqr5oQ/6"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Xqn49jYz9sMr for ; Thu, 14 Feb 2019 21:36:20 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45802 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guENM-0002L9-4K for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:36:16 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46110) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEML-000297-HI for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEFw-0003ya-Ow for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:38 -0500 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:39242) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEFs-0003lG-Vk for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:35 -0500 Received: by mail-wr1-x442.google.com with SMTP id l5so4766616wrw.6 for ; Thu, 14 Feb 2019 02:28:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xgyqIteJDA8A8gslVlpPNbSOD5Z2HmWyq3Wfr3J3rwg=; b=xqr5oQ/6nnE/XdEIaa+knRVd4CX4wnBfmNtGz+ilqUkq1TNcXyFkFdlJHzhK4PK5Ox 5v0Y2qyeb5kPrcU9njykfhw5hL7BxQ5qnKzqiasJm3C1+mcxK0Az9yWKUZUzSx1OcdE3 08ZD59SNLEGfJEsd9Ou4Gbb4qonFJBCqJEUqfgVZDLYNwpiRU9pAuwuOvyTdn+R886N7 pjKk0KXgMk90uZnBt5zQvM1QWMGMISCPMtYHzzlw67ckd6uBQh0vPSAkwqg/PBBgu59s 7hA4G3WTZS0LqyjrIzy2jXzcATPwoEmyjonn5rIi1yfimuzQBX5IOY3xhtR0Ouuu0u2q 0yhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xgyqIteJDA8A8gslVlpPNbSOD5Z2HmWyq3Wfr3J3rwg=; b=SKl+rK/FH5jUPPk5WtN6Y8Dz9X+gILBREe+nTUzfPsIAjAIvytCXkC78U4cYWIqR3E i/KEZZJs6sr+YyvoZjzDnHcwkzsCiuUpCs49hRY2R/yOHIlzWGxPLWYoJBLAUNVonrLL 7Hrfcu19/i/PFS2nFYLVT71hAPjh+PVT58jTrCmZv8qIzkz2x04vuiQpzix12IrPpdB8 4VQ0E+uKwZVzm05fPjPZ6pPUEdvYVeiN3szQ1HcBjxFpG6NgDEujuUblZ+q7o7I/HvSt R7rnNDSCHbNYR1bhDUWykhQY4arhJlhTVjCTIKhqVpCpjEEviBmrsBfteLHzf/UPNT7e /JsA== X-Gm-Message-State: AHQUAuaBoRs4g/9gf0J8xlltyMpV3rpeqv1Jb3qK6FzaXWJgxtj6IYtO 1oIAJ2Jzu3ri1olXrt+5RRe/PW0Lj24VIg== X-Google-Smtp-Source: AHgI3IZxc1AqWvP2h82cepY8T41DHS6laA9IJXeyPCSYipOFCw57KdjD0mDyDelvsWIxqYaFjqq7fQ== X-Received: by 2002:adf:e548:: with SMTP id z8mr2336220wrm.52.1550140100078; Thu, 14 Feb 2019 02:28:20 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:19 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:10 +0000 Message-Id: <20190214102816.3393-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 Subject: [Qemu-devel] [PATCH v2 1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The Cocoa UI should run on the main thread; this is enforced in OSX Mojave. In order to be able to run on the main thread, we need to make sure we hold the iothread lock whenever we call into various QEMU UI midlayer functions. Signed-off-by: Peter Maydell Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- ui/cocoa.m | 83 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index e2567d6946..2931c751fd 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -129,6 +129,21 @@ NSTextField *pauseLabel; NSArray * supportedImageFileTypes; +// Utility function to run specified code block with iothread lock held +typedef void (^CodeBlock)(void); + +static void with_iothread_lock(CodeBlock block) +{ + bool locked = qemu_mutex_iothread_locked(); + if (!locked) { + qemu_mutex_lock_iothread(); + } + block(); + if (!locked) { + qemu_mutex_unlock_iothread(); + } +} + // Mac to QKeyCode conversion const int mac_to_qkeycode_map[] = { [kVK_ANSI_A] = Q_KEY_CODE_A, @@ -306,6 +321,7 @@ - (void) ungrabMouse; - (void) toggleFullScreen:(id)sender; - (void) handleMonitorInput:(NSEvent *)event; - (void) handleEvent:(NSEvent *)event; +- (void) handleEventLocked:(NSEvent *)event; - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled; /* The state surrounding mouse grabbing is potentially confusing. * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated @@ -649,8 +665,14 @@ - (void) handleMonitorInput:(NSEvent *)event - (void) handleEvent:(NSEvent *)event { - COCOA_DEBUG("QemuCocoaView: handleEvent\n"); + with_iothread_lock(^{ + [self handleEventLocked:event]; + }); +} +- (void) handleEventLocked:(NSEvent *)event +{ + COCOA_DEBUG("QemuCocoaView: handleEvent\n"); int buttons = 0; int keycode = 0; bool mouse_event = false; @@ -945,15 +967,18 @@ - (QEMUScreen) gscreen {return screen;} */ - (void) raiseAllKeys { - int index; const int max_index = ARRAY_SIZE(modifiers_state); - for (index = 0; index < max_index; index++) { - if (modifiers_state[index]) { - modifiers_state[index] = 0; - qemu_input_event_send_key_qcode(dcl->con, index, false); - } - } + with_iothread_lock(^{ + int index; + + for (index = 0; index < max_index; index++) { + if (modifiers_state[index]) { + modifiers_state[index] = 0; + qemu_input_event_send_key_qcode(dcl->con, index, false); + } + } + }); } @end @@ -1215,13 +1240,17 @@ - (void)removePause /* Restarts QEMU */ - (void)restartQEMU:(id)sender { - qmp_system_reset(NULL); + with_iothread_lock(^{ + qmp_system_reset(NULL); + }); } /* Powers down QEMU */ - (void)powerDownQEMU:(id)sender { - qmp_system_powerdown(NULL); + with_iothread_lock(^{ + qmp_system_powerdown(NULL); + }); } /* Ejects the media. @@ -1237,9 +1266,11 @@ - (void)ejectDeviceMedia:(id)sender return; } - Error *err = NULL; - qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding], - false, NULL, false, false, &err); + __block Error *err = NULL; + with_iothread_lock(^{ + qmp_eject(true, [drive cStringUsingEncoding: NSASCIIStringEncoding], + false, NULL, false, false, &err); + }); handleAnyDeviceErrors(err); } @@ -1271,16 +1302,18 @@ - (void)changeDeviceMedia:(id)sender return; } - Error *err = NULL; - qmp_blockdev_change_medium(true, - [drive cStringUsingEncoding: - NSASCIIStringEncoding], - false, NULL, - [file cStringUsingEncoding: - NSASCIIStringEncoding], - true, "raw", - false, 0, - &err); + __block Error *err = NULL; + with_iothread_lock(^{ + qmp_blockdev_change_medium(true, + [drive cStringUsingEncoding: + NSASCIIStringEncoding], + false, NULL, + [file cStringUsingEncoding: + NSASCIIStringEncoding], + true, "raw", + false, 0, + &err); + }); handleAnyDeviceErrors(err); } } @@ -1419,7 +1452,9 @@ - (void)adjustSpeed:(id)sender // get the throttle percentage throttle_pct = [sender tag]; - cpu_throttle_set(throttle_pct); + with_iothread_lock(^{ + cpu_throttle_set(throttle_pct); + }); COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(), '%'); } From patchwork Thu Feb 14 10:28:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041982 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="brJjVgnW"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Xqz1gnmz9sML for ; Thu, 14 Feb 2019 21:36:31 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guENZ-0002cj-60 for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:36:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46222) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEMK-0002Bg-Ta for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEG2-00044s-51 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:45 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:35192) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEFw-0003mN-Ph for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:38 -0500 Received: by mail-wm1-x341.google.com with SMTP id t200so5541070wmt.0 for ; Thu, 14 Feb 2019 02:28:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tP5QNALKs/J9psBFnzNNUZlZbCP3Vurs9RTkFSAFnGA=; b=brJjVgnW5v+jdufW6tWlOsaYPt0RO2mAKquLbcKC70Br66sXWVIroMrDd8HgJ1vEAn 668m7yo67xy8BPC7F5qSqTNGp8Tn+AQtvLhhPrYw3bEvwHwNpaF9DLoAEZAjKZesgxxZ bHp892rX+B+ZWtsIDCSPgtqfW8FAGjN3uUd5/buXomEAQLS+FrC8SL99+XufJa4FzGk9 7wZzmHbZC1cRl/PfAMW2NmTGDhXS1JyakTAUhvtMQtdHXrhGgKV8I6A7XUuCMW865424 KS2YjETh24/6TWCJh9cfmAtr/3BsyZ/W5R5HrLcSqW75Tlmkg1I6pzUOC2fU0vLx/UGv h2yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tP5QNALKs/J9psBFnzNNUZlZbCP3Vurs9RTkFSAFnGA=; b=AreBmgyMI/Ws0exM4sXH7COAb1ukca/Nr2NPXBDGyoxh02uZyp3O/7zKePc2CUaCNK J5mQhoKy79/wTrYMvFdzzpoJ7NpsGFMkQnro3O6kyj9UkdG1laHbtBMFfYlxAujQ6BKU ZDq9uQtpEi4qPENFetxnDwlVEQv8ziI82wHpyTIzh1rfZX9HJPAG/RRJyjBj9HE04Mrp IPF/i4ljj1G1kksC91Sus/qljpfTWLKfQkUM7jTOMZ0Ufk4jwbosh8yOj3NmH5bUUErN CIQvMF+8V58LyvDZmtuz0xnCsFCXT90COmkW8PZhxrdEJ+nzDHLSefuotB0BLm7FrN1v Tl+A== X-Gm-Message-State: AHQUAuZA9uq0JRP16v0g9fJDiuNiqnfuGHi2byL+QOxO0slP51LbD6Ij Hssk+TytnHal3uBRTn1tllknJcoboWwglg== X-Google-Smtp-Source: AHgI3IbSf4S0P9nY4OFmeU/s5IRm6Ul93I/cyyHrzzFsTQoMVOQZQDSB1O7eqrO888bVRi8kbROxvw== X-Received: by 2002:a1c:a185:: with SMTP id k127mr2100127wme.134.1550140101371; Thu, 14 Feb 2019 02:28:21 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:20 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:11 +0000 Message-Id: <20190214102816.3393-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v2 2/7] ui/cocoa: Use the pixman image directly in switchSurface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently the switchSurface method takes a DisplaySurface. We want to change our DisplayChangeListener's dpy_gfx_switch callback to do this work asynchronously on a different thread. The caller of the switch callback will free the old DisplaySurface immediately the callback returns, so to ensure that the other thread doesn't access freed data we need to switch to using the underlying pixman image instead. The pixman image is reference counted, so we will be able to take a reference to it to avoid it vanishing too early. In this commit we only change the switchSurface method to take a pixman image, and keep the flow of control synchronous for now. Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- ui/cocoa.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 2931c751fd..9d23732ff9 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -315,7 +315,7 @@ @interface QemuCocoaView : NSView BOOL isAbsoluteEnabled; BOOL isMouseDeassociated; } -- (void) switchSurface:(DisplaySurface *)surface; +- (void) switchSurface:(pixman_image_t *)image; - (void) grabMouse; - (void) ungrabMouse; - (void) toggleFullScreen:(id)sender; @@ -495,12 +495,13 @@ - (void) setContentDimensions } } -- (void) switchSurface:(DisplaySurface *)surface +- (void) switchSurface:(pixman_image_t *)image { COCOA_DEBUG("QemuCocoaView: switchSurface\n"); - int w = surface_width(surface); - int h = surface_height(surface); + int w = pixman_image_get_width(image); + int h = pixman_image_get_height(image); + pixman_format_code_t image_format = pixman_image_get_format(image); /* cdx == 0 means this is our very first surface, in which case we need * to recalculate the content dimensions even if it happens to be the size * of the initial empty window. @@ -522,10 +523,10 @@ - (void) switchSurface:(DisplaySurface *)surface CGDataProviderRelease(dataProviderRef); //sync host window color space with guests - screen.bitsPerPixel = surface_bits_per_pixel(surface); - screen.bitsPerComponent = surface_bytes_per_pixel(surface) * 2; + screen.bitsPerPixel = PIXMAN_FORMAT_BPP(image_format); + screen.bitsPerComponent = DIV_ROUND_UP(screen.bitsPerPixel, 8) * 2; - dataProviderRef = CGDataProviderCreateWithData(NULL, surface_data(surface), w * 4 * h, NULL); + dataProviderRef = CGDataProviderCreateWithData(NULL, pixman_image_get_data(image), w * 4 * h, NULL); // update windows if (isFullscreen) { @@ -1625,7 +1626,7 @@ static void cocoa_switch(DisplayChangeListener *dcl, NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; COCOA_DEBUG("qemu_cocoa: cocoa_switch\n"); - [cocoaView switchSurface:surface]; + [cocoaView switchSurface:surface->image]; [pool release]; } From patchwork Thu Feb 14 10:28:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041986 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="dqI9ffDR"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Xtt5vQxz9sMr for ; Thu, 14 Feb 2019 21:39:02 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45830 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEQ0-0004nq-Pn for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:39:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEML-00029E-24 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEG2-00044x-56 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:45 -0500 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:34091) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEFw-0003p8-Qv for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:38 -0500 Received: by mail-wm1-x32d.google.com with SMTP id y185so3953839wmd.1 for ; Thu, 14 Feb 2019 02:28:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PLM2/74UtOU0eSkgAa16v4YbF1HJYo83zpFvQXl3jCI=; b=dqI9ffDRg8ChGGDgUvROMQdi55sSYWUTXyUTSU8lVtoVq5LxOaer2OY9MtkoIhCrnA 3ztbWo9nV2LtSyWe1/vLLbvWW0Ctk6YkaIP3XX955BrdHL3S+MeKtmJOcj4Nyx0NDtZ1 qGvKygkXjjVoaIGksv0L/DzdUYyrG4+6TNpgmDybZrrPFQHed2GcTpgdIRFQhlIUe96L tRcSynknaZRClrUQ6Y7gnnVMxpEF2dsNfQ+QLiOTefCZShpeP5lFjOzL4NbsOjhsiMhy c7JJj5jtJrgJhalnIhR+G5zZGYzjaR4YKzc74cBk8VVBJ7JR+kWw0G+AnklVYK9DWjJe uV8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PLM2/74UtOU0eSkgAa16v4YbF1HJYo83zpFvQXl3jCI=; b=iDyyoATHFzZD/HfpSqvp5PuEd32QRd2pewYPMLQBXI4e8dj3Vt3FD+/cAlqrJY+19u BZrA3sjw/7JKcZC4o72oSlbdJM3PSZUXgIjZmRwuie+pMoLLNEWkh8TrhVLp56QP37qt IuYt/U716D3DB1boaqsnrbBxC5g45+VUkkB7vVldPgKMbFxNaBdxTwiyTgYPoH+vcaeA zqivPzbvcvk8aygNx1hMiVHyVbMFqz6HsRwSNs3Ug6xK8BKC7+X4JujQTcW08Xn2iGL2 fAW1kiogNXVHQ3ggKU9Ok+70iR7sTZndjPq14eKahx2WJeUc8BflTkkvZKhEXgQ4fLbB nyug== X-Gm-Message-State: AHQUAuZWQp5utFUNKka2qqHcxq03gFUHVyzTp51udkVkLvW9H7d8SLeu S8abRuRgfb3bLwLX1PKjyvkYwalYG9QXoQ== X-Google-Smtp-Source: AHgI3IZXV5V1DQLhKXVddo2PyDWvyJ8yIv9KaKSAhOBR8bLOKKrnVW1fYdfUF7N9cnvlNVRDceLHnw== X-Received: by 2002:a1c:26c1:: with SMTP id m184mr2048997wmm.25.1550140102683; Thu, 14 Feb 2019 02:28:22 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:22 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:12 +0000 Message-Id: <20190214102816.3393-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32d Subject: [Qemu-devel] [PATCH v2 3/7] ui/cocoa: Factor out initial menu creation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Factor out the long code sequence in main() which creates the initial set of menus. This will make later patches which move initialization code around a bit clearer. Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- ui/cocoa.m | 78 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 9d23732ff9..0b1cd31543 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1461,43 +1461,8 @@ - (void)adjustSpeed:(id)sender @end - -int main (int argc, const char * argv[]) { - - gArgc = argc; - gArgv = (char **)argv; - int i; - - /* In case we don't need to display a window, let's not do that */ - for (i = 1; i < argc; i++) { - const char *opt = argv[i]; - - if (opt[0] == '-') { - /* Treat --foo the same as -foo. */ - if (opt[1] == '-') { - opt++; - } - if (!strcmp(opt, "-h") || !strcmp(opt, "-help") || - !strcmp(opt, "-vnc") || - !strcmp(opt, "-nographic") || - !strcmp(opt, "-version") || - !strcmp(opt, "-curses") || - !strcmp(opt, "-display") || - !strcmp(opt, "-qtest")) { - return qemu_main(gArgc, gArgv, *_NSGetEnviron()); - } - } - } - - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - // Pull this console process up to being a fully-fledged graphical - // app with a menubar and Dock icon - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - - [NSApplication sharedApplication]; - +static void create_initial_menus(void) +{ // Add menus NSMenu *menu; NSMenuItem *menuItem; @@ -1581,6 +1546,45 @@ int main (int argc, const char * argv[]) { menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease]; [menuItem setSubmenu:menu]; [[NSApp mainMenu] addItem:menuItem]; +} + +int main (int argc, const char * argv[]) { + + gArgc = argc; + gArgv = (char **)argv; + int i; + + /* In case we don't need to display a window, let's not do that */ + for (i = 1; i < argc; i++) { + const char *opt = argv[i]; + + if (opt[0] == '-') { + /* Treat --foo the same as -foo. */ + if (opt[1] == '-') { + opt++; + } + if (!strcmp(opt, "-h") || !strcmp(opt, "-help") || + !strcmp(opt, "-vnc") || + !strcmp(opt, "-nographic") || + !strcmp(opt, "-version") || + !strcmp(opt, "-curses") || + !strcmp(opt, "-display") || + !strcmp(opt, "-qtest")) { + return qemu_main(gArgc, gArgv, *_NSGetEnviron()); + } + } + } + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + // Pull this console process up to being a fully-fledged graphical + // app with a menubar and Dock icon + ProcessSerialNumber psn = { 0, kCurrentProcess }; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + [NSApplication sharedApplication]; + + create_initial_menus(); // Create an Application controller QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init]; From patchwork Thu Feb 14 10:28:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041989 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="d1OVXcoA"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440XxG6N0Nz9sMr for ; Thu, 14 Feb 2019 21:41:06 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45888 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guES0-0006ZC-TH for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:41:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46058) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEMK-000276-56 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEGF-0004WI-UM for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:59 -0500 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:42794) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEG9-0003pv-94 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:50 -0500 Received: by mail-wr1-x444.google.com with SMTP id q18so5833819wrx.9 for ; Thu, 14 Feb 2019 02:28:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=S6NYZnQQZrqoXz0/AWPoW7pHcNDCfRFCnTCPJKk+rd0=; b=d1OVXcoAwY1aIZvEcmm++wjFN253AV4VQl+rFHGGPUfTVh26PDDT4jlXXkn/ruNpja aaynfghXEUeIlzRzNd7zAqe5TO20Vc9KU6H431eTajTE2tBBzFOPgw5bXKdY2Zq4F864 H/7lDqcjcasXJ1bhXmE71EPouWoel6xIAkNMpgKALmlQu//j35Us/kIiSAhlS3qEiXO2 tthxLbIPNPc9oPOE5ZCkOfM1i1ablJQYy71xxlF5gMHHkDfusDd/rHs7cB5tit4ddNFD vecJAtWvPbTThQDF1HMv58BkmcxH/6Br245v+Ywk0kEQHrzpSJb/gyoO4Uy6/fQ0QBxc YDiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=S6NYZnQQZrqoXz0/AWPoW7pHcNDCfRFCnTCPJKk+rd0=; b=ojVnf5wtGB1folyQyYJHT2VXa2R+SKnCzeo5aW6dpzAL3aV/sH19buKgO8RiuEJHWC rtfypSuqCuS91KpR3Bae3r38H8D3tg1rI7E5CiVMt5H3BfwjIvAFVyDGzgDbRRBKLZEY 6tTEIYXha5BUipzDVT/zslasXuSrnDq34Riz0Ps4Epr53Kt5eAFKtNMFTUEL6IE79jdP 0wX7QfbVppI7KR80/Nd2ICEFJmdABYHVNKEIvrCnlpPMZ6twfyDDLpeUlELJsRMRcUHE fuHqz/3CNAudHF5BJxV3ESVf6ojxGnUBqXqwGvER69QUjLOXDEq0Y9M1PHCL0SUwX6AK 9nVQ== X-Gm-Message-State: AHQUAuaPZaxM4WlFYyVVwVElYyxv/C+l3SdKZDMzaf/+rip/NrTQLQU6 9Xo+q/cw7OqMnaiSnEbDcthftDKnaTQfjQ== X-Google-Smtp-Source: AHgI3IbZkxlAoLmQmxqjUvG3U0dxgu2Q73ZRZbp4Y70i+wactXs1zqrm0SErSF7axtE+xK53Iqm66w== X-Received: by 2002:a05:6000:92:: with SMTP id m18mr2224568wrx.258.1550140104379; Thu, 14 Feb 2019 02:28:24 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:23 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:13 +0000 Message-Id: <20190214102816.3393-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH v2 4/7] ui/cocoa: Move console/device menu creation code up in file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Move the console/device menu creation code functions further up in the source file, next to the code which creates the initial menus. We're going to want to change the location we call these functions from in the next patch. This commit is a pure code move with no other changes. Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- ui/cocoa.m | 184 ++++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 0b1cd31543..2d943b6e2a 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1548,6 +1548,98 @@ static void create_initial_menus(void) [[NSApp mainMenu] addItem:menuItem]; } +/* Returns a name for a given console */ +static NSString * getConsoleName(QemuConsole * console) +{ + return [NSString stringWithFormat: @"%s", qemu_console_get_label(console)]; +} + +/* Add an entry to the View menu for each console */ +static void add_console_menu_entries(void) +{ + NSMenu *menu; + NSMenuItem *menuItem; + int index = 0; + + menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu]; + + [menu addItem:[NSMenuItem separatorItem]]; + + while (qemu_console_lookup_by_index(index) != NULL) { + menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index)) + action: @selector(displayConsole:) keyEquivalent: @""] autorelease]; + [menuItem setTag: index]; + [menu addItem: menuItem]; + index++; + } +} + +/* Make menu items for all removable devices. + * Each device is given an 'Eject' and 'Change' menu item. + */ +static void addRemovableDevicesMenuItems(void) +{ + NSMenu *menu; + NSMenuItem *menuItem; + BlockInfoList *currentDevice, *pointerToFree; + NSString *deviceName; + + currentDevice = qmp_query_block(NULL); + pointerToFree = currentDevice; + if(currentDevice == NULL) { + NSBeep(); + QEMU_Alert(@"Failed to query for block devices!"); + return; + } + + menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu]; + + // Add a separator between related groups of menu items + [menu addItem:[NSMenuItem separatorItem]]; + + // Set the attributes to the "Removable Media" menu item + NSString *titleString = @"Removable Media"; + NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString]; + NSColor *newColor = [NSColor blackColor]; + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + NSFont *font = [fontManager fontWithFamily:@"Helvetica" + traits:NSBoldFontMask|NSItalicFontMask + weight:0 + size:14]; + [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])]; + [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])]; + [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])]; + + // Add the "Removable Media" menu item + menuItem = [NSMenuItem new]; + [menuItem setAttributedTitle: attString]; + [menuItem setEnabled: NO]; + [menu addItem: menuItem]; + + /* Loop through all the block devices in the emulator */ + while (currentDevice) { + deviceName = [[NSString stringWithFormat: @"%s", currentDevice->value->device] retain]; + + if(currentDevice->value->removable) { + menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Change %s...", currentDevice->value->device] + action: @selector(changeDeviceMedia:) + keyEquivalent: @""]; + [menu addItem: menuItem]; + [menuItem setRepresentedObject: deviceName]; + [menuItem autorelease]; + + menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device] + action: @selector(ejectDeviceMedia:) + keyEquivalent: @""]; + [menu addItem: menuItem]; + [menuItem setRepresentedObject: deviceName]; + [menuItem autorelease]; + } + currentDevice = currentDevice->next; + } + qapi_free_BlockInfoList(pointerToFree); +} + int main (int argc, const char * argv[]) { gArgc = argc; @@ -1676,98 +1768,6 @@ static void cocoa_cleanup(void) .dpy_refresh = cocoa_refresh, }; -/* Returns a name for a given console */ -static NSString * getConsoleName(QemuConsole * console) -{ - return [NSString stringWithFormat: @"%s", qemu_console_get_label(console)]; -} - -/* Add an entry to the View menu for each console */ -static void add_console_menu_entries(void) -{ - NSMenu *menu; - NSMenuItem *menuItem; - int index = 0; - - menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu]; - - [menu addItem:[NSMenuItem separatorItem]]; - - while (qemu_console_lookup_by_index(index) != NULL) { - menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index)) - action: @selector(displayConsole:) keyEquivalent: @""] autorelease]; - [menuItem setTag: index]; - [menu addItem: menuItem]; - index++; - } -} - -/* Make menu items for all removable devices. - * Each device is given an 'Eject' and 'Change' menu item. - */ -static void addRemovableDevicesMenuItems(void) -{ - NSMenu *menu; - NSMenuItem *menuItem; - BlockInfoList *currentDevice, *pointerToFree; - NSString *deviceName; - - currentDevice = qmp_query_block(NULL); - pointerToFree = currentDevice; - if(currentDevice == NULL) { - NSBeep(); - QEMU_Alert(@"Failed to query for block devices!"); - return; - } - - menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu]; - - // Add a separator between related groups of menu items - [menu addItem:[NSMenuItem separatorItem]]; - - // Set the attributes to the "Removable Media" menu item - NSString *titleString = @"Removable Media"; - NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString]; - NSColor *newColor = [NSColor blackColor]; - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSFont *font = [fontManager fontWithFamily:@"Helvetica" - traits:NSBoldFontMask|NSItalicFontMask - weight:0 - size:14]; - [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])]; - [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])]; - [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])]; - - // Add the "Removable Media" menu item - menuItem = [NSMenuItem new]; - [menuItem setAttributedTitle: attString]; - [menuItem setEnabled: NO]; - [menu addItem: menuItem]; - - /* Loop through all the block devices in the emulator */ - while (currentDevice) { - deviceName = [[NSString stringWithFormat: @"%s", currentDevice->value->device] retain]; - - if(currentDevice->value->removable) { - menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Change %s...", currentDevice->value->device] - action: @selector(changeDeviceMedia:) - keyEquivalent: @""]; - [menu addItem: menuItem]; - [menuItem setRepresentedObject: deviceName]; - [menuItem autorelease]; - - menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device] - action: @selector(ejectDeviceMedia:) - keyEquivalent: @""]; - [menu addItem: menuItem]; - [menuItem setRepresentedObject: deviceName]; - [menuItem autorelease]; - } - currentDevice = currentDevice->next; - } - qapi_free_BlockInfoList(pointerToFree); -} - static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) { COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n"); From patchwork Thu Feb 14 10:28:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041985 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Yc2VCI5E"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Xtn72d9z9sML for ; Thu, 14 Feb 2019 21:38:57 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45826 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEPv-0004hl-9t for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:38:55 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46222) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEMJ-0002Bg-Op for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEGN-0004pn-Ff for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:29:05 -0500 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:33154) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEGN-0003ql-5l for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:29:03 -0500 Received: by mail-wm1-x341.google.com with SMTP id h22so3953734wmb.0 for ; Thu, 14 Feb 2019 02:28:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LHb/P8td/PzHuDb8bpIJF6NNTwrUvvJOnY5eUgA/sQw=; b=Yc2VCI5E+SEftRkdoT+/cmevLvKVbpSwG1LmMBTtoDnnNr1e0/AoBTvsAvSB85KWlE oxONFzln+dXQZGROS0c2mtONlSMJ3TN9PQK0rsL9M0e33LcvNdCGI4tuSOSLnXt0oaoE H4wZJT4x70pi53TiU6GBeZDehwOkUhVaxCM7TDjIXg4JBOuUj3EdiqIQU+iIHnhFl8Yu AMedv9RvfrpEBgwqs1Cypciryz0YTLu0L7YBW6Q/q0VOIM3vTyQxqioHSyPAdJR2QxWb WPG8lWEE4cXvPTy9vl4XsT1ROnVPkh6K7ohKArsdPpuUWDnNwmI7OE2732227iGkyxFR Entg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LHb/P8td/PzHuDb8bpIJF6NNTwrUvvJOnY5eUgA/sQw=; b=l3Y2PKsCwkjipobRT6WiBYl/yoeMBZS6Bp0NFU8bOgnB9H5vrHUWCF5ib4E1Tdd8VQ ePhygawQS6X6pAOAN8fIdBcuoVL2iJ0mhAuA9TVs3TR5Is3hw4bFV4sRz19Tyyf/oCln wAJjyXMYSDn7rg4GPY09uNPmysfMUIOfghPefWTOCnSNDWp5sJQsVXPvjfy82DM2M8JW 9SQgyUFekd97QHUONncHOKVQERZvZVH6Hvd6HMsiOKU4Alxt+oauf30rRSX508XuXy72 gHEJern5zd+MLuwmYGPDApTTz2ncOQSknjNr59CwzNBZlT2r8hR1Jjmo825hlpAw/dpC z2PA== X-Gm-Message-State: AHQUAubLwstoFF1CLxlClpZZrQfF7bt20XUcZ8pdcGY1njEPHW3KpxSC /x1IbDPkzZA06Gu4vPeFoOXVfj+G6m8hlQ== X-Google-Smtp-Source: AHgI3IY+ztYkrHKzjcolGyLbd1qD3fmYwZeKovOsTeVnO+W5lr29Njo55GpIlqCJQQSp9IIIulEueg== X-Received: by 2002:a1c:eb10:: with SMTP id j16mr1998606wmh.64.1550140105832; Thu, 14 Feb 2019 02:28:25 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:25 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:14 +0000 Message-Id: <20190214102816.3393-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 Subject: [Qemu-devel] [PATCH v2 5/7] ui/cocoa: Don't call NSApp sendEvent directly from handleEvent X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently the handleEvent method will directly call the NSApp sendEvent method for any events that we want to let OSX deal with. When we rearrange the event handling code, the way that we say "let OSX have this event" is going to change. Prepare for that by refactoring so that handleEvent returns a flag indicating whether it consumed the event. Suggested-by: BALATON Zoltan Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- New patch in v2 --- ui/cocoa.m | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 2d943b6e2a..5a84e1aea7 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -129,8 +129,9 @@ NSTextField *pauseLabel; NSArray * supportedImageFileTypes; -// Utility function to run specified code block with iothread lock held +// Utility functions to run specified code block with iothread lock held typedef void (^CodeBlock)(void); +typedef bool (^BoolCodeBlock)(void); static void with_iothread_lock(CodeBlock block) { @@ -144,6 +145,21 @@ static void with_iothread_lock(CodeBlock block) } } +static bool bool_with_iothread_lock(BoolCodeBlock block) +{ + bool locked = qemu_mutex_iothread_locked(); + bool val; + + if (!locked) { + qemu_mutex_lock_iothread(); + } + val = block(); + if (!locked) { + qemu_mutex_unlock_iothread(); + } + return val; +} + // Mac to QKeyCode conversion const int mac_to_qkeycode_map[] = { [kVK_ANSI_A] = Q_KEY_CODE_A, @@ -320,8 +336,8 @@ - (void) grabMouse; - (void) ungrabMouse; - (void) toggleFullScreen:(id)sender; - (void) handleMonitorInput:(NSEvent *)event; -- (void) handleEvent:(NSEvent *)event; -- (void) handleEventLocked:(NSEvent *)event; +- (bool) handleEvent:(NSEvent *)event; +- (bool) handleEventLocked:(NSEvent *)event; - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled; /* The state surrounding mouse grabbing is potentially confusing. * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated @@ -664,15 +680,16 @@ - (void) handleMonitorInput:(NSEvent *)event } } -- (void) handleEvent:(NSEvent *)event +- (bool) handleEvent:(NSEvent *)event { - with_iothread_lock(^{ - [self handleEventLocked:event]; + return bool_with_iothread_lock(^{ + return [self handleEventLocked:event]; }); } -- (void) handleEventLocked:(NSEvent *)event +- (bool) handleEventLocked:(NSEvent *)event { + /* Return true if we handled the event, false if it should be given to OSX */ COCOA_DEBUG("QemuCocoaView: handleEvent\n"); int buttons = 0; int keycode = 0; @@ -743,8 +760,7 @@ - (void) handleEventLocked:(NSEvent *)event if (keycode == Q_KEY_CODE_F) { switched_to_fullscreen = true; } - [NSApp sendEvent:event]; - return; + return false; } // default @@ -759,12 +775,12 @@ - (void) handleEventLocked:(NSEvent *)event // enable graphic console case '1' ... '9': console_select(key - '0' - 1); /* ascii math */ - return; + return true; // release the mouse grab case 'g': [self ungrabMouse]; - return; + return true; } } } @@ -781,7 +797,7 @@ - (void) handleEventLocked:(NSEvent *)event // don't pass the guest a spurious key-up if we treated this // command-key combo as a host UI action if (!isMouseGrabbed && ([event modifierFlags] & NSEventModifierFlagCommand)) { - return; + return true; } if (qemu_console_is_graphic(NULL)) { @@ -875,7 +891,7 @@ - (void) handleEventLocked:(NSEvent *)event mouse_event = false; break; default: - [NSApp sendEvent:event]; + return false; } if (mouse_event) { @@ -911,10 +927,11 @@ - (void) handleEventLocked:(NSEvent *)event qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]); } } else { - [NSApp sendEvent:event]; + return false; } qemu_input_event_sync(); } + return true; } - (void) grabMouse @@ -1749,7 +1766,9 @@ static void cocoa_refresh(DisplayChangeListener *dcl) event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES]; if (event != nil) { - [cocoaView handleEvent:event]; + if (![cocoaView handleEvent:event]) { + [NSApp sendEvent:event]; + } } } while(event != nil); [pool release]; From patchwork Thu Feb 14 10:28:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ul4kPPKZ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Xqs2KKSz9sMr for ; Thu, 14 Feb 2019 21:36:25 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45810 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guENT-0002Xn-3j for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:36:23 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46375) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEMK-0002Fs-MO for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEG5-0004C0-90 for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:46 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]:36074) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEG2-0003rs-9L for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:44 -0500 Received: by mail-wm1-x334.google.com with SMTP id j125so5536499wmj.1 for ; Thu, 14 Feb 2019 02:28:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lheevBq1gTeHIYE+Qj1KLoVPcfU34jZDty+FQ9dOu44=; b=ul4kPPKZ5awJkbSIXKUfCX++9AGqEzT1XNPZ8vl4WlxTX1mlxjbhqh45khkkJ26TYD PKqP3tiRNoVcNlVzfnsFa8y+OOlmI+H2JrDi+GUGNM24FyHgRF1UoI8hKuga/4Egv2eI xgf/CBynUpp+UXWjkmzsYeomDvY1AX2Q87OALlxlwzn0NuPXybSET7OZOBltYVDO6V4+ gEJ/DRlo82xN1UW3yJ/9cevV4HrlmY9Ll9qw+fVjMmXy79Xg+fHquqfslfMGa3y+8O1B fJA2LH3Ya/PvcQx68xamEOK3ICkwQ12MAkJsdLuTaIXatAv5ACIEyPMbY1jOJM79dTs0 Wt1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lheevBq1gTeHIYE+Qj1KLoVPcfU34jZDty+FQ9dOu44=; b=q8jt2Yn5oFhPaNR5NOFnxK01WoT0mv+oFzI1lbL1F+19BElSmvu7SewgOYSG+EcErh cqSU5ammSESPikSp+FMny1qoh/UWrYN3rr50/orfqTY7aXgOg87phaHrNkwN5kAvAZzk AXD5dgPf2Kr+hH0vUn1Zmr8+s6o4E/UXPemFmAsuGX4H2BqlAWmwRu0UaK7CN7IPK/Wi ipTu9tzaGa1nWTnYB/m74Br81RxBq+CkLGZSxp785GMNnl0Pghse64semAY61VvIT6Z+ eetRJ3G0aseDpMWhHyYp+6BoeYZ4IuNyE+b/3Xm1/d19b7poBd5a6Z9ZuF4a1NDubE5R lftw== X-Gm-Message-State: AHQUAuZRAgT4FZ3MhLzJOIyOAFvLADRfDD8SFQk3mPyaitVFeRGuREML 2leEVTjuDU8xHskn6vhoPHIQBhX99xndZg== X-Google-Smtp-Source: AHgI3IZf4mj+MFw5QIJzTpltkcd8UUXuLlGuw5jxZiboWybK6ff8RlSZQoeCmICF4z7MZtKN0DhO9Q== X-Received: by 2002:a1c:d18a:: with SMTP id i132mr2096139wmg.27.1550140107202; Thu, 14 Feb 2019 02:28:27 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:26 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:15 +0000 Message-Id: <20190214102816.3393-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::334 Subject: [Qemu-devel] [PATCH v2 6/7] ui/cocoa: Subclass NSApplication so we can implement sendEvent X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" When we switch away from our custom event handling, we still want to be able to have first go at any events our application receives, because in full-screen mode we want to send key events to the guest, even if they would be menu item activation events. There are several ways we could do that, but one simple approach is to subclass NSApplication so we can implement a custom sendEvent method. Do that, but for the moment have our sendEvent just invoke the superclass method. Signed-off-by: Peter Maydell Reviewed-by: BALATON Zoltan Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- New patch in v2 --- ui/cocoa.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 5a84e1aea7..184fbd877d 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1478,6 +1478,17 @@ - (void)adjustSpeed:(id)sender @end +@interface QemuApplication : NSApplication +@end + +@implementation QemuApplication +- (void)sendEvent:(NSEvent *)event +{ + COCOA_DEBUG("QemuApplication: sendEvent\n"); + [super sendEvent: event]; +} +@end + static void create_initial_menus(void) { // Add menus @@ -1691,7 +1702,7 @@ int main (int argc, const char * argv[]) { ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToForegroundApplication); - [NSApplication sharedApplication]; + [QemuApplication sharedApplication]; create_initial_menus(); From patchwork Thu Feb 14 10:28:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1041994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Mt5oawDT"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 440Y1H197Kz9sMx for ; Thu, 14 Feb 2019 21:44:35 +1100 (AEDT) Received: from localhost ([127.0.0.1]:45943 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEVN-0000Z5-4T for incoming@patchwork.ozlabs.org; Thu, 14 Feb 2019 05:44:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46380) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1guEMK-0002G8-LV for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:35:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1guEG7-0004GG-DN for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:50 -0500 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:38139) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1guEG5-0003tN-Jd for qemu-devel@nongnu.org; Thu, 14 Feb 2019 05:28:45 -0500 Received: by mail-wm1-x344.google.com with SMTP id v26so5525378wmh.3 for ; Thu, 14 Feb 2019 02:28:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tHIXdKLzCfVDEdo6vUIvGThxiCS0S7O3izq49fTJxds=; b=Mt5oawDTA815orSxLaWc28IjplEQOCjpgLXBmjbRcaZKgzbedG7rbGSdFshE5paSAl DKKeEDlxPmkZ1fpr4WWXBKn5NcqrJ/a5CgXdTkzwa9g92f0qd7hIxG/Ie2nDJ7EaQUFA n8JxJq4CdzSJnK9NWnkQWVue24z7W4A6FdIH5Z57Wu3k24mh5k+j9wXacLjaFFuJ0XwY NMr94qio+w24b3gJzTojHPiF9Uydc15wwBSKuzy+b56xHc3jzuqnQ4jAJktMuWD/LY5a 7UZiSfK495c4l9i00Yit9l3oV286EgNMTTmW283Xs/KG+JOs7qBONeljs8x1lzJey8Ng tcLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tHIXdKLzCfVDEdo6vUIvGThxiCS0S7O3izq49fTJxds=; b=psfA2E3rOqWy8hlnI9LCwBPtL/xJTOM/X79B/UYnlVAC8+ldrsKEW5I+b7UVJQWb5K V92u+6bJqUINsWsUqw4s/4rlzKr81v+4KRgw1L6pEFFiEjqKk2OPiMc2hhZFxb/3SyKo zMWK0WPo2YYIKEaxkBKukRC3zSkbkcpozBBfkECl3DDYt/Ybz9eHj76JMnz9AWQPCPnl aEtTf9UfFWqbuKRTqOLBnhQAo7SPH1CaFZ3eN3O9k9aqDgz6vZxOAXrBoAgRFipDCynF lhtx4nUudqSkdgjza2kQijvgpZFGV/Zby3bFQC9IU9c3TJEEsfXsf7vCqEm8WO8bi/Rf rvuw== X-Gm-Message-State: AHQUAuaNNbZd3Wgg5zKUMsuoYAYkunYt5ZvvcQaaaIysz2VshGXxXUyY FCI/2zzNxI0YlBlpVMzM5IekPirDnVDyXg== X-Google-Smtp-Source: AHgI3Ib2MboEP20L1kiUyLqaGRoGVguCK1X8sXXLNxETqQLCDwP5hRWn4l98k03usU2Qfy8az3+x0w== X-Received: by 2002:a1c:2544:: with SMTP id l65mr2224030wml.93.1550140108703; Thu, 14 Feb 2019 02:28:28 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id o5sm6473817wrh.34.2019.02.14.02.28.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 02:28:28 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 14 Feb 2019 10:28:16 +0000 Message-Id: <20190214102816.3393-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190214102816.3393-1-peter.maydell@linaro.org> References: <20190214102816.3393-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::344 Subject: [Qemu-devel] [PATCH v2 7/7] ui/cocoa: Perform UI operations only on the main thread X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org, John Arbuckle , Roman Bolshakov , Gerd Hoffmann , Ben Hekster , Berkus Decker Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The OSX Mojave release is more picky about enforcing the Cocoa API restriction that only the main thread may perform UI calls. To accommodate this we need to restructure the Cocoa code: * the special OSX main() creates a second thread and uses that to call the vl.c qemu_main(); the original main thread goes into the OSX event loop * the refresh, switch and update callbacks asynchronously tell the main thread to do the necessary work * the refresh callback no longer does the "get events from the UI event queue and handle them" loop, since we now use the stock OSX event loop. Instead our NSApplication sendEvent method will either deal with them or pass them on to OSX All these things have to be changed in one commit, to avoid breaking bisection. Note that since we use dispatch_get_main_queue(), this bumps our minimum version requirement to OSX 10.10 Yosemite (released in 2014, unsupported by Apple since 2017). Signed-off-by: Peter Maydell Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov --- v2 changes: call handleEvent from sendEvent --- ui/cocoa.m | 191 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 113 insertions(+), 78 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 184fbd877d..201a294ed4 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -129,6 +129,9 @@ NSTextField *pauseLabel; NSArray * supportedImageFileTypes; +QemuSemaphore display_init_sem; +QemuSemaphore app_started_sem; + // Utility functions to run specified code block with iothread lock held typedef void (^CodeBlock)(void); typedef bool (^BoolCodeBlock)(void); @@ -325,6 +328,7 @@ @interface QemuCocoaView : NSView NSWindow *fullScreenWindow; float cx,cy,cw,ch,cdx,cdy; CGDataProviderRef dataProviderRef; + pixman_image_t *pixman_image; BOOL modifiers_state[256]; BOOL isMouseGrabbed; BOOL isFullscreen; @@ -535,13 +539,16 @@ - (void) switchSurface:(pixman_image_t *)image } // update screenBuffer - if (dataProviderRef) + if (dataProviderRef) { CGDataProviderRelease(dataProviderRef); + pixman_image_unref(pixman_image); + } //sync host window color space with guests screen.bitsPerPixel = PIXMAN_FORMAT_BPP(image_format); screen.bitsPerComponent = DIV_ROUND_UP(screen.bitsPerPixel, 8) * 2; + pixman_image = image; dataProviderRef = CGDataProviderCreateWithData(NULL, pixman_image_get_data(image), w * 4 * h, NULL); // update windows @@ -1013,7 +1020,6 @@ @interface QemuCocoaAppController : NSObject #endif { } -- (void)startEmulationWithArgc:(int)argc argv:(char**)argv; - (void)doToggleFullScreen:(id)sender; - (void)toggleFullScreen:(id)sender; - (void)showQEMUDoc:(id)sender; @@ -1101,8 +1107,8 @@ - (void) dealloc - (void)applicationDidFinishLaunching: (NSNotification *) note { COCOA_DEBUG("QemuCocoaAppController: applicationDidFinishLaunching\n"); - // launch QEMU, with the global args - [self startEmulationWithArgc:gArgc argv:(char **)gArgv]; + /* Tell cocoa_display_init to proceed */ + qemu_sem_post(&app_started_sem); } - (void)applicationWillTerminate:(NSNotification *)aNotification @@ -1145,15 +1151,6 @@ - (void) applicationWillResignActive: (NSNotification *)aNotification [cocoaView raiseAllKeys]; } -- (void)startEmulationWithArgc:(int)argc argv:(char**)argv -{ - COCOA_DEBUG("QemuCocoaAppController: startEmulationWithArgc\n"); - - int status; - status = qemu_main(argc, argv, *_NSGetEnviron()); - exit(status); -} - /* We abstract the method called by the Enter Fullscreen menu item * because Mac OS 10.7 and higher disables it. This is because of the * menu item's old selector's name toggleFullScreen: @@ -1485,7 +1482,9 @@ @implementation QemuApplication - (void)sendEvent:(NSEvent *)event { COCOA_DEBUG("QemuApplication: sendEvent\n"); - [super sendEvent: event]; + if (!cocoaView || ![cocoaView handleEvent:event]) { + [super sendEvent: event]; + } } @end @@ -1668,32 +1667,59 @@ static void addRemovableDevicesMenuItems(void) qapi_free_BlockInfoList(pointerToFree); } -int main (int argc, const char * argv[]) { +/* + * 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 + * need to start a second thread which runs the vl.c qemu_main(): + * + * Initial thread: 2nd thread: + * in main(): + * create qemu-main thread + * wait on display_init semaphore + * call qemu_main() + * ... + * in cocoa_display_init(): + * post the display_init semaphore + * wait on app_started semaphore + * create application, menus, etc + * enter OSX run loop + * in applicationDidFinishLaunching: + * post app_started semaphore + * tell main thread to fullscreen if needed + * [...] + * run qemu main-loop + * + * We do this in two stages so that we don't do the creation of the + * GUI application menus and so on for command line options like --help + * where we want to just print text to stdout and exit immediately. + */ +static void *call_qemu_main(void *opaque) +{ + int status; + + COCOA_DEBUG("Second thread: calling qemu_main()\n"); + status = qemu_main(gArgc, gArgv, *_NSGetEnviron()); + COCOA_DEBUG("Second thread: qemu_main() returned, exiting\n"); + exit(status); +} + +int main (int argc, const char * argv[]) { + QemuThread thread; + + COCOA_DEBUG("Entered main()\n"); gArgc = argc; gArgv = (char **)argv; - int i; - /* In case we don't need to display a window, let's not do that */ - for (i = 1; i < argc; i++) { - const char *opt = argv[i]; + qemu_sem_init(&display_init_sem, 0); + qemu_sem_init(&app_started_sem, 0); - if (opt[0] == '-') { - /* Treat --foo the same as -foo. */ - if (opt[1] == '-') { - opt++; - } - if (!strcmp(opt, "-h") || !strcmp(opt, "-help") || - !strcmp(opt, "-vnc") || - !strcmp(opt, "-nographic") || - !strcmp(opt, "-version") || - !strcmp(opt, "-curses") || - !strcmp(opt, "-display") || - !strcmp(opt, "-qtest")) { - return qemu_main(gArgc, gArgv, *_NSGetEnviron()); - } - } - } + qemu_thread_create(&thread, "qemu_main", call_qemu_main, + NULL, QEMU_THREAD_DETACHED); + + COCOA_DEBUG("Main thread: waiting for display_init_sem\n"); + qemu_sem_wait(&display_init_sem); + COCOA_DEBUG("Main thread: initializing app\n"); NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; @@ -1706,12 +1732,24 @@ int main (int argc, const char * argv[]) { create_initial_menus(); + /* + * Create the menu entries which depend on QEMU state (for consoles + * and removeable devices). These make calls back into QEMU functions, + * which is OK because at this point we know that the second thread + * holds the iothread lock and is synchronously waiting for us to + * finish. + */ + add_console_menu_entries(); + addRemovableDevicesMenuItems(); + // Create an Application controller QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init]; [NSApp setDelegate:appController]; // Start the main event loop + COCOA_DEBUG("Main thread: entering OSX run loop\n"); [NSApp run]; + COCOA_DEBUG("Main thread: left OSX run loop, exiting\n"); [appController release]; [pool release]; @@ -1729,17 +1767,19 @@ static void cocoa_update(DisplayChangeListener *dcl, COCOA_DEBUG("qemu_cocoa: cocoa_update\n"); - NSRect rect; - if ([cocoaView cdx] == 1.0) { - rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h); - } else { - rect = NSMakeRect( - x * [cocoaView cdx], - ([cocoaView gscreen].height - y - h) * [cocoaView cdy], - w * [cocoaView cdx], - h * [cocoaView cdy]); - } - [cocoaView setNeedsDisplayInRect:rect]; + dispatch_async(dispatch_get_main_queue(), ^{ + NSRect rect; + if ([cocoaView cdx] == 1.0) { + rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h); + } else { + rect = NSMakeRect( + x * [cocoaView cdx], + ([cocoaView gscreen].height - y - h) * [cocoaView cdy], + w * [cocoaView cdx], + h * [cocoaView cdy]); + } + [cocoaView setNeedsDisplayInRect:rect]; + }); [pool release]; } @@ -1748,9 +1788,19 @@ static void cocoa_switch(DisplayChangeListener *dcl, DisplaySurface *surface) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + pixman_image_t *image = surface->image; COCOA_DEBUG("qemu_cocoa: cocoa_switch\n"); - [cocoaView switchSurface:surface->image]; + + // The DisplaySurface will be freed as soon as this callback returns. + // We take a reference to the underlying pixman image here so it does + // not disappear from under our feet; the switchSurface method will + // deref the old image when it is done with it. + pixman_image_ref(image); + + dispatch_async(dispatch_get_main_queue(), ^{ + [cocoaView switchSurface:image]; + }); [pool release]; } @@ -1762,26 +1812,15 @@ static void cocoa_refresh(DisplayChangeListener *dcl) graphic_hw_update(NULL); if (qemu_input_is_absolute()) { - if (![cocoaView isAbsoluteEnabled]) { - if ([cocoaView isMouseGrabbed]) { - [cocoaView ungrabMouse]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (![cocoaView isAbsoluteEnabled]) { + if ([cocoaView isMouseGrabbed]) { + [cocoaView ungrabMouse]; + } } - } - [cocoaView setAbsoluteEnabled:YES]; + [cocoaView setAbsoluteEnabled:YES]; + }); } - - NSDate *distantPast; - NSEvent *event; - distantPast = [NSDate distantPast]; - do { - event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:distantPast - inMode: NSDefaultRunLoopMode dequeue:YES]; - if (event != nil) { - if (![cocoaView handleEvent:event]) { - [NSApp sendEvent:event]; - } - } - } while(event != nil); [pool release]; } @@ -1802,10 +1841,17 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) { COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n"); + /* Tell main thread to go ahead and create the app and enter the run loop */ + qemu_sem_post(&display_init_sem); + qemu_sem_wait(&app_started_sem); + COCOA_DEBUG("cocoa_display_init: app start completed\n"); + /* if fullscreen mode is to be used */ if (opts->has_full_screen && opts->full_screen) { - [NSApp activateIgnoringOtherApps: YES]; - [(QemuCocoaAppController *)[[NSApplication sharedApplication] delegate] toggleFullScreen: nil]; + dispatch_async(dispatch_get_main_queue(), ^{ + [NSApp activateIgnoringOtherApps: YES]; + [(QemuCocoaAppController *)[[NSApplication sharedApplication] delegate] toggleFullScreen: nil]; + }); } dcl = g_malloc0(sizeof(DisplayChangeListener)); @@ -1816,17 +1862,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) // register cleanup function atexit(cocoa_cleanup); - - /* At this point QEMU has created all the consoles, so we can add View - * menu entries for them. - */ - add_console_menu_entries(); - - /* Give all removable devices a menu item. - * Has to be called after QEMU has started to - * find out what removable devices it has. - */ - addRemovableDevicesMenuItems(); } static QemuDisplay qemu_display_cocoa = {