system metrics update

Alex Pasadyn ajp at mail.utexas.edu
Fri Jan 30 15:19:49 CST 2004


ChangeLog:
- Ensure system metrics are accurate for all processes after resolution 
changes



As suggested in wine-devel, this is just the sysmetrics portion of my 
last patch by itself.

I wrote a small test program that just displays the desktop window size 
(from GetWindowRect) and the size from the sysmetrics and lets you 
change the resolution as well.  After a little testing with running 
multiple copies of that program, I think this patch is fine on its own.

Here's what happens.  If you are using XRandR, then all copies of the 
program find out the correct size when any of them changes it.  If you 
are using desktop mode, then each instance appears in its own desktop 
window, and only that one is affected when you resize it, and in all 
cases the program displays values that match the size of the desktop 
window it resides in.  Note that if you are still using XVidMode instead 
of XRandR, the sysmetrics values are updated, but not the desktop size 
from GetWindowRect because the desktop window does not change size in 
that case!

**** Lionel, I looked at your ClipCursor patch, and I think it will work 
correctly with this for the currently running process, but for it to 
take effect in other processes, the code you put in settings.c probably 
needs to go to the new X11DRV_handle_desktop_resize function I just added.

-ajp

-------------- next part --------------
Index: dlls/x11drv/desktop.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/desktop.c,v
retrieving revision 1.18
diff -u -r1.18 desktop.c
--- dlls/x11drv/desktop.c	21 Nov 2003 21:50:59 -0000	1.18
+++ dlls/x11drv/desktop.c	30 Jan 2004 20:54:04 -0000
@@ -178,13 +178,6 @@
     XResizeWindow( display, w, width, height );
     screen_width  = width;
     screen_height = height;
-#if 0 /* FIXME */
-    SYSMETRICS_Set( SM_CXSCREEN, width );
-    SYSMETRICS_Set( SM_CYSCREEN, height );
-#else
-    FIXME("Need to update SYSMETRICS after resizing display (now %dx%d)\n", 
-          width, height);
-#endif
 
     /* clean up */
     XFree( size_hints );
Index: dlls/x11drv/window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.69
diff -u -r1.69 window.c
--- dlls/x11drv/window.c	21 Jan 2004 02:22:26 -0000	1.69
+++ dlls/x11drv/window.c	30 Jan 2004 20:54:05 -0000
@@ -743,6 +743,7 @@
     X11DRV_InitClipboard();
 
     if (root_window != DefaultRootWindow(display)) X11DRV_create_desktop_thread();
+    XSelectInput(display, root_window, StructureNotifyMask);
 }
 
 
Index: dlls/x11drv/winpos.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/winpos.c,v
retrieving revision 1.74
diff -u -r1.74 winpos.c
--- dlls/x11drv/winpos.c	20 Jan 2004 22:48:57 -0000	1.74
+++ dlls/x11drv/winpos.c	30 Jan 2004 20:54:07 -0000
@@ -1551,6 +1551,44 @@
 }
 
 
+ /***********************************************************************
+ *		USER_EnumCallbackCDS (USER32.@)
+ *
+ * Callback function so we can update all existing windows
+ */
+static int new_bpp, new_width, new_height;
+static BOOL CALLBACK USER_EnumCallbackCDS(HWND hwnd, LPARAM ignored)
+{
+    WND *win;
+    WPARAM wParam = new_bpp;
+    LPARAM lParam = (new_height<<16) | new_width;
+    /* only send to windows in the current process */
+    win = WIN_GetPtr( hwnd );
+    if ( (!win) || (win == WND_OTHER_PROCESS)) return TRUE;
+    WIN_ReleasePtr( win );
+    TRACE("sending WM_DISPLAYCHANGE to %p\n", hwnd);
+    SendMessageA( hwnd, WM_DISPLAYCHANGE, wParam, lParam );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *		X11DRV_handle_desktop_resize
+ */
+void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height )
+{
+    RECT rect;
+    HWND hwnd = GetDesktopWindow();
+    screen_width  = width;
+    screen_height = height;
+    TRACE("HWND: %p change to (%dx%d)\n", hwnd, width, height);
+    SetRect( &rect, 0, 0, width, height );
+    WIN_SetRectangles( hwnd, &rect, &rect );
+    EnumWindows(USER_EnumCallbackCDS, 0);
+}
+
+
+
 /***********************************************************************
  *		X11DRV_ConfigureNotify
  */
@@ -1562,6 +1600,8 @@
     RECT rect;
     WINDOWPOS winpos;
     int x = event->x, y = event->y;
+
+    if (hwnd == GetDesktopWindow()) X11DRV_handle_desktop_resize( event->width, event->height );
 
     if (!(win = WIN_GetPtr( hwnd ))) return;
     data = win->pDriverData;
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.20
diff -u -r1.20 x11drv.h
--- dlls/x11drv/x11drv.h	21 Jan 2004 02:22:26 -0000	1.20
+++ dlls/x11drv/x11drv.h	30 Jan 2004 20:54:07 -0000
@@ -222,6 +222,7 @@
 extern int client_side_antialias_with_core;
 extern int client_side_antialias_with_render;
 extern int using_client_side_fonts;
+extern int using_wine_desktop;
 extern void X11DRV_XRender_Init(void);
 extern void X11DRV_XRender_Finalize(void);
 extern BOOL X11DRV_XRender_SelectFont(X11DRV_PDEVICE*, HFONT);
@@ -551,6 +552,7 @@
 extern int X11DRV_sync_client_window_position( Display *display, WND *win );
 extern void X11DRV_set_wm_hints( Display *display, WND *win );
 
+extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
 extern void X11DRV_Settings_AddDepthModes(void);
 extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq);
 extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info);
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.86
diff -u -r1.86 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	21 Jan 2004 02:22:26 -0000	1.86
+++ dlls/x11drv/x11drv_main.c	30 Jan 2004 20:54:08 -0000
@@ -90,6 +90,7 @@
 int client_side_with_render = 1;
 int client_side_antialias_with_core = 1;
 int client_side_antialias_with_render = 1;
+int using_wine_desktop = 0;
 
 unsigned int X11DRV_server_startticks;
 
@@ -379,7 +380,10 @@
     X11DRV_Settings_Init();
 
     if (desktop_geometry)
+    {
         root_window = X11DRV_create_desktop( desktop_vi, desktop_geometry );
+        using_wine_desktop = 1;
+    }
 
     /* initialize GDI */
     if(!X11DRV_GDI_Initialize( display ))
Index: dlls/x11drv/xrandr.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xrandr.c,v
retrieving revision 1.3
diff -u -r1.3 xrandr.c
--- dlls/x11drv/xrandr.c	21 Nov 2003 21:50:59 -0000	1.3
+++ dlls/x11drv/xrandr.c	30 Jan 2004 20:54:08 -0000
@@ -56,7 +56,6 @@
     return 1;
 }
 
-static Bool in_desktop_mode;
 
 /* create the mode structures */
 static void make_modes(void)
@@ -154,8 +153,6 @@
                               dd_modes[mode].dwWidth, dd_modes[mode].dwHeight, rate);
                         stat = XRRSetScreenConfigAndRate (gdi_display, sc, root, 
                                                           size, rot, rate, CurrentTime);
-                        FIXME("Need to update SYSMETRICS after resizing display (now %ldx%ld)\n",
-                              dd_modes[mode].dwWidth, dd_modes[mode].dwHeight);
                     }
                 }
             }
@@ -165,12 +162,15 @@
                       dd_modes[mode].dwWidth, dd_modes[mode].dwHeight);
                 stat = XRRSetScreenConfig (gdi_display, sc, root, 
                                            size, rot, CurrentTime);
-                FIXME("Need to update SYSMETRICS after resizing display (now %ldx%ld)\n",
-                      dd_modes[mode].dwWidth, dd_modes[mode].dwHeight);
             }
         }
     }
-    if (stat != RRSetConfigSuccess)
+    if (stat == RRSetConfigSuccess)
+    {
+        screen_width  = dd_modes[mode].dwWidth;
+        screen_height = dd_modes[mode].dwHeight;
+    }
+    else
     {
         ERR("Resolution change not successful -- perhaps display has changed?\n");
     }
@@ -183,11 +183,10 @@
     Bool ok;
     int nmodes = 0;
     int i;
-    in_desktop_mode = (root_window != DefaultRootWindow(gdi_display));
 
     if (xrandr_major) return; /* already initialized? */
     if (!usexrandr) return; /* disabled in config */
-    if (in_desktop_mode) return; /* not compatible with desktop mode */
+    if (using_wine_desktop) return; /* not compatible with desktop mode */
 
     /* see if Xrandr is available */
     wine_tsx11_lock();
@@ -222,6 +221,7 @@
             }
         }
     }
+    /* XRRSelectInput(gdi_display, root_window, RRScreenChangeNotifyMask); */
     wine_tsx11_unlock();
     if (!ok) return;
 
Index: dlls/x11drv/xvidmode.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xvidmode.c,v
retrieving revision 1.27
diff -u -r1.27 xvidmode.c
--- dlls/x11drv/xvidmode.c	20 Jan 2004 22:48:57 -0000	1.27
+++ dlls/x11drv/xvidmode.c	30 Jan 2004 20:54:08 -0000
@@ -93,8 +93,6 @@
     return 1;
 }
 
-static Bool in_desktop_mode;
-
 int X11DRV_XF86VM_GetCurrentMode(void)
 {
   XF86VidModeModeLine line;
@@ -132,13 +130,8 @@
   TRACE("Resizing X display to %dx%d\n", 
         real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay);
   XF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), real_xf86vm_modes[mode]);
-#if 0 /* FIXME */
-  SYSMETRICS_Set( SM_CXSCREEN, real_xf86vm_modes[mode]->hdisplay );
-  SYSMETRICS_Set( SM_CYSCREEN, real_xf86vm_modes[mode]->vdisplay );
-#else
-  FIXME("Need to update SYSMETRICS after resizing display (now %dx%d)\n",
-        real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay);
-#endif
+  screen_width  = real_xf86vm_modes[mode]->hdisplay;
+  screen_height = real_xf86vm_modes[mode]->vdisplay;
 #if 0 /* it is said that SetViewPort causes problems with some X servers */
   XF86VidModeSetViewPort(gdi_display, DefaultScreen(gdi_display), 0, 0);
 #else
@@ -155,8 +148,6 @@
   DWORD dwBpp = screen_depth;
   if (dwBpp == 24) dwBpp = 32;
 
-  in_desktop_mode = (root_window != DefaultRootWindow(gdi_display));
-
   if (xf86vm_major) return; /* already initialized? */
 
   if (!usexvidmode) return;
@@ -183,13 +174,13 @@
 #endif /* X_XF86VidModeSetGammaRamp */
 
       /* retrieve modes */
-      if (!in_desktop_mode) ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes);
+      if (!using_wine_desktop) ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes);
   }
   wine_tsx11_unlock();
   if (!ok) return;
 
   /* In desktop mode, do not switch resolution... But still use the Gamma ramp stuff */
-  if (in_desktop_mode) return;
+  if (using_wine_desktop) return;
   
   TRACE("XVidMode modes: count=%d\n", nmodes);
 
Index: windows/sysmetrics.c
===================================================================
RCS file: /home/wine/wine/windows/sysmetrics.c,v
retrieving revision 1.35
diff -u -r1.35 sysmetrics.c
--- windows/sysmetrics.c	5 Sep 2003 23:15:39 -0000	1.35
+++ windows/sysmetrics.c	30 Jan 2004 20:54:10 -0000
@@ -298,6 +298,40 @@
  */
 INT WINAPI GetSystemMetrics( INT index )
 {
+    HDC hdc;
+    /* return 0 if out of range */
     if ((index < 0) || (index > SM_WINE_CMETRICS)) return 0;
+    /* obtain and update the screen resolution if we need it */
+    switch (index)
+    {
+    case SM_CXFULLSCREEN:
+    case SM_CYFULLSCREEN:
+    case SM_CXMAXTRACK:
+    case SM_CYMAXTRACK:
+    case SM_CXSCREEN:
+    case SM_CYSCREEN:
+    case SM_CXVIRTUALSCREEN:
+    case SM_CYVIRTUALSCREEN:
+    case SM_CXMAXIMIZED:
+    case SM_CYMAXIMIZED:
+        hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
+	sysMetrics[SM_CXSCREEN] = GetDeviceCaps( hdc, HORZRES );
+	sysMetrics[SM_CYSCREEN] = GetDeviceCaps( hdc, VERTRES );
+	DeleteDC( hdc );
+
+	sysMetrics[SM_CXFULLSCREEN] = sysMetrics[SM_CXSCREEN];
+	sysMetrics[SM_CYFULLSCREEN] = sysMetrics[SM_CYSCREEN] - sysMetrics[SM_CYCAPTION];
+
+	/* FIXME: How do I calculate these? */
+	sysMetrics[SM_CXMAXTRACK] = sysMetrics[SM_CXSCREEN] + 4 + 2 * sysMetrics[SM_CXFRAME];
+	sysMetrics[SM_CYMAXTRACK] = sysMetrics[SM_CYSCREEN] + 4 + 2 * sysMetrics[SM_CYFRAME];
+	sysMetrics[SM_CXMAXIMIZED] = sysMetrics[SM_CXSCREEN] + 2 * sysMetrics[SM_CXFRAME];
+	sysMetrics[SM_CYMAXIMIZED] = sysMetrics[SM_CYSCREEN] + 2 * sysMetrics[SM_CXFRAME];
+
+	sysMetrics[SM_CXVIRTUALSCREEN] = sysMetrics[SM_CXSCREEN];
+	sysMetrics[SM_CYVIRTUALSCREEN] = sysMetrics[SM_CYSCREEN];
+
+	break;
+    }
     return sysMetrics[index];
 }


More information about the wine-patches mailing list