winex11drv/user32: Add ClipCursor to x11drv to pass clip rectangle to x11drv.

This commit is contained in:
Vitaliy Margolen 2007-01-04 12:24:50 -07:00 committed by Alexandre Julliard
parent 005bb87342
commit c3dc692b20
8 changed files with 83 additions and 14 deletions

View file

@ -1565,9 +1565,13 @@ BOOL WINAPI ClipCursor( const RECT *rect )
OffsetRect( &virt, GetSystemMetrics( SM_XVIRTUALSCREEN ), OffsetRect( &virt, GetSystemMetrics( SM_XVIRTUALSCREEN ),
GetSystemMetrics( SM_YVIRTUALSCREEN ) ); GetSystemMetrics( SM_YVIRTUALSCREEN ) );
TRACE( "Clipping to: %s was: %s screen: %s\n", wine_dbgstr_rect(rect),
wine_dbgstr_rect(&CURSOR_ClipRect), wine_dbgstr_rect(&virt) );
if (!IntersectRect( &CURSOR_ClipRect, &virt, rect )) if (!IntersectRect( &CURSOR_ClipRect, &virt, rect ))
CURSOR_ClipRect = virt; CURSOR_ClipRect = virt;
USER_Driver->pClipCursor( rect );
return TRUE; return TRUE;
} }

View file

@ -88,6 +88,7 @@ static const USER_DRIVER *load_driver(void)
GET_USER_FUNC(SetCursor); GET_USER_FUNC(SetCursor);
GET_USER_FUNC(GetCursorPos); GET_USER_FUNC(GetCursorPos);
GET_USER_FUNC(SetCursorPos); GET_USER_FUNC(SetCursorPos);
GET_USER_FUNC(ClipCursor);
GET_USER_FUNC(GetScreenSaveActive); GET_USER_FUNC(GetScreenSaveActive);
GET_USER_FUNC(SetScreenSaveActive); GET_USER_FUNC(SetScreenSaveActive);
GET_USER_FUNC(AcquireClipboard); GET_USER_FUNC(AcquireClipboard);
@ -229,6 +230,11 @@ static BOOL nulldrv_SetCursorPos( INT x, INT y )
return FALSE; return FALSE;
} }
static BOOL nulldrv_ClipCursor( LPCRECT clip )
{
return FALSE;
}
static BOOL nulldrv_GetScreenSaveActive(void) static BOOL nulldrv_GetScreenSaveActive(void)
{ {
return FALSE; return FALSE;
@ -431,6 +437,7 @@ static const USER_DRIVER null_driver =
nulldrv_SetCursor, nulldrv_SetCursor,
nulldrv_GetCursorPos, nulldrv_GetCursorPos,
nulldrv_SetCursorPos, nulldrv_SetCursorPos,
nulldrv_ClipCursor,
/* screen saver functions */ /* screen saver functions */
nulldrv_GetScreenSaveActive, nulldrv_GetScreenSaveActive,
nulldrv_SetScreenSaveActive, nulldrv_SetScreenSaveActive,
@ -560,6 +567,11 @@ static BOOL loaderdrv_SetCursorPos( INT x, INT y )
return load_driver()->pSetCursorPos( x, y ); return load_driver()->pSetCursorPos( x, y );
} }
static BOOL loaderdrv_ClipCursor( LPCRECT clip )
{
return load_driver()->pClipCursor( clip );
}
static BOOL loaderdrv_GetScreenSaveActive(void) static BOOL loaderdrv_GetScreenSaveActive(void)
{ {
return load_driver()->pGetScreenSaveActive(); return load_driver()->pGetScreenSaveActive();
@ -754,6 +766,7 @@ static const USER_DRIVER lazy_load_driver =
loaderdrv_SetCursor, loaderdrv_SetCursor,
loaderdrv_GetCursorPos, loaderdrv_GetCursorPos,
loaderdrv_SetCursorPos, loaderdrv_SetCursorPos,
loaderdrv_ClipCursor,
/* screen saver functions */ /* screen saver functions */
loaderdrv_GetScreenSaveActive, loaderdrv_GetScreenSaveActive,
loaderdrv_SetScreenSaveActive, loaderdrv_SetScreenSaveActive,

View file

@ -538,6 +538,7 @@ static void test_keynames(void)
} }
static POINT pt_old, pt_new; static POINT pt_old, pt_new;
static BOOL clipped;
#define STEP 20 #define STEP 20
static LRESULT CALLBACK hook_proc1( int code, WPARAM wparam, LPARAM lparam ) static LRESULT CALLBACK hook_proc1( int code, WPARAM wparam, LPARAM lparam )
@ -558,7 +559,10 @@ static LRESULT CALLBACK hook_proc1( int code, WPARAM wparam, LPARAM lparam )
pt.y = pt_old.y + STEP; pt.y = pt_old.y + STEP;
SetCursorPos(pt.x, pt.y); SetCursorPos(pt.x, pt.y);
GetCursorPos(&pt1); GetCursorPos(&pt1);
ok(pt.x == pt1.x && pt.y == pt1.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y); if (clipped)
ok(pt1.x == pt_old.x && pt1.y == pt_old.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
else
ok(pt1.x == pt.x && pt1.y == pt.y, "Wrong set pos: (%d,%d)\n", pt1.x, pt1.y);
} }
return CallNextHookEx( 0, code, wparam, lparam ); return CallNextHookEx( 0, code, wparam, lparam );
} }
@ -575,8 +579,10 @@ static LRESULT CALLBACK hook_proc2( int code, WPARAM wparam, LPARAM lparam )
/* Should match position set above */ /* Should match position set above */
GetCursorPos(&pt); GetCursorPos(&pt);
ok(pt.x == pt_old.x +STEP && pt.y == pt_old.y +STEP, "GetCursorPos: (%d,%d)\n", if (clipped)
pt.x, pt.y); ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
else
ok(pt.x == pt_old.x +STEP && pt.y == pt_old.y +STEP, "GetCursorPos: (%d,%d)\n", pt.x, pt.y);
} }
return CallNextHookEx( 0, code, wparam, lparam ); return CallNextHookEx( 0, code, wparam, lparam );
} }
@ -586,11 +592,12 @@ static void test_mouse_ll_hook(void)
HWND hwnd; HWND hwnd;
HHOOK hook1, hook2; HHOOK hook1, hook2;
POINT pt_org, pt; POINT pt_org, pt;
RECT rc;
GetCursorPos(&pt_org); GetCursorPos(&pt_org);
hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW, hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10, 10, 200, 200, NULL, NULL, NULL, NULL); 10, 10, 200, 200, NULL, NULL, NULL, NULL);
SetCursorPos(300, 300); SetCursorPos(100, 100);
hook2 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc2, GetModuleHandleA(0), 0); hook2 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc2, GetModuleHandleA(0), 0);
hook1 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc1, GetModuleHandleA(0), 0); hook1 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc1, GetModuleHandleA(0), 0);
@ -609,6 +616,23 @@ static void test_mouse_ll_hook(void)
GetCursorPos(&pt_old); GetCursorPos(&pt_old);
ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); ok(pt_old.x == pt_new.x && pt_old.y == pt_new.y, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y);
SetRect(&rc, 50, 50, 151, 151);
ClipCursor(&rc);
clipped = TRUE;
SetCursorPos(40, 40);
GetCursorPos(&pt_old);
ok(pt_old.x == 50 && pt_old.y == 50, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
SetCursorPos(160, 160);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
mouse_event(MOUSEEVENTF_MOVE, +STEP, +STEP, 0, 0);
GetCursorPos(&pt_old);
ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_new.x, pt_new.y);
clipped = FALSE;
pt_new.x = pt_new.y = 150;
ClipCursor(NULL);
UnhookWindowsHookEx(hook1); UnhookWindowsHookEx(hook1);
/* Now check that mouse buttons do not change mouse position /* Now check that mouse buttons do not change mouse position

View file

@ -120,6 +120,7 @@ typedef struct tagUSER_DRIVER {
void (*pSetCursor)(struct tagCURSORICONINFO *); void (*pSetCursor)(struct tagCURSORICONINFO *);
BOOL (*pGetCursorPos)(LPPOINT); BOOL (*pGetCursorPos)(LPPOINT);
BOOL (*pSetCursorPos)(INT,INT); BOOL (*pSetCursorPos)(INT,INT);
BOOL (*pClipCursor)(LPCRECT);
/* screen saver functions */ /* screen saver functions */
BOOL (*pGetScreenSaveActive)(void); BOOL (*pGetScreenSaveActive)(void);
void (*pSetScreenSaveActive)(BOOL); void (*pSetScreenSaveActive)(BOOL);

View file

@ -71,6 +71,7 @@ static const UINT button_up_flags[NB_BUTTONS] =
POINT cursor_pos; POINT cursor_pos;
static DWORD last_time_modified; static DWORD last_time_modified;
static RECT cursor_clip; /* Cursor clipping rect */
BOOL X11DRV_SetCursorPos( INT x, INT y ); BOOL X11DRV_SetCursorPos( INT x, INT y );
@ -89,6 +90,18 @@ static inline void get_coords( HWND hwnd, int x, int y, POINT *pt )
pt->y = y + data->whole_rect.top; pt->y = y + data->whole_rect.top;
} }
/***********************************************************************
* clip_point_to_rect
*
* Clip point to the provided rectangle
*/
static inline void clip_point_to_rect( LPCRECT rect, LPPOINT pt )
{
if (pt->x < rect->left) pt->x = rect->left;
else if (pt->x >= rect->right) pt->x = rect->right - 1;
if (pt->y < rect->top) pt->y = rect->top;
else if (pt->y >= rect->bottom) pt->y = rect->bottom - 1;
}
/*********************************************************************** /***********************************************************************
* update_button_state * update_button_state
@ -257,12 +270,6 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
wine_tsx11_lock(); wine_tsx11_lock();
pt.x = cursor_pos.x + (long)x * xMult; pt.x = cursor_pos.x + (long)x * xMult;
pt.y = cursor_pos.y + (long)y * yMult; pt.y = cursor_pos.y + (long)y * yMult;
/* Clip to the current screen size */
if (pt.x < 0) pt.x = 0;
else if (pt.x >= screen_width) pt.x = screen_width - 1;
if (pt.y < 0) pt.y = 0;
else if (pt.y >= screen_height) pt.y = screen_height - 1;
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
else else
@ -284,6 +291,7 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
else else
{ {
wine_tsx11_lock(); wine_tsx11_lock();
clip_point_to_rect( &cursor_clip, &pt);
cursor_pos = pt; cursor_pos = pt;
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
@ -683,6 +691,7 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
BOOL X11DRV_SetCursorPos( INT x, INT y ) BOOL X11DRV_SetCursorPos( INT x, INT y )
{ {
Display *display = thread_display(); Display *display = thread_display();
POINT pt;
TRACE( "warping to (%d,%d)\n", x, y ); TRACE( "warping to (%d,%d)\n", x, y );
@ -695,11 +704,12 @@ BOOL X11DRV_SetCursorPos( INT x, INT y )
return TRUE; return TRUE;
} }
pt.x = x; pt.y = y;
clip_point_to_rect( &cursor_clip, &pt);
XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, XWarpPointer( display, root_window, root_window, 0, 0, 0, 0,
x - virtual_screen_rect.left, y - virtual_screen_rect.top ); pt.x - virtual_screen_rect.left, pt.y - virtual_screen_rect.top );
XFlush( display ); /* avoids bad mouse lag in games that do their own mouse warping */ XFlush( display ); /* avoids bad mouse lag in games that do their own mouse warping */
cursor_pos.x = x; cursor_pos = pt;
cursor_pos.y = y;
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE; return TRUE;
} }
@ -731,6 +741,20 @@ BOOL X11DRV_GetCursorPos(LPPOINT pos)
return TRUE; return TRUE;
} }
/***********************************************************************
* ClipCursor (X11DRV.@)
*
* Set the cursor clipping rectangle.
*/
BOOL X11DRV_ClipCursor( LPCRECT clip )
{
if (!IntersectRect( &cursor_clip, &virtual_screen_rect, clip ))
cursor_clip = virtual_screen_rect;
return TRUE;
}
/*********************************************************************** /***********************************************************************
* X11DRV_ButtonPress * X11DRV_ButtonPress
*/ */

View file

@ -79,6 +79,7 @@
@ cdecl SetCursor(ptr) X11DRV_SetCursor @ cdecl SetCursor(ptr) X11DRV_SetCursor
@ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos @ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos
@ cdecl SetCursorPos(long long) X11DRV_SetCursorPos @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos
@ cdecl ClipCursor(ptr) X11DRV_ClipCursor
@ cdecl GetScreenSaveActive() X11DRV_GetScreenSaveActive @ cdecl GetScreenSaveActive() X11DRV_GetScreenSaveActive
@ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive @ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive
@ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) X11DRV_ChangeDisplaySettingsEx @ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) X11DRV_ChangeDisplaySettingsEx

View file

@ -667,6 +667,7 @@ extern int X11DRV_AcquireClipboard(HWND hWndClipWindow);
extern void X11DRV_ResetSelectionOwner(void); extern void X11DRV_ResetSelectionOwner(void);
extern void X11DRV_SetFocus( HWND hwnd ); extern void X11DRV_SetFocus( HWND hwnd );
extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr ); extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
extern BOOL X11DRV_ClipCursor( LPCRECT clip );
extern void X11DRV_InitKeyboard(void); extern void X11DRV_InitKeyboard(void);
extern void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time, extern void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
DWORD dwExtraInfo, UINT injected_flags ); DWORD dwExtraInfo, UINT injected_flags );

View file

@ -441,6 +441,7 @@ static BOOL process_attach(void)
X11DRV_XRandR_Init(); X11DRV_XRandR_Init();
#endif #endif
X11DRV_ClipCursor( NULL );
X11DRV_InitKeyboard(); X11DRV_InitKeyboard();
X11DRV_InitClipboard(); X11DRV_InitClipboard();