From patchwork Mon Feb 25 10:24:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159162 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859750jad; Mon, 25 Feb 2019 02:24:38 -0800 (PST) X-Received: by 2002:adf:81a1:: with SMTP id 30mr1810149wra.285.1551090278239; Mon, 25 Feb 2019 02:24:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090278; cv=none; d=google.com; s=arc-20160816; b=bUEov0hK8GLVwVxYeiggXhBxNaSoGMTken+okDXXv6tScs55QLdUVVA+URMJmjnUcY mmRXuFNnVg6sBYFO2LQhEpjeDHJqTTaL6a/gLw8IhMmTA8RJtQIMbrcDdDE7ZxE1+D8K 3aX61yCEfGRd+6XBa2OjsHbIt7cWV9YOH1a+W9FgXpx1SH6s8nHPIsX+8/jFBwLn3xm3 Gs6bHzyOEoqeG2N/vALX08KLeQQ8y71k3ugopLlpInwSs5SLNedDm5JffCqBs+q7HH6b SB0p9iGwz1aqXaBT5UCzam8ryfUWCTtlMWjwwG4/WoSHnccVO88oBUzgJGavWJLpA+uf Fwrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=I0kTAUlhb54s5r88zvNpSgW3m1NNSybQGlzrJJNrpNM=; b=Ld1QUHQeLUBbMHjgAD/tlh2WfBuR2+cVq8bjvUGAVHDrVNcACtVc646MuN4ODYr6mF oL4gFZBdPIXl6lsySwNnWm6GiLy40ihc0sKc6rjuPBGq7P8+xfGnuyY2NMmRscW/iEy5 Vfh9ZaEvhRhQVNF9LhouaOk4UqLPsLRJDiEo477726bU/2cq60HUJE2KVDeH41PYlZSU aGBXlqq7HjkYfR/eH4EWKQ2U71NTN1/+ztUnZx70L4b4k44ynpfMoCtPAVR7egqVpJsN PHd9jUa8wPVXXpMaj3Gpw2KL2GQCni9kLb+sx1DIgBm4KQ2Z6EO1217/TMHzSZ02W86u wrXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KPWkLSUY; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id l14sor5718506wrw.0.2019.02.25.02.24.38 for (Google Transport Security); Mon, 25 Feb 2019 02:24:38 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KPWkLSUY; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=I0kTAUlhb54s5r88zvNpSgW3m1NNSybQGlzrJJNrpNM=; b=KPWkLSUYlf/iMbA1pJsbyW7Akq+GqrnqFtKyD71vv/pgMk07ki5rVU7HlZvrhyv01K 3YjVhRwrZYrGYDcbsSn9t7830fxIgvK6g8cOH2A2IbDeDtSZ+9RA0MM9HWpLYob65ulN al0lUOPKwDUQiwUv78l1dtIIS5auRL5LpWEhcJxd/0/drE/9L8V4ghilyqvmKp6n4lfu yjEy5/nrPgJmxDcXTRj25DNFE5ZODTEhlqRP2JK7tV81G/uTqJXULsMmpF2UNuEekB3D pWsdirRcqixDPPYjJBZ8I8Lrp3NIg/R0kX8Bhnbfd1EBsdy69e2SBmBBwrgO2xCJKGv0 oCOg== 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=I0kTAUlhb54s5r88zvNpSgW3m1NNSybQGlzrJJNrpNM=; b=p0xHacdlh9IUWt/5QGmYXbZ827fyC5c7erDlkyRIj5DKBeHfOCcU22++s0t1h+/8BZ U2nYQNmkQRYd+3AbxrzePhosWDP/4F8PT06sU4RamtoQLrrVIHfGiSnflw1f8ZvFx9Jj L2BwXCPvCri+c7VpviPJkcKWfebpGXGPDqL60d8q0cTjF6gqXYWNu9Ch9rAA+B6w1uhZ 47TZUH1yHTmv0Cdke8SAFd+d0DJlACpL4RaOCfLq+fSur0dHqvZOJOzhRqPGEAE/dnBN 31Gdp05Mg7/JKlmui4AbcN6Pxx1xhZwHlRM/WT/mf1LzZVJ7T3V65nJzc7LaebuJ3cx+ dOtw== X-Gm-Message-State: AHQUAuZNLVe9A20mCeLngT8WmzC/EEXUJ2lUKUhRoX/Bn373hvoIQ1fZ ahOUD/kzwzf94auW8GjWlA5LnYoc0rON+Q== X-Google-Smtp-Source: AHgI3IZDzpNz5o6q+LP61BL57v8XYFv4dQW1M+W7ExwYix2OhQgu3NSEb6UcO3+Ojvqbf9mpnV56OQ== X-Received: by 2002:a5d:500e:: with SMTP id e14mr11404952wrt.219.1551090277813; Mon, 25 Feb 2019 02:24:37 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:37 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 1/7] ui/cocoa: Ensure we have the iothread lock when calling into QEMU Date: Mon, 25 Feb 2019 10:24:27 +0000 Message-Id: <20190225102433.22401-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-2-peter.maydell@linaro.org --- Changes since v2: add with_iothread_lock wrap to the qmp_stop()/qmp_cont() calls --- ui/cocoa.m | 91 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 26 deletions(-) -- 2.17.2 (Apple Git-113) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Roman Bolshakov <r.bolshakv@yadro.com>
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
diff --git a/ui/cocoa.m b/ui/cocoa.m index e2567d6946..f1171c4865 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 @@ -1178,7 +1203,9 @@ - (void)displayConsole:(id)sender /* Pause the guest */ - (void)pauseQEMU:(id)sender { - qmp_stop(NULL); + with_iothread_lock(^{ + qmp_stop(NULL); + }); [sender setEnabled: NO]; [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES]; [self displayPause]; @@ -1187,7 +1214,9 @@ - (void)pauseQEMU:(id)sender /* Resume running the guest operating system */ - (void)resumeQEMU:(id) sender { - qmp_cont(NULL); + with_iothread_lock(^{ + qmp_cont(NULL); + }); [sender setEnabled: NO]; [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES]; [self removePause]; @@ -1215,13 +1244,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 +1270,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 +1306,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 +1456,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 Mon Feb 25 10:24:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159163 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859764jad; Mon, 25 Feb 2019 02:24:39 -0800 (PST) X-Received: by 2002:a1c:a58c:: with SMTP id o134mr9857999wme.79.1551090279895; Mon, 25 Feb 2019 02:24:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090279; cv=none; d=google.com; s=arc-20160816; b=rqBLM81YFYBBnrjb124LelMPSI0BP5I7yPnugwq+LBOgTXqljGBWsOAnRyZ1cBbtYo pVBbFpB0RaL0aIoPxs0ERN/8/T2pG2qM24v/H3/9GjUCY/pMQl0OGaTMUDIRj9LIwDL2 yYzk7Foge2pr1XStZ9XrQ4we2OSAoHMD4epyawweqoGPP8UnzHm9gjOGgjsLh6SP7G2a sldahLrmsTjNdp9TXsuN6vn5cyJ0Js586aA3Oc5A8Z0mrDtAwekGXj9XThUBG83af2P1 FrMNfDBx0prqKPc1lZIuAzoAZmFR+14gcu64IOKMjWh/Azdkh3rBCqZjnPxehA5VSVTE TlLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=bmDgQhAr7tyLraO8i1ouLXjQaT6+r93opd/eZp7ELdo=; b=iV91wafM62jXOzL+b9qlQ0iheuzq+lBQYuWQqbpFsfK+jg+2JVelEEflUH6fJpel7B Oq5WmjqKzr2UW8IYj2r0GAlaXn3m/wB0KNCumUwAjVaDDB2cPDD2QM518AYc2bQX56Uh 07LuNtKb/HYK49bdENi3IMxqcI3NfVfchRLmA57tKZRa1Y8K2zNMOXuY/EHznPVUo5er 9ocvvzyOeLLhwFahz4A5i1L3mOVQ1GznAUzXoHzQ1sQdQMpJ2xtPMVk7GKBazA6Xi1mO 03EYyxiD28MrhL0nSZsJucSvw4qJDjiR7b/LIscvtfwVrnmlQbj3q/MxT21CweoVWVuy hVNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pRGpeWJz; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id o206sor746915wma.11.2019.02.25.02.24.39 for (Google Transport Security); Mon, 25 Feb 2019 02:24:39 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=pRGpeWJz; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=bmDgQhAr7tyLraO8i1ouLXjQaT6+r93opd/eZp7ELdo=; b=pRGpeWJz5vrS4mnjdmlsnOSZZ6wB2kwACIQBn4lYKCRgpxn8yhruTrIf9WoDkneG+r Z8zw/0PCM3Lj9PYPXIU3q4dhK4dZwlv3QCS2UKftACza0xSpe9smXSDeZGMZClqtGDpS uhCGm5NzOgr1XlDJ9GiTWMGChBgXGMFkFdpKBDQQ1+NunvUQRsh0cUv5Ynf8UxjuPb4G ekGAq7lB42WSrdhE3H0OPgsYwbr2njzwBZRuCePg/YaLqepTLBoNNWgTuslqHOQ1BEHV IGNdVRZfPcSvjOWNWeDv0sFestBTlwV1yoSX7Qv6xKYkX/pSlXhxXfCYGYn+mqhQIje9 MzWw== 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=bmDgQhAr7tyLraO8i1ouLXjQaT6+r93opd/eZp7ELdo=; b=kRhPEjg4FvEX8wm/BkGiV6kvhHcCLZtoB+1MwCidIJIXsoy3tblWGa16ph4USiDQbY TUYvnyHLeIn8x3R8zXX0OeFNUQ/Cw3+E4sXrpPI9UIMxaKYyxhL5Cq9Nn2oeGl/aue/E 2DJxF34xEK9Mb3AkbQC8ciUjvHhDtTwWCbQ4yhYpcSxcz6bv3fbTimG1AdoAifX5nst4 xVOH9YV19u+Nhpyy/8Ns63VRYDvWswMZWtevzwQL3pv6kIrBkKrepLB1GycJWf4i8Vx2 TqFscApgqwSCEOE4QiYxZiyCjY742zhBFAr1/pb4VMMSnI9Ax10qWC+XqIQU4rfnzzfB AxUQ== X-Gm-Message-State: AHQUAuaMzfn0Pb8xOOzMbyoXMM/53/2Pn9oP701kQP+BAEoefhSErQjw m+OonJWHN5V0TvIcZVjkS2T7dHGW X-Google-Smtp-Source: AHgI3IZvbedHkfi40MWvk/xzKy6OhIYUce/G5Rwh8rdnR7RgOg3sdd4TniiutJqitQPKlRWN144lSQ== X-Received: by 2002:a1c:9692:: with SMTP id y140mr10469724wmd.67.1551090279517; Mon, 25 Feb 2019 02:24:39 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:38 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 2/7] ui/cocoa: Use the pixman image directly in switchSurface Date: Mon, 25 Feb 2019 10:24:28 +0000 Message-Id: <20190225102433.22401-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-3-peter.maydell@linaro.org --- ui/cocoa.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index f1171c4865..a913a51a2d 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) { @@ -1629,7 +1630,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 Mon Feb 25 10:24:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159164 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859786jad; Mon, 25 Feb 2019 02:24:41 -0800 (PST) X-Received: by 2002:adf:e548:: with SMTP id z8mr12325557wrm.52.1551090281478; Mon, 25 Feb 2019 02:24:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090281; cv=none; d=google.com; s=arc-20160816; b=ScLyeJ53375Bupr5W7rrWYYJfvDOY1HTrMLgw2WUtbytwHV1u1QLVtanRNJRT30zBw i0jk8DpltkjQvd7srIO9mwVHSwM7JX74ihExRm7lvvSdoE0YqkDSlZt02JGgUd9r3u0D 0BX0/H/e4R37xzWpalTW1HX0IMun0znmM6l0WyKicCO7Vqc8NHwTxGWvEHctkfQ9rA65 BnIhcvTqZ1AyShLESoXFg7frIKX78byY1kLDbThuvyV1yD/8AYRJwXWH+VGQxHGuafoB nZ9OyWaiZpV9q9gCgVsdVgmIsGefuA43OmEmlD9VJO73rx5zQGfVoE8xRh0Sby1FZCFn gdZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=i/Mt82y4dHNRk1P+265eWJmzywuWVVP6gso7jf/FCQQ=; b=AsJX9x7NSWyTpEJRM0pMNZbReGBqGj7gt3e1UdVFDn9s+puXhBvz2/aD97C7RrSzOG SLcoKvn7FPfw+fWAYVs7X9UR1L65MNDSYbfo28f+K+VTr7BHCIBng3jBapsqJAJNH5Im mB3iXOcxyJUtKuYvVp0GNNdrc/FDhfaymxh4ZGnJhtR5Q5dHrggT3bwG/sp0LDXSixRY NITL2i/Nz6vAX54uy2SWwJ/QoCD8j7SyoZH0IkXc1vs9eLbrEtnyuSbtNKY8CCVO9ASI EHn1e2zAcRxTqSgUVBV6hZvoQl3+Jn1oC+tAqDOJjabnDpGCY0Wo1LvjwfoWzuS5feVw knVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cFocpPd9; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id x10sor4978187wmc.25.2019.02.25.02.24.41 for (Google Transport Security); Mon, 25 Feb 2019 02:24:41 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cFocpPd9; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=i/Mt82y4dHNRk1P+265eWJmzywuWVVP6gso7jf/FCQQ=; b=cFocpPd9Gwptx1TKBkT80B1i9+2VIdupz4itXR8DwZtWjRV4OBgxVedAhDYUgdIze9 CVKLk2yANvU1BoM/wx7dAsiiDMvZ9kKxG08hNMrf+fUEHQ7B633++QcRxwDsnNWStV4c t3ccBicEApm87C8Pu1rs6etdnwF+hePEOfLDgZvvd9urq36brMGmCbHXPhxH6uR/5/Ro jG62wQwcpdQbgYEfTmz5RJvwuBLGyANx8GRj9Zs6K80bqP+C6SzrIWsbuqhCneztHNlV 9LXvtRMxwxLV3Cu6Pdc/8COfgaNqdIKd7Q+q8X6OqoEZcl+YUfpvQIAsyc9LqfrQ7DVU IlEg== 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=i/Mt82y4dHNRk1P+265eWJmzywuWVVP6gso7jf/FCQQ=; b=OAObrz151enJGQp1SVJ3PZ3Cn4gsUdXYFkmked6jkTWIOoTU5vDs17gz7ybevDqVS9 3yhrwRj4SA5xwVCn0nYcucDqJybwuxabNS2/mdI68minqbwAALavVPkTVWa3nBvKNJlu cpuSV7/6g4CNT7ZNQdqmCU3esPbfflJUtIBMkCumaY8pxbTmc+WhYBGdeqr1PCdWk4QI JLd/qxBMU+3XPfZ4DN3YLN1kEnJgLBYRrV+M4GKJ2yfFUxzTp+7ntsaJxxbfcpp1x58z XZACQP215ACAwEbAA2tPKa9vabOYO7YCMPFVEjZmuKHOB1gyIo9R0a+lqMP0J8CqCS14 mabw== X-Gm-Message-State: AHQUAuZZnyQj2V8+V3uanFSQdxY1oKxPG2fGfNeSyqqSyxYR2sgTRC7H DWMjaZ2gvaiIozn3HINNjJvhC7ii X-Google-Smtp-Source: AHgI3IYn2oS6gdyz96u1iikweLWDY2KJZu3l2g4k/Z9GVVqHvXuucidc88OMRYODTPigTBgoOKLG9g== X-Received: by 2002:a1c:700a:: with SMTP id l10mr10904349wmc.13.1551090281075; Mon, 25 Feb 2019 02:24:41 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:40 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 3/7] ui/cocoa: Factor out initial menu creation Date: Mon, 25 Feb 2019 10:24:29 +0000 Message-Id: <20190225102433.22401-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-4-peter.maydell@linaro.org --- ui/cocoa.m | 78 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 37 deletions(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index a913a51a2d..4baec0b2ff 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1465,43 +1465,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; @@ -1585,6 +1550,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 Mon Feb 25 10:24:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159165 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859810jad; Mon, 25 Feb 2019 02:24:43 -0800 (PST) X-Received: by 2002:adf:9dc4:: with SMTP id q4mr12559642wre.330.1551090282990; Mon, 25 Feb 2019 02:24:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090282; cv=none; d=google.com; s=arc-20160816; b=M44vjQRD+pHrNCocdVGX9OOC7mXOewpXDpivD5KycK+av3aFwCXvbaSuRolNjz/p6q WWcimdoODMkXM0BHBGRGMgUXg8lfb7Sgd+8umne8uvgBEiHHGMEPObcdwdoczkBIRVWZ V/y/ddGMo2StOYy6F51cIjr2i1CKQr1Zp2omd/9R2brdPFd6jcQjmc4RqjoXU5yFXY/r 46qj61hIs0+qzbDyL4oP1sSyEb/wGDxxbeWuad6rfs2lj1kA8tYWKvdLXP/17eHbjhnw j6kjmvImliHMPdwvxDANDnyNLiofWB5+CT6V6o1HQOWkmUXA0Q4coSKbqJmd1Pxm1U6X NOtw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=qKHYmK4Qjd/L8Bxby+U0AcrdM9zpOx8LLP3umMgo5pY=; b=Ul/tNNK8rF4RrdUX1hEWZS7HjHcu6KN0735pePgtEmBEp6T6VhEewMy3yt0gOmnVIN lBszMjUIGuIRHnRWjSEHM9CFC4YRfIRuzIELX6/PswIWSCQlrvnaKgUsHO3BPoXLcAZt Ixb7iHuznkBPqmFWbs3ArWQk6b+HEsu0yWwos1DrQY8fsyNL7kNrB4v2vhVLikSxdfgS NYqb2xuh1VWji/uealNgCTgVpfKs4Cop7vW4VeypeVuqZcxUB3HiqvMPZ9/HQNipp4Uq BEeGlMOLr92PDcN7oyNunDXi6DgwLMlyu6xnJFSch94B19Wjj/bhFnHLRVvsL0sGHeXV Gr3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="v/u0vHn9"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id h5sor4936377wml.3.2019.02.25.02.24.42 for (Google Transport Security); Mon, 25 Feb 2019 02:24:42 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="v/u0vHn9"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=qKHYmK4Qjd/L8Bxby+U0AcrdM9zpOx8LLP3umMgo5pY=; b=v/u0vHn9KwcBYMfLhyQQm3KF4O/JStEDEgcg5HhwD6BX4sX82HvKXrCzcAC8xkzLf+ QGk9ZWjij1sVIBB08UkSGEIHs+mqlz7YyBQZwuVPVNBfXhM92JTkMs8tTZ8YkfUzHDey TEmMOPiIwK0fw1KXYOETlYKuGxJ3pcypG/nvNzbyRqcuxoSyxaT7FjMVdgl1WyZJLj0c bXtIJpTSO83ws+NaWClIlRDWikI0jxKsGqvfkrmMeaN+ZxmdlSUcL1SZSmh/VQbVoejs UC3UWd6hOcsog5TFuqN7UBIAXFM72avUuA3V77/hDkKEg4xyg4iwXb8qmL0wH9C2uBx/ DnQQ== 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=qKHYmK4Qjd/L8Bxby+U0AcrdM9zpOx8LLP3umMgo5pY=; b=aadgPkuKVT0tX6bUNfS85bkBHUjKyCuuZBTkjkyFFMu0eQN2WIOjg2SgbFHFzcIY/Y OO98+YSvheeb1XsmclmUGkxN/PYVmOZwVNts0D1HZEcN3Owk1DenemBzsY3v6caQ2Z+Z w1sVOe5BNFOJ5XO9L6cxYgsYZeaFa6mpGeHobGl4l8HmkzmshoUqFYTHrhY3KwJ7AoDq 3Coe999AyYb0Hc+hzD7W2uMycaAjgTF1SI0tVmJ/+uKy9r7rWzftCSAVHC1/8q41/JgH x6JlbWSIuop5X3D+P26khWlkiD1XWSRpqioj5xIFZ039HxEoqGxyLnt3HtXBd9hh/f1g yhog== X-Gm-Message-State: AHQUAuZlSbmy/PQfOWa0q+neE9Ih5POj+AyRWi0ReNLjTEibT5Vm8TqE qjOogC61ImsU34xA04Y5wVumOM5E X-Google-Smtp-Source: AHgI3IaG9i0vQrA6L2HJT6rbuYYcTmyFUkielQ0yg2ZvqxbgLuZjzZ0C2mhfz/8AZPD3zy8DIfnQsA== X-Received: by 2002:a1c:5fc5:: with SMTP id t188mr9784494wmb.86.1551090282499; Mon, 25 Feb 2019 02:24:42 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:41 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 4/7] ui/cocoa: Move console/device menu creation code up in file Date: Mon, 25 Feb 2019 10:24:30 +0000 Message-Id: <20190225102433.22401-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-5-peter.maydell@linaro.org --- ui/cocoa.m | 184 ++++++++++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index 4baec0b2ff..d1fc1a6aff 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1552,6 +1552,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; @@ -1680,98 +1772,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 Mon Feb 25 10:24:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159166 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859824jad; Mon, 25 Feb 2019 02:24:44 -0800 (PST) X-Received: by 2002:a7b:c38d:: with SMTP id s13mr9536611wmj.151.1551090284533; Mon, 25 Feb 2019 02:24:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090284; cv=none; d=google.com; s=arc-20160816; b=d1TdqTofYDNFX4uqZZKNWBkz1oZ87tE0lEihDf+yHIyEaHqNE++DQdCVRQuxiVpvTK SjfNOipyYoA9T2OBfOJYa9/m7gkLCHStxGnV5iU+KyItBtOzrBuL/aFqkSJofAFycql3 s6tll6ttDChP4vBmibZw7PB4tZfqhKCbalXRXj53YqZYPU/efzhoKLZ025CJz3gdM1Id WY5kTdDqbQ7l6iB3lMMCUGKNlP3Mf/zVrdrmcts7neozDWoT9Xr6lUaV6yxKm/lmDvyd 8iS0cN/aJol2OMml3TsIv1PAfitJFBZ9hgq6SCHeFiRa2hN7h5CbN9LOx1MRmDXkSYkN jWLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=wbnpQMYk0xGvZOa47pDN5/IqA0K+yihWn/3R2zb8SJU=; b=RHEH58CcltpWNKUca7D1b1SW+8Py8ES26jAfIMvh0KUZIKbn+heOzwFnEPQwZz2UXv h7LF5/ux6KyOMwgDTxzu0P9qzmBW87BWyxb7Vz7a4QzZ5P2FrfbfSm1QPDHdqynVGNZy 4jI6VwPclaeS0VECvJ1DDtTqvucpKPVYygztOkVovBEXZ1gQGKap//FWGSk3kM9qwcbf 0VP68rT21yq67RE1BGVpT2gDI02o89pHUkhqByZXv715mBXHQ8R7exvT9VIA/W8z8D8Y 4YKi4CSllqoIpIQAKOF2YK7rCzpltzVi7+xUib7CX9xrZu8S6EEqZszm5ONi2+GgT5DK 1amQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ac6cQBZk; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id x4sor3664073wro.11.2019.02.25.02.24.44 for (Google Transport Security); Mon, 25 Feb 2019 02:24:44 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ac6cQBZk; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=wbnpQMYk0xGvZOa47pDN5/IqA0K+yihWn/3R2zb8SJU=; b=ac6cQBZktnwzMsfE2h18B4tYKoXeFdNQxkSnrrCnMovjgAy84u4RckloC6+RXPx3/q hHooS0+bi4iSnVmEufqFUDQGTbxOyi1S/Hk8636/AT/42/sALEubWjZGwU8iQact3ZER WXVgo5YjdBi3eGOVfU3f6ROY77PlNJErr7yISLN6hpPpO5NwqrLi9d1JKU58hueUBfnY I5TfnUx474mkEZ2YaJxa4eDelFa+ynCldduoDR50ww3ofxGH+2mEs2hUxO/qf9kV51KH sa0vPFDs53lbblVx3lssSZrRhaG+5QGgWIJKQEsxmGujzsK8BGgtSAdG9XqdpwjYePxj l/Wg== 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=wbnpQMYk0xGvZOa47pDN5/IqA0K+yihWn/3R2zb8SJU=; b=KdgCjx2Q9xfHQ5O67MqGUegtm7nwKq5lc+Tv5wjBtYfSpSTQEA+LqSGtacrfbETJEf bVCkH02y9Giaqt7kJiU0oq0PEljyqi68v50EZ8sOMrc5kgSMG7IEl+JOHwTvTMTt/srX ZA0noYUph3mEkwi4J8tvh/+jxW/aSgWaHROzMTJ0hIex/ufjrS4lDkgHRsAzR1Fs7Ma+ qgAcWUoKpide9mukqbqqygq6EhH1rTKy6VzNvAGxZvViUKa7buiu4djXVJJSbtBjp9tl ssWbi8JBBqsjLIUqcOUzPDvnr1z0oCJFKYIWewo8x2gAhHQNDquyj0QUXyod4YnLu3Ns Ln4A== X-Gm-Message-State: AHQUAubqqPRyUOrYuhupZwaHLwXtYvR19SgkX15CLCLz3ZOnb2Ws8lRz NWQzFCd0G3UjigNRPbPtzpmEDE7Z X-Google-Smtp-Source: AHgI3IaRDmkzOP1+CVDkIv5psfsOmgeMqJxHgRHI9sD3zv96GPPKmldp5Bc3Lk+qns6zXfZVemvypA== X-Received: by 2002:adf:f543:: with SMTP id j3mr11513733wrp.220.1551090284111; Mon, 25 Feb 2019 02:24:44 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:43 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 5/7] ui/cocoa: Don't call NSApp sendEvent directly from handleEvent Date: Mon, 25 Feb 2019 10:24:31 +0000 Message-Id: <20190225102433.22401-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-6-peter.maydell@linaro.org --- Changes since v2: remove stray whitespace --- ui/cocoa.m | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index d1fc1a6aff..1b54d42aba 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 @@ -1753,7 +1770,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 Mon Feb 25 10:24:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159167 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859844jad; Mon, 25 Feb 2019 02:24:45 -0800 (PST) X-Received: by 2002:adf:e8c7:: with SMTP id k7mr12310754wrn.298.1551090285745; Mon, 25 Feb 2019 02:24:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090285; cv=none; d=google.com; s=arc-20160816; b=GUwUSD9YAiCMHGZAlFdhgw0zTEKRaEVYAFSP2O4nXrLu3HfTkXWPwreovX1pLwPjWE R2D/lPzmm9PphqKU8lgSefym981FGuTWzURjD8z7V7PX3Ispii5CDUw1o+ZI3ROkqsjm 8Vklf6JowfYxpn0dEYwSWxxFVLRqcPvOQ/27pV91aubltcWZ6KR1dsC8eyjsb77BhCKz qY54dHsQxLxxshbPyZF6NVS7Bmkxombyqb+eNCs6u525762uCodtVLxdnHO0RVjT06MP sJDvwHi164he7PLDyOaujmI5uBJp0aisg8PaLU+0h3fU5ol4SAAxi66wBXtViygWWXYO AiaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=OQubsVuFR/3sd2NQ4tJInwiBhLa2q6Blp0Uha5UjYKY=; b=S0LHNymin81LF+AfuEIQJ6ivvSXRqa7lNgK4ZkK2cM208ASuyZ2vOIBgbt7KBWqOfr QrL9GzUZz29Ksnis3eK70AEGFRgpDQzrW1v376xpulKLjofiDI8Rqag2wvEfNeoaxexj 01bddeT7vf20EsW1n9I6vBpqZU/G87iqWE/nYpxBsYAR2q0T4ohGWdF+wXTltgkUQPOT Ehbd3dq3p58sI4i9o5dQYzOAk07A+1jaq/4uGkUknGS1UczU2R2h3BarphCimL2CeMqY lI3caSjdlZtiFcsXe8RyMqi943FXz2YmvbMHGxms27kJORsDwYAc8bs28iYoPd8XT4u9 BpPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Gmm/dKIu"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.41 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id g11sor5666574wru.22.2019.02.25.02.24.45 for (Google Transport Security); Mon, 25 Feb 2019 02:24:45 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Gmm/dKIu"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.41 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=OQubsVuFR/3sd2NQ4tJInwiBhLa2q6Blp0Uha5UjYKY=; b=Gmm/dKIuXWVIqy+n02OVc9/4yWqq8L+li2EJfkdMwntmm7aV4iU6ZH89q8WdBD4Hfh bQxQeb3aQirrQaRg44XL0JTseSfB+LNhQIxvndCfZzcj9uXyzKFBetMgUOGG2sSeMw0M TmN9WqmW6hXPF8FM5Lr5n/aLRh5kyL++IlZ9WG0YocanIwQu7NZYNI259mjjv6L3jZO2 iWwOinjnrku5PqrALZFZKTsR4A0UUvaaPdY6ilvC5nV2ceeQmnuEDC+I9hkPNJfTN3Xy sQUCYytBqXEOLkMNpkp/Y9THl0ZWnq1uIOeb9yPdpeOgYPQRmB5QdHExmFGp+vbCxkYp BNOw== 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=OQubsVuFR/3sd2NQ4tJInwiBhLa2q6Blp0Uha5UjYKY=; b=NLhSN6MEtHLrYWhA+pprSSAQa4HkWJz/Nw3hzjjEuqB1+1KBMIfbI/qNIwxgCsJyRF tiWhRsEvgvwb6kc9imZeC3U0Ju+2+b4mOnp+Vcz0hmO4ziI23eOBKRsQPR7KA3kjo+77 CkrqWXOdQevMS5bpwIvm5EnR7fdjaJZ9cW2DS4J688Ydv9ewNSz0uQQY1Q+T/L4embLi uHB4mWwUMOrqYGzO8v95RRS2qwW0eE7tmpjKKcNcbqTCMk+um8cQAFQnRBRb6fetE1vG 4ruMr/hGUppkO6HUfPgRAqqZMn8aC2yHyBKKPOM3vAN8KMsih/k+uVfIK2GBN74105lz sRJQ== X-Gm-Message-State: AHQUAuY+scAYKOBD192UR11Ph8r8pVU33BbFsTBJtKAFeligKqrvYvyR msBzuvsjXbGA3/H2SOZ1ActWzr8i X-Google-Smtp-Source: AHgI3IYPg9H2DA00gWqAPpAfzF8KiIS8qJowQHIXtOKW4io1SOYRf2ec2ATp5c+vRvAosXgxAnCC8Q== X-Received: by 2002:adf:b784:: with SMTP id s4mr11715726wre.155.1551090285461; Mon, 25 Feb 2019 02:24:45 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:44 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 6/7] ui/cocoa: Subclass NSApplication so we can implement sendEvent Date: Mon, 25 Feb 2019 10:24:32 +0000 Message-Id: <20190225102433.22401-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-7-peter.maydell@linaro.org --- ui/cocoa.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index 1b54d42aba..00e3db69c9 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1482,6 +1482,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 @@ -1695,7 +1706,7 @@ int main (int argc, const char * argv[]) { ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToForegroundApplication); - [NSApplication sharedApplication]; + [QemuApplication sharedApplication]; create_initial_menus(); From patchwork Mon Feb 25 10:24:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 159168 Delivered-To: patches@linaro.org Received: by 2002:a02:5cc1:0:0:0:0:0 with SMTP id w62csp1859863jad; Mon, 25 Feb 2019 02:24:47 -0800 (PST) X-Received: by 2002:a5d:4412:: with SMTP id z18mr11825846wrq.111.1551090287509; Mon, 25 Feb 2019 02:24:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551090287; cv=none; d=google.com; s=arc-20160816; b=vhSjk26/2uVr0OhPUVfGslxBOj/wmdWKeX4E51qMI6thGZVYS8Wq2Ly3ojIQZokW4y 6p2ete9tgaNJIE4N4tJFSoeN2gWFHOX65jg2sCXb/DYgggF57S89T0HOZpsNmz4nZp+p PeQXMhdbMqLeD+TUtv98coR3xmHJ/a7CcaeFThio2bY7a5kHiRNWWsIi1SilsRm3uqw1 6HNwLQ/DeP9f5m+jcGBPVLM6afVDnab/2TVpIaOjSf4VP0XJTfvCEcr/5ALePFQ8tFST azEqX/tkcbRbHKGbDgCgblMAICi17M4lLyUWxKLZHh70dR+kSZ8jLcJg+C572/+4DUM1 TU3A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=E+TwchfkM+TIEcmoNkECReQjSzjUD48vWmRIG1Td3oo=; b=0uIfSWkCaOiWkSL1b5vToXvg/v1bXfcOIUADaHfcCG/2Iue3OvpM6U1HxHe1uQRUKw 23orUZdnGgzp+J/LLpUNIoMIWTQyG+ZTNRin4mPM/AqTLqoObVwH9+lCiBJa4eUlix6J GL6t1OT4F6gKGofFUlr3USjzrK7wU/6DVrW8EyW3a7id21gBxNID1wqwqtiuslX3jmCD 7NuKlzj+eZxK5zoFc6M9HJu445TzOSc21Nhz4308mudB4U9mBZ0ZTjNzwkqhGJngzt6A 9l3iTIkxGadrwi/yOYmIuhtcJhiOonSgrLwTCTs65612Wxo5pN/ZLNIounTumR4HFnLU ZNHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="CXp/+gMX"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id n5sor5705198wrr.10.2019.02.25.02.24.47 for (Google Transport Security); Mon, 25 Feb 2019 02:24:47 -0800 (PST) Received-SPF: pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="CXp/+gMX"; spf=pass (google.com: domain of peter.maydell@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=peter.maydell@linaro.org 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=E+TwchfkM+TIEcmoNkECReQjSzjUD48vWmRIG1Td3oo=; b=CXp/+gMXAlqvnf2jofD/T8w5sGQGGjvPAWgkUsBwbad3IfydgAEGotn5GJraFxhMQX qKuJS1Ll81nEZm1oHJw1ukfCJc6+mNLpsh+ElEtTmoPpceuIHa/gH8JaySJoGgsq6bcf KdFGJpeLiDkYIXCKUzh1i34te/4xOi3aQtpobsPtUlTx8SJtqd12sp4VPsDkit/PSSBx aXaI4Kfzq8ROdfa0045npbehdK2392KziLNUC3vQBcpCCFUjcHAPHgtn/b6muBlLpdfB AesSqY1PaTis/cth1OdFtvDMqUAZ1VvtV3ToPxPHyo9bM2uSXBFfb1mxeJ8iOqj4iMXj iBeQ== 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=E+TwchfkM+TIEcmoNkECReQjSzjUD48vWmRIG1Td3oo=; b=SBQqpXWXBCCc5vQHIyb90/We9suojVlGWkZ+KplaBy4R//UGoly+6M9u8j8u6T8kuf XZWvw89wduRdKJz+AZswvVLgfA2oc627LPR2gDpuYDvnpJaDO/IzSRp26zip3hawOr4s 7Ds0jvNtfGCCzQlZJgsypHjcu7nBpv1TO0vKRivGINhVAXapTkPMNnViFocoA+xnW1Hq ZgCbUnH19X07WcHsXfJ88YUVKrMA6FFRABw6klsJ7vYzg5inoiIbRKc4MSRiptx0cgIc OMu/T3OQEIOaWo4OCK3wpay+BRAY4n0okNT369DnSxwsZCQJdle8TXbclKozMFVLw5la XxVg== X-Gm-Message-State: AHQUAuaXyn/UQRKjWB2Gx7UOXCkyjrVbWV1kCQTSADcFM+KPT0veQ+rD Wg+4kF46BMGA/Xg6oUyHn2yFbo30 X-Google-Smtp-Source: AHgI3IYPaegnOZd9wAA5f18K6Jmd/lpC+s6bp7x8oEhLFO5lX8Gwl/vlpNJAFkEWPAdTPKfaZxUxlg== X-Received: by 2002:adf:9c85:: with SMTP id d5mr11903955wre.68.1551090286967; Mon, 25 Feb 2019 02:24:46 -0800 (PST) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v10sm1764692wrn.26.2019.02.25.02.24.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Feb 2019 02:24:46 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Roman Bolshakov , BALATON Zoltan , John Arbuckle , Berkus Decker , Gerd Hoffmann , Ben Hekster Subject: [PATCH v3 7/7] ui/cocoa: Perform UI operations only on the main thread Date: Mon, 25 Feb 2019 10:24:33 +0000 Message-Id: <20190225102433.22401-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190225102433.22401-1-peter.maydell@linaro.org> References: <20190225102433.22401-1-peter.maydell@linaro.org> MIME-Version: 1.0 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 Message-id: 20190214102816.3393-8-peter.maydell@linaro.org --- Changes since v2: * remove unnecessary null check on cocoaView * make semaphores file-local * deref pixman_image in dealloc --- ui/cocoa.m | 195 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 116 insertions(+), 79 deletions(-) -- 2.17.2 (Apple Git-113) diff --git a/ui/cocoa.m b/ui/cocoa.m index 00e3db69c9..420b2411c1 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -129,6 +129,9 @@ NSTextField *pauseLabel; NSArray * supportedImageFileTypes; +static QemuSemaphore display_init_sem; +static 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; @@ -383,8 +387,10 @@ - (void) dealloc { COCOA_DEBUG("QemuCocoaView: dealloc\n"); - if (dataProviderRef) + if (dataProviderRef) { CGDataProviderRelease(dataProviderRef); + pixman_image_unref(pixman_image); + } [super dealloc]; } @@ -535,13 +541,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 +1022,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 +1109,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 +1153,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: @@ -1489,7 +1488,9 @@ @implementation QemuApplication - (void)sendEvent:(NSEvent *)event { COCOA_DEBUG("QemuApplication: sendEvent\n"); - [super sendEvent: event]; + if (![cocoaView handleEvent:event]) { + [super sendEvent: event]; + } } @end @@ -1672,32 +1673,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]; @@ -1710,12 +1738,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]; @@ -1733,17 +1773,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]; } @@ -1752,9 +1794,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]; } @@ -1766,26 +1818,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]; } @@ -1806,10 +1847,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)); @@ -1820,17 +1868,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 = {