No subject


Tue Mar 17 14:04:44 CDT 2009


course neither one of them work on Wine ATM.

>>> Either way, that doesn't work for Wine because not every window on
>>> screen has a WndProc for us to hook. Unless I've missed something,
>>> that's the basis of my position that you cannot do correct background DI
>>> using only a WndProc hook, because you miss all the events that do not
>>> get fed to _any_ WndProc hook.
>> You missing something (see above). This doesn't work because lots of games
>> buggy and think they acquire mouse in exclusive mode, while in fact they
>> end-up using non-exclusive foreground mode.
> Buggy in that they pass in the wrong flags, or buggy in that they don't
> check the result?
Both. They call SetCooperativeLevel(did, NULL, DISCL_EXCLUSIVE |
DISCL_FOREGROUND) which is wrong - they have to specify the window, it can't
be null. And they don't check for return, assuming call was successful. And
ending up with default (non-exclusive, background).

> It _seems_ to indicate it's a program bug that is hidden because
> the game is running full-screen so is always the window under the
> cursor, but I think that problem needs to be addressed separately.
Well, Wine have to do what native does - at least make these games work in
full screen.

> We can't exactly misimplement the API to benefit games that are using it
> wrong, if it involves breaking things that are using it right.
Eventually we might have to - native has all sorts of "shims" to fix broken
programs. But this is a topic for another big and long discussion.

>>> I'll review your earlier patches for this change as well at that time,
>>> and make sure I understand how to go about this correctly.
>> That might be waste of time. I was trying to make x11org do all the magic
>> (warping & grabbing pointer). This won't be aplicable as much with XI2.
> Actually, I still think it has to do that. To my mind, we only want
> dinput telling the graphics driver when it has acquired a device (so the
> graphics driver can start pumping the WH_*_LL hooks) and when it has
> acquired a device exclusively so the graphics driver can prevent events
> propagating to the normal windows event loop.
Most likely - yes. Or at least for the time being to test new XI2 to make
things easier.

> Whether this involves warping the mouse every 10ms, using XI2 to perform
Now this is something we can not do. Wine can not warp mouse - some games
break because of that.

> a grab on the pointer, or some mysterious quartz driver voodoo,
> shouldn't be visible to dinput, or rawinput, or 
This might be necessary in virtual-desktop mode. Full screen is kind of easy
way to solve this problem for most game developers. So they don't envision
their games running in a windowed mode (I'm looking at you Ubi).

>>> So from my reading, my suggestion above probably makes sense, to keep
>>> the current pair of methods I added for DI (wine_directinput_AcquireMouse
>>> and wine_dinput_MouseUnacquire), make it non-optional for a graphics
>>> driver to provide such methods and a system mouse, rename them without
>>> directinput, and then add RawInput to user32 such that it also takes an
>>> acquire on mouse and keyboard if those're what's asked for by the client
>>> software.
>> That's what I was thinking too. Only they would need to be more
>> sophisticated to handle multiple "users". Some games using multiple keyboard
>> & mouse DInput devices. Also don't forget additional software, like
>> ventrilo, running in parallel with the game.
> Can games use multiple mouse and keyboard devices? MSDN states that
> Windows XP's DI only enumerates one mouse and one keyboard, so I assumed
> people program with that assumption. Not that this is a hard assumption
> to manage.
That's not what I meant. Some games create more then one keyboard/mouse
devices (IDirectInput_CreateDevice). And expect them all to work.

> So I guess the way to implement the XI2 support from the above is to
> restart this patch series again, as follows:
> 
> Move mouse warping into winex11.drv, and add a MouseAcquire/MouseDeacquire
> interface pair to winex11.drv.
Not move warping, remove it (it shouldn't be done at all).

> 	That pair of functions will enable mouse warping if exclusive
> 	acquisition occurs. They probably need to keep a reference count, and
> 	ensure that we only stop doing what we've been asked if everything
> 	that acquired us has deacquired us. Only one thing at a time can
> 	have an exclusive acquisition (the foreground window) but this
> 	interface needs to be able to be used by RawInput too, so it might
> 	need to protect against multiple exclusive efforts by the foreground
> 	window. (Pathological case of program using both DI and RawInput!)
Correct. DI does something like that currently - it has a dedicated thread
that receives all the events. Then it dispatches them to each acquired
device. X11drv will have to do something similar - it needs a dedicated
thread with a dedicated X11 connection - we can't relay on the owner of the
foreground window to pump events, as some don't.

> Add an XI2 variation of the MouseAcquire/MouseDeacquire functions that
> use a grab instead of mouse warping, and feed raw events into
> queue_raw_mouse_message if no Wine window has X focus.
Correct. It might be a complete replacement for the current raw event
generator (regular X events).

> However, there's at least one issue here:
> 
> Feeding LL_HOOKS from XI2 which then feeds DirectInput means we're going
> from relative to absolute values and back to relative (and then back to
> absolute if DI has the mouse axes in absolute mode).
We can always change DInput to talk to X11 directly. Or use ... RawInput
events. It sure would be cool to make it in a native compatible way (using
driver interface) but it would be too much work. No something we'd like to
spend our time on ATM.

> The middle part of this will see co-ordinates that aren't sensible (ie
> the hook will see absolute co-ordinates that are outside its virtual
> desktop if running in a virtual desktop smaller than the screen)
> 
> The larger problem is that certain mouse movements can't work with an
> absolute value in the middle, namely those that happen when the cursor
> is already on the edge of the screen. If we support those by using the
> absolute position in the WH_MOUSE_LL data structure as accumulated
> relative position (as DirectInput does when providing absolute mouse
> axis data) then when we get a real cursor position later, the mouse is
> going to appear to jump quite sharply by however much movement was
> applied relatively without affecting the absolute pointer position on
> screen.
In theory LL hook events should contain raw mouse events regardless of the
pointer. In practice - I don't remember what native does. I think if the
cursor "stuck" on the border it just (dec|inc)rements it's position by the
relative move amount and send these "fake" coords to the hook. Of course the
cursor position doesn't change, so (hook_coords - GetCursorPos() = relative
coords) still works.

> This would make the prototype for MouseAcquire be something like
> MouseAcquire( BOOL foreground, BOOL exclusive, BOOL relative )
> * foreground true disables use of XI2, since by definition data will
>   come through the normal X channel
> * exclusive enables pointer grab or warping and killing of normal Mouse
>   handling.
> * relative enables sending of WH_WINEMOUSE_REL hook messages.
> 
> Again, it'd have to be a reference counted system, so any outstanding
> acquisitions would ensure messages of the type they acquire are being
> resent.
Looks good. Might even add a callback instead of piping messages through the
whole Wine.

Vitaliy.



More information about the wine-devel mailing list