[USER] Fix ClipCursor.
Lionel Ulmer
lionel.ulmer at free.fr
Fri Jan 30 12:03:52 CST 2004
As seen on Wine-devel, DungeonKeeper relies on the ClipCursor being updated
on resolution changes. At the same time, I checked what Windows does on
whacky rectangles :-)
Lionel
Changelog:
- initialize the cursor clip rectangle at USER loading
- update it on resolution changes
- do the same checks as real Windows do (tested on Win2K)
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
diff -ur ../wine_CVS/windows/cursoricon.c windows/cursoricon.c
--- ../wine_CVS/windows/cursoricon.c 2004-01-27 15:59:35.000000000 +0100
+++ windows/cursoricon.c 2004-01-30 17:07:50.000000000 +0100
@@ -1419,7 +1419,11 @@
BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
{
if (!rect) SetRectEmpty( &CURSOR_ClipRect );
- else CONV_RECT16TO32( rect, &CURSOR_ClipRect );
+ else {
+ RECT rect_32;
+ CONV_RECT16TO32(rect, &rect_32);
+ return ClipCursor(&rect_32);
+ }
return TRUE;
}
@@ -1430,7 +1434,29 @@
BOOL WINAPI ClipCursor( const RECT *rect )
{
if (!rect) SetRectEmpty( &CURSOR_ClipRect );
- else CopyRect( &CURSOR_ClipRect, rect );
+ else {
+ /* Some sanity checks (verified on Win2K) */
+ RECT screen_rect;
+
+ screen_rect.top = screen_rect.left = 0;
+ screen_rect.right = GetSystemMetrics(SM_CXSCREEN);
+ screen_rect.bottom = GetSystemMetrics(SM_CYSCREEN);
+
+ /* If the rectangle is bad or out of the screen rectangle, the clip cursor is set
+ * to the whole screen.
+ */
+ if ((rect->top > rect->bottom) || (rect->left > rect->right) ||
+ (rect->top >= screen_rect.bottom) ||
+ (rect->bottom < screen_rect.top) ||
+ (rect->left >= screen_rect.right) ||
+ (rect->right < screen_rect.left))
+ rect = &screen_rect;
+
+ /* If the rectangle is empty, keep the same rectangle */
+ if (IsRectEmpty(rect)) CopyRect(&CURSOR_ClipRect, rect);
+ /* Otherwise, it's the intersection of the given rectangle with the screen */
+ else IntersectRect(&CURSOR_ClipRect, rect, &screen_rect);
+ }
return TRUE;
}
diff -ur ../wine_CVS/dlls/x11drv/settings.c dlls/x11drv/settings.c
--- ../wine_CVS/dlls/x11drv/settings.c 2003-10-16 02:21:42.000000000 +0200
+++ dlls/x11drv/settings.c 2004-01-30 17:19:31.000000000 +0100
@@ -239,6 +239,7 @@
{
DWORD i;
DEVMODEW dm;
+ int cur_mode;
TRACE("(%s,%p,%p,0x%08lx,%p)\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid);
TRACE("flags=%s\n",_CDS_flags(flags));
@@ -260,6 +261,8 @@
devmode = &dm;
}
+ cur_mode = pGetCurrentMode();
+
for (i = 0; i < dd_mode_count; i++)
{
if (devmode->dmFields & DM_BITSPERPEL)
@@ -285,6 +288,27 @@
/* we have a valid mode */
TRACE("Requested display settings match mode %ld (%s)\n", i, handler_name);
pSetCurrentMode(i);
+
+ if (i != cur_mode) {
+ /* This means that we choose another resolution .. Update the clip cursor accordingly.
+ *
+ * Note: at this point, as 'pSetCurrentMode' has been called, we suppose that the System
+ * metrics have been updated properly and that the sanity checks in ClipCursor
+ * won't give us any problems.
+ */
+ RECT rect;
+
+ TRACE("New mode (%ld) different from current mode (%d) - updating clip cursor.\n", i, cur_mode);
+
+ rect.top = 0;
+ rect.bottom = dd_modes[i].dwHeight;
+
+ rect.left = 0;
+ rect.right = dd_modes[i].dwWidth;
+
+ ClipCursor(&rect);
+ }
+
return DISP_CHANGE_SUCCESSFUL;
}
diff -ur ../wine_CVS/dlls/user/user_main.c dlls/user/user_main.c
--- ../wine_CVS/dlls/user/user_main.c 2004-01-27 15:59:23.000000000 +0100
+++ dlls/user/user_main.c 2004-01-29 19:43:01.000000000 +0100
@@ -186,6 +186,7 @@
static BOOL process_attach( HINSTANCE inst )
{
HINSTANCE16 instance;
+ RECT rect;
/* Create USER heap */
if ((instance = LoadLibrary16( "USER.EXE" )) >= 32) USER_HeapSel = instance | 7;
@@ -203,6 +204,13 @@
SYSMETRICS_Init();
SYSCOLOR_Init();
+ /* Now that system metrics are set-up, we can initialize the clip rectangle */
+ rect.left = 0;
+ rect.right = GetSystemMetrics(SM_CXSCREEN);
+ rect.top = 0;
+ rect.bottom = GetSystemMetrics(SM_CYSCREEN);
+ ClipCursor(&rect);
+
/* Setup palette function pointers */
palette_init();
More information about the wine-patches
mailing list