Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-24 Thread Vitaliy Margolen
On 01/22/2010 03:42 PM, Lauri Kenttä wrote:
>> The SetCursorPos() calls hooks on Wine because Wine has big issue - it
>> doesn't filter pointer move messages that were caused by Wine itself.
> 
> The first patch (http://source.winehq.org/patches/data/57569) tries to
> address exactly this. I think XWarpCursor is not a problem, as the event
> comes asynchronously with some delay. So my patch fixes the easier but
> worse case, calling hooks directly from SetCursorPos.
> 
> What's wrong with this, why is it wrong, and do you have a better idea?
> What else causes Wine to produce extra messages?
I'm fine with this patch. According to your test SetCursorPos() indeed
doesn't generate ll hook. Was an oversight on my part when I added that
extra queue_raw_mouse_message() call.

Just Keep the formatting the same (curly brace on it's own line). And remove
FIXME comment - it's not the only place that calls XWarpPointer(). Oh and
make it a series with your test patch. This patch being #1 and the test #2.

> Also, is there a reason why I shouldn't write a test for this to make the
> issue better known?
By all means. The way things work in Wine - if tests fail on Wine you should
use "todo_wine" at front of each failing ok() call. So 'make test' always
succeeds.

>>> I'm aware that my version causes hooks to be called with clipped
>>> coordinates on mouse move, when they should in that case be called with
>>> the unclipped ones.
>> This particular change will break all games using dinput when mouse
>> pointer goes outside of virtual desktop.
> 
> (This was the elaboration I was asking for.) I didn't know that, and I
> don't have any such games. Feel free to reject the patch, I'll rewrite it
> without this bug and in smaller chunks. (It would be helpful if the first
> two patches were also either accepted or rejected.)
I'm not the one accepting or rejecting patches - Alexandre is. I'm just one
of the developers who made lots of changes to that particular area of the
code to match what native does.

In this case I'm worrying about mouse movements on the edge of the screen.
Remember that ll hook is supposed to be called with whatever came straight
from the mouse driver. Not the pointer. And to test it you'll need to use
injected events (mouse_event). SetCursorPos() won't do for this, it only
alters pointer position.

>>> returns unclipped coordinates from GetCursorPos
>> This is what native will do inside hook handler. Add some tests.
> That's not true. (See below.)
Yes, you right here. I was thinking about something else - GetCursorPos()
returns previous position while inside hook handler.

> I've attached a program that outputs coordinates from hookproc and
> wndproc, both the passed ones and the ones from GetCursorPos. If you try
> it, you can see that Wine has the following bugs:
> - incorrect coordinates in some WM:s
> - incorrect coordinates in some hook calls
> - incorrect coordinates and missing WM:s after clipping
> - extra hook calls on SetCursorPos, even if the pos doesn't change
All these can be fixed. But will need Wine tests to verify and keep it from
breaking in the future. And need one patch for each problem unless it's a
same fix for all of them. If things break separate patch per issue will help
identify the change during regression testing.

> - extra WM_MOUSEMOVE after zero-length moves
Careful with this. Some games do require it. That's why it's there with the
comment (in SetCursorPos). Or is there another source of them?

> - some other extra hook calls and WM:s due to XWarpPointer
To fix this Wine have to keep track of all XWarpPointer calls and all
generated X events so it can filter ones that came from warping pointer.

> As you can see, the correct order would be:
> - call hooks for moving, return old pos from GetCursorPos
> - clip and store the new position
> - send the move message using the new position
> - call hooks and send the button message, both using the clipped position
Looks right.

>> What exactly is wrong with [border scrolling]?
> Many games (for example, Baldur's Gate) check for mouse coordinates. If
> the pointer is outside the virtual desktop, Wine gives negative
> coordinates and the game doesn't scroll left/up, because x != 0 and y !=
> 0. The same thing happens to right/bottom, of course. Correct clipping
> fixes it.
That explains why some games have this issue.

>> Who said that Wine should keep the pointer inside virtual desktop?
> Ok, I'll not do it. But don't you think it's a bit confusing if the
> pointer moves freely but the program thinks it's clipped to an area?
I've had that discussion with Alexandre. His point was - don't confine
pointer to the virtual desktop because Wine has it exactly for the reason of
letting you run full-screen games in the window, as a work around for games
not having windowed mode. And to let you use your system when Wine
crashes/locks up.

The question of what to do when cursor is outside of VD - I personally thing
we should just clip coordina

Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-23 Thread James McKenzie
Lauri Kenttä wrote:
> James McKenzie wrote:
>   
>> Programming can and is brutal.
>> 
>
> Yes, I know. But programming can also be nice and fun. It will be exactly
> what the community makes it. I've seen both kinds, and guess which ones
> have had more active users. This was my point, so do not misunderstand:
> I'm certainly not saying that bad patches should be accepted.
>
>   
Been there, done that.  It is always desireable to have harmony. 
However, there will always be the person or persons that will be
brutal.  That is Vitaly's way and nothing so far has changed.  I just
accept comments and dismiss the other items.  That is best for now.
>> Windows does not trap the mouse and neither should Wine.
>> 
>
> I'm not sure what you mean.
What I mean is that windowed games do not trap the mouse at the windows
edge and prevent it from leaving the window. 

>  If you're saying that ClipCursor doesn't
> actually trap it, please try it out first. As simple as this:
>
> #include 
> #include 
>
> int main()
> {
> RECT rc;
> SetRect(&rc, 100, 100, 200, 200);
> ClipCursor(&rc);
> getchar();
> ClipCursor(NULL);
> return 0;
> }
>
> If you're running Windows on a virtual machine, remember to disable things
> like "mouse pointer integration" before testing.
>
>   
I don't run Windows here.  And I cannot build programs on my office
machine.  If you want to compile the program and provide it via PM then
feel free to do so.  Otherwise, I will not be able to test this.

>> If you are in a virtual desktop, the mouse should stop at the edge of
>> the window and move to where you re-enter it.
>> 
>
> I think we all agree about that, but GetCursorPos currently doesn't.
>   
That is brokenness then.  Please continue to try and fix it.

James McKenzie





Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-23 Thread Lauri Kenttä
Ricardo Filipe wrote:
> see: http://bugs.winehq.org/show_bug.cgi?id=6971

Ok, that really explains something. Thanks a lot, I'll find a game to test.

-- 
Lauri Kenttä





Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-23 Thread Lauri Kenttä
James McKenzie wrote:
> Programming can and is brutal.

Yes, I know. But programming can also be nice and fun. It will be exactly
what the community makes it. I've seen both kinds, and guess which ones
have had more active users. This was my point, so do not misunderstand:
I'm certainly not saying that bad patches should be accepted.

But enough of that, now.

> Windows does not trap the mouse and neither should Wine.

I'm not sure what you mean. If you're saying that ClipCursor doesn't
actually trap it, please try it out first. As simple as this:

#include 
#include 

int main()
{
RECT rc;
SetRect(&rc, 100, 100, 200, 200);
ClipCursor(&rc);
getchar();
ClipCursor(NULL);
return 0;
}

If you're running Windows on a virtual machine, remember to disable things
like "mouse pointer integration" before testing.

> If you are in a virtual desktop, the mouse should stop at the edge of
> the window and move to where you re-enter it.

I think we all agree about that, but GetCursorPos currently doesn't.

Also, the last WM_MOUSEMOVE comes from the last position inside the
desktop, which probably is not at the edge. But that's something I'll not
try to fix.

Thanks for your comments!

-- 
Lauri Kenttä





Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-23 Thread Ricardo Filipe
2010/1/22 Lauri Kenttä :
>

hi lauri.
i'm glad you take people's comments with a grain of salt. vitaliy was
a bit condescending but he said "please" :D
it's unfortunate but we have to get used to it. i know it's not the
best to entice developers but it's what we have, and it's good, stay
around and you'll see ;)

as to your issue, you should write tests for all that you can, that
show bugs in wine and inconformances with windows. test driven
development is appreciated. that little test app you shown is a start.
do that first with todo_wine() where needed and you will have an
easier walk.

as to the clipping to virtual desktop problem, we are still waiting on
someone to integrate xinput2 in wine. it should help alot for this
kind of situation, there are alot of games that require it. see:
http://bugs.winehq.org/show_bug.cgi?id=6971
that bug is why vitaliy is a bit more picky with this kind of patch ;)

regards.




Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-22 Thread James McKenzie
Lauri Kenttä wrote:
> My apologies for bringing up something that is actually none of my
> business, but I think you should pay more attention to the way you write
> your comments. First, even small positive comments are considered
> psychologically very important, but you have given none. Second, most of
> your negative feedback has only stated that the patches are bad and wrong,
> often without giving much details or any better ideas. That is, the
> comments haven't been very constructive. Currently your messages look a
> bit like "f*** off, noob", which hopefully is not what you had in mind.
> Anyway, this is certainly not a good way to encourage spending time to
> Wine development. Some (luckily not me) would take it badly and just rm
> -rf wine-git and never try again, even if they could be a great help with
> some guidance. So let's all be nice to each other, and everyone will be
> happier.
>
>   
Lauri:

Programming can and is brutal.  I deal with this daily and I've learned
to keep a smile on my face, even when I'm being chastised.  Drives folks
'nuts'.  However, you have to learn the lesson, even if you win.  One
thing is that Windows does not trap the mouse and neither should Wine. 
If you are in a virtual desktop, the mouse should stop at the edge of
the window and move to where you re-enter it.  This is what you should
strive for.  If you cannot do this, then step back and take another try
at it.  I have been working on a fix for ONE function in Richedit for
over one and one-half year now and the complaints still come in. 
However, I take them as constructive hints and work towards fixing and
clearing them off.

Soon, the patch will be submitted and I will move onto other problems
that will rise because of the implementation of this code that are
outside the scope of the code.  That is the way it is in this business.

James McKenzie






Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-22 Thread Lauri Kenttä
> The SetCursorPos() calls hooks on Wine because Wine has big issue - it
doesn't filter pointer move messages that were caused by Wine itself.

The first patch (http://source.winehq.org/patches/data/57569) tries to
address exactly this. I think XWarpCursor is not a problem, as the event
comes asynchronously with some delay. So my patch fixes the easier but
worse case, calling hooks directly from SetCursorPos.

What's wrong with this, why is it wrong, and do you have a better idea?
What else causes Wine to produce extra messages?

Also, is there a reason why I shouldn't write a test for this to make the
issue better known?

>> I'm aware that my version causes hooks to be called with clipped
coordinates on mouse move, when they should in that case be called with
the unclipped ones.
> This particular change will break all games using dinput when mouse
pointer goes outside of virtual desktop.

(This was the elaboration I was asking for.) I didn't know that, and I
don't have any such games. Feel free to reject the patch, I'll rewrite it
without this bug and in smaller chunks. (It would be helpful if the first
two patches were also either accepted or rejected.)

>> returns unclipped coordinates from GetCursorPos
> This is what native will do inside hook handler. Add some tests.

That's not true. (See below.)

>> and even sends incorrect WM_* messages.
> Tests please.

I've attached a program that outputs coordinates from hookproc and
wndproc, both the passed ones and the ones from GetCursorPos. If you try
it, you can see that Wine has the following bugs:
- incorrect coordinates in some WM:s
- incorrect coordinates in some hook calls
- incorrect coordinates and missing WM:s after clipping
- extra hook calls on SetCursorPos, even if the pos doesn't change
- extra WM_MOUSEMOVE after zero-length moves
- some other extra hook calls and WM:s due to XWarpPointer

The next snippets show the WM bug and how GetCursorPos works inside hook
handlers. This first one is from Win2k8 Server. First, the pointer is at
(34,34) and clipping is set to (30,30)-(40,40). Then the program calls
mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE, 0, 6, 0, 0).
11: hookproc: WM_MOUSEMOVE: (34,40), get = (34,34), injected = 1
11: hookproc: WM_LBUTTONUP: (34,39), get = (34,39), injected = 1
11: wndproc:  WM_MOUSEMOVE: (34,39), get = (34,39)
11: wndproc:  WM_LBUTTONUP: (34,39), get = (34,39)

As you can see, the correct order would be:
- call hooks for moving, return old pos from GetCursorPos
- clip and store the new position
- send the move message using the new position
- call hooks and send the button message, both using the clipped position

Compare to current Wine output:
11: hookproc: WM_MOUSEMOVE: (34,40), get = (34,34), injected = 1
11: hookproc: WM_LBUTTONUP: (34,40), get = (34,39), injected = 1
11: hookproc: WM_MOUSEMOVE: (34,39), get = (34,39), injected = 0
11: wndproc:  WM_MOUSEMOVE: (34,40), get = (34,39)
11: wndproc:  WM_LBUTTONUP: (34,40), get = (34,39)
11: wndproc:  WM_MOUSEMOVE: (34,39), get = (34,39)

Aside of the extra move caused by XWarpPointer, the second hook and both
injected messages have incorrect (unclipped) coordinates.

> What exactly is wrong with [border scrolling]?

Many games (for example, Baldur's Gate) check for mouse coordinates. If
the pointer is outside the virtual desktop, Wine gives negative
coordinates and the game doesn't scroll left/up, because x != 0 and y !=
0. The same thing happens to right/bottom, of course. Correct clipping
fixes it.

> Who said that Wine should keep the pointer inside virtual desktop?

Ok, I'll not do it. But don't you think it's a bit confusing if the
pointer moves freely but the program thinks it's clipped to an area?


My apologies for bringing up something that is actually none of my
business, but I think you should pay more attention to the way you write
your comments. First, even small positive comments are considered
psychologically very important, but you have given none. Second, most of
your negative feedback has only stated that the patches are bad and wrong,
often without giving much details or any better ideas. That is, the
comments haven't been very constructive. Currently your messages look a
bit like "f*** off, noob", which hopefully is not what you had in mind.
Anyway, this is certainly not a good way to encourage spending time to
Wine development. Some (luckily not me) would take it badly and just rm
-rf wine-git and never try again, even if they could be a great help with
some guidance. So let's all be nice to each other, and everyone will be
happier.

-- 
Lauri Kenttä
#define _WIN32_WINNT 0x0500
#include 
#include 

int stage = 0;

RECT *tmp_rect(int x0, int y0, int x1, int y1) {
static RECT r;
SetRect(&r, x0, y0, x1, y1);
return &r;
}

INPUT *tmp_input(DWORD flags, int x, int y) {
static INPUT input;
input.type = INPUT_MOUSE;
input.mi.dwFlags = flags;
input.mi.dx = x;
input.mi.dy = y;
return &input;
}

const char *tmp_pos_s

Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-21 Thread Vitaliy Margolen
Lauri Kenttä wrote:
> The new series of patches has some related changes (including a new test) 
> applied before this one.
You have some issues in your test as well. The SetCursorPos() calls hooks on
Wine because Wine has big issue - it doesn't filter pointer move messages
that were caused by Wine itself. What you did in your patch is a half fix
the wrong way.

> Could you please elaborate that "so many"?
I can't give you all the programs/games that depend on particular behavior -
there are big number of them.

> I'm aware that my version causes hooks to be called with clipped
> coordinates on mouse move, when they should in that case be called with
> the unclipped ones.
This particular change will break all games using dinput when mouse pointer
goes outside of virtual desktop.

> returns unclipped coordinates from GetCursorPos
This is what native will do inside hook handler. Add some tests.

> and even sends incorrect WM_* messages.
Tests please.

> This is clearly wrong and causes many problems (example: border
> scrolling is next to impossible in many full-screen games when played on
> Wine virtual desktop).
What exactly is wrong with them? And what part are you trying to fix?

> I sincerely think my version is less likely to break anything. Surely
> there are more applications using WM_* and GetCursorPos than hooks.
This is not a reason to break anything. You either fix things without
breaking anything else. Or you don't touch the code at all.

> Anyone could do exactly the same thing "manually" by calling SetCursorPos,
> so why shouldn't ClipCursor do it automatically? Also, apparently Wine
> won't (or can't) warp the mouse if it lies outside the virtual desktop.
Number of reasons:
- Who said that Wine should keep the pointer inside virtual desktop? It's
there for the exact reason so users can have other apps running outside of
Wine at the same time as full-screen game inside Wine.
- You doing it wrong. Warping pointer is not the right way. If you really
must do it, then you should be using pointer grab. Also you are not dealing
with all the extra pointer move messages generated as a result of
XWarpPointer().


Vitaliy.




Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-21 Thread Lauri Kenttä
Thanks for your comments, Vitaliy.

At first, I must point out that you're commenting on a patch that has
already been superseded. Not that there's much difference, but the new
series of patches has some related changes (including a new test) applied
before this one.

Vitaliy Margolen wrote:
> Lots of those areas you touch will break oh so many apps.

Could you please elaborate that "so many"?

I'm aware that my version causes hooks to be called with clipped
coordinates on mouse move, when they should in that case be called with
the unclipped ones. Still, please note that the current version calls all
hooks (not just on mouse move) with the unclipped coordinates, returns
unclipped coordinates from GetCursorPos and even sends incorrect WM_*
messages. This is clearly wrong and causes many problems (example: border
scrolling is next to impossible in many full-screen games when played on
Wine virtual desktop).

I sincerely think my version is less likely to break anything. Surely
there are more applications using WM_* and GetCursorPos than hooks.

Maybe I will have time to fix the remaining bugs some day. I will also try
to write some Wine tests so that these problems (be they in my version or
the old one) are not forgotten.

Vitaliy Margolen wrote:
> And don't try to keep pointer inside Wine's window

Anyone could do exactly the same thing "manually" by calling SetCursorPos,
so why shouldn't ClipCursor do it automatically? Also, apparently Wine
won't (or can't) warp the mouse if it lies outside the virtual desktop.

As I see it, clipping should first be implemented correctly, because
that's what Windows applications expect. Then, if this causes problems, we
could use a registry key similar to DXGrab to disable (or restrict)
XWarpPointer usage.

-- 
Lauri Kenttä





Re: winex11.drv: Added missing mouse position clipping. (try 2)

2010-01-20 Thread Vitaliy Margolen
Lauri Kenttä wrote:
> When the cursor position is clipped with ClipCursor, the cursor should be
> confined to that area. This patch fixes cursor position clipping in
> X11DRV_ClipCursor, X11DRV_GetCursorPos, X11DRV_SetCursorPos and
> X11DRV_send_mouse_input and makes the mouse warp to the new position if
> moved outside the clip rect.
> 
> The previous try fixed only clipping (not warping) and only in
> GetCursorPos, but the problem wasn't that small after all.
> ---
>  dlls/winex11.drv/mouse.c |   52
> -
>  1 files changed, 41 insertions(+), 11 deletions(-)
> 

You changing way too many things without a single test. Lots of those areas
you touch will break oh so many apps.

For starters write some tests and verify what you doing is correct. You
should be able to write tests for all injected messages (send_mouse_event).
If you can't make an automated test, write a visual test for the rest and
send to wine-devel. Especially pay attention to all messages sent, and order
of calling hook, sending messages, modifying values returned from
GetCursorPos(). You breaking that.

And don't try to keep pointer inside Wine's window - this won't get past AJ.

Vitaliy.