[ros-diffs] [fireball] 42325: Giannis Adamopoulos - Remove hardcoded dependency to 800x600 (and 640x480 in monitor functions) display size (see arwinss issue nr. 18), explorer now correctly shows its desktop on a full screen.

fireball at svn.reactos.org fireball at svn.reactos.org
Sat Aug 1 20:24:40 CEST 2009


Author: fireball
Date: Sat Aug  1 20:24:39 2009
New Revision: 42325

URL: http://svn.reactos.org/svn/reactos?rev=42325&view=rev
Log:
Giannis Adamopoulos
- Remove hardcoded dependency to 800x600 (and 640x480 in monitor functions) display size (see arwinss issue nr. 18), explorer now correctly shows its desktop on a full screen.

Added:
    branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h   (with props)
    branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c   (with props)
Modified:
    branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
    branches/arwinss/reactos/include/reactos/win32k/rosuser.h
    branches/arwinss/reactos/subsystems/win32/csrss/win32csr/input.c
    branches/arwinss/reactos/subsystems/win32/win32k/eng/device.c
    branches/arwinss/reactos/subsystems/win32/win32k/gdi/misc.c
    branches/arwinss/reactos/subsystems/win32/win32k/gre/lineto.c
    branches/arwinss/reactos/subsystems/win32/win32k/gre/rect.c
    branches/arwinss/reactos/subsystems/win32/win32k/include/user.h
    branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h
    branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db
    branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild

Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -89,7 +89,7 @@
 
 void CDECL RosDrv_Beep(void)
 {
-    UNIMPLEMENTED;
+    Beep(500, 100);
 }
 
 SHORT CDECL RosDrv_GetAsyncKeyState( INT key )
@@ -361,12 +361,62 @@
 
 BOOL CDECL RosDrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
 {
-    RECT monrect = {0, 0, 640, 480};
-
-    FIXME("RosDrv_EnumDisplayMonitors is a hack\n");
-
-    proc((HMONITOR)1, hdc, &monrect, lp);
-
+    int i;
+    int nb_monitors;
+    HMONITOR *monitors;
+    RECT *monitors_rect;
+
+    /* Get the count of the display monitors */
+    nb_monitors = RosUserEnumDisplayMonitors(NULL, NULL, 0);
+    if (nb_monitors <= 0)
+    {
+        return FALSE;
+    }
+
+    /* Allocate the buffers that will be filled by RosUserEnumDisplayMonitors */
+    monitors = HeapAlloc( GetProcessHeap(), 0, nb_monitors * sizeof(HMONITOR));
+    monitors_rect = HeapAlloc( GetProcessHeap(), 0, nb_monitors * sizeof(RECT));
+    if(!monitors || !monitors_rect)
+    {
+        return FALSE;
+    }
+
+    /* Fill the buffers with the handles and the rects of all display monitors */
+    nb_monitors = RosUserEnumDisplayMonitors(monitors, (PRECTL)monitors_rect, nb_monitors);
+    if (nb_monitors <= 0)
+    {
+        return FALSE;
+    }
+
+    if (hdc)
+    {
+        POINT origin;
+        RECT limit;
+
+        if (!GetDCOrgEx( hdc, &origin )) return FALSE;
+        if (GetClipBox( hdc, &limit ) == ERROR) return FALSE;
+
+        if (rect && !IntersectRect( &limit, &limit, rect )) return TRUE;
+
+        for (i = 0; i < nb_monitors; i++)
+        {
+            RECT monrect = monitors_rect[i];
+            OffsetRect( &monrect, -origin.x, -origin.y );
+            if (IntersectRect( &monrect, &monrect, &limit ))
+                if (!proc( monitors[i], hdc, &monrect, lp ))
+                    return FALSE;
+        }
+    }
+    else
+    {
+        for (i = 0; i < nb_monitors; i++)
+        {
+            RECT unused;
+            if (!rect || IntersectRect( &unused, &monitors_rect[i], rect ))
+                if (!proc( monitors[i], 0, &monitors_rect[i], lp ))
+                    return FALSE;
+        }
+    }
     return TRUE;
 }
 
@@ -378,14 +428,7 @@
 
 BOOL CDECL RosDrv_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
 {
-    RECT monrect = {0, 0, 640, 480};
-
-    FIXME("RosDrv_GetMonitorInfo(%x %p) is a hack\n", handle, info);
-
-    info->rcMonitor = monrect;
-    info->rcWork = monrect;
-
-    return TRUE;
+    return RosUserGetMonitorInfo(handle, info);
 }
 
 BOOL CDECL RosDrv_CreateDesktopWindow( HWND hwnd )
@@ -413,8 +456,8 @@
             req->flags         = SWP_NOZORDER;
             req->window.left   = 0;
             req->window.top    = 0;
-            req->window.right  = 800; // FIXME: Use primary surface's dimensions!
-            req->window.bottom = 600;
+            req->window.right  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+            req->window.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
             req->client        = req->window;
             wine_server_call( req );
         }

Modified: branches/arwinss/reactos/include/reactos/win32k/rosuser.h
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/include/reactos/win32k/rosuser.h?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] (original)
+++ branches/arwinss/reactos/include/reactos/win32k/rosuser.h [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -49,6 +49,19 @@
 void NTAPI 
 RosUserSetCursor( ICONINFO* IconInfo );
 
+INT
+APIENTRY
+RosUserEnumDisplayMonitors(
+   OPTIONAL OUT HMONITOR *hMonitorList,
+   OPTIONAL OUT PRECTL monitorRectList,
+   OPTIONAL IN DWORD listSize);
+
+BOOL
+APIENTRY
+RosUserGetMonitorInfo(
+   IN HMONITOR hMonitor,
+   OUT LPMONITORINFO pMonitorInfo);
+
 VOID NTAPI
 RosUserConnectCsrss();
 

Modified: branches/arwinss/reactos/subsystems/win32/csrss/win32csr/input.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/csrss/win32csr/input.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/csrss/win32csr/input.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/csrss/win32csr/input.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -183,8 +183,6 @@
     HANDLE MouseThreadHandle;
 
     ClipCursor(NULL);
-    SetCursorPos(GetSystemMetrics( SM_CXVIRTUALSCREEN ) /2,
-                 GetSystemMetrics( SM_CYVIRTUALSCREEN ) /2);
 
     MouseThreadHandle = CreateThread(NULL, 0, MouseInputThread, NULL, 0,NULL);
 }

Modified: branches/arwinss/reactos/subsystems/win32/win32k/eng/device.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/eng/device.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/eng/device.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/eng/device.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -534,14 +534,17 @@
     SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
     //EngEraseSurface(SurfObj, &SurfaceRect, 0);
 
-    /* Put the pointer in the center of the screen */
-    //gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
-    //gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
-
     /* Give the PDEV a MovePointer function */
     PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer;
     if (!PrimarySurface.pfnMovePointer)
         PrimarySurface.pfnMovePointer = EngMovePointer;
+
+    /* attach monitor */
+    AttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+
+    /* Put the pointer in the center of the screen */
+    RosUserSetCursorPos((SurfaceRect.right - SurfaceRect.left) / 2,
+                        (SurfaceRect.bottom - SurfaceRect.top) / 2);
 
     EngUnlockSurface(SurfObj);
 

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gdi/misc.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gdi/misc.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gdi/misc.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gdi/misc.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -12,6 +12,8 @@
 #define NDEBUG
 #include <debug.h>
 
+extern PDEVOBJ PrimarySurface;
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 BOOL APIENTRY RosGdiArc( HDC physDev, INT left, INT top, INT right, INT bottom,
@@ -79,8 +81,8 @@
     pDC = DC_Lock(physDev);
 
     scrRect.left = scrRect.top = 0;
-    scrRect.right = 800;
-    scrRect.bottom = 600;
+    scrRect.right = PrimarySurface.GDIInfo.ulHorzRes;
+    scrRect.bottom = PrimarySurface.GDIInfo.ulVertRes;
 
     pClipObj = IntEngCreateClipRegion(1, NULL, &scrRect);
 

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/lineto.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gre/lineto.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/lineto.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/lineto.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -13,6 +13,8 @@
 #include <win32k.h>
 #define NDEBUG
 #include <debug.h>
+
+extern PDEVOBJ PrimarySurface;
 
 /* PUBLIC FUNCTIONS **********************************************************/
 
@@ -112,8 +114,8 @@
     // HACK
     DestRect.left = 0;
     DestRect.top = 0;
-    DestRect.bottom = 600;
-    DestRect.right = 800;
+    DestRect.bottom = PrimarySurface.GDIInfo.ulVertRes;
+    DestRect.right = PrimarySurface.GDIInfo.ulHorzRes;
 
     /* Draw pen-based polygon */
     if (!(pDC->pLineBrush->flAttrs & GDIBRUSH_IS_NULL))

Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/rect.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/gre/rect.c?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/gre/rect.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/gre/rect.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -11,6 +11,8 @@
 #include <win32k.h>
 #define NDEBUG
 #include <debug.h>
+
+extern PDEVOBJ PrimarySurface;
 
 /* PUBLIC FUNCTIONS **********************************************************/
 
@@ -105,8 +107,8 @@
     // HACK
     DestRect.left = 0;
     DestRect.top = 0;
-    DestRect.bottom = 600;
-    DestRect.right = 800;
+    DestRect.bottom = PrimarySurface.GDIInfo.ulVertRes;
+    DestRect.right = PrimarySurface.GDIInfo.ulHorzRes;
 
     /* Draw brush-based polygon */
     if (pDC->pFillBrush)

Added: branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h?rev=42325&view=auto
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h (added)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -1,0 +1,26 @@
+#ifndef _WIN32K_MONITOR_H
+#define _WIN32K_MONITOR_H
+
+typedef struct _MONITOR_OBJECT
+{
+    HANDLE         Handle;     /* system object handle */
+    FAST_MUTEX     Lock;       /* R/W lock */
+
+    BOOL           IsPrimary;  /* wether this is the primary monitor */
+    UNICODE_STRING DeviceName; /* name of the monitor */
+    PDEVOBJ     *GdiDevice;    /* pointer to the GDI device to
+                                  which this monitor is attached */
+    struct _MONITOR_OBJECT *Prev, *Next; /* double linked list */
+
+    RECT    rcMonitor;
+    RECT    rcWork;
+} MONITOR, *PMONITOR;
+
+NTSTATUS
+AttachMonitor(IN PDEVOBJ *pGdiDevice,
+                 IN ULONG DisplayNumber);
+
+NTSTATUS
+DetachMonitor(IN PDEVOBJ *pGdiDevice);
+
+#endif /* _WIN32K_MONITOR_H */

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/include/monitor.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/user.h
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/user.h?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/user.h [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/user.h [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -35,7 +35,8 @@
 enum user_object
 {
     USER_WINDOW = 1,
-    USER_HOOK
+    USER_HOOK,
+    USER_MONITOR
 };
 
 #define DESKTOP_ATOM  ((atom_t)32769)

Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/win32kp.h [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -48,6 +48,7 @@
 #include <xlateobj.h>
 #include <cursor.h>
 #include <gre.h>
+#include <monitor.h>
 
 #include "winesup.h"
 

Added: branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c?rev=42325&view=auto
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c (added)
+++ branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -1,0 +1,457 @@
+/*
+ *  ReactOS W32 Subsystem
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  COPYRIGHT:        See COPYING in the top level directory
+ *  PROJECT:          ReactOS kernel
+ *  PURPOSE:          Monitor support
+ *  FILE:             subsys/win32k/ntuser/monitor.c
+ *  PROGRAMER:        Anich Gregor (blight at blight.eu.org)
+ *  REVISION HISTORY:
+ *       26-02-2004  Created
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <win32k.h>
+#include "object.h"
+#include "user.h"
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+/* list of monitors */
+static PMONITOR gMonitorList = NULL;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+/* IntCreateMonitorObject
+ *
+ * Creates a MONITOR struct
+ *
+ * Return value
+ *   If the function succeeds a pointer to a MONITOR struct is returned. On failure
+ *   NULL is returned.
+ */
+static
+PMONITOR
+IntCreateMonitorObject()
+{
+   PMONITOR Monitor;
+
+   Monitor = ExAllocatePool( PagedPool, sizeof (MONITOR) );
+   if (Monitor == NULL)
+   {
+      return NULL;
+   }
+
+   RtlZeroMemory(Monitor, sizeof (MONITOR));
+   Monitor->Handle = (HANDLE)alloc_user_handle(Monitor, USER_MONITOR);
+
+   ExInitializeFastMutex(&Monitor->Lock);
+
+   return Monitor;
+}
+
+/* IntDestroyMonitorObject
+ *
+ * Destroys a MONITOR struct
+ * You have to be the owner of the monitors lock to safely destroy it.
+ *
+ * Arguments
+ *
+ *   pMonitor
+ *      Pointer to the MONITOR struct which shall be deleted
+ */
+static
+void
+IntDestroyMonitorObject(IN PMONITOR pMonitor)
+{
+   RtlFreeUnicodeString(&pMonitor->DeviceName);
+   free_user_handle((user_handle_t)pMonitor->Handle);
+   //UserDereferenceObject(pMonitor);
+}
+
+
+PMONITOR FASTCALL
+UserGetMonitorObject(IN HMONITOR hMonitor)
+{
+   PMONITOR Monitor;
+
+   if (!hMonitor)
+   {
+      SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
+      return NULL;
+   }
+
+   Monitor = (PMONITOR)get_user_object((user_handle_t)hMonitor, USER_MONITOR);
+   if (!Monitor)
+   {
+      SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
+      return NULL;
+   }
+
+   return Monitor;
+}
+
+
+/* IntAttachMonitor
+ *
+ * Creates a new MONITOR struct and appends it to the list of monitors.
+ *
+ * Arguments
+ *
+ *   pGdiDevice     Pointer to the PDEVOBJ onto which the monitor was attached
+ *   DisplayNumber  Display Number (starting with 0)
+ *
+ * Return value
+ *   Returns a NTSTATUS
+ */
+NTSTATUS
+AttachMonitor(IN PDEVOBJ *pGdiDevice,
+                 IN ULONG DisplayNumber)
+{
+   PMONITOR Monitor;
+   WCHAR Buffer[CCHDEVICENAME];
+
+   DPRINT("Attaching monitor...\n");
+
+   /* create new monitor object */
+   Monitor = IntCreateMonitorObject();
+   if (Monitor == NULL)
+   {
+      DPRINT1("Couldnt create monitor object\n");
+      return STATUS_INSUFFICIENT_RESOURCES;
+   }
+
+   _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
+   if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
+   {
+      DPRINT1("Couldn't duplicate monitor name!\n");
+      //UserDereferenceObject(Monitor);
+      //UserDeleteObject(Monitor->Handle, Monitor);
+	  free_user_handle((user_handle_t)Monitor->Handle);
+      return STATUS_INSUFFICIENT_RESOURCES;
+   }
+
+   Monitor->GdiDevice = pGdiDevice;
+   if (gMonitorList == NULL)
+   {
+      DPRINT("Primary monitor is beeing attached\n");
+      Monitor->IsPrimary = TRUE;
+      gMonitorList = Monitor;
+   }
+   else
+   {
+      PMONITOR p;
+      DPRINT("Additional monitor is beeing attached\n");
+      for (p = gMonitorList; p->Next != NULL; p = p->Next)
+         ;
+      {
+         p->Next = Monitor;
+      }
+      Monitor->Prev = p;
+   }
+
+   return STATUS_SUCCESS;
+}
+
+/* IntDetachMonitor
+ *
+ * Deletes a MONITOR struct and removes it from the list of monitors.
+ *
+ * Arguments
+ *
+ *   pGdiDevice  Pointer to the PDEVOBJ from which the monitor was detached
+ *
+ * Return value
+ *   Returns a NTSTATUS
+ */
+NTSTATUS
+DetachMonitor(IN PDEVOBJ *pGdiDevice)
+{
+   PMONITOR Monitor;
+
+   for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+   {
+      if (Monitor->GdiDevice == pGdiDevice)
+         break;
+   }
+
+   if (Monitor == NULL)
+   {
+      /* no monitor for given device found */
+      return STATUS_INVALID_PARAMETER;
+   }
+
+   if (Monitor->IsPrimary && (Monitor->Next != NULL || Monitor->Prev != NULL))
+   {
+      PMONITOR NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) : (Monitor->Next);
+
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&NewPrimaryMonitor->Lock);
+      NewPrimaryMonitor->IsPrimary = TRUE;
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&NewPrimaryMonitor->Lock);
+   }
+
+   if (gMonitorList == Monitor)
+   {
+      gMonitorList = Monitor->Next;
+      if (Monitor->Next != NULL)
+         Monitor->Next->Prev = NULL;
+   }
+   else
+   {
+      Monitor->Prev->Next = Monitor->Next;
+      if (Monitor->Next != NULL)
+         Monitor->Next->Prev = Monitor->Prev;
+   }
+
+   IntDestroyMonitorObject(Monitor);
+
+   return STATUS_SUCCESS;
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/* RosUserEnumDisplayMonitors
+ *
+ * Fills hMonitorList with handles to all available monitors and their rectangles
+ *
+ */
+INT
+APIENTRY
+RosUserEnumDisplayMonitors(
+   OPTIONAL OUT HMONITOR *hMonitorList,
+   OPTIONAL OUT PRECTL monitorRectList,
+   OPTIONAL IN DWORD listSize)
+{
+   INT numMonitors = 0,i =0;
+   HMONITOR *safeHMonitorList = NULL;
+   PMONITOR Monitor;
+   PRECTL safeRectList = NULL;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+	DPRINT("RosUserEnumDisplayMonitors called\n");
+
+   /* get monitors count */
+   for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+   {
+	   numMonitors++;
+   }
+
+   if (numMonitors == 0 || listSize == 0 || (hMonitorList == NULL && monitorRectList == NULL))
+   {
+      return numMonitors;
+   }
+
+      safeHMonitorList = ExAllocatePool(PagedPool, sizeof (HMONITOR) * listSize);
+      if (safeHMonitorList == NULL)
+      {
+         /* FIXME: SetLastWin32Error? */
+		  DPRINT1("safeHMonitorList == NULL\n");
+         return -1;
+      }
+
+      safeRectList = ExAllocatePool(PagedPool, sizeof (RECT) * listSize);
+      if (safeRectList == NULL)
+      {
+         ExFreePool(safeHMonitorList);
+         /* FIXME: SetLastWin32Error? */
+		 DPRINT1("safeRectList == NULL\n");
+         return -1;
+      }
+
+   for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
+   {
+		safeHMonitorList[i] = Monitor->Handle;
+		safeRectList[i].left = 0; /* FIXME: get origin */
+		safeRectList[i].top = 0; /* FIXME: get origin */
+		safeRectList[i].right = safeRectList->left + Monitor->GdiDevice->GDIInfo.ulHorzRes;
+		safeRectList[i].bottom = safeRectList->top + Monitor->GdiDevice->GDIInfo.ulVertRes;
+	
+		i++;
+   }
+
+   /* output result */
+   if (hMonitorList != NULL)
+   {
+		_SEH2_TRY
+		{
+			ProbeForWrite(hMonitorList, sizeof (HMONITOR) * listSize, 1);
+			RtlCopyMemory(hMonitorList,safeHMonitorList,sizeof (HMONITOR) * listSize);
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			Status = _SEH2_GetExceptionCode();
+		}
+		_SEH2_END;
+
+      if (!NT_SUCCESS(Status))
+      {
+         ExFreePool(safeHMonitorList);
+         SetLastNtError(Status);
+         return -1;
+      }
+   }
+   if (monitorRectList != NULL)
+   {
+	   	_SEH2_TRY
+		{
+			ProbeForWrite(monitorRectList, sizeof (RECT) * listSize, 1);
+			RtlCopyMemory(monitorRectList,safeRectList,sizeof (RECT) * listSize);
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			Status = _SEH2_GetExceptionCode();
+		}
+		_SEH2_END;
+
+      ExFreePool(safeRectList);
+      if (!NT_SUCCESS(Status))
+      {
+         SetLastNtError(Status);
+         return -1;
+      }
+   }
+
+   return numMonitors;
+}
+
+/* RosUserGetMonitorInfo
+ *
+ * Retrieves information about a given monitor
+ *
+ * Arguments
+ *
+ *   hMonitor
+ *      Handle to a monitor for which to get information
+ *
+ *   pMonitorInfo
+ *      Pointer to a MONITORINFO struct which is filled with the information.
+ *      The cbSize member must be set to sizeof(MONITORINFO) or
+ *      sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts
+ *      from MONITORINFO will be filled.
+ *
+ *   pDevice
+ *      Pointer to a UNICODE_STRING which will recieve the device's name. The
+ *      length should be CCHDEVICENAME
+ *      Can be NULL
+ *
+ * Return value
+ *   TRUE on success; FALSE on failure (calls SetLastNtError())
+ *
+ */
+BOOL
+APIENTRY
+RosUserGetMonitorInfo(
+   IN HMONITOR hMonitor,
+   OUT LPMONITORINFO pMonitorInfo)
+{
+   PMONITOR Monitor;
+   MONITORINFOEXW MonitorInfo;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   DPRINT("Enter NtUserGetMonitorInfo\n");
+   //FIXME: lock
+
+   /* get monitor object */
+   if (!(Monitor = UserGetMonitorObject(hMonitor)))
+   {
+      DPRINT1("Couldnt find monitor 0x%lx\n", hMonitor);
+      return FALSE;
+   }
+
+   if(pMonitorInfo == NULL)
+   {
+      SetLastNtError(STATUS_INVALID_PARAMETER);
+      return FALSE;
+   }
+
+   /* get size of pMonitorInfo */
+   _SEH2_TRY
+    {
+        ProbeForRead(&pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize), 1);
+        RtlCopyMemory(&MonitorInfo.cbSize, &pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return FALSE;
+   }
+   if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) &&
+         (MonitorInfo.cbSize != sizeof (MONITORINFOEXW)))
+   {
+      SetLastNtError(STATUS_INVALID_PARAMETER);
+      return FALSE;
+   }
+
+   /* fill monitor info */
+   MonitorInfo.rcMonitor.left = 0; /* FIXME: get origin */
+   MonitorInfo.rcMonitor.top = 0; /* FIXME: get origin */
+   MonitorInfo.rcMonitor.right = MonitorInfo.rcMonitor.left + Monitor->GdiDevice->GDIInfo.ulHorzRes;
+   MonitorInfo.rcMonitor.bottom = MonitorInfo.rcMonitor.top + Monitor->GdiDevice->GDIInfo.ulVertRes;
+   MonitorInfo.rcWork = MonitorInfo.rcMonitor; /* FIXME: use DEVMODE panning to calculate work area? */
+   MonitorInfo.dwFlags = 0;
+
+   if (Monitor->IsPrimary)
+      MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;
+
+   /* fill device name */
+   if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW))
+   {
+      WCHAR nul = L'\0';
+      INT len = Monitor->DeviceName.Length;
+      if (len >= CCHDEVICENAME * sizeof (WCHAR))
+         len = (CCHDEVICENAME - 1) * sizeof (WCHAR);
+
+      memcpy(MonitorInfo.szDevice, Monitor->DeviceName.Buffer, len);
+      memcpy(MonitorInfo.szDevice + (len / sizeof (WCHAR)), &nul, sizeof (WCHAR));
+   }
+
+   /* output data */
+	   	_SEH2_TRY
+		{
+			ProbeForWrite(pMonitorInfo, MonitorInfo.cbSize, 1);
+			RtlCopyMemory(pMonitorInfo,&MonitorInfo,MonitorInfo.cbSize);
+		}
+		_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+		{
+			Status = _SEH2_GetExceptionCode();
+		}
+		_SEH2_END;
+
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastNtError(Status);
+      return FALSE;
+   }
+
+   //FIXME: unlock
+
+   DPRINT("GetMonitorInfo: success\n");
+
+   return TRUE;
+
+
+}

Propchange: branches/arwinss/reactos/subsystems/win32/win32k/main/monitor.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/w32ksvc.db [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -65,4 +65,6 @@
 RosUserGetCursorPos                1
 RosUserSetCursorPos                2
 RosUserClipCursor                  1
-RosUserSetCursor                   1
+RosUserSetCursor                   1
+RosUserEnumDisplayMonitors         3
+RosUserGetMonitorInfo              2

Modified: branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild?rev=42325&r1=42324&r2=42325&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] Sat Aug  1 20:24:39 2009
@@ -114,6 +114,7 @@
 		<file>init.c</file>
 		<file>usrheap.c</file>
 		<file>cursor.c</file>
+		<file>monitor.c</file>
 	</directory>
 	<directory name="wine">
 		<file>atom.c</file>




More information about the Ros-diffs mailing list