[Wine] Re: Disabling mouse tracking when X11 focus leaves wine?

laut wineforum-user at winehq.org
Mon Sep 29 16:03:00 CDT 2008


I am not 100% happy with the following quick-and-dirty snippet,
but it  seems to work well-enough for my limited goal of 
running Age Of Empires II in the computer-vs-computer mode.

              Some Windows games assume full-screen operation, and query
              mouse position continuously, even when Wine has no focus or
              when cursor is outside Wine window.  When these programs are
              non-focused, it may be useful to report mouse as being in a
              constant position, especially when running in a virtual
              desktop window.

              Consider the following cases:
              1. Wine has input focus and X11 cursor is within Wine
              2. Wine has focus but cursor is outside Wine
              3. no focus and cursor is outside Wine
              4. no focus but cursor is inside Wine

The following snippet handles cases 1 and 4 as before.
When the  pointer resides outside Wine, the environment
variable WINE_FAKED_POINTER will be used to decide
if a constant position will be reported:

              1: Report where the mouse really is, relative to the Wine window.
                 This is the original (and default) functionality.
              2: Report mouse as being in the middle of the wine window.
              3: Report mouse as being in an "initial" position.

              example:
              export WINE_FAKED_POINTER=3
              wine age2_x1.exe

The logic for returning the fake position report does not check for
input focus. When using FocusFollowMouse or SloppyFocus
this should be enough.

Or maybe someone who uses click-to-focus feels an urge to continue
working on this...

Anyway, recommendations on cleaner ways to 
interact with Wine innards will be appreciated.  :) 

--laut


Code:

/* This function resides in dlls/winex11.drv/mouse.c */

/********************************************************************
 *		GetCursorPos (X11DRV.@)
 */
BOOL X11DRV_GetCursorPos(LPPOINT pos)
{
    Display *display = thread_display();
    Window root, child;
    int rootX, rootY, winX, winY;
    unsigned int xstate;

    wine_tsx11_lock();
    if ((GetTickCount() - last_time_modified > 100) &&
        XQueryPointer( display, root_window, &root, &child,
                       &rootX, &rootY, &winX, &winY, &xstate ))
    {
        int have_pointer = child != 0;

        static int fake_pointer_mode = -1;
        static int original_x = 0;
        static int original_y = 0;
         
        /* FIXME: thread-safety ? Or is wine_tsx11_lock() enough? */
        if (fake_pointer_mode < 1) {
            char* opt = getenv("WINE_FAKED_POINTER");
            fake_pointer_mode =
                (opt && *opt >= '1' && *opt <= '9')
                ? *opt - '0'
                : 1;
                /* Save initial position to be used in mode 3 */
            if (have_pointer) {
                original_x = winX;
                original_y = winY;
            } else {
                original_x = (virtual_screen_rect.right - virtual_screen_rect.left) / 2;
                original_y = (virtual_screen_rect.bottom - virtual_screen_rect.top) / 2;
            }
            WINE_DPRINTF("%s: mode=%d, x=%d, y=%d\n",
                         __FUNCTION__, fake_pointer_mode,
                         original_x, original_y);
        }
        
        /* Pointer within Wine window: report truthfully */
        if (have_pointer) {
            update_button_state( xstate );
            winX += virtual_screen_rect.left;
            winY += virtual_screen_rect.top;
            TRACE("pointer at (%d,%d)\n", winX, winY );
            cursor_pos.x = winX;
            cursor_pos.y = winY;
        } else {
         
            switch (fake_pointer_mode) {
            case 2:
                winX = (virtual_screen_rect.right - virtual_screen_rect.left) / 2;
                winY = (virtual_screen_rect.bottom - virtual_screen_rect.top) / 2;
                break;
            case 3:
                winX = original_x; winY = original_y;
                break;
            case 1:
            default:
                /* like before, report mouse in its correct position */
                winX = winX; winY = winY;
                break;
            }
            
            /* For the moment, we do not update button state here. */
            cursor_pos.x = winX;
            cursor_pos.y = winY;
            cursor_pos.x += virtual_screen_rect.left;
            cursor_pos.y += virtual_screen_rect.top;
        }
    }
    *pos = cursor_pos;
    wine_tsx11_unlock();
    return TRUE;
}










More information about the wine-users mailing list