[Qemu-devel] [PATCH] vfio: fix a typo

2019-08-22 Thread Chen Zhang via Qemu-devel
Signed-off-by: Chen Zhang 
---
 hw/vfio/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index dc3479c..c5e6fe6 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -44,7 +44,7 @@
 #define TYPE_VFIO_PCI "vfio-pci"
 #define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
 
-#define TYPE_VIFO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
+#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
 
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
 static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
@@ -3199,7 +3199,7 @@ static void vfio_pci_nohotplug_dev_class_init(ObjectClass 
*klass, void *data)
 }
 
 static const TypeInfo vfio_pci_nohotplug_dev_info = { 
-.name = TYPE_VIFO_PCI_NOHOTPLUG,
+.name = TYPE_VFIO_PCI_NOHOTPLUG,
 .parent = TYPE_VFIO_PCI,
 .instance_size = sizeof(VFIOPCIDevice),
 .class_init = vfio_pci_nohotplug_dev_class_init,
-- 
2.7.4





Re: [Qemu-devel] [PATCH 0/2] ui/cocoa: Fix input device issues on Mojave

2019-06-12 Thread Chen Zhang via Qemu-devel
Thank you and best regards.

> On Jun 12, 2019, at 6:39 PM, Peter Maydell  wrote:
> 
> On Tue, 4 Jun 2019 at 10:34, Chen Zhang  wrote:
>> 
>> The following patches fixed issues of absolute and relative input devices
>> on macOS Mojave.
>> 
>> Chen Zhang (2):
>>  ui/cocoa: Fix absolute input device grabbing issue on Mojave
>>  ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
>>device
>> 
>> ui/cocoa.m | 50 +++---
>> 1 file changed, 47 insertions(+), 3 deletions(-)
> 
> Reviewed-by: Peter Maydell 
> I'll apply these to master some time this week.
> 
> thanks
> -- PMM




[Qemu-devel] [PATCH 0/2] ui/cocoa: Fix input device issues on Mojave

2019-06-04 Thread Chen Zhang via Qemu-devel
The following patches fixed issues of absolute and relative input devices on 
macOS Mojave.

Chen Zhang (2):
  ui/cocoa: Fix absolute input device grabbing issue on Mojave
  ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
device

 ui/cocoa.m | 50 +++---
 1 file changed, 47 insertions(+), 3 deletions(-)

-- 
2.21.0




[Qemu-devel] [PATCH 1/2] ui/cocoa: Fix absolute input device grabbing issue on Mojave

2019-06-04 Thread Chen Zhang via Qemu-devel
On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
the cursor in re-entry into the virtual screen area. In some cases,
the `window` property of NSEvent object was nil after cursor exiting from
window, hinting that the `-locationInWindow` method would return value in 
screen coordinates. The current implementation used raw locations from 
NSEvent without considering whether the value was for the window coordinates
or the macOS screen coordinates, nor the zooming factor for Zoom-to-Fit in
fullscreen mode.

In fullscreen mode, the fullscreen cocoa window might not be the key
window, therefore the location of event in virtual coordinates should
suffice.

This patches fixed boundary check methods for cursor in normal
and fullscreen with/without Zoom-to-Fit in Mojave.

Note: CGRect, -convertRectToScreen: and -convertRectFromScreen: were
used in coordinates conversion for compatibility reason.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..474d44cb9f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,41 @@ QemuCocoaView *cocoaView;
 return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
 }
 
+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+// XXX: Use CGRect and -convertRectFromScreen: to support macOS 10.10
+CGRect r = CGRectZero;
+r.origin = [ev locationInWindow];
+if (!eventWindow) {
+if (!isFullscreen) {
+return [[self window] convertRectFromScreen:r].origin;
+} else {
+CGPoint locationInSelfWindow = [[self window] 
convertRectFromScreen:r].origin;
+CGPoint loc = [self convertPoint:locationInSelfWindow 
fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return r.origin;
+} else {
+CGPoint loc = [self convertPoint:r.origin fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else {
+return [[self window] convertRectFromScreen:[eventWindow 
convertRectToScreen:r]].origin;
+}
+}
+
 - (void) hideCursor
 {
 if (!cursor_hide) {
@@ -704,7 +739,8 @@ QemuCocoaView *cocoaView;
 int keycode = 0;
 bool mouse_event = false;
 static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
+// Location of event in virtual screen coordinates
+NSPoint p = [self screenLocationOfEvent:event];
 
 switch ([event type]) {
 case NSEventTypeFlagsChanged:
@@ -815,7 +851,10 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeMouseMoved:
 if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+// Cursor re-entered into a window might generate events bound 
to screen coordinates
+// and `nil` window property, and in full screen mode, current 
window might not be
+// key window, where event location alone should suffice.
+if (![self screenContainsPoint:p] || !([[self window] 
isKeyWindow] || isFullscreen)) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
-- 
2.21.0




[Qemu-devel] [PATCH 2/2] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-06-04 Thread Chen Zhang via Qemu-devel
In fullscreen mode, the window property of cocoaView may not be the key
window, and the current implementation would not re-grab cursor by left click
in fullscreen mode after ungrabbed in fullscreen mode with hot-key ctrl-opt-g.

This patch used value of isFullscreen as a short-cirtuit condition for
relative input device grabbing.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 474d44cb9f..aa7cf07368 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -901,7 +901,12 @@ QemuCocoaView *cocoaView;
 case NSEventTypeLeftMouseUp:
 mouse_event = true;
 if (!isMouseGrabbed && [self screenContainsPoint:p]) {
-if([[self window] isKeyWindow]) {
+/*
+ * In fullscreen mode, the window of cocoaView may not be the
+ * key window, therefore the position relative to the virtual
+ * screen alone will be sufficient.
+ */
+if(isFullscreen || [[self window] isKeyWindow]) {
 [self grabMouse];
 }
 }
-- 
2.21.0




[Qemu-devel] [PATCH 2/2] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-06-04 Thread Chen Zhang via Qemu-devel
In fullscreen mode, the window property of cocoaView may not be the key
window, and the current implementation would not re-grab cursor by left click
in fullscreen mode after ungrabbed in fullscreen mode with hot-key ctrl-opt-g.

This patch used value of isFullscreen as a short-cirtuit condition for
relative input device grabbing.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 474d44cb9f..aa7cf07368 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -901,7 +901,12 @@ QemuCocoaView *cocoaView;
 case NSEventTypeLeftMouseUp:
 mouse_event = true;
 if (!isMouseGrabbed && [self screenContainsPoint:p]) {
-if([[self window] isKeyWindow]) {
+/*
+ * In fullscreen mode, the window of cocoaView may not be the
+ * key window, therefore the position relative to the virtual
+ * screen alone will be sufficient.
+ */
+if(isFullscreen || [[self window] isKeyWindow]) {
 [self grabMouse];
 }
 }
-- 
2.21.0





[Qemu-devel] [PATCH 1/2] ui/cocoa: Fix absolute input device grabbing issue on Mojave

2019-06-04 Thread Chen Zhang via Qemu-devel
On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
the cursor in re-entry into the virtual screen area. In some cases,
the `window` property of NSEvent object was nil after cursor exiting from
window, hinting that the `-locationInWindow` method would return value in 
screen coordinates. The current implementation used raw locations from 
NSEvent without considering whether the value was for the window coordinates
or the macOS screen coordinates, nor the zooming factor for Zoom-to-Fit in
fullscreen mode.

In fullscreen mode, the fullscreen cocoa window might not be the key
window, therefore the location of event in virtual coordinates should
suffice.

This patches fixed boundary check methods for cursor in normal
and fullscreen with/without Zoom-to-Fit in Mojave.

Note: CGRect, -convertRectToScreen: and -convertRectFromScreen: were
used in coordinates conversion for compatibility reason.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..474d44cb9f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,41 @@ QemuCocoaView *cocoaView;
 return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
 }
 
+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+// XXX: Use CGRect and -convertRectFromScreen: to support macOS 10.10
+CGRect r = CGRectZero;
+r.origin = [ev locationInWindow];
+if (!eventWindow) {
+if (!isFullscreen) {
+return [[self window] convertRectFromScreen:r].origin;
+} else {
+CGPoint locationInSelfWindow = [[self window] 
convertRectFromScreen:r].origin;
+CGPoint loc = [self convertPoint:locationInSelfWindow 
fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return r.origin;
+} else {
+CGPoint loc = [self convertPoint:r.origin fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else {
+return [[self window] convertRectFromScreen:[eventWindow 
convertRectToScreen:r]].origin;
+}
+}
+
 - (void) hideCursor
 {
 if (!cursor_hide) {
@@ -704,7 +739,8 @@ QemuCocoaView *cocoaView;
 int keycode = 0;
 bool mouse_event = false;
 static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
+// Location of event in virtual screen coordinates
+NSPoint p = [self screenLocationOfEvent:event];
 
 switch ([event type]) {
 case NSEventTypeFlagsChanged:
@@ -815,7 +851,10 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeMouseMoved:
 if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+// Cursor re-entered into a window might generate events bound 
to screen coordinates
+// and `nil` window property, and in full screen mode, current 
window might not be
+// key window, where event location alone should suffice.
+if (![self screenContainsPoint:p] || !([[self window] 
isKeyWindow] || isFullscreen)) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
-- 
2.21.0





[Qemu-devel] [PATCH 0/2] ui/cocoa: Fix input device issues on Mojave

2019-06-04 Thread Chen Zhang via Qemu-devel
The following patches fixed issues of absolute and relative input devices 
on macOS Mojave.

Chen Zhang (2):
  ui/cocoa: Fix absolute input device grabbing issue on Mojave
  ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
device

 ui/cocoa.m | 50 +++---
 1 file changed, 47 insertions(+), 3 deletions(-)

-- 
2.21.0




[Qemu-devel] [PATCH RESEND 0/2] ui/cocoa: Fix absolute and relative input issues on Mojave

2019-04-27 Thread Chen Zhang via Qemu-devel
The following patches fixed absolute and relative input device issues on macOS 
Mojave.

Chen Zhang (2):
  ui/cocoa: Fix absolute input device grabbing issue on Mojave
  ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
device

 ui/cocoa.m | 50 +++---
 1 file changed, 47 insertions(+), 3 deletions(-)

-- 
2.19.2

[Qemu-devel] [PATCH RESEND 1/2] ui/cocoa: Fix absolute input device grabbing issue on Mojave

2019-04-27 Thread Chen Zhang via Qemu-devel
This patches fixed boundary check methods for cursor in normal and
fullscreen modes with/without Zoom-to-Fit on Mojave.

On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
the cursor in re-entry into the virtual screen area. In some cases,
the `window` property of NSEvent object was nil after exit of cursor,
meaning that the `-locationInWindow` method would return value in screen
coordinates. The current implementation used raw locations frrom NSEvent
without considering whether the value was for the window coordinates or
the macOS screen coordinates, nor the zooming factor for Zoom-to-Fit in
fullscreen mode.

In fullscreen mode, the fullscreen cocoa window might not be the key
window, therefore the location of event in virtual coordinates should
suffice.

Note: CGRect, -convertRectToScreen: and -convertRectFromScreen: were
used in coordinates conversion for compatibility reason.

Signed-off-by: Chen Zhang mailto:tgfb...@me.com>>
---
ui/cocoa.m | 43 +--
1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..474d44cb9f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,41 @@ QemuCocoaView *cocoaView;
return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
}

+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+// XXX: Use CGRect and -convertRectFromScreen: to support macOS 10.10
+CGRect r = CGRectZero;
+r.origin = [ev locationInWindow];
+if (!eventWindow) {
+if (!isFullscreen) {
+return [[self window] convertRectFromScreen:r].origin;
+} else {
+CGPoint locationInSelfWindow = [[self window] 
convertRectFromScreen:r].origin;
+CGPoint loc = [self convertPoint:locationInSelfWindow 
fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return r.origin;
+} else {
+CGPoint loc = [self convertPoint:r.origin fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else {
+return [[self window] convertRectFromScreen:[eventWindow 
convertRectToScreen:r]].origin;
+}
+}
+
- (void) hideCursor
{
if (!cursor_hide) {
@@ -704,7 +739,8 @@ QemuCocoaView *cocoaView;
int keycode = 0;
bool mouse_event = false;
static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
+// Location of event in virtual screen coordinates
+NSPoint p = [self screenLocationOfEvent:event];

switch ([event type]) {
case NSEventTypeFlagsChanged:
@@ -815,7 +851,10 @@ QemuCocoaView *cocoaView;
break;
case NSEventTypeMouseMoved:
if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+// Cursor re-entered into a window might generate events bound 
to screen coordinates
+// and `nil` window property, and in full screen mode, current 
window might not be
+// key window, where event location alone should suffice.
+if (![self screenContainsPoint:p] || !([[self window] 
isKeyWindow] || isFullscreen)) {
if (isMouseGrabbed) {
[self ungrabMouse];
}
-- 
2.19.2

[Qemu-devel] [PATCH RESEND 2/2] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-04-27 Thread Chen Zhang via Qemu-devel
In fullscreen mode, the window property of cocoaView may not be the key
window, and the current implementation would not grab mouse in fullscreen
mode after user ungrabs cursor in fullscreen mode with hot-key, and left
clicks the relative input devices to re-grab it.

This patch used value of isFullscreen as a short-cirtuit condition for
relative input device grabbing.

Signed-off-by: Chen Zhang mailto:tgfb...@me.com>>
---
ui/cocoa.m | 7 ++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 474d44cb9f..aa7cf07368 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -901,7 +901,12 @@ QemuCocoaView *cocoaView;
case NSEventTypeLeftMouseUp:
mouse_event = true;
if (!isMouseGrabbed && [self screenContainsPoint:p]) {
-if([[self window] isKeyWindow]) {
+/*
+ * In fullscreen mode, the window of cocoaView may not be the
+ * key window, therefore the position relative to the virtual
+ * screen alone will be sufficient.
+ */
+if(isFullscreen || [[self window] isKeyWindow]) {
[self grabMouse];
}
}
-- 
2.19.2

Re: [Qemu-devel] [PATCH 0/2] ui/cocoa: Fix absolute and relative input issues on Mojave

2019-04-21 Thread Chen Zhang via Qemu-devel
Ping

https://patchwork.kernel.org/patch/10888727/ 


https://patchwork.kernel.org/patch/10888725/ 



> On Apr 8, 2019, at 10:04 AM, Chen Zhang  wrote:
> 
> The following patches fixed absolute and relative input device issues on 
> macOS Mojave.
> 
> Chen Zhang (2):
>   ui/cocoa: Fix absolute input device grabbing issue on Mojave
>   ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
> device
> 
>  ui/cocoa.m | 50 +++---
>  1 file changed, 47 insertions(+), 3 deletions(-)
> 
> -- 
> 2.19.2
> 



[Qemu-devel] [PATCH] hvf: Add missing break statement

2019-04-21 Thread Chen Zhang via Qemu-devel
In target/i386/hvf/hvf.c, a break statement was probably missing in 
`hvf_vcpu_exec()`, in handling EXIT_REASON_HLT.

These lines seemed to be equivalent to `kvm_handle_halt()`.

Signed-off-by: Chen Zhang 
---
 target/i386/hvf/hvf.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 42f9447303..2751c8125c 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -708,6 +708,7 @@ int hvf_vcpu_exec(CPUState *cpu)
 !(idtvec_info & VMCS_IDT_VEC_VALID)) {
 cpu->halted = 1;
 ret = EXCP_HLT;
+break;
 }
 ret = EXCP_INTERRUPT;
 break;
-- 
2.21.0




Re: [Qemu-devel] [PATCH 0/2] ui/cocoa: Fix absolute and relative input issues on Mojave

2019-04-14 Thread Chen Zhang via Qemu-devel
ping

> On Apr 8, 2019, at 10:04 AM, Chen Zhang  wrote:
> 
> The following patches fixed absolute and relative input device issues on 
> macOS Mojave.
> 
> Chen Zhang (2):
>   ui/cocoa: Fix absolute input device grabbing issue on Mojave
>   ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
> device
> 
>  ui/cocoa.m | 50 +++---
>  1 file changed, 47 insertions(+), 3 deletions(-)
> 
> -- 
> 2.19.2
> 



[Qemu-devel] [PATCH 1/2] ui/cocoa: Fix absolute input device grabbing issue on

2019-04-07 Thread Chen Zhang via Qemu-devel
This patches fixed boundary check methods for cursor in normal and
fullscreen modes with/without Zoom-to-Fit on Mojave.

On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
the cursor in re-entry into the virtual screen area. In some cases,
the `window` property of NSEvent object was nil after exit of cursor,
meaning that the `-locationInWindow` method would return value in screen
coordinates. The current implementation used raw locations frrom NSEvent
without considering whether the value was for the window coordinates or
the macOS screen coordinates, nor the zooming factor for Zoom-to-Fit in
fullscreen mode.

In fullscreen mode, the fullscreen cocoa window might not be the key
window, therefore the location of event in virtual coordinates should
suffice.

Note: CGRect, -convertRectToScreen: and -convertRectFromScreen: were
used in coordinates conversion for compatibility reason.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..474d44cb9f 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,41 @@ QemuCocoaView *cocoaView;
 return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
 }
 
+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+// XXX: Use CGRect and -convertRectFromScreen: to support macOS 10.10
+CGRect r = CGRectZero;
+r.origin = [ev locationInWindow];
+if (!eventWindow) {
+if (!isFullscreen) {
+return [[self window] convertRectFromScreen:r].origin;
+} else {
+CGPoint locationInSelfWindow = [[self window] 
convertRectFromScreen:r].origin;
+CGPoint loc = [self convertPoint:locationInSelfWindow 
fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return r.origin;
+} else {
+CGPoint loc = [self convertPoint:r.origin fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else {
+return [[self window] convertRectFromScreen:[eventWindow 
convertRectToScreen:r]].origin;
+}
+}
+
 - (void) hideCursor
 {
 if (!cursor_hide) {
@@ -704,7 +739,8 @@ QemuCocoaView *cocoaView;
 int keycode = 0;
 bool mouse_event = false;
 static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
+// Location of event in virtual screen coordinates
+NSPoint p = [self screenLocationOfEvent:event];
 
 switch ([event type]) {
 case NSEventTypeFlagsChanged:
@@ -815,7 +851,10 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeMouseMoved:
 if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+// Cursor re-entered into a window might generate events bound 
to screen coordinates
+// and `nil` window property, and in full screen mode, current 
window might not be
+// key window, where event location alone should suffice.
+if (![self screenContainsPoint:p] || !([[self window] 
isKeyWindow] || isFullscreen)) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
-- 
2.19.2




[Qemu-devel] [PATCH 2/2] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-04-07 Thread Chen Zhang via Qemu-devel
In fullscreen mode, the window property of cocoaView may not be the key
window, and the current implementation would not grab mouse in fullscreen
mode after user ungrabs cursor in fullscreen mode with hot-key, and left
clicks the relative input devices to re-grab it.

This patch used value of isFullscreen as a short-cirtuit condition for
relative input device grabbing.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 474d44cb9f..aa7cf07368 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -901,7 +901,12 @@ QemuCocoaView *cocoaView;
 case NSEventTypeLeftMouseUp:
 mouse_event = true;
 if (!isMouseGrabbed && [self screenContainsPoint:p]) {
-if([[self window] isKeyWindow]) {
+/*
+ * In fullscreen mode, the window of cocoaView may not be the
+ * key window, therefore the position relative to the virtual
+ * screen alone will be sufficient.
+ */
+if(isFullscreen || [[self window] isKeyWindow]) {
 [self grabMouse];
 }
 }
-- 
2.19.2




[Qemu-devel] [PATCH 0/2] ui/cocoa: Fix absolute and relative input issues on Mojave

2019-04-07 Thread Chen Zhang via Qemu-devel
The following patches fixed absolute and relative input device issues on macOS 
Mojave.

Chen Zhang (2):
  ui/cocoa: Fix absolute input device grabbing issue on Mojave
  ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input
device

 ui/cocoa.m | 50 +++---
 1 file changed, 47 insertions(+), 3 deletions(-)

-- 
2.19.2



Re: [Qemu-devel] [PATCH] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-04-05 Thread Chen Zhang via Qemu-devel
ping

http://patchwork.ozlabs.org/patch/1059842/

> On Mar 27, 2019, at 10:00 AM, Chen Zhang  wrote:
> 
> 
> 
>> On Mar 27, 2019, at 12:20 AM, Peter Maydell  wrote:
>> 
>> On Thu, 21 Mar 2019 at 07:10, Chen Zhang  wrote:
>>> 
>>> In fullscreen mode, the window property of cocoaView may not be the key
>>> window, and the current implementation would not grab mouse in
>>> fullscreen mode after left clicks on relative input devices.
>>> 
>>> This patch used isFullscreen value as a short-cirtuit condition for
>>> relative input device grabbing.
>>> 
>>> Note that this patch should be tested after applying a previous patch
>>> which fixed event location conversion for relative input devices.
>>> 
>>> Signed-off-by: Chen Zhang 
>> 
>> Can you explain in more detail when this patch makes a
>> difference, please? (for instance, a set of instructions
>> for reproducing the issue).
>> 
> 
>> I'm confused, because in the toggleFullScreen method, when
>> we switch to full screen mode (which is the only place where
>> we set isFullscreen to true) we always do a [self grabMouse].
>> So if we get into the event handling function and isFullscreen
>> is true, I think the mouse should already be grabbed. What
>> am I missing ?
> Hi,
> 
> In fullscreen mode, when the mouse is un-grabbed by pressing Cmd-Opt-g, it 
> would not be re-grabbed by clicks in the view, as the window of the view 
> would not be key window by then.
> 
> BTW, the Ctrl-Alt-Xs in ui/cocoa.m was confusing in the context. Should they 
> be replaced by Cmd-Opt-Xs?
>> 
>> thanks
>> -- PMM
> 
> Best Regards,



Re: [Qemu-devel] [PATCH v2] ui/cocoa: Fix absolute input device grabbing issues on Mojave

2019-04-05 Thread Chen Zhang via Qemu-devel
ping

http://patchwork.ozlabs.org/patch/1058186/

> On Mar 28, 2019, at 10:05 AM, Chen Zhang  wrote:
> 
> 
> 
>> On Mar 27, 2019, at 7:37 PM, Peter Maydell  wrote:
>> 
>> On Wed, 27 Mar 2019 at 01:09, Chen Zhang  wrote:
>>> Just double-checked on a MacMini mid 2011 with macOS 10.13.6, Xcode 10.1. 
>>> This NSWindow API did exist, and the patch could be built without error.
>>> Searching convertPointFromScreen in Xcode.app’s platform SDK showed that it 
>>> was defined at line 440 in NSWindow.h of AppKit.framework.
>>> 
>>> May I ask what build environment did you use (as printed by `xcode-select 
>>> -p`)?
>> 
>> manooth$ xcode-select -p
>> /Applications/Xcode.app/Contents/Developer
>> 
>> But that doesn't seem to be what the C compiler is actually
>> using, because the error messages quote the filename
>> /System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h
>> There is no convertPointFromScreen in that header; but there
>> is one in both of
>> 
>> /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h
>> 
>> and
>> /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h
>> 
>> which are the other two copies of NSWindow.h this machine has.
>> 
>> thanks
>> -- PMM
> This was really odd.
> 
> I tried to figure out what was wrong with the toolchain and run `xcode-select 
> --install` and `xcode-select --switch`. After the this, clang failed like 
> what you mentioned.
> 
> I had to re-configure qemu with --extra-cflags="-isysroot `xcrun 
> --show-sdk-path`”, forcing clang to use the correct SDK root, and then it 
> would compile.
> 
> Thanks and best regards,




Re: [Qemu-devel] [PATCH v2] ui/cocoa: Fix absolute input device grabbing issues on Mojave

2019-03-27 Thread Chen Zhang via Qemu-devel



> On Mar 27, 2019, at 7:37 PM, Peter Maydell  wrote:
> 
> On Wed, 27 Mar 2019 at 01:09, Chen Zhang  wrote:
>> Just double-checked on a MacMini mid 2011 with macOS 10.13.6, Xcode 10.1. 
>> This NSWindow API did exist, and the patch could be built without error.
>> Searching convertPointFromScreen in Xcode.app’s platform SDK showed that it 
>> was defined at line 440 in NSWindow.h of AppKit.framework.
>> 
>> May I ask what build environment did you use (as printed by `xcode-select 
>> -p`)?
> 
> manooth$ xcode-select -p
> /Applications/Xcode.app/Contents/Developer
> 
> But that doesn't seem to be what the C compiler is actually
> using, because the error messages quote the filename
> /System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h
> There is no convertPointFromScreen in that header; but there
> is one in both of
> 
> /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h
> 
> and
> /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSWindow.h
> 
> which are the other two copies of NSWindow.h this machine has.
> 
> thanks
> -- PMM
This was really odd.

I tried to figure out what was wrong with the toolchain and run `xcode-select 
--install` and `xcode-select --switch`. After the this, clang failed like what 
you mentioned.

I had to re-configure qemu with --extra-cflags="-isysroot `xcrun 
--show-sdk-path`”, forcing clang to use the correct SDK root, and then it would 
compile.

Thanks and best regards,


Re: [Qemu-devel] [PATCH] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-03-26 Thread Chen Zhang via Qemu-devel



> On Mar 27, 2019, at 12:20 AM, Peter Maydell  wrote:
> 
> On Thu, 21 Mar 2019 at 07:10, Chen Zhang  wrote:
>> 
>> In fullscreen mode, the window property of cocoaView may not be the key
>> window, and the current implementation would not grab mouse in
>> fullscreen mode after left clicks on relative input devices.
>> 
>> This patch used isFullscreen value as a short-cirtuit condition for
>> relative input device grabbing.
>> 
>> Note that this patch should be tested after applying a previous patch
>> which fixed event location conversion for relative input devices.
>> 
>> Signed-off-by: Chen Zhang 
> 
> Can you explain in more detail when this patch makes a
> difference, please? (for instance, a set of instructions
> for reproducing the issue).
> 

> I'm confused, because in the toggleFullScreen method, when
> we switch to full screen mode (which is the only place where
> we set isFullscreen to true) we always do a [self grabMouse].
> So if we get into the event handling function and isFullscreen
> is true, I think the mouse should already be grabbed. What
> am I missing ?
Hi,

In fullscreen mode, when the mouse is un-grabbed by pressing Cmd-Opt-g, it 
would not be re-grabbed by clicks in the view, as the window of the view would 
not be key window by then.

BTW, the Ctrl-Alt-Xs in ui/cocoa.m was confusing in the context. Should they be 
replaced by Cmd-Opt-Xs?
> 
> thanks
> -- PMM

Best Regards,


Re: [Qemu-devel] [PATCH v2] ui/cocoa: Fix absolute input device grabbing issues on Mojave

2019-03-26 Thread Chen Zhang via Qemu-devel



> On Mar 27, 2019, at 12:15 AM, Peter Maydell  wrote:
> 
> On Tue, 19 Mar 2019 at 03:51, Chen Zhang  > wrote:
>> 
>> On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
>> the cursor in re-entry into the virtual screen area. In some cases,
>> the `window` property of NSEvent object is nil, after exit of cursor,
>> meaning that the `-locationInWindow` method would return value in screen
>> coordinates. Current implementation used raw locations from NSEvent
>> without considering whether the value was for the window coordinates or
>> the macOS screen coordinates, nor was the zooming factor for Zoom-to-Fit
>> included for fullscreen mode.
>> 
>> In fullscreen mode, the fullscreen cocoa window might not be the key
>> window, therefore location of event in virtual coordinates should suffice
>> for the condition of grabbing.
>> 
>> This patch fixed boundary check methods for cursor in normal and fullscreen
>> with/without Zoom-to-Fit on macOS Mojave.
>> 
>> Signed-off-by: Chen Zhang 
>> ---
>> ui/cocoa.m | 39 +--
>> 1 file changed, 37 insertions(+), 2 deletions(-)
>> 
> 
> Hi; this doesn't compile for me, I'm afraid. I've appended the full
> compiler error log, but the problem seems to be that
> the convertPointFromScreen method of NSWindow doesn't exist.
> I'm not entirely sure why, since the API docs say that method
> was introduced in OSX 10.12 and I'm running 10.13.6, but
> at least at the moment our minimum OSX version is 10.10,
> so we need something to handle that anyway.
Hi,

Just double-checked on a MacMini mid 2011 with macOS 10.13.6, Xcode 10.1. This 
NSWindow API did exist, and the patch could be built without error.
Searching convertPointFromScreen in Xcode.app’s platform SDK showed that it was 
defined at line 440 in NSWindow.h of AppKit.framework.

May I ask what build environment did you use (as printed by `xcode-select -p`)?
> 
> (http://codeworkshop.net/objc-diff/sdkdiffs/macos/10.14/AppKit.html 
> 
> suggests that maybe the docs are wrong and this method
> was only added in 10.14; that would certainly fit the symptoms.)
> 
> 
> /Users/pm215/src/qemu/ui/cocoa.m:414:35: warning: instance method
> '-convertPointFromScreen:' not found
>  (return type defaults to 'id') [-Wobjc-method-access]
>return [[self window] convertPointFromScreen:[ev 
> locationInWindow]];
>  ^~
> /System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:191:12:
> note: receiver is instance of class declared here
> @interface NSWindow : NSResponder  NSUserInterfaceValidations, NSUserInterfaceItemIdenti...
>   ^
> /Users/pm215/src/qemu/ui/cocoa.m:414:20: error: returning 'id' from a
> function with incompatible result type 'CGPoint'
>  (aka 'struct CGPoint')
>return [[self window] convertPointFromScreen:[ev 
> locationInWindow]];
>   ^~~~
> /Users/pm215/src/qemu/ui/cocoa.m:416:61: warning: instance method
> '-convertPointFromScreen:' not found
>  (return type defaults to 'id') [-Wobjc-method-access]
>CGPoint loc = [self convertPoint:[[self window]
> convertPointFromScreen:[ev locationInWindow]] fromView:nil];
> 
> ^~
> /System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:191:12:
> note: receiver is instance of class declared here
> @interface NSWindow : NSResponder  NSUserInterfaceValidations, NSUserInterfaceItemIdenti...
>   ^
> /Users/pm215/src/qemu/ui/cocoa.m:416:46: error: sending 'id' to
> parameter of incompatible type 'NSPoint' (aka 'struct CGPoint')
>CGPoint loc = [self convertPoint:[[self window]
> convertPointFromScreen:[ev locationInWindow]] fromView:nil];
> 
> ^~~~
> /System/Library/Frameworks/AppKit.framework/Headers/NSView.h:196:34:
> note: passing argument to parameter 'point' here
> - (NSPoint)convertPoint:(NSPoint)point fromView:(nullable NSView *)view;
> ^
> /Users/pm215/src/qemu/ui/cocoa.m:435:67: warning: instance method
> '-convertPointToScreen:' not found
>  (return type defaults to 'id') [-Wobjc-method-access]
>return [[self window] convertPointFromScreen:[eventWindow
> convertPointToScreen:[ev locationInWindow]]];
> 
> ^~~~
> /System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:191:12:
> note: receiver is instance of class declared here
> @interface NSWindow : NSResponder  NSUserInterfaceValidations, NSUserInterfaceItemIdenti...
>   ^
> /Users/pm215/src/qemu/ui/cocoa.m:435:31: warning: instance method
> '-convertPointFromScreen:' not found
>  (return type defaults to 'id') [-Wobjc-method-access]
>return [[self window] convertPointFromScreen:[eventWindow
> convertPointToScreen:[ev 

[Qemu-devel] [PATCH] ui/cocoa: Fix mouse grabbing in fullscreen mode for relative input device

2019-03-21 Thread Chen Zhang via Qemu-devel
In fullscreen mode, the window property of cocoaView may not be the key
window, and the current implementation would not grab mouse in
fullscreen mode after left clicks on relative input devices.

This patch used isFullscreen value as a short-cirtuit condition for
relative input device grabbing.

Note that this patch should be tested after applying a previous patch
which fixed event location conversion for relative input devices.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..51463bb931 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -862,7 +862,12 @@ QemuCocoaView *cocoaView;
 case NSEventTypeLeftMouseUp:
 mouse_event = true;
 if (!isMouseGrabbed && [self screenContainsPoint:p]) {
-if([[self window] isKeyWindow]) {
+/*
+ * In fullscreen mode, the window of cocoaView may not be the
+ * key window, therefore the position relative to the virtual
+ * screen alone will be sufficient.
+ */
+if(isFullscreen || [[self window] isKeyWindow]) {
 [self grabMouse];
 }
 }
-- 
2.19.2




[Qemu-devel] [PATCH v2] ui/cocoa: Fix absolute input device grabbing issues on Mojave

2019-03-18 Thread Chen Zhang via Qemu-devel
On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing
the cursor in re-entry into the virtual screen area. In some cases,
the `window` property of NSEvent object is nil, after exit of cursor,
meaning that the `-locationInWindow` method would return value in screen
coordinates. Current implementation used raw locations from NSEvent
without considering whether the value was for the window coordinates or
the macOS screen coordinates, nor was the zooming factor for Zoom-to-Fit
included for fullscreen mode.

In fullscreen mode, the fullscreen cocoa window might not be the key 
window, therefore location of event in virtual coordinates should suffice
for the condition of grabbing.

This patch fixed boundary check methods for cursor in normal and fullscreen
with/without Zoom-to-Fit on macOS Mojave.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 39 +--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..21c20e8dd9 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,37 @@ QemuCocoaView *cocoaView;
 return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
 }
 
+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+if (!eventWindow) {
+if (!isFullscreen) {
+return [[self window] convertPointFromScreen:[ev 
locationInWindow]];
+} else {
+CGPoint loc = [self convertPoint:[[self window] 
convertPointFromScreen:[ev locationInWindow]] fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return [ev locationInWindow];
+} else {
+CGPoint loc = [self convertPoint:[ev locationInWindow] 
fromView:nil];
+if (stretch_video) {
+loc.x /= cdx;
+loc.y /= cdy;
+}
+return loc;
+}
+} else {
+return [[self window] convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
+}
+}
+
 - (void) hideCursor
 {
 if (!cursor_hide) {
@@ -704,7 +735,8 @@ QemuCocoaView *cocoaView;
 int keycode = 0;
 bool mouse_event = false;
 static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
+// Location of event in virtual screen coordinates
+NSPoint p = [self screenLocationOfEvent:event];
 
 switch ([event type]) {
 case NSEventTypeFlagsChanged:
@@ -815,7 +847,10 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeMouseMoved:
 if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+// Cursor re-entered into a window may generate events in 
screen coordinates
+// and `nil` window property, and in full screen mode, current 
window may not be
+// key window, where event location alone should suffice.
+if (![self screenContainsPoint:p] || !([[self window] 
isKeyWindow] || isFullscreen)) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
-- 
2.19.2




[Qemu-devel] [PATCH 1/2] ui/cocoa: Fix absolute input device grabbing issues on Mojave

2019-03-15 Thread Chen Zhang via Qemu-devel


Signed-off-by: Chen Zhang mailto:tgfb...@me.com>>
---
ui/cocoa.m | 29 +
1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..5d0a6599d9 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,24 @@ QemuCocoaView *cocoaView;
return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
}

+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+if (!eventWindow) {
+   return [self.window convertPointFromScreen:[ev locationInWindow]];
+} else if ([self.window isEqual:eventWindow]) {
+return [ev locationInWindow];
+} else {
+return [self.window convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
+}
+}
+
+- (BOOL) screenContainsPointOfEvent:(NSEvent *)ev
+{
+return [self screenContainsPoint:[self screenLocationOfEvent:ev]];
+}
+
- (void) hideCursor
{
if (!cursor_hide) {
@@ -815,7 +833,9 @@ QemuCocoaView *cocoaView;
break;
case NSEventTypeMouseMoved:
if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+BOOL is_key_window = [[self window] isKeyWindow];
+BOOL is_in_screen =  [self screenContainsPointOfEvent: event];
+if (!is_in_screen || !is_key_window) {
if (isMouseGrabbed) {
[self ungrabMouse];
}
@@ -927,9 +947,10 @@ QemuCocoaView *cocoaView;
 * The check on screenContainsPoint is to avoid sending out of 
range values for
 * clicks in the titlebar.
 */
-if ([self screenContainsPoint:p]) {
-qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, 0, 
screen.width);
-qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height 
- p.y, 0, screen.height);
+if ([self screenContainsPointOfEvent:event]) {
+CGPoint loc = [self screenLocationOfEvent: event];
+qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, loc.x, 0, 
screen.width);
+qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height 
- loc.y, 0, screen.height);
}
} else {
qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event 
deltaX]);
-- 
2.19.2

[Qemu-devel] [PATCH 2/2] ui/cocoa: fix grabbing issue in fullscreen mode

2019-03-15 Thread Chen Zhang via Qemu-devel
Signed-off-by: Chen Zhang mailto:tgfb...@me.com>>
---
ui/cocoa.m | 35 +++
1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5d0a6599d9..8e74f6e283 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -410,11 +410,31 @@ QemuCocoaView *cocoaView;
{
NSWindow *eventWindow = [ev window];
if (!eventWindow) {
-   return [self.window convertPointFromScreen:[ev locationInWindow]];
-} else if ([self.window isEqual:eventWindow]) {
-return [ev locationInWindow];
+if (!isFullscreen) {
+return [[self window] convertPointFromScreen:[ev 
locationInWindow]];
+} else {
+CGPoint loc = [self convertPoint:[[self window] 
convertPointFromScreen:[ev locationInWindow]] fromView:nil];
+if (!stretch_video) {
+return loc;
+}
+loc.x /= cdx;
+loc.y /= cdy;
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return [ev locationInWindow];
+} else {
+CGPoint loc = [self convertPoint:[ev locationInWindow] 
fromView:nil];
+if (!stretch_video) {
+return loc;
+}
+loc.x /= cdx;
+loc.y /= cdy;
+return loc;
+}
} else {
-return [self.window convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
+return [[self window] convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
}
}

@@ -722,7 +742,6 @@ QemuCocoaView *cocoaView;
int keycode = 0;
bool mouse_event = false;
static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];

switch ([event type]) {
case NSEventTypeFlagsChanged:
@@ -835,7 +854,7 @@ QemuCocoaView *cocoaView;
if (isAbsoluteEnabled) {
BOOL is_key_window = [[self window] isKeyWindow];
BOOL is_in_screen =  [self screenContainsPointOfEvent: event];
-if (!is_in_screen || !is_key_window) {
+if (!is_in_screen || !(is_key_window || isFullscreen)) {
if (isMouseGrabbed) {
[self ungrabMouse];
}
@@ -881,7 +900,7 @@ QemuCocoaView *cocoaView;
break;
case NSEventTypeLeftMouseUp:
mouse_event = true;
-if (!isMouseGrabbed && [self screenContainsPoint:p]) {
+if (!isMouseGrabbed && [self screenContainsPointOfEvent:event]) {
if([[self window] isKeyWindow]) {
[self grabMouse];
}
@@ -944,7 +963,7 @@ QemuCocoaView *cocoaView;
if (isMouseGrabbed) {
if (isAbsoluteEnabled) {
/* Note that the origin for Cocoa mouse coords is bottom left, 
not top left.
- * The check on screenContainsPoint is to avoid sending out of 
range values for
+ * The check on screenContainsPointOfEvent is to avoid sending 
out of range values for
 * clicks in the titlebar.
 */
if ([self screenContainsPointOfEvent:event]) {
-- 
2.19.2

[Qemu-devel] [PATCH 2/2] ui/cocoa: fix grabbing issue in fullscreen mode

2019-03-15 Thread Chen Zhang via Qemu-devel
Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 5d0a6599d9..8e74f6e283 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -410,11 +410,31 @@ QemuCocoaView *cocoaView;
 {
 NSWindow *eventWindow = [ev window];
 if (!eventWindow) {
-   return [self.window convertPointFromScreen:[ev locationInWindow]];
-} else if ([self.window isEqual:eventWindow]) {
-return [ev locationInWindow];
+if (!isFullscreen) {
+return [[self window] convertPointFromScreen:[ev 
locationInWindow]];
+} else {
+CGPoint loc = [self convertPoint:[[self window] 
convertPointFromScreen:[ev locationInWindow]] fromView:nil];
+if (!stretch_video) {
+return loc;
+}
+loc.x /= cdx;
+loc.y /= cdy;
+return loc;
+}
+} else if ([[self window] isEqual:eventWindow]) {
+if (!isFullscreen) {
+return [ev locationInWindow];
+} else {
+CGPoint loc = [self convertPoint:[ev locationInWindow] 
fromView:nil];
+if (!stretch_video) {
+return loc;
+}
+loc.x /= cdx;
+loc.y /= cdy;
+return loc;
+}
 } else {
-return [self.window convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
+return [[self window] convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
 }
 }
 
@@ -722,7 +742,6 @@ QemuCocoaView *cocoaView;
 int keycode = 0;
 bool mouse_event = false;
 static bool switched_to_fullscreen = false;
-NSPoint p = [event locationInWindow];
 
 switch ([event type]) {
 case NSEventTypeFlagsChanged:
@@ -835,7 +854,7 @@ QemuCocoaView *cocoaView;
 if (isAbsoluteEnabled) {
 BOOL is_key_window = [[self window] isKeyWindow];
 BOOL is_in_screen =  [self screenContainsPointOfEvent: event];
-if (!is_in_screen || !is_key_window) {
+if (!is_in_screen || !(is_key_window || isFullscreen)) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
@@ -881,7 +900,7 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeLeftMouseUp:
 mouse_event = true;
-if (!isMouseGrabbed && [self screenContainsPoint:p]) {
+if (!isMouseGrabbed && [self screenContainsPointOfEvent:event]) {
 if([[self window] isKeyWindow]) {
 [self grabMouse];
 }
@@ -944,7 +963,7 @@ QemuCocoaView *cocoaView;
 if (isMouseGrabbed) {
 if (isAbsoluteEnabled) {
 /* Note that the origin for Cocoa mouse coords is bottom left, 
not top left.
- * The check on screenContainsPoint is to avoid sending out of 
range values for
+ * The check on screenContainsPointOfEvent is to avoid sending 
out of range values for
  * clicks in the titlebar.
  */
 if ([self screenContainsPointOfEvent:event]) {
-- 
2.19.2




[Qemu-devel] [PATCH 1/2] Fix absolute input device grabbing issues on Mojave

2019-03-15 Thread Chen Zhang via Qemu-devel


Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 29 +
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..5d0a6599d9 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -405,6 +405,24 @@ QemuCocoaView *cocoaView;
 return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
 }
 
+/* Get location of event and convert to virtual screen coordinate */
+- (CGPoint) screenLocationOfEvent:(NSEvent *)ev
+{
+NSWindow *eventWindow = [ev window];
+if (!eventWindow) {
+   return [self.window convertPointFromScreen:[ev locationInWindow]];
+} else if ([self.window isEqual:eventWindow]) {
+return [ev locationInWindow];
+} else {
+return [self.window convertPointFromScreen:[eventWindow 
convertPointToScreen:[ev locationInWindow]]];
+}
+}
+
+- (BOOL) screenContainsPointOfEvent:(NSEvent *)ev
+{
+return [self screenContainsPoint:[self screenLocationOfEvent:ev]];
+}
+
 - (void) hideCursor
 {
 if (!cursor_hide) {
@@ -815,7 +833,9 @@ QemuCocoaView *cocoaView;
 break;
 case NSEventTypeMouseMoved:
 if (isAbsoluteEnabled) {
-if (![self screenContainsPoint:p] || ![[self window] 
isKeyWindow]) {
+BOOL is_key_window = [[self window] isKeyWindow];
+BOOL is_in_screen =  [self screenContainsPointOfEvent: event];
+if (!is_in_screen || !is_key_window) {
 if (isMouseGrabbed) {
 [self ungrabMouse];
 }
@@ -927,9 +947,10 @@ QemuCocoaView *cocoaView;
  * The check on screenContainsPoint is to avoid sending out of 
range values for
  * clicks in the titlebar.
  */
-if ([self screenContainsPoint:p]) {
-qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, 0, 
screen.width);
-qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height 
- p.y, 0, screen.height);
+if ([self screenContainsPointOfEvent:event]) {
+CGPoint loc = [self screenLocationOfEvent: event];
+qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, loc.x, 0, 
screen.width);
+qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height 
- loc.y, 0, screen.height);
 }
 } else {
 qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event 
deltaX]);
-- 
2.19.2




[Qemu-devel] [PATCH 0/2] ui/cocoa: Fix absolute input device grabbing issue on Mojave

2019-03-15 Thread Chen Zhang via Qemu-devel
On Mojave, absolute input device, i.e. tablet, had trouble re-grabbing the 
cursor in re-entry into the virtual screen area. In some cases, the `window` 
property of NSEvent object is nil, after exit of cursor, meaning that the 
`-locationInWindow` method would return value in screen coordinates. The 
current implementation used raw locations from NSEvent without considering 
whether the value was for the window coordinates or the macOS screen 
coordinates, nor the zooming factor for Zoom-to-Fit in fullscreen mode.

The following patches fixed boundary check methods for cursor in normal and 
fullscreen with/without Zoom-to-Fit in Mojave.

Chen Zhang (2):
  Fix absolute input device grabbing issues on Mojave
  ui/cocoa: fix grabbing issue in fullscreen mode

 ui/cocoa.m | 54 +++---
 1 file changed, 47 insertions(+), 7 deletions(-)

-- 
2.19.2




Re: [Qemu-devel] [PATCH] ui/cocoa: Adding cursor support

2019-03-14 Thread Chen Zhang via Qemu-devel



> On Mar 14, 2019, at 1:35 AM, BALATON Zoltan  wrote:
> 
> On Wed, 13 Mar 2019, Chen Zhang wrote:
>> I sympathize with your situation, but the things on macOS seems a little 
>> different.
>> 
>> The QEMU Cocoa UI starts in the `main` thread and detach a `qemu_main` 
>> thread which runs stuff in vl.c etc. On the contrary, QEMU with gtk and 
>> other UIs just scheduled its event loop in the qemu_main thread without 
>> detaching a dedicated thread. These two kinds of event loop(, the cocoa one 
>> and the glib one,) do not mix well.
> 
> I was following the recent ui/cocoa.m changes so I'm aware of this.
> 
>> A second problem is that recently Cocoa UI event handling routine is locking 
>> io threads with qemu_mutex_lock_iothread(), and this may delay bottom halves 
>> and subsequently the dpy_mouse_set calls, as glib_pollfds_poll() is also 
>> protected by qemu_mutex_lock_iothread().
>> 
>> My preliminary guess is that all mouse NSEvents must be queued and processed 
>> in a way not breaking any causal order.  Maybe the next NSEvent shall not be 
>> processed before the corresponding dpy_mouse_set call.
> 
> Sorry if this was not clear but the cursor change to black square problem is 
> not cocoa UI related and we've actually seen it on Linux with gtk (I think, 
> it was reported to me, not reproduced by me). Maybe I should not have mixed 
> that in here and report independently.
> 
> Based on my experience with the ati-vga model where I've implemented hardware 
> cursor both with dpy_cursor_define()/dpy_mouse_set() and with 
> cursor_invalidate()/cursor_draw_line() callbacks I've found the latter to 
> work more smoothly. I don't know why jumpy mouse pointer happens with the 
> dpy_mouse_set() way but that's what I see. With mouse drawn from screen 
> refresh the pointer may stop when guest is busy but it won't jump around 
> unlike when it's updated on the host side on register writes not tied to 
> screen refresh. I don't know how much does it relate to your case with Cocoa 
> UI but there may be some similarities that's why I've brought this up here. 
> If it's not related just ignore my comment.
For the Cocoa UI, I tried to isolate the cursor movement issue after calling 
CGWarpMouseCursorPosition(). 

In an empty Cocoa window app with a minimal overridden -sendEvent:, a minimal 
-handleEvent:, calling CGWarpMouseCursorPosition calls upon mouse-moved event 
showed the similar cursor movement issue as in QEMU.

It was suggested that Apple throttled how frequently the cursor could be moved 
in earlier version of macOS. [1][2] However none of these workaround methods I 
found worked on Mojave so far.

Best Regards,

[1] 
https://stackoverflow.com/questions/10196603/using-cgeventsourcesetlocaleventssuppressioninterval-instead-of-the-deprecated

[2] https://lists.apple.com/archives/cocoa-dev/2012/Feb/msg00372.html
> 
> Regards,
> BALATON Zoltan
> 
>> 
>>> On Mar 12, 2019, at 8:32 PM, BALATON Zoltan  wrote:
>>> 
>>> On Tue, 12 Mar 2019, Chen Zhang via Qemu-devel wrote:
>>>> Hi,
>>>> 
>>>> I did try to utilize NSCursor and CGWarpMouseCursorPosition API before 
>>>> this compromise. In cocoa_mouse_set, the position of cursor should to be 
>>>> modified, but the bottom half that called it was not scheduled on main 
>>>> thread. UI operations have to be queued on main thread asynchronously 
>>>> thereafter. This introduced troubles.
>>>> 
>>>> One issue was that once CGWarpMouseCursorPosition(), which should not 
>>>> trigger any mouse events, was called from cocoa_mouse_set(), the cursor 
>>>> position accelerated in a positive feedback manner. This was independent 
>>>> from the association state between mouse movement and cursor.
>>>> 
>>>> Another issue was that the cursor moved several steps later than the Cocoa 
>>>> mouse events.
>>>> 
>>>> All these phenomena made me wonder if I was messing up with the host input 
>>>> source, runloop, the bottom halves and the asynchronous changes made to 
>>>> cursor positions.
>>>> 
>>>> On the other hand, rendering the cursor in the window frame buffer only 
>>>> introduce a few more dirty rectangles per second and this does not seem to 
>>>> add up any significant amount of overhead. At least it keeps the troubles 
>>>> above away.
>>> 
>>> We've also found similar mouse jumping problems with the ati-vga after 
>>> using define_cursor and host side cursor but also another problem where 
>>> cursor turned into a black square sometimes. I

Re: [Qemu-devel] [PATCH] ui/cocoa: Adding cursor support

2019-03-12 Thread Chen Zhang via Qemu-devel
Hi,

I sympathize with your situation, but the things on macOS seems a little 
different.

The QEMU Cocoa UI starts in the `main` thread and detach a `qemu_main` thread 
which runs stuff in vl.c etc. On the contrary, QEMU with gtk and other UIs just 
scheduled its event loop in the qemu_main thread without detaching a dedicated 
thread. These two kinds of event loop(, the cocoa one and the glib one,) do not 
mix well. 

A second problem is that recently Cocoa UI event handling routine is locking io 
threads with qemu_mutex_lock_iothread(), and this may delay bottom halves and 
subsequently the dpy_mouse_set calls, as glib_pollfds_poll() is also protected 
by qemu_mutex_lock_iothread().

My preliminary guess is that all mouse NSEvents must be queued and processed in 
a way not breaking any causal order.  Maybe the next NSEvent shall not be 
processed before the corresponding dpy_mouse_set call.

> On Mar 12, 2019, at 8:32 PM, BALATON Zoltan  wrote:
> 
> On Tue, 12 Mar 2019, Chen Zhang via Qemu-devel wrote:
>> Hi,
>> 
>> I did try to utilize NSCursor and CGWarpMouseCursorPosition API before this 
>> compromise. In cocoa_mouse_set, the position of cursor should to be 
>> modified, but the bottom half that called it was not scheduled on main 
>> thread. UI operations have to be queued on main thread asynchronously 
>> thereafter. This introduced troubles.
>> 
>> One issue was that once CGWarpMouseCursorPosition(), which should not 
>> trigger any mouse events, was called from cocoa_mouse_set(), the cursor 
>> position accelerated in a positive feedback manner. This was independent 
>> from the association state between mouse movement and cursor.
>> 
>> Another issue was that the cursor moved several steps later than the Cocoa 
>> mouse events.
>> 
>> All these phenomena made me wonder if I was messing up with the host input 
>> source, runloop, the bottom halves and the asynchronous changes made to 
>> cursor positions.
>> 
>> On the other hand, rendering the cursor in the window frame buffer only 
>> introduce a few more dirty rectangles per second and this does not seem to 
>> add up any significant amount of overhead. At least it keeps the troubles 
>> above away.
> 
> We've also found similar mouse jumping problems with the ati-vga after using 
> define_cursor and host side cursor but also another problem where cursor 
> turned into a black square sometimes. I think the latter happens when guest 
> sets the memory offset to the cursor (which is when I call cursor_define) but 
> only writes cursor data there later. This works if cursor data is read only 
> when rendering the cursor but fails in QEMU with cursor_define. Problem does 
> not happen with guest_hwcursor option of ati-vga that uses the cirrus 
> callbacks that read cursor data when rendering but that needs another display 
> surface to render cursor into. I cannot fix this by calling define_cursor on 
> all register writes because guest writes offset on every mouse move even if 
> it's not changed and calling cursor_define causes flickering of the pointer.
Is it possible to compare the cursor pixel data before calling define_cursor 
and avoid some redundant calls?
> 
> So I wonder if this defining cursor in the host is a good idea after all 
> given all the above problems with it. (It might be wanted for remote displays 
> as an optimisation with tradeoffs for accuracy but not as a default on local 
> displays.) Could it be modified to be called from screen update at least 
> instead of being completely async which might fix some of the problems. (I 
> can't do that from ati-vga itself because I don't want to have custom screen 
> refresh function just for this which would need reimplementing all of vga.) 
> Or maybe the cirrus callbacks could be fixed to render cursor in a similar 
> way like this patch and then use that?
> 
> I think my point is that there seems to be a problem with host side cursor 
> which would need to be solved more generally within QEMU instead of inventing 
> workarounds individually within device models and ui backends.
> 
> Regards,
> BALATON Zoltan
> 
>> 
>> Best regards,
>> 
>>> On Mar 12, 2019, at 3:26 PM, Gerd Hoffmann  wrote:
>>> 
>>> Hi,
>>> 
>>>> +if (cursorVisible && cursorImage && NSIntersectsRect(rect, 
>>>> cursorRect)) {
>>>> +CGContextDrawImage (viewContextRef, cursorRect, cursorImage);
>>> 
>>> So you are rendering the cursor to the window.
>>> 
>>> Better approach would be to just set the cursor of the host window,
>>> like the gtk UI does, using gdk_window_set_cursor().
>>> 
>>> cheers,
>>> Gerd




Re: [Qemu-devel] [PATCH] ui/cocoa: Adding cursor support

2019-03-12 Thread Chen Zhang via Qemu-devel
Hi,

I did try to utilize NSCursor and CGWarpMouseCursorPosition API before this 
compromise. In cocoa_mouse_set, the position of cursor should to be modified, 
but the bottom half that called it was not scheduled on main thread. UI 
operations have to be queued on main thread asynchronously thereafter. This 
introduced troubles.

One issue was that once CGWarpMouseCursorPosition(), which should not trigger 
any mouse events, was called from cocoa_mouse_set(), the cursor position 
accelerated in a positive feedback manner. This was independent from the 
association state between mouse movement and cursor.

Another issue was that the cursor moved several steps later than the Cocoa 
mouse events.

All these phenomena made me wonder if I was messing up with the host input 
source, runloop, the bottom halves and the asynchronous changes made to cursor 
positions.

On the other hand, rendering the cursor in the window frame buffer only 
introduce a few more dirty rectangles per second and this does not seem to add 
up any significant amount of overhead. At least it keeps the troubles above 
away.

Best regards,

> On Mar 12, 2019, at 3:26 PM, Gerd Hoffmann  wrote:
> 
>  Hi,
> 
>> +if (cursorVisible && cursorImage && NSIntersectsRect(rect, 
>> cursorRect)) {
>> +CGContextDrawImage (viewContextRef, cursorRect, cursorImage);
> 
> So you are rendering the cursor to the window.
> 
> Better approach would be to just set the cursor of the host window,
> like the gtk UI does, using gdk_window_set_cursor().
> 
> cheers,
>  Gerd



[Qemu-devel] [PATCH] ui/cocoa: Adding cursor support

2019-03-11 Thread Chen Zhang via Qemu-devel
This patch added cocoa_mouse_set() and cocoa_cursor_define(),
supporting virtio-gpu simple rendering on macOS host.

Image content, rect and visibility of the cursor buffer were added as
ivars in QemuCocoaView class. Corresponding accessors were added.

Note that the rect of the cursor was in coordinates of the QEMU
screen, not the NSScreen or the NSView, for convenience of blending.

Signed-off-by: Chen Zhang 
---
 ui/cocoa.m | 79 ++
 1 file changed, 79 insertions(+)

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 420b2411c1..8beed6e514 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -334,6 +334,9 @@ static void handleAnyDeviceErrors(Error * err)
 BOOL isFullscreen;
 BOOL isAbsoluteEnabled;
 BOOL isMouseDeassociated;
+CGRect cursorRect;
+CGImageRef cursorImage;
+BOOL cursorVisible;
 }
 - (void) switchSurface:(pixman_image_t *)image;
 - (void) grabMouse;
@@ -362,6 +365,12 @@ static void handleAnyDeviceErrors(Error * err)
 - (float) cdy;
 - (QEMUScreen) gscreen;
 - (void) raiseAllKeys;
+- (CGRect) cursorRect;
+- (void) setCursorRect:(CGRect)rect;
+- (CGImageRef) cursorImage;
+- (void) setCursorImage:(CGImageRef)image;
+- (BOOL) isCursorVisible;
+- (void) setCursorVisible:(BOOL)visible;
 @end
 
 QemuCocoaView *cocoaView;
@@ -392,6 +401,10 @@ QemuCocoaView *cocoaView;
 pixman_image_unref(pixman_image);
 }
 
+if (cursorImage) {
+CGImageRelease(cursorImage);
+}
+
 [super dealloc];
 }
 
@@ -479,6 +492,10 @@ QemuCocoaView *cocoaView;
 );
 CGContextDrawImage (viewContextRef, cgrect(rectList[i]), 
clipImageRef);
 CGImageRelease (clipImageRef);
+
+}
+if (cursorVisible && cursorImage && NSIntersectsRect(rect, 
cursorRect)) {
+CGContextDrawImage (viewContextRef, cursorRect, cursorImage);
 }
 CGImageRelease (imageRef);
 }
@@ -987,6 +1004,19 @@ QemuCocoaView *cocoaView;
 - (float) cdy {return cdy;}
 - (QEMUScreen) gscreen {return screen;}
 
+- (CGRect) cursorRect {return cursorRect;}
+- (void) setCursorRect:(CGRect)rect {cursorRect = rect;}
+- (CGImageRef) cursorImage {return cursorImage;}
+- (void) setCursorImage:(CGImageRef)image
+{
+if (cursorImage && cursorImage != image) {
+CGImageRelease(cursorImage);
+}
+cursorImage = image;
+}
+- (BOOL) isCursorVisible {return cursorVisible;}
+- (void) setCursorVisible:(BOOL)visible {cursorVisible = visible;}
+
 /*
  * Makes the target think all down keys are being released.
  * This prevents a stuck key problem, since we will not see
@@ -1830,6 +1860,53 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
 [pool release];
 }
 
+static void cocoa_cursor_define(DisplayChangeListener *dcl, QEMUCursor *c)
+{
+NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+int bitsPerComponent = [cocoaView gscreen].bitsPerComponent;
+int bitsPerPixel = [cocoaView gscreen].bitsPerPixel;
+CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, c->data, 
c->width * 4 * c->height, NULL);
+
+CGImageRef img = CGImageCreate(c->width, c->height,
+   bitsPerComponent, bitsPerPixel, c->width * 
bitsPerComponent / 2,
+#ifdef __LITTLE_ENDIAN__
+   
CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //colorspace for OS X >= 
10.4
+   kCGBitmapByteOrder32Little | 
kCGImageAlphaFirst,
+#else
+   CGColorSpaceCreateDeviceRGB(), //colorspace 
for OS X < 10.4 (actually ppc)
+   kCGImageAlphaFirst, //bitmapInfo
+#endif
+   provider, NULL, 0, 
kCGRenderingIntentDefault);
+
+CGDataProviderRelease(provider);
+CGFloat width = c->width;
+CGFloat height = c->height;
+dispatch_async(dispatch_get_main_queue(), ^{
+[cocoaView setCursorImage:img];
+CGRect rect = [cocoaView cursorRect];
+rect.size = CGSizeMake(width, height);
+[cocoaView setCursorRect:rect];
+});
+[pool release];
+}
+static void cocoa_mouse_set(DisplayChangeListener *dcl,
+int x, int y, int visible)
+{
+NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+dispatch_async(dispatch_get_main_queue(), ^{
+QEMUScreen screen = [cocoaView gscreen];
+CGRect rect = [cocoaView cursorRect];
+// Mark old cursor rect as dirty
+[cocoaView setNeedsDisplayInRect:rect];
+rect.origin = CGPointMake(x, screen.height - (y + rect.size.height));
+[cocoaView setCursorRect:rect];
+[cocoaView setCursorVisible:visible ? YES : NO];
+// Mark new cursor rect as dirty
+[cocoaView setNeedsDisplayInRect:rect];
+});
+[pool release];
+}
+
 static void cocoa_cleanup(void)
 {
 COCOA_DEBUG("qemu_cocoa: cocoa_cleanup\n");
@@ -1841,6 

[Qemu-devel] [PATCH v2] ui/egl-helpers: Augment parameter list of egl_texture_blend() to convey scales of viewport

2019-01-24 Thread Chen Zhang via Qemu-devel
From 0be823a56682be57fe0370bb91e4062ec7b47be5 Mon Sep 17 00:00:00 2001
From: Chen Zhang 
Date: Fri, 25 Jan 2019 15:33:08 +0800
Subject: [PATCH v2] ui/egl-helpers: Augment parameter list of
 egl_texture_blend() to convey scales of viewport.

 This would help gtk-egl display showing scaled DMABuf cursor images when
 gtk window was zoomed. A default scale of (1.0, 1.0) was presumed for
 call sites where no scaling is needed.

Signed-off-by: Chen Zhang 
---
 include/ui/egl-helpers.h | 2 +-
 ui/egl-headless.c| 3 ++-
 ui/egl-helpers.c | 9 +
 ui/gtk-egl.c | 3 ++-
 ui/spice-display.c   | 2 +-
 5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 3fc656a..b976cb8 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -27,7 +27,7 @@ void egl_fb_read(void *dst, egl_fb *src);
 
 void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip);
 void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
-   int x, int y);
+   int x, int y, double scale_x, double scale_y);
 
 #ifdef CONFIG_OPENGL_DMABUF
 
diff --git a/ui/egl-headless.c b/ui/egl-headless.c
index 519e7ba..e67b47a 100644
--- a/ui/egl-headless.c
+++ b/ui/egl-headless.c
@@ -142,7 +142,8 @@ static void egl_scanout_flush(DisplayChangeListener *dcl,
 egl_texture_blit(edpy->gls, >blit_fb, >guest_fb,
  !edpy->y_0_top);
 egl_texture_blend(edpy->gls, >blit_fb, >cursor_fb,
-  !edpy->y_0_top, edpy->pos_x, edpy->pos_y);
+  !edpy->y_0_top, edpy->pos_x, edpy->pos_y,
+  1.0, 1.0);
 } else {
 /* no cursor -> use simple framebuffer blit */
 egl_fb_blit(>blit_fb, >guest_fb, edpy->y_0_top);
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 5e115b3..e90eef8 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -120,14 +120,15 @@ void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, 
egl_fb *src, bool flip)
 }
 
 void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
-   int x, int y)
+   int x, int y, double scale_x, double scale_y)
 {
 glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
+int w = scale_x * src->width;
+int h = scale_y * src->height;
 if (flip) {
-glViewport(x, y, src->width, src->height);
+glViewport(x, y, w, h);
 } else {
-glViewport(x, dst->height - src->height - y,
-   src->width, src->height);
+glViewport(x, dst->height - h - y, w, h);
 }
 glEnable(GL_TEXTURE_2D);
 glBindTexture(GL_TEXTURE_2D, src->texture);
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index afd1714..42801b6 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -278,7 +278,8 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
  vc->gfx.y0_top);
 egl_texture_blend(vc->gfx.gls, >gfx.win_fb, >gfx.cursor_fb,
   vc->gfx.y0_top,
-  vc->gfx.cursor_x, vc->gfx.cursor_y);
+  vc->gfx.cursor_x, vc->gfx.cursor_y,
+  vc->gfx.scale_x, vc->gfx.scale_y);
 } else {
 egl_fb_blit(>gfx.win_fb, >gfx.guest_fb, !vc->gfx.y0_top);
 }
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 52f8cb5..aea6f6e 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -1090,7 +1090,7 @@ static void qemu_spice_gl_update(DisplayChangeListener 
*dcl,
 egl_texture_blit(ssd->gls, >blit_fb, >guest_fb,
  !y_0_top);
 egl_texture_blend(ssd->gls, >blit_fb, >cursor_fb,
-  !y_0_top, x, y);
+  !y_0_top, x, y, 1.0, 1.0);
 glFlush();
 }
 
-- 
2.7.4

Re: [Qemu-devel] [PATCH]gtk-egl: Blend cursor buffer within a scaled viewport

2019-01-24 Thread Chen Zhang via Qemu-devel
Hi,

> On Jan 24, 2019, at 8:07 PM, Gerd Hoffmann  wrote:
> 
>> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
>> index 3fc656a..63ffc2d 100644
>> --- a/include/ui/egl-helpers.h
>> +++ b/include/ui/egl-helpers.h
>> @@ -28,6 +28,8 @@ void egl_fb_read(void *dst, egl_fb *src);
>> void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool 
>> flip);
>> void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool 
>> flip,
>>int x, int y);
>> +void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool 
>> flip,
>> +int x, int y, int w, int h);
> 
> Why do you add egl_texture_blend2()?
> How about adding scale_{x,y} parameters to egl_texture_blend() instead?
It is valid to augment parameter list of egl_texture_blend(), however, there 
are 
two other callers: namely, spicy-display and egl-headless, neither of which
seems to scale any underlying viewports. In that case, default scales (1.0, 
1.0) 
shall be provided.
> 
>> +   vc->gfx.scale_x * vc->gfx.cursor_fb.width,
>> +   vc->gfx.scale_x * vc->gfx.cursor_fb.height);
>^ this should be y I guess ?
Sorry for this typo.
> 
> cheers,
>  Gerd
> 
Best regards,


Re: [Qemu-devel] [PATCH]gtk-egl: Blend cursor buffer within a scaled viewport

2019-01-23 Thread Chen Zhang via Qemu-devel
The patch pasted in previous mail lost some indentations and spaces.
Sorry.

From 7921a69f106233ebc0ff9bdc29d7c6182160fc6f Mon Sep 17 00:00:00 2001
From: Chen Zhang 
Date: Thu, 24 Jan 2019 09:16:23 +0800
Subject: [PATCH] DMABuf: Blend cursor buf within a scaled viewport

Signed-off-by: Chen Zhang 
---
 include/ui/egl-helpers.h |  2 ++
 ui/egl-helpers.c | 18 ++
 ui/gtk-egl.c |  8 +---
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 3fc656a..63ffc2d 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -28,6 +28,8 @@ void egl_fb_read(void *dst, egl_fb *src);
 void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip);
 void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
int x, int y);
+void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
+int x, int y, int w, int h);
 
 #ifdef CONFIG_OPENGL_DMABUF
 
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 5e115b3..9dddee9 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -137,6 +137,24 @@ void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, 
egl_fb *src, bool flip,
 glDisable(GL_BLEND);
 }
 
+void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
+int x, int y, int w, int h)
+{
+glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
+if (flip) {
+glViewport(x, y, w, h);
+} else {
+glViewport(x, dst->height - h - y,
+   w, h);
+}
+glEnable(GL_TEXTURE_2D);
+glBindTexture(GL_TEXTURE_2D, src->texture);
+glEnable(GL_BLEND);
+glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+qemu_gl_run_texture_blit(gls, flip);
+glDisable(GL_BLEND);
+}
+
 /* -- */
 
 #ifdef CONFIG_OPENGL_DMABUF
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index afd1714..afff0e1 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -276,9 +276,11 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
 if (vc->gfx.cursor_fb.texture) {
 egl_texture_blit(vc->gfx.gls, >gfx.win_fb, >gfx.guest_fb,
  vc->gfx.y0_top);
-egl_texture_blend(vc->gfx.gls, >gfx.win_fb, >gfx.cursor_fb,
-  vc->gfx.y0_top,
-  vc->gfx.cursor_x, vc->gfx.cursor_y);
+egl_texture_blend2(vc->gfx.gls, >gfx.win_fb, >gfx.cursor_fb,
+   vc->gfx.y0_top,
+   vc->gfx.cursor_x, vc->gfx.cursor_y,
+   vc->gfx.scale_x * vc->gfx.cursor_fb.width,
+   vc->gfx.scale_x * vc->gfx.cursor_fb.height);
 } else {
 egl_fb_blit(>gfx.win_fb, >gfx.guest_fb, !vc->gfx.y0_top);
 }
-- 
2.7.4


> On Jan 24, 2019, at 9:31 AM, Chen Zhang  wrote:
> 
> When a gtk-egl window (for gvt-g DMABuf) was zoomed, the cursor plane buffer 
> did not zoom covariantly, resulting in a mismatched cursor size. In this 
> patch, `egl_texture_blend()` is augmented with two extra parameters to convey 
> the size for a scaled viewport, as in `egl_texture_blend2()`. 
> 
> Signed-off-by: Chen Zhang 
> ---
> include/ui/egl-helpers.h | 2 ++
> ui/egl-helpers.c | 18 ++
> ui/gtk-egl.c | 8 +---
> 3 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
> index 3fc656a..63ffc2d 100644
> --- a/include/ui/egl-helpers.h
> +++ b/include/ui/egl-helpers.h
> @@ -28,6 +28,8 @@ void egl_fb_read(void *dst, egl_fb *src);
> void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip);
> void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
> int x, int y);
> +void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool 
> flip,
> + int x, int y, int w, int h);
> 
> #ifdef CONFIG_OPENGL_DMABUF
> 
> diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
> index 5e115b3..9dddee9 100644
> --- a/ui/egl-helpers.c
> +++ b/ui/egl-helpers.c
> @@ -137,6 +137,24 @@ void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, 
> egl_fb *src, bool flip,
> glDisable(GL_BLEND);
> }
> 
> +void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool 
> flip,
> + int x, int y, int w, int h)
> +{
> + glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
> + if (flip) {
> + glViewport(x, y, w, h);
> + } else {
> + glViewport(x, dst->height - h - y,
> + w, h);
> + }
> + glEnable(GL_TEXTURE_2D);
> + glBindTexture(GL_TEXTURE_2D, src->texture);
> + glEnable(GL_BLEND);
> + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
> + qemu_gl_run_texture_blit(gls, flip);
> + glDisable(GL_BLEND);
> +}
> +
> /* -- */
> 
> #ifdef CONFIG_OPENGL_DMABUF
> diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c

[Qemu-devel] [PATCH]gtk-egl: Blend cursor buffer within a scaled viewport

2019-01-23 Thread Chen Zhang via Qemu-devel

When a gtk-egl window (for gvt-g DMABuf) was zoomed, the cursor plane buffer 
did not zoom covariantly, resulting in a mismatched cursor size. In this patch, 
`egl_texture_blend()` is augmented with two extra parameters to convey the size 
for a scaled viewport, as in `egl_texture_blend2()`. 

Signed-off-by: Chen Zhang 
---
include/ui/egl-helpers.h | 2 ++
ui/egl-helpers.c | 18 ++
ui/gtk-egl.c | 8 +---
3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 3fc656a..63ffc2d 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -28,6 +28,8 @@ void egl_fb_read(void *dst, egl_fb *src);
void egl_texture_blit(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip);
void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
int x, int y);
+void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
+ int x, int y, int w, int h);

#ifdef CONFIG_OPENGL_DMABUF

diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 5e115b3..9dddee9 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -137,6 +137,24 @@ void egl_texture_blend(QemuGLShader *gls, egl_fb *dst, 
egl_fb *src, bool flip,
glDisable(GL_BLEND);
}

+void egl_texture_blend2(QemuGLShader *gls, egl_fb *dst, egl_fb *src, bool flip,
+ int x, int y, int w, int h)
+{
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, dst->framebuffer);
+ if (flip) {
+ glViewport(x, y, w, h);
+ } else {
+ glViewport(x, dst->height - h - y,
+ w, h);
+ }
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, src->texture);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ qemu_gl_run_texture_blit(gls, flip);
+ glDisable(GL_BLEND);
+}
+
/* -- */

#ifdef CONFIG_OPENGL_DMABUF
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index afd1714..afff0e1 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -276,9 +276,11 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
if (vc->gfx.cursor_fb.texture) {
egl_texture_blit(vc->gfx.gls, >gfx.win_fb, >gfx.guest_fb,
vc->gfx.y0_top);
- egl_texture_blend(vc->gfx.gls, >gfx.win_fb, >gfx.cursor_fb,
- vc->gfx.y0_top,
- vc->gfx.cursor_x, vc->gfx.cursor_y);
+ egl_texture_blend2(vc->gfx.gls, >gfx.win_fb, >gfx.cursor_fb,
+ vc->gfx.y0_top,
+ vc->gfx.cursor_x, vc->gfx.cursor_y,
+ vc->gfx.scale_x * vc->gfx.cursor_fb.width,
+ vc->gfx.scale_x * vc->gfx.cursor_fb.height);
} else {
egl_fb_blit(>gfx.win_fb, >gfx.guest_fb, !vc->gfx.y0_top);
}
--
2.7.4



Re: [Qemu-devel] [PATCH] gtk: sync guest display updates to host display refresh

2018-11-25 Thread Chen Zhang via Qemu-devel
Update refresh interval upon frame tick;
Add callback of window state events to adjust refresh rate during iconified.
The callback handle is saved in struct VirtualConsole for its removal when the 
window is iconified.

Signed-off-by: Chen Zhang 
---
 include/ui/gtk.h |  1 +
 ui/gtk.c | 48 
 2 files changed, 49 insertions(+)

diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 99edd3c..c1f7655 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -76,6 +76,7 @@ typedef struct VirtualConsole {
 GtkWidget *tab_item;
 GtkWidget *focus;
 VirtualConsoleType type;
+guint frame_tick_cb;
 union {
 VirtualGfxConsole gfx;
 #if defined(CONFIG_VTE)
diff --git a/ui/gtk.c b/ui/gtk.c
index 579990b..9bc5812 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1661,6 +1661,43 @@ static gboolean gd_configure(GtkWidget *widget,
 return FALSE;
 }
 
+static gboolean gd_frame_tick(GtkWidget *widget,
+  GdkFrameClock *frame_clock,
+  gpointer opaque)
+{
+VirtualConsole *vc = opaque;
+gint64 interval;
+gdk_frame_clock_get_refresh_info(frame_clock,
+0,
+,
+NULL);
+interval = interval / 1000;
+if (vc->gfx.dcl.update_interval != interval) {
+update_displaychangelistener(>gfx.dcl, interval);
+}
+return G_SOURCE_CONTINUE;
+}
+
+static void gd_window_state_event(GtkWidget *widget,
+   GdkEventWindowState *event,
+   GtkDisplayState *s)
+{
+if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) {
+bool iconified = (event->new_window_state & 
GDK_WINDOW_STATE_ICONIFIED) != 0;
+VirtualConsole *vc = gd_vc_find_current(s);
+if (iconified) {
+gtk_widget_remove_tick_callback(vc->gfx.drawing_area,
+vc->frame_tick_cb);
+update_displaychangelistener(>gfx.dcl, 
GUI_REFRESH_INTERVAL_IDLE);
+} else {
+vc->frame_tick_cb =
+gtk_widget_add_tick_callback(vc->gfx.drawing_area,
+ gd_frame_tick, vc, NULL);
+update_displaychangelistener(>gfx.dcl, 
GUI_REFRESH_INTERVAL_DEFAULT);
+}
+}
+}
+
 /** Virtual Console Callbacks **/
 
 static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
@@ -1911,6 +1948,17 @@ static void gd_connect_vc_gfx_signals(VirtualConsole *vc)
  G_CALLBACK(gd_focus_out_event), vc);
 g_signal_connect(vc->gfx.drawing_area, "configure-event",
  G_CALLBACK(gd_configure), vc);
+if (1 /* make that a config option ??? */) {
+update_displaychangelistener(>gfx.dcl,
+ GUI_REFRESH_INTERVAL_IDLE);
+vc->frame_tick_cb =
+gtk_widget_add_tick_callback(vc->gfx.drawing_area,
+ gd_frame_tick, vc, NULL);
+
+gtk_widget_add_events(vc->s->window, GDK_STRUCTURE_MASK);
+g_signal_connect(vc->s->window, "window-state-event",
+ G_CALLBACK(gd_window_state_event), vc->s);
+}
 } else {
 g_signal_connect(vc->gfx.drawing_area, "key-press-event",
  G_CALLBACK(gd_text_key_down), vc);
-- 
2.7.4


> On Nov 14, 2018, at 5:40 PM, Chen Zhang  wrote:
> 
> Additionally, the aforementioned patch performs OK for non-vfio OpenGL 
> enabled GTK displays, and fails DMA Buf iGVT-g display only, so far as I 
> could tell.
> 
> Perhaps a change like the following is better?
> 
>  static gboolean gd_frame_tick(GtkWidget *widget,
>GdkFrameClock *frame_clock,
>gpointer opaque)
>  {
>  VirtualConsole *vc = opaque;
> -
> -vc->gfx.dcl.ops->dpy_refresh(>gfx.dcl);
> +gint64 interval;
> +gdk_frame_clock_get_refresh_info(frame_clock,
> +0,
> +,
> +NULL);
> +interval /= 1000;
> +if (vc->gfx.dcl.update_interval != interval) {
> +update_displaychangelistener(>gfx.dcl, interval);
> +}
>  return G_SOURCE_CONTINUE;
>  }
> 
> 
>> On Nov 14, 2018, at 11:10 AM, Chen Zhang > > wrote:
>> 
>> Hi,
>> 
>> I have briefly tested this patch. Unfortunately, it apparently caused 
>> deteriorated performance on a previously working Windows 10 guest with DMA 
>> Buf.
>> 
>> The patched qemu not only clogged up graphics drawing, but also obstructed 
>> the guest OS. The boot time and latency for guest operations (e.g. clicking 
>> Start menu in guest) dramatically increased. My best guess would be that GTK 
>> update events messed up with some polling in main_loop_wait(false), leading 
>> to blocked IO, or conversely the GUI being blocked by IO.
>> 
>> Best regards,
>> 
>> --
>> P.S:
>> 
>> The arguments for 

Re: [Qemu-devel] [PATCH] gtk: sync guest display updates to host display refresh

2018-11-14 Thread Chen Zhang via Qemu-devel
Additionally, the aforementioned patch performs OK for non-vfio OpenGL enabled 
GTK displays, and fails DMA Buf iGVT-g display only, so far as I could tell.

Perhaps a change like the following is better?

 static gboolean gd_frame_tick(GtkWidget *widget,
   GdkFrameClock *frame_clock,
   gpointer opaque)
 {
 VirtualConsole *vc = opaque;
-
-vc->gfx.dcl.ops->dpy_refresh(>gfx.dcl);
+gint64 interval;
+gdk_frame_clock_get_refresh_info(frame_clock,
+0,
+,
+NULL);
+interval /= 1000;
+if (vc->gfx.dcl.update_interval != interval) {
+update_displaychangelistener(>gfx.dcl, interval);
+}
 return G_SOURCE_CONTINUE;
 }


> On Nov 14, 2018, at 11:10 AM, Chen Zhang  wrote:
> 
> Hi,
> 
> I have briefly tested this patch. Unfortunately, it apparently caused 
> deteriorated performance on a previously working Windows 10 guest with DMA 
> Buf.
> 
> The patched qemu not only clogged up graphics drawing, but also obstructed 
> the guest OS. The boot time and latency for guest operations (e.g. clicking 
> Start menu in guest) dramatically increased. My best guess would be that GTK 
> update events messed up with some polling in main_loop_wait(false), leading 
> to blocked IO, or conversely the GUI being blocked by IO.
> 
> Best regards,
> 
> --
> P.S:
> 
> The arguments for qemu:
> 
> /tmp/qemu-system-x86_64 -nodefaults -machine 
> pc,accel=kvm,usb=off,kernel_irqchip=on \
>  -vga none -display gtk,gl=on  -rtc base=localtime \
>  -device 
> vfio-pci,sysfsdev=/sys/bus/pci/devices/:00:02.0/{UUID-FOR-MDEV},x-igd-opregion=on,display=on,rombar=0
>  \
>  -m 3000 -realtime mlock=off -smp 3,sockets=1,cores=1 \
>  -drive file=/home/user/disk.img,format=qcow2,media=disk,if=ide \
>  -usb -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 \
>  -cpu host -monitor stdio
> 
> The host runs a Ubuntu 18.04 desktop.
> 
>> On Nov 13, 2018, at 5:02 PM, Gerd Hoffmann  wrote:
>> 
>> Reduce console refresh timer to idle refresh rate.  Register a frame
>> tick callback (called by gtk on each display frame) and use that to kick
>> display updates instead.
>> 
>> That should sync qemu refresh rate to display refresh rate.  It'll also
>> stop updating the qemu display in case the qemu is not visible (gtk
>> stops calling the frame tick callback then).
>> 
>> Buglink: https://bugs.launchpad.net/bugs/1802915
>> Suggested-by: Chen Zhang 
>> Signed-off-by: Gerd Hoffmann 
>> ---
>> ui/gtk.c | 16 
>> 1 file changed, 16 insertions(+)
>> 
>> diff --git a/ui/gtk.c b/ui/gtk.c
>> index 579990b865..8f79dfe42c 100644
>> --- a/ui/gtk.c
>> +++ b/ui/gtk.c
>> @@ -1661,6 +1661,16 @@ static gboolean gd_configure(GtkWidget *widget,
>>return FALSE;
>> }
>> 
>> +static gboolean gd_frame_tick(GtkWidget *widget,
>> +  GdkFrameClock *frame_clock,
>> +  gpointer opaque)
>> +{
>> +VirtualConsole *vc = opaque;
>> +
>> +vc->gfx.dcl.ops->dpy_refresh(>gfx.dcl);
>> +return G_SOURCE_CONTINUE;
>> +}
>> +
>> /** Virtual Console Callbacks **/
>> 
>> static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
>> @@ -1911,6 +1921,12 @@ static void gd_connect_vc_gfx_signals(VirtualConsole 
>> *vc)
>> G_CALLBACK(gd_focus_out_event), vc);
>>g_signal_connect(vc->gfx.drawing_area, "configure-event",
>> G_CALLBACK(gd_configure), vc);
>> +if (1 /* make that a config option ??? */) {
>> +update_displaychangelistener(>gfx.dcl,
>> + GUI_REFRESH_INTERVAL_IDLE);
>> +gtk_widget_add_tick_callback(vc->gfx.drawing_area,
>> + gd_frame_tick, vc, NULL);
>> +}
>>} else {
>>g_signal_connect(vc->gfx.drawing_area, "key-press-event",
>> G_CALLBACK(gd_text_key_down), vc);
>> -- 
>> 2.9.3
>> 
> 



Re: [Qemu-devel] [PATCH] gtk: sync guest display updates to host display refresh

2018-11-13 Thread Chen Zhang via Qemu-devel
Hi,

I have briefly tested this patch. Unfortunately, it apparently caused 
deteriorated performance on a previously working Windows 10 guest with DMA Buf.

The patched qemu not only clogged up graphics drawing, but also obstructed the 
guest OS. The boot time and latency for guest operations (e.g. clicking Start 
menu in guest) dramatically increased. My best guess would be that GTK update 
events messed up with some polling in main_loop_wait(false), leading to blocked 
IO, or conversely the GUI being blocked by IO.

Best regards,

--
P.S:

The arguments for qemu:

/tmp/qemu-system-x86_64 -nodefaults -machine 
pc,accel=kvm,usb=off,kernel_irqchip=on \
  -vga none -display gtk,gl=on  -rtc base=localtime \
  -device 
vfio-pci,sysfsdev=/sys/bus/pci/devices/:00:02.0/{UUID-FOR-MDEV},x-igd-opregion=on,display=on,rombar=0
 \
  -m 3000 -realtime mlock=off -smp 3,sockets=1,cores=1 \
  -drive file=/home/user/disk.img,format=qcow2,media=disk,if=ide \
  -usb -device qemu-xhci,id=xhci -device usb-tablet,bus=xhci.0 \
  -cpu host -monitor stdio

The host runs a Ubuntu 18.04 desktop.

> On Nov 13, 2018, at 5:02 PM, Gerd Hoffmann  wrote:
> 
> Reduce console refresh timer to idle refresh rate.  Register a frame
> tick callback (called by gtk on each display frame) and use that to kick
> display updates instead.
> 
> That should sync qemu refresh rate to display refresh rate.  It'll also
> stop updating the qemu display in case the qemu is not visible (gtk
> stops calling the frame tick callback then).
> 
> Buglink: https://bugs.launchpad.net/bugs/1802915
> Suggested-by: Chen Zhang 
> Signed-off-by: Gerd Hoffmann 
> ---
> ui/gtk.c | 16 
> 1 file changed, 16 insertions(+)
> 
> diff --git a/ui/gtk.c b/ui/gtk.c
> index 579990b865..8f79dfe42c 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -1661,6 +1661,16 @@ static gboolean gd_configure(GtkWidget *widget,
> return FALSE;
> }
> 
> +static gboolean gd_frame_tick(GtkWidget *widget,
> +  GdkFrameClock *frame_clock,
> +  gpointer opaque)
> +{
> +VirtualConsole *vc = opaque;
> +
> +vc->gfx.dcl.ops->dpy_refresh(>gfx.dcl);
> +return G_SOURCE_CONTINUE;
> +}
> +
> /** Virtual Console Callbacks **/
> 
> static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
> @@ -1911,6 +1921,12 @@ static void gd_connect_vc_gfx_signals(VirtualConsole 
> *vc)
>  G_CALLBACK(gd_focus_out_event), vc);
> g_signal_connect(vc->gfx.drawing_area, "configure-event",
>  G_CALLBACK(gd_configure), vc);
> +if (1 /* make that a config option ??? */) {
> +update_displaychangelistener(>gfx.dcl,
> + GUI_REFRESH_INTERVAL_IDLE);
> +gtk_widget_add_tick_callback(vc->gfx.drawing_area,
> + gd_frame_tick, vc, NULL);
> +}
> } else {
> g_signal_connect(vc->gfx.drawing_area, "key-press-event",
>  G_CALLBACK(gd_text_key_down), vc);
> -- 
> 2.9.3
> 




[Qemu-devel] GTK: default display refresh rate at 60Hz

2018-11-08 Thread Chen Zhang via Qemu-devel
Hi,

It’s observed that GTK display performs poorly compared with native 
environment. The display refresh timer fires at a interval of 
GUI_REFRESH_INTERVAL_DEFAULT milliseconds which is defined as 30 in 
include/ui/console.h. This throttles refresh rate to 33Hz.

Changing its value to 16 (i.e. 60Hz) seems reasonable and may actually improve 
performance.

Best regards 


Re: [Qemu-devel] [PATCH] gtk: Fix mouse offset in scaled gtk-gl display for VFIO/iGVT-g DMA Buf mode

2018-11-06 Thread Chen Zhang via Qemu-devel

Yes, this patch just works.

Thank you.

Best regards

On Nov 06, 2018, at 08:22 PM, Gerd Hoffmann  wrote:

On Wed, Oct 31, 2018 at 06:24:56AM +, Chen Zhang wrote:
The issue was reported as in https://bugs.launchpad.net/qemu/+bug/1793859

When an OpenGL accelerated GTK window is used for iGVT-g DMA Buf device,
window scaling would cause guest cursor to move in undesirable velocity.

To fix this usability issue, the gtk mouse motion events was modified to
scale the position of event to match the coordinates of the scaled GL
surface.

Hmm, we already have logic in place to deal with that. I suspect the
root cause is simply that the scale_{x,y} variables are not set properly
in egl mode. Can you try the patch below?

thanks,
Gerd

== [ cut here ] ===
From ebecaab0102aca37a3101131c20f45576835b6b3 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann 
Date: Tue, 6 Nov 2018 13:18:39 +0100
Subject: [PATCH] try fix gtk egl cursor

---
ui/gtk-egl.c | 17 -
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index a77c25b490..5420c2362b 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -68,8 +68,15 @@ void gd_egl_draw(VirtualConsole *vc)
return;
}

+ window = gtk_widget_get_window(vc->gfx.drawing_area);
+ ww = gdk_window_get_width(window);
+ wh = gdk_window_get_height(window);
+
if (vc->gfx.scanout_mode) {
gd_egl_scanout_flush(>gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
+
+ vc->gfx.scale_x = (double)ww / vc->gfx.w;
+ vc->gfx.scale_y = (double)wh / vc->gfx.h;
} else {
if (!vc->gfx.ds) {
return;
@@ -77,13 +84,13 @@ void gd_egl_draw(VirtualConsole *vc)
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
vc->gfx.esurface, vc->gfx.ectx);

- window = gtk_widget_get_window(vc->gfx.drawing_area);
- ww = gdk_window_get_width(window);
- wh = gdk_window_get_height(window);
surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);

eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
+
+ vc->gfx.scale_x = (double)ww / surface_width(vc->gfx.ds);
+ vc->gfx.scale_y = (double)wh / surface_height(vc->gfx.ds);
}
}

@@ -232,8 +239,8 @@ void gd_egl_cursor_position(DisplayChangeListener *dcl,
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);

- vc->gfx.cursor_x = pos_x;
- vc->gfx.cursor_y = pos_y;
+ vc->gfx.cursor_x = pos_x * vc->gfx.scale_x;
+ vc->gfx.cursor_y = pos_y * vc->gfx.scale_y;
}

void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
--
2.9.3



[Qemu-devel] [PATCH] gtk: Fix mouse offset in scaled gtk-gl display for VFIO/iGVT-g DMA Buf mode

2018-10-31 Thread Chen Zhang via Qemu-devel

The issue was reported as in https://bugs.launchpad.net/qemu/+bug/1793859

When an OpenGL accelerated GTK window is used for iGVT-g DMA Buf device,
window scaling would cause guest cursor to move in undesirable velocity.

To fix this usability issue, the gtk mouse motion events was modified to
scale the position of event to match the coordinates of the scaled GL
surface.

Signed-off-by: Chen Zhang 
---
 ui/gtk-egl.c | 10 +++---
 ui/gtk.c     | 19 +--
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index a77c25b..824beed 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -231,9 +231,13 @@ void gd_egl_cursor_position(DisplayChangeListener *dcl,
                             uint32_t pos_x, uint32_t pos_y)
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
-    vc->gfx.cursor_x = pos_x;
-    vc->gfx.cursor_y = pos_y;
+    uint32_t sw = surface_width(vc->gfx.ds);
+    uint32_t sh = surface_height(vc->gfx.ds);
+    GdkWindow *window = gtk_widget_get_window(vc->gfx.drawing_area);
+    uint32_t ww = gdk_window_get_width(window);
+    uint32_t wh = gdk_window_get_height(window);
+    vc->gfx.cursor_x = pos_x * ww / sw;
+    vc->gfx.cursor_y = pos_y * wh / sh;
 }
 
 void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
diff --git a/ui/gtk.c b/ui/gtk.c
index 579990b..41c82e5 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -875,20 +875,27 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
     x = (motion->x - mx) / vc->gfx.scale_x;
     y = (motion->y - my) / vc->gfx.scale_y;
 
+    bool scaled = display_opengl && !gtk_use_gl_area && s->free_scale;
     if (qemu_input_is_absolute()) {
+        int max_w = scaled ? ww : surface_width(vc->gfx.ds);
+        int max_h = scaled ? wh : surface_height(vc->gfx.ds);
         if (x < 0 || y < 0 ||
-            x >= surface_width(vc->gfx.ds) ||
-            y >= surface_height(vc->gfx.ds)) {
+            x >= max_w ||
+            y >= max_h) {
             return TRUE;
         }
         qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
-                             0, surface_width(vc->gfx.ds));
+                             0, max_w);
         qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
-                             0, surface_height(vc->gfx.ds));
+                             0, max_h);
         qemu_input_event_sync();
     } else if (s->last_set && s->ptr_owner == vc) {
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
-        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, y - s->last_y);
+        int diff_x = scaled
+            ? (x - s->last_x) * surface_width(vc->gfx.ds) / ww : (x - 
s->last_x);
+        int diff_y = scaled
+            ? (y - s->last_y) * surface_height(vc->gfx.ds) / wh : (y - 
s->last_y);
+        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, diff_x);
+        qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, diff_y);
         qemu_input_event_sync();
     }
     s->last_x = x;
-- 
2.7.4


[Qemu-devel] [PATCH] Add support for TCP path/QMP_PATH in scripts/qmp/qmp

2018-08-28 Thread Chen Zhang via Qemu-devel
From a1f93198020b8c043edab5292db39b52ac77f78b Mon Sep 17 00:00:00 2001

Signed-off-by: Zhang Chen 
---
 scripts/qmp/qmp | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/scripts/qmp/qmp b/scripts/qmp/qmp
index 6cb46fd..0e8ed19 100755
--- a/scripts/qmp/qmp
+++ b/scripts/qmp/qmp
@@ -63,6 +63,16 @@ def main(args):
 if not path:
 print("QMP path isn't set, use --path=qmp-monitor-address or set 
QMP_PATH")
 return 1
+tcp_addr = path.split(':')
+if len(tcp_addr) == 2:
+try:
+port = int(tcp_addr[1])
+except ValueError:
+print("QMP path contains a non-numeric TCP port")
+return 1
+addr = ( tcp_addr[0], port )
+else:
+addr = path
 
 if len(args):
 command, args = args[0], args[1:]
@@ -74,7 +84,7 @@ def main(args):
 if command in ['help']:
 os.execlp('man', 'man', 'qmp')
 
-srv = QEMUMonitorProtocol(path)
+srv = QEMUMonitorProtocol(addr)
 srv.connect()
 
 def do_command(srv, cmd, **kwds):
@@ -99,7 +109,7 @@ def main(args):
 raise
 return 0
 
-srv = QEMUMonitorProtocol(path)
+srv = QEMUMonitorProtocol(addr)
 srv.connect()
 
 arguments = {}
-- 
2.7.4