Index: trunk/src/gdi32/blit.cpp
===================================================================
--- trunk/src/gdi32/blit.cpp	(revision 3704)
+++ trunk/src/gdi32/blit.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: blit.cpp,v 1.13 2000-05-29 22:43:54 sandervl Exp $ */
+/* $Id: blit.cpp,v 1.14 2000-06-14 13:17:49 sandervl Exp $ */
 
 /*
@@ -256,5 +256,5 @@
                                (PBITMAPINFO)infoLoc, DIB_RGB_COLORS, dwRop);
 
-      	if(rc != heightDst) {
+      	if(rc != heightSrc) {
 		dprintf(("StretchDIBits failed with rc %x", rc));
       	}
Index: trunk/src/gdi32/dbglocal.cpp
===================================================================
--- trunk/src/gdi32/dbglocal.cpp	(revision 3704)
+++ trunk/src/gdi32/dbglocal.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.cpp,v 1.2 2000-02-22 19:11:48 sandervl Exp $ */
+/* $Id: dbglocal.cpp,v 1.3 2000-06-14 13:17:49 sandervl Exp $ */
 
 /*
@@ -35,5 +35,6 @@
 "dibitmap",
 "blit",
-"rgbcvt"
+"rgbcvt",
+"objhandle"
 };
 //******************************************************************************
Index: trunk/src/gdi32/dbglocal.h
===================================================================
--- trunk/src/gdi32/dbglocal.h	(revision 3704)
+++ trunk/src/gdi32/dbglocal.h	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.h,v 1.2 2000-02-22 19:11:49 sandervl Exp $ */
+/* $Id: dbglocal.h,v 1.3 2000-06-14 13:17:49 sandervl Exp $ */
 
 /*
@@ -36,5 +36,6 @@
 #define DBG_blit            15
 #define DBG_rgbcvt          16
-#define DBG_MAXFILES        17
+#define DBG_objhandle       17
+#define DBG_MAXFILES        18
 
 extern USHORT DbgEnabled[DBG_MAXFILES];
Index: trunk/src/gdi32/gdi32.DEF
===================================================================
--- trunk/src/gdi32/gdi32.DEF	(revision 3704)
+++ trunk/src/gdi32/gdi32.DEF	(revision 3705)
@@ -1,3 +1,3 @@
-; $Id: gdi32.DEF,v 1.7 2000-04-03 18:30:47 sandervl Exp $
+; $Id: gdi32.DEF,v 1.8 2000-06-14 13:17:49 sandervl Exp $
 
 ;Created by BLAST for IBM's compiler
@@ -358,2 +358,9 @@
     InternalGetTabbedTextExtentA @1004
     InternalGetTabbedTextExtentW @1005
+
+    setWinDeviceRegionFromPMDeviceRegion__FUlT1P7_DCDataT1     @1006
+
+    ObjAllocateHandle__FPUlUl10ObjectType                      @1007
+    ObjFreeHandle__FUl					       @1008
+    ObjGetHandleData__FUl                                      @1009
+    ObjGetHandleType__FUl                                      @1010
Index: trunk/src/gdi32/gdi32.cpp
===================================================================
--- trunk/src/gdi32/gdi32.cpp	(revision 3704)
+++ trunk/src/gdi32/gdi32.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: gdi32.cpp,v 1.50 2000-06-08 18:07:06 sandervl Exp $ */
+/* $Id: gdi32.cpp,v 1.51 2000-06-14 13:17:50 sandervl Exp $ */
 
 /*
@@ -85,55 +85,4 @@
 //******************************************************************************
 //******************************************************************************
-int WIN32API GetObjectA( HGDIOBJ hObject, int size, void *lpBuffer)
-{
- int rc;
-
-  if(size == 0 || lpBuffer == NULL) {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-  }
-
-  if(DIBSection::getSection() != NULL)
-  {
-        DIBSection *dsect = DIBSection::find(hObject);
-        if(dsect)
-        {
-                rc = dsect->GetDIBSection(size, lpBuffer);
-                if(rc == 0) {
-                        SetLastError(ERROR_INVALID_PARAMETER);
-                        return 0;
-                }
-                SetLastError(ERROR_SUCCESS);
-                return rc;
-        }
-  }
-
-  dprintf(("GDI32: GetObject %X %X %X\n", hObject, size, lpBuffer));
-  return O32_GetObject(hObject, size, lpBuffer);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API GetObjectW( HGDIOBJ arg1, int arg2, void *  arg3)
-{
-    dprintf(("GDI32: GetObjectW %X, %d %X not complete!", arg1, arg2, arg3));
-    return GetObjectA(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-DWORD WIN32API GetObjectType( HGDIOBJ arg1)
-{
-    dprintf2(("GDI32: GetObjectType\n"));
-    return O32_GetObjectType(arg1);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API DeleteObject(HANDLE hObj)
-{
-    dprintf(("GDI32: DeleteObject %x", hObj));
-    DIBSection::deleteSection((DWORD)hObj);
-    return O32_DeleteObject(hObj);
-}
-//******************************************************************************
-//******************************************************************************
 BOOL WIN32API DeleteDC( HDC hdc)
 {
@@ -205,39 +154,4 @@
     dprintf(("GDI32: StrokePath\n"));
     return O32_StrokePath(arg1);
-}
-//******************************************************************************
-//******************************************************************************
-HGDIOBJ WIN32API SelectObject(HDC hdc, HGDIOBJ hObj)
-{
- HGDIOBJ rc;
-
-    dprintf2(("GDI32: SelectObject %x %x", hdc, hObj));
-
-    if(DIBSection::getSection() != NULL)
-    {
-      DIBSection *dsect;
-
-      dsect = DIBSection::find(hdc);
-      if(dsect)
-      {
-        //remove previously selected dibsection
-        dsect->UnSelectDIBObject();
-      }
-      dsect = DIBSection::find((DWORD)hObj);
-      if(dsect)
-      {
-        dsect->SelectDIBObject(hdc);
-      }
-    }
-    rc = O32_SelectObject(hdc, hObj);
-    if(rc != 0 && DIBSection::getSection != NULL)
-    {
-      DIBSection *dsect = DIBSection::find((DWORD)rc);
-      if(dsect)
-      {
-        dsect->UnSelectDIBObject();
-      }
-    }
-    return(rc);
 }
 //******************************************************************************
@@ -1486,11 +1400,4 @@
 
 //******************************************************************************
-BOOL WIN32API SetObjectOwner( HGDIOBJ arg1, int arg2 )
-{
-  // Here is a guess for a undocumented entry
-  dprintf(("GDI32: SetObjectOwner - stub (TRUE)\n"));
-  return TRUE;
-}
-//******************************************************************************
 
 
Index: trunk/src/gdi32/initterm.cpp
===================================================================
--- trunk/src/gdi32/initterm.cpp	(revision 3704)
+++ trunk/src/gdi32/initterm.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: initterm.cpp,v 1.10 2000-02-16 14:18:10 sandervl Exp $ */
+/* $Id: initterm.cpp,v 1.11 2000-06-14 13:17:50 sandervl Exp $ */
 
 /*
@@ -38,4 +38,5 @@
 #define DBG_LOCALLOG	DBG_initterm
 #include "dbglocal.h"
+#include "region.h"
 
 extern "C" {
@@ -97,4 +98,7 @@
          /*******************************************************************/
 
+	 if(InitRegionSpace() == FALSE) {
+		return 0UL;
+	 }
 	 if(RegisterLxDll(hModule, LibMain, (PVOID)&_Resource_PEResTab) == FALSE) 
 		return 0UL;
Index: trunk/src/gdi32/makefile
===================================================================
--- trunk/src/gdi32/makefile	(revision 3704)
+++ trunk/src/gdi32/makefile	(revision 3705)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.25 2000-06-01 11:27:06 sandervl Exp $
+# $Id: makefile,v 1.26 2000-06-14 13:17:50 sandervl Exp $
 
 #
@@ -41,4 +41,5 @@
 $(OBJDIR)\blit.obj \
 $(OBJDIR)\rgbcvt.obj \
+$(OBJDIR)\objhandle.obj \
 $(OBJDIR)\dbglocal.obj \
 $(OBJDIR)\gdi32rsrc.obj
Index: trunk/src/gdi32/objhandle.cpp
===================================================================
--- trunk/src/gdi32/objhandle.cpp	(revision 3705)
+++ trunk/src/gdi32/objhandle.cpp	(revision 3705)
@@ -0,0 +1,225 @@
+/* $Id: objhandle.cpp,v 1.1 2000-06-14 13:17:51 sandervl Exp $ */
+/*
+ * Win32 Handle Management Code for OS/2
+ *
+ *
+ * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ *
+ * TODO: The table should be dynamically increased when necessary
+ *       This is just a quick and dirty implementation 
+ * 
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+#include <os2win.h>
+#include <vmutex.h>
+#include <objhandle.h>
+#include "dibsect.h"
+#include "region.h"
+
+#define DBG_LOCALLOG	DBG_objhandle
+#include "dbglocal.h"
+
+//******************************************************************************
+
+static ULONG  objHandleTable[MAX_OBJECT_HANDLES] = {0};
+static ULONG  lowestFreeIndex = 0;
+static VMutex objTableMutex;
+
+//******************************************************************************
+//******************************************************************************
+BOOL ObjAllocateHandle(HANDLE *hObject, DWORD dwUserData, ObjectType type)
+{
+  objTableMutex.enter(VMUTEX_WAIT_FOREVER);
+  if(lowestFreeIndex == -1) {
+	//oops, out of handles
+	dprintf(("ERROR: GDI: HwAllocateWindowHandle OUT OF GDI OBJECT HANDLES!!"));
+	objTableMutex.leave();
+	DebugInt3();
+	return FALSE;
+  }
+  *hObject  = lowestFreeIndex;
+  *hObject |= MAKE_HANDLE(type);
+  objHandleTable[lowestFreeIndex] = dwUserData;
+
+  lowestFreeIndex = -1;
+
+  //find next free handle
+  for(int i=0;i<MAX_OBJECT_HANDLES;i++) {
+	if(objHandleTable[i] == 0) {
+		lowestFreeIndex = i;
+		break;
+	}
+  }
+  objTableMutex.leave();
+  return TRUE;
+}
+//******************************************************************************
+//******************************************************************************
+void ObjFreeHandle(HANDLE hObject)
+{
+  hObject &= OBJHANDLE_MAGIC_MASK;
+  if(hObject < MAX_OBJECT_HANDLES) {
+	objTableMutex.enter(VMUTEX_WAIT_FOREVER);
+	objHandleTable[hObject] = 0;
+	if(lowestFreeIndex == -1 || hObject < lowestFreeIndex) 
+		lowestFreeIndex = hObject;
+
+	objTableMutex.leave();
+  }
+}
+//******************************************************************************
+//******************************************************************************
+DWORD ObjGetHandleData(HANDLE hObject)
+{
+  switch(GET_OBJTYPE(hObject))
+  {
+  case GDIOBJ_REGION:
+	break;
+  //case GDIOBJ_BITMAP
+  //case GDIOBJ_BRUSH
+  //case GDIOBJ_PALETTE
+  //case GDIOBJ_FONT
+  default:
+	return HANDLE_OBJ_ERROR;
+  }
+
+  hObject &= OBJHANDLE_MAGIC_MASK;
+  if(hObject < MAX_OBJECT_HANDLES) {
+	return objHandleTable[hObject];
+  }
+  return HANDLE_OBJ_ERROR;
+}
+//******************************************************************************
+//******************************************************************************
+ObjectType ObjGetHandleType(HANDLE hObject)
+{
+  switch(GET_OBJTYPE(hObject))
+  {
+  case GDIOBJ_REGION:
+	return GDIOBJ_REGION;
+  //case GDIOBJ_BITMAP
+  //case GDIOBJ_BRUSH
+  //case GDIOBJ_PALETTE
+  //case GDIOBJ_FONT
+  default:
+	return GDIOBJ_ERROR;
+  }
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API GetObjectA( HGDIOBJ hObject, int size, void *lpBuffer)
+{
+ int rc;
+
+  if(size == 0 || lpBuffer == NULL) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+  }
+
+  if(ObjGetHandleType(hObject) == GDIOBJ_REGION) {
+        SetLastError(ERROR_SUCCESS);
+	return 0;
+  }
+  if(DIBSection::getSection() != NULL)
+  {
+        DIBSection *dsect = DIBSection::find(hObject);
+        if(dsect)
+        {
+                rc = dsect->GetDIBSection(size, lpBuffer);
+                if(rc == 0) {
+                        SetLastError(ERROR_INVALID_PARAMETER);
+                        return 0;
+                }
+                SetLastError(ERROR_SUCCESS);
+                return rc;
+        }
+  }
+
+  dprintf(("GDI32: GetObject %X %X %X\n", hObject, size, lpBuffer));
+  return O32_GetObject(hObject, size, lpBuffer);
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API GetObjectW( HGDIOBJ arg1, int arg2, void *  arg3)
+{
+  dprintf(("GDI32: GetObjectW %X, %d %X not complete!", arg1, arg2, arg3));
+  return GetObjectA(arg1, arg2, arg3);
+}
+//******************************************************************************
+//******************************************************************************
+HGDIOBJ WIN32API SelectObject(HDC hdc, HGDIOBJ hObj)
+{
+ HGDIOBJ rc;
+
+    dprintf2(("GDI32: SelectObject %x %x", hdc, hObj));
+
+    if(ObjGetHandleType(hObj) == GDIOBJ_REGION) {
+	//Return complexity here; not previously selected clip region
+     	return (HGDIOBJ)SelectClipRgn(hdc, hObj);
+    }
+
+    if(DIBSection::getSection() != NULL)
+    {
+      DIBSection *dsect;
+
+      dsect = DIBSection::find(hdc);
+      if(dsect)
+      {
+        //remove previously selected dibsection
+        dsect->UnSelectDIBObject();
+      }
+      dsect = DIBSection::find((DWORD)hObj);
+      if(dsect)
+      {
+        dsect->SelectDIBObject(hdc);
+      }
+    }
+    rc = O32_SelectObject(hdc, hObj);
+    if(rc != 0 && DIBSection::getSection != NULL)
+    {
+      DIBSection *dsect = DIBSection::find((DWORD)rc);
+      if(dsect)
+      {
+        dsect->UnSelectDIBObject();
+      }
+    }
+    return(rc);
+}
+//******************************************************************************
+//******************************************************************************
+DWORD WIN32API GetObjectType( HGDIOBJ hObj)
+{
+  dprintf2(("GDI32: GetObjectType\n"));
+  if(ObjGetHandleType(hObj) == GDIOBJ_REGION) {
+        SetLastError(ERROR_SUCCESS);
+	return OBJ_REGION;
+  }
+  return O32_GetObjectType(hObj);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API DeleteObject(HANDLE hObj)
+{
+  dprintf(("GDI32: DeleteObject %x", hObj));
+  if(ObjGetHandleType(hObj) == GDIOBJ_REGION) {
+	OSLibDeleteRegion(ObjGetHandleData(hObj));
+	ObjFreeHandle(hObj);
+        SetLastError(ERROR_SUCCESS);
+	return OBJ_REGION;
+  }
+  DIBSection::deleteSection((DWORD)hObj);
+  return O32_DeleteObject(hObj);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API SetObjectOwner( HGDIOBJ arg1, int arg2 )
+{
+  // Here is a guess for a undocumented entry
+  dprintf(("WARNING: GDI32: SetObjectOwner - stub (TRUE)\n"));
+  return TRUE;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/gdi32/oslibgpi.cpp
===================================================================
--- trunk/src/gdi32/oslibgpi.cpp	(revision 3704)
+++ trunk/src/gdi32/oslibgpi.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: oslibgpi.cpp,v 1.4 2000-02-16 14:18:11 sandervl Exp $ */
+/* $Id: oslibgpi.cpp,v 1.5 2000-06-14 13:17:51 sandervl Exp $ */
 
 /*
@@ -17,4 +17,5 @@
 #include <math.h>
 #include "win32type.h"
+#include <winconst.h>
 #include "oslibgpi.h"
 #include "dcdata.h"
@@ -116,4 +117,40 @@
 
   return TRUE;
+}
+
+BOOL includeBottomRightPoint(PVOID pHps,PPOINTLOS2 pptl)
+{
+    if(GetDCData(pHps)->graphicsMode != GM_COMPATIBLE_W)
+    {
+        return TRUE;  // already inclusive/inclusive
+    }
+
+    if(pptl[0].x == pptl[1].x || pptl[0].y == pptl[1].y)
+    {
+        return FALSE; // empty rectangle
+    }
+
+    if(GetDCData(pHps)->isLeftLeft)
+    {
+        pptl[1].x += abs(GetDCData(pHps)->worldXDeltaFor1Pixel);
+        sortAscending(pptl[0].x, pptl[1].x);
+    }
+    else
+    {
+        pptl[0].x -= abs(GetDCData(pHps)->worldXDeltaFor1Pixel);
+        sortAscending(pptl[1].x, pptl[0].x);
+    }
+
+    if(GetDCData(pHps)->isTopTop)
+    {
+        pptl[1].y += abs(GetDCData(pHps)->worldYDeltaFor1Pixel);
+        sortAscending(pptl[1].y, pptl[0].y);
+    }
+    else
+    {
+        pptl[0].y -= abs(GetDCData(pHps)->worldYDeltaFor1Pixel);
+        sortAscending(pptl[0].y, pptl[1].y);
+    }
+    return TRUE;
 }
 
@@ -351,2 +388,3 @@
 }
 
+
Index: trunk/src/gdi32/oslibgpi.h
===================================================================
--- trunk/src/gdi32/oslibgpi.h	(revision 3704)
+++ trunk/src/gdi32/oslibgpi.h	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: oslibgpi.h,v 1.5 2000-04-03 18:29:05 sandervl Exp $ */
+/* $Id: oslibgpi.h,v 1.6 2000-06-14 13:17:51 sandervl Exp $ */
 
 /*
@@ -12,8 +12,4 @@
 #define __OSLIBGPI_H__
 
-/* DC Graphics Mode */
-#define GM_COMPATIBLE_W     1
-#define GM_ADVANCED_W       2
-
 #define APIENTRYOS2 _System
 
@@ -88,4 +84,5 @@
 
 BOOL excludeBottomRightPoint(PVOID pHps,PPOINTLOS2 pptl);
+BOOL includeBottomRightPoint(PVOID pHps,PPOINTLOS2 pptl);
 BOOL getAlignUpdateCP(PVOID pHps);
 INT  getWorldYDeltaFor1Pixel(PVOID pHps);
@@ -192,3 +189,99 @@
 BOOL  OSLibGpiSetCp(HDC hdc, ULONG codepage);
 
+
+   // from pmddi.h:
+   /* CopyClipRegion */
+
+   #define COPYCRGN_ALLINTERSECT        0L
+   #define COPYCRGN_VISRGN              1L
+   #define COPYCRGN_CLIPRGN             2L
+
+   /* SetupDC */
+
+   #define SETUPDC_VISRGN               0x00000001L
+   #define SETUPDC_ORIGIN               0x00000002L
+   #define SETUPDC_ACCUMBOUNDSON        0x00000004L
+   #define SETUPDC_ACCUMBOUNDSOFF       0x00000008L
+   #define SETUPDC_RECALCCLIP           0x00000010L
+   #define SETUPDC_SETOWNER             0x00000020L
+   #define SETUPDC_CLEANDC              0x00000040L
+
+ULONG APIENTRY Gre32Entry4(ULONG,ULONG,ULONG,ULONG);
+
+inline ULONG APIENTRY _Gre32Entry4 (ULONG a, ULONG b, ULONG c, ULONG d)
+{
+ ULONG yyrc;
+ USHORT sel = RestoreOS2FS();
+
+    yyrc = Gre32Entry4(a,b,c,d);
+    SetFS(sel);
+
+    return yyrc;
+}
+
+ULONG APIENTRY Gre32Entry5(ULONG,ULONG,ULONG,ULONG,ULONG);
+
+inline ULONG APIENTRY _Gre32Entry5 (ULONG a, ULONG b, ULONG c, ULONG d, ULONG e)
+{
+ ULONG yyrc;
+ USHORT sel = RestoreOS2FS();
+
+    yyrc = Gre32Entry5(a,b,c,d,e);
+    SetFS(sel);
+
+    return yyrc;
+}
+
+
+ULONG APIENTRY Gre32Entry6(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
+
+inline ULONG APIENTRY _Gre32Entry6 (ULONG a, ULONG b, ULONG c, ULONG d, ULONG e, ULONG f)
+{
+ ULONG yyrc;
+ USHORT sel = RestoreOS2FS();
+
+    yyrc = Gre32Entry6(a,b,c,d,e,f);
+    SetFS(sel);
+
+    return yyrc;
+}
+
+ULONG APIENTRY Gre32Entry7(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
+
+inline ULONG APIENTRY _Gre32Entry7 (ULONG a, ULONG b, ULONG c, ULONG d, ULONG e, ULONG f, ULONG g)
+{
+ ULONG yyrc;
+ USHORT sel = RestoreOS2FS();
+
+    yyrc = Gre32Entry7(a,b,c,d,e,f,g);
+    SetFS(sel);
+
+    return yyrc;
+}
+
+ULONG APIENTRY Gre32Entry8(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
+
+inline ULONG APIENTRY _Gre32Entry8 (ULONG a, ULONG b, ULONG c, ULONG d, ULONG e, ULONG f, ULONG g, ULONG h)
+{
+ ULONG yyrc;
+ USHORT sel = RestoreOS2FS();
+
+    yyrc = Gre32Entry8(a,b,c,d,e,f,g,h);
+    SetFS(sel);
+
+    return yyrc;
+}
+
+
+   #define GreSetupDC(a,b,c,d,e,f) (BOOL) _Gre32Entry8((ULONG)(HDC)(a),(ULONG)(HRGN)(b),(ULONG)(LONG)(c),(ULONG)(LONG)(d),(ULONG)(PRECTL)(e),(ULONG)(ULONG)(f),0L,0x00004081L)
+   #define GreCreateRectRegion(a,b,c) (HRGN) _Gre32Entry5((ULONG)(HDC)(a),(ULONG)(PRECTL)(b),(ULONG)(LONG)(c),0L,0x00004062L)
+   #define GreGetPageUnits(a,b) (LONG) _Gre32Entry4((ULONG)(HDC)(a),(ULONG)(PULONG)(b),0L,0x00004083L)
+   #define GreCopyClipRegion(a,b,c,d) (INT) _Gre32Entry6((ULONG)(HDC)(a),(ULONG)(HRGN)(b),(ULONG)(PRECTL)(c),(ULONG)(ULONG)(d),0L,0x00004080L)
+   #define GreCombineRegion(a,b,c,d,e) (INT) _Gre32Entry7((ULONG)(HDC)(a),(ULONG)(HRGN)(b),(ULONG)(HRGN)(c),(ULONG)(HRGN)(d),(ULONG)(ULONG)(e),0L,0x00004065L)
+   #define GreDestroyRegion(a,b) (BOOL) _Gre32Entry4((ULONG)(HDC)(a),(ULONG)(HRGN)(b),0L,0x00004063L)
+   #define GreGetDCOrigin(a,b) (BOOL) _Gre32Entry4((ULONG)(HDC)(a),(ULONG)(PPOINTL)(b),0L,0x000040BAL)
+   #define GreDeviceSetDCOrigin(a,b) (BOOL) _Gre32Entry4((ULONG)(HDC)(a),(ULONG)(PPOINTL)(b),0L,0x000040BBL)
+   #define GreSelectClipRegion(a,b,c) (INT) _Gre32Entry5((ULONG)(HDC)(a),(ULONG)(HRGN)(b),(ULONG)(PHRGN)(c),0L,0x00004074L)
+   #define GreIntersectClipRectangle(a,b) (INT) _Gre32Entry4((ULONG)(HDC)(a),(ULONG)(PRECTL)(b),0L,0x00004075L)
+
 #endif
Index: trunk/src/gdi32/region.cpp
===================================================================
--- trunk/src/gdi32/region.cpp	(revision 3704)
+++ trunk/src/gdi32/region.cpp	(revision 3705)
@@ -1,180 +1,1498 @@
-/* $Id: region.cpp,v 1.5 2000-06-08 18:07:07 sandervl Exp $ */
+/* $Id: region.cpp,v 1.6 2000-06-14 13:17:51 sandervl Exp $ */
 
 /*
  * GDI32 region code
  *
- * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
+ * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
  * Copyright 1998 Patrick Haller
+ *
+ * TODO: Metafile recording
+ * TODO: Do we need to translate & set the last error for Gpi operations?
  *
  * Project Odin Software License can be found in LICENSE.TXT
  *
  */
-#include <os2win.h>
+#define  INCL_GPI
+#define  INCL_WIN
+#include <os2wrap.h>
+
+#include <win32type.h>
+#include <win32api.h>
+#include <winconst.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
-#include "misc.h"
-
-#define DBG_LOCALLOG	DBG_region
+#include <misc.h>
+#include <objhandle.h>
+#include <dcdata.h>
+#include <winuser32.h>
+#include <win32wnd.h>
+#include "oslibgpi.h"
+
+#define DBG_LOCALLOG    DBG_region
 #include "dbglocal.h"
 
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreatePolyPolygonRgn( const POINT * arg1, const INT * arg2, int arg3, int  arg4)
-{
-    dprintf(("GDI32: CreatePolyPolygonRgn\n"));
-    return O32_CreatePolyPolygonRgn(arg1, arg2, arg3, arg4);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreatePolygonRgn(const POINT * arg1, int arg2, int arg3)
-{
-    dprintf(("GDI32: CreatePolygonRgn"));
-    return O32_CreatePolygonRgn(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API CombineRgn( HRGN arg1, HRGN  arg2, HRGN  arg3, int  arg4)
-{
-    dprintf(("GDI32: CombineRgn"));
-    return O32_CombineRgn(arg1, arg2, arg3, arg4);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreateEllipticRgn( int arg1, int arg2, int arg3, int  arg4)
-{
-    dprintf(("GDI32: CreateEllipticRgn"));
-    return O32_CreateEllipticRgn(arg1, arg2, arg3, arg4);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreateEllipticRgnIndirect( const RECT * arg1)
-{
-    dprintf(("GDI32: CreateEllipticRgnIndirect"));
-    return O32_CreateEllipticRgnIndirect(arg1);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreateRectRgn( int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
-{
-    dprintf(("GDI32: CreateRectRgn (%d,%d)(%d,%d)", nLeftRect, nTopRect, nRightRect, nBottomRect));
-    return O32_CreateRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreateRectRgnIndirect( const RECT * lpRect)
-{
-    if(lpRect == NULL) {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-    }
-    dprintf(("GDI32: CreateRectRgnIndirect (%d,%d)(%d,%d)", lpRect->left, lpRect->top, lpRect->right, lpRect->bottom));
-    return O32_CreateRectRgnIndirect(lpRect);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
-                                 int nWidthEllipse, int nHeightEllipse)
-{
-    dprintf(("GDI32: CreateRoundRectRgn (%d,%d)(%d,%d) (%d,%d)", nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse));
-    return O32_CreateRoundRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, nWidthEllipse, nHeightEllipse);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API EqualRgn( HRGN arg1, HRGN  arg2)
-{
-    dprintf(("GDI32: EqualRgn"));
-    return O32_EqualRgn(arg1, arg2);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API ExtCreateRegion( const XFORM * arg1, DWORD arg2, const RGNDATA *  arg3)
-{
- HRGN hRgn;
-
-    hRgn = O32_ExtCreateRegion(arg1, arg2, arg3);
-    dprintf(("GDI32: ExtCreateRegion %x %x %x returned %x", arg1, arg2, arg3, hRgn));
-    return hRgn;
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API FillRgn( HDC arg1, HRGN arg2, HBRUSH  arg3)
-{
-    dprintf(("GDI32: FillRgn"));
-    return O32_FillRgn(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API FrameRgn( HDC arg1, HRGN arg2, HBRUSH arg3, int arg4, int  arg5)
-{
-    dprintf(("GDI32: FrameRgn"));
-    return O32_FrameRgn(arg1, arg2, arg3, arg4, arg5);
-}
-//******************************************************************************
-//******************************************************************************
-DWORD WIN32API GetRegionData( HRGN arg1, DWORD arg2, PRGNDATA  arg3)
-{
-    dprintf(("GDI32: GetRegionData"));
-    return O32_GetRegionData(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API GetRgnBox(HRGN hRgn, PRECT pRect)
-{
-    dprintf(("GDI32: GetRgnBox %x %x", hRgn, pRect));
-    if(hRgn == 0) {
-////	SetLastError(ERROR_INVALID_PARAMETER);
-	return NULLREGION;
-    }
-    return O32_GetRgnBox(hRgn, pRect);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API InvertRgn( HDC arg1, HRGN  arg2)
-{
-    dprintf(("GDI32: InvertRgn"));
-    return O32_InvertRgn(arg1, arg2);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API OffsetRgn( HRGN arg1, int arg2, int  arg3)
-{
-    dprintf(("GDI32: OffsetRgn"));
-    return O32_OffsetRgn(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API PaintRgn( HDC arg1, HRGN  arg2)
-{
-    dprintf(("GDI32: PaintRgn"));
-    return O32_PaintRgn(arg1, arg2);
-}
-//******************************************************************************
-//******************************************************************************
-HRGN WIN32API PathToRegion( HDC arg1)
-{
-    dprintf(("GDI32: PathToRegion"));
-    return O32_PathToRegion(arg1);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API PtInRegion( HRGN arg1, int arg2, int  arg3)
-{
-    dprintf(("GDI32: PtInRegion"));
-    return O32_PtInRegion(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API RectInRegion( HRGN arg1, const RECT *  arg2)
-{
-    dprintf(("GDI32: RectInRegion"));
-    return O32_RectInRegion(arg1, arg2);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API SetRectRgn( HRGN arg1, int arg2, int arg3, int arg4, int  arg5)
-{
-    dprintf(("GDI32: SetRectRgn"));
-    return O32_SetRectRgn(arg1, arg2, arg3, arg4, arg5);
+typedef enum
+{
+    AS_DEVICE,
+    AS_WORLD
+} InterpMode;
+
+#define MEM_HPS_MAX 768
+
+static void convertDeviceRect(HWND hwnd, pDCData pHps, PRECTL pRectl, ULONG count);
+
+#define convertWinDeviceRectToPMDeviceRect(arg1, arg2, arg3) convertDeviceRect(arg1, arg2, arg3)
+#define convertPMDeviceRectToWinDeviceRect(arg1, arg2, arg3) convertDeviceRect(arg1, arg2, arg3)
+
+inline void convertDeviceRect(pDCData pHps, PRECTL pRectl, ULONG count)
+{
+   convertDeviceRect(0, pHps, pRectl, count);
+}
+inline void convertDeviceRect(HWND hwnd, PRECTL pRectl, ULONG count)
+{
+   convertDeviceRect(hwnd, 0, pRectl, count);
+}
+
+HPS hpsRegion = 0;
+
+//******************************************************************************
+//******************************************************************************
+BOOL InitRegionSpace()
+{
+    hpsRegion = WinGetScreenPS(HWND_DESKTOP);
+    return hpsRegion != 0;
+}
+//******************************************************************************
+//******************************************************************************
+static LONG clientHeight(HWND hwnd, pDCData pHps)
+{
+    if(hwnd == 0 && pHps != 0)
+        hwnd = pHps->hwnd;
+
+    if(hwnd != 0 || pHps == 0)
+    {
+        RECT rect;
+        RECTL rectl;
+        LONG y = 0;
+
+        if(pHps == 0 || pHps->isClient) //client area
+        {
+            if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
+                y = rect.bottom - rect.top;
+            }
+        }
+        else
+        if(WinQueryWindowRect(hwnd, &rectl))    //whole window
+            y = rectl.yTop;
+
+        return y;
+   }
+   else
+   if(pHps->bitmapHandle)
+   {
+      return pHps->bitmapHeight;
+   }
+   else
+   if(pHps->isMetaPS)
+   {
+      return 0;
+   }
+   else
+   if(pHps->isPrinter)
+   {
+      return pHps->printPageHeight;
+   }
+   else
+   {
+      return MEM_HPS_MAX;
+   }
+}
+//******************************************************************************
+//******************************************************************************
+static LONG clientWidth(HWND hwnd, pDCData pHps)
+{
+    if(hwnd == 0 && pHps != 0)
+        hwnd = pHps->hwnd;
+
+    if(hwnd != 0 || pHps == 0)
+    {
+        RECT rect;
+        RECTL rectl;
+        LONG x = 0;
+
+        if(pHps == 0 || pHps->isClient) //client area
+        {
+            if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
+                x = rect.right - rect.left;
+            }
+        }
+        else
+        if(WinQueryWindowRect(hwnd, &rectl))    //whole window
+            x = rectl.xRight;
+
+        return x;
+   }
+   else DebugInt3();
+   return 0;
+}
+//******************************************************************************
+//******************************************************************************
+static void convertWinWorldRectToPMDeviceRect(pDCData pHps_Hdc, PRECTL pRects, UINT count = 1)
+{
+   PRECTL pRectl;
+   for (int x=0; x < count; x++)
+   {
+        pRectl = &pRects[x];
+
+        if(pRectl->yTop < pRectl->yBottom) {
+            ULONG temp      = pRectl->yBottom;
+            pRectl->yBottom = pRectl->yTop;
+            pRectl->yTop    = temp;
+        }
+        BOOL success = GpiConvert( pHps_Hdc->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)pRectl);
+        if(!success)
+        {
+            break;
+        }
+        if(pRectl->yTop < pRectl->yBottom) {
+            ULONG temp      = pRectl->yBottom;
+            pRectl->yBottom = pRectl->yTop;
+            pRectl->yTop    = temp;
+        }
+   }
+}
+//******************************************************************************
+//******************************************************************************
+static void convertDeviceRect(HWND hwnd, pDCData pHps, PRECTL pRectl, ULONG count)
+{
+   long wHeight, wWidth;
+
+    if(hwnd == HWND_DESKTOP) {
+        wHeight = OSLibGetScreenHeight();
+        wWidth  = OSLibGetScreenWidth();
+    }
+    else {
+        wHeight = clientHeight(hwnd, pHps);
+        wWidth  = clientWidth(hwnd, pHps);
+    }
+
+    if(pHps)
+    {
+         wHeight += pHps->HPStoHDCInversionHeight;
+    }
+
+    if(hwnd || (pHps && pHps->hwnd)) {
+        for(int x=0; x < count; x++)
+        {
+            if(pRectl[x].xRight > wWidth) {
+                 pRectl[x].xRight = wWidth;
+            }
+            if(pRectl[x].yTop > wHeight) {
+                 pRectl[x].yTop = 0;
+            }
+            else pRectl[x].yTop    = wHeight - pRectl[x].yTop;
+
+            pRectl[x].yBottom = wHeight - pRectl[x].yBottom;
+        }
+    }
+    else {
+        for(int x=0; x < count; x++)
+        {
+            pRectl[x].yTop    = wHeight - pRectl[x].yTop;
+            pRectl[x].yBottom = wHeight - pRectl[x].yBottom;
+        }
+    }
+}
+//******************************************************************************
+//******************************************************************************
+static void convertPMDeviceRectToWinWorldRect(pDCData pHps_Hdc, PRECTL pRectl)
+{
+   GpiConvert(pHps_Hdc->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)pRectl );
+}
+//******************************************************************************
+//******************************************************************************
+BOOL interpretRegionAs(pDCData pHps, HRGN hrgnDest, HRGN hrgnSrc, InterpMode mode)
+{
+ BOOL success = FALSE;
+ int  x, i;
+ HPS  hpsDest;
+
+    if(pHps)
+    {
+        if(!hrgnDest) {
+                hrgnDest = pHps->hrgnHDC;
+#ifdef DEBUG
+                if(hrgnDest == 0) {
+                    DebugInt3();
+                }
+#endif
+        }
+        hpsDest  = pHps->hps;
+    }
+    else {
+        DebugInt3();
+        return FALSE;
+    }
+
+    RGNRECT  rgnRect;
+    rgnRect.ircStart    = 1;
+    rgnRect.crc         = 0;
+    rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
+    success = GpiQueryRegionRects(hpsRegion, hrgnSrc, NULL, &rgnRect, NULL);
+    if(success)
+    {
+        if(rgnRect.crcReturned > 0)
+        {
+            rgnRect.crc = rgnRect.crcReturned;
+            PRECTL pRectl = new RECTL[rgnRect.crcReturned];
+            success = GpiQueryRegionRects(hpsRegion, hrgnSrc, NULL, &rgnRect, pRectl);
+            if(success)
+            {
+                if(mode == AS_DEVICE)
+                {
+                    ULONG temp;
+                    for(x=0; x < rgnRect.crcReturned; x++)
+                    {
+                        temp = pRectl[x].yBottom;
+                        pRectl[x].yBottom = pRectl[x].yTop;
+                        pRectl[x].yTop    = temp;
+                    }
+                    convertWinDeviceRectToPMDeviceRect(pHps, pRectl, rgnRect.crcReturned);
+                }
+                else
+                {
+                    GpiConvert(pHps->hps, CVTC_WORLD, CVTC_DEVICE, rgnRect.crcReturned<<1, (PPOINTL)pRectl);
+
+                    ULONG temp;
+                    for(i=0; i < rgnRect.crcReturned; i++)
+                    {
+                        if(pRectl[i].yTop < pRectl[i].yBottom)
+                        {
+                            temp              = pRectl[i].yBottom + 1;
+                            pRectl[i].yBottom = pRectl[i].yTop + 1;
+                            pRectl[i].yTop    = temp;
+                        }
+                        else
+                        {
+                            pRectl[i].yTop++;
+                            pRectl[i].yBottom++;
+                        }
+                    }
+                }
+                success = GpiSetRegion(hpsDest, hrgnDest, rgnRect.crcReturned, pRectl);
+            }
+            delete[] pRectl;
+        }
+        else
+        {
+            success = GpiSetRegion(hpsDest, hrgnDest, 0, NULL);
+        }
+    }
+    return success;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL setWinDeviceRegionFromPMDeviceRegion(HRGN winHrgn, HRGN pmHrgn, pDCData pHpsPmHrgn, HWND hwndPmHrgn)
+{
+    BOOL    success;
+    int     x;
+    BOOL    mustReleaseScreenPS = FALSE;
+    HPS     hps;
+
+    if(pHpsPmHrgn || hwndPmHrgn)
+    {
+        if(pHpsPmHrgn)
+            hps = pHpsPmHrgn->hps;
+        else
+        {
+            hps = WinGetScreenPS(HWND_DESKTOP);
+            mustReleaseScreenPS = TRUE;
+        }
+
+        RGNRECT  rgnRect;
+        rgnRect.ircStart    = 1;
+        rgnRect.crc         = 0;
+        rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
+        success = GpiQueryRegionRects(hps, pmHrgn, NULL, &rgnRect, NULL);
+        if(success )
+        {
+            if(rgnRect.crcReturned > 0)
+            {
+                rgnRect.crc = rgnRect.crcReturned;
+                PRECTL pRectl = new RECTL[rgnRect.crcReturned];
+                success = GpiQueryRegionRects(hps, pmHrgn, NULL, &rgnRect, pRectl);
+                if(success)
+                {
+                    if(pHpsPmHrgn)
+                        convertPMDeviceRectToWinDeviceRect(pHpsPmHrgn, pRectl, rgnRect.crcReturned);
+                    else
+                        convertPMDeviceRectToWinDeviceRect(hwndPmHrgn, pRectl, rgnRect.crcReturned);
+
+                    for(x=0; x < rgnRect.crcReturned; x++)
+                    {
+                        ULONG temp         = pRectl[x].yBottom;
+                        pRectl[x].yBottom  = pRectl[x].yTop;
+                        pRectl[x].yTop     = temp;
+                    }
+
+                    success = GpiSetRegion(hpsRegion, winHrgn, rgnRect.crcReturned, pRectl);
+                }
+                delete[] pRectl;
+            }
+            else
+            {
+                success = GpiSetRegion(hpsRegion, winHrgn, 0, NULL);
+            }
+        }
+    }
+    else
+        success = FALSE;
+
+    if(mustReleaseScreenPS)
+        WinReleasePS(hps);
+
+   return success;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API SelectClipRgn(HDC hdc, HRGN hrgn)
+{
+ LONG lComplexity = RGN_NULL;
+ HRGN hrgnNewClip;
+ HRGN hrgnOldClip;
+
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+    if(!pHps)
+    {
+        dprintf(("WARNING: SelectClipRgn: invalid hdc!", hdc, hrgn));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+
+    if(hrgn)
+    {
+        hrgn = ObjGetHandleData(hrgn);
+        if(hrgn == HANDLE_OBJ_ERROR) {
+            dprintf(("WARNING: SelectClipRgn: invalid region!", hdc, hrgn));
+            SetLastError(ERROR_INVALID_HANDLE_W);
+            return ERROR_W;
+        }
+    }
+
+    if(hrgn)
+    {
+        RECTL rectl = {0,0,1,1};
+        hrgnNewClip = GpiCreateRegion(pHps->hps, 1, &rectl);
+        if(interpretRegionAs(pHps, hrgnNewClip, hrgn, AS_DEVICE) == 0)
+        {
+            lComplexity = RGN_ERROR;
+        }
+    }
+    else
+        hrgnNewClip = 0;
+
+    if(lComplexity != RGN_ERROR)
+    {
+        if(hrgnNewClip == 0) {
+            GpiSetClipPath(pHps->hps, 0, SCP_RESET);
+        }
+        lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
+        if (lComplexity != RGN_ERROR )
+        {
+            dprintf(("SelectClipRgn: %x %x", hdc, hrgn));
+            if(hrgnOldClip)
+                GpiDestroyRegion(pHps->hps, hrgnOldClip);
+
+            //todo: metafile recording
+            SetLastError(ERROR_SUCCESS_W);
+            return lComplexity;
+        }
+    }
+
+    dprintf(("WARNING: SelectClipRgn: RGN_ERROR!", hdc, hrgn));
+    if(hrgnNewClip)
+        GpiDestroyRegion(pHps->hps, hrgnNewClip);
+
+    SetLastError(ERROR_SUCCESS_W);
+    return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API ExtSelectClipRgn(HDC hdc, HRGN hrgn, int mode)
+{
+   pDCData    pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+   if (!pHps)
+   {
+        dprintf(("WARNING: ExtSelectRgn %x %x %d invalid hdc", hdc, hrgn, mode));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+   }
+
+   LONG lComplexity;
+   HRGN hrgnCurrent = NULLHANDLE;
+
+   if(!hrgn && mode != RGN_COPY_W)
+   {
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        dprintf(("WARNING: ExtSelectRgn %x %x %d invalid parameter", hdc, hrgn, mode));
+        return ERROR_W;
+   }
+
+   LONG lMode;
+   switch (mode)
+   {
+        case  RGN_AND_W  : lMode = CRGN_AND ; break;
+        case  RGN_COPY_W : lMode = CRGN_COPY; break;
+        case  RGN_DIFF_W : lMode = CRGN_DIFF; break;
+        case  RGN_OR_W   : lMode = CRGN_OR  ; break;
+        case  RGN_XOR_W  : lMode = CRGN_XOR ; break;
+        default:
+        {
+            SetLastError(ERROR_INVALID_PARAMETER_W);
+            dprintf(("WARNING: ExtSelectRgn %x %x %d invalid parameter", hdc, hrgn, mode));
+            return ERROR_W;
+        }
+   }
+
+   if(hrgn)
+   {
+        hrgn = ObjGetHandleData(hrgn);
+        if(hrgn == HANDLE_OBJ_ERROR) {
+            dprintf(("WARNING: ExtSelectRgn %x %x %d invalid region handle", hdc, hrgn, mode));
+            SetLastError(ERROR_INVALID_HANDLE_W);
+            return 0;
+        }
+   }
+
+   dprintf(("WARNING: ExtSelectRgn %x %x %d", hdc, hrgn, mode));
+   //TODO: metafile recording
+   if(hrgn)
+   {
+        if(!interpretRegionAs(pHps, 0, hrgn, AS_DEVICE) )
+        {
+            return ERROR_W;
+        }
+   }
+   else
+   {
+        //remove clip region
+        GpiSetClipPath(pHps->hps, 0, SCP_RESET);
+        GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
+
+        if(hrgnCurrent)
+            GpiDestroyRegion(pHps->hps, hrgnCurrent);
+
+        return NULLREGION_W;
+   }
+
+   GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
+
+   if(hrgnCurrent == NULLHANDLE)
+   {
+        lMode = CRGN_COPY;
+        RECTL rectl = {0, 0, 1, 1};
+        hrgnCurrent = GpiCreateRegion(pHps->hps, 1, &rectl);
+   }
+
+   HRGN hrgnSrc1;
+   HRGN hrgnSrc2;
+   if(lMode != CRGN_COPY)
+   {
+        hrgnSrc1 = hrgnCurrent;
+        hrgnSrc2 = pHps->hrgnHDC;
+   }
+   else
+   {
+        hrgnSrc1 = pHps->hrgnHDC;
+        hrgnSrc2 = NULLHANDLE;
+   }
+
+   lComplexity = GpiCombineRegion(pHps->hps, hrgnCurrent, hrgnSrc1, hrgnSrc2, lMode);
+   if (lComplexity != RGN_ERROR)
+   {
+        HRGN hrgnOld;
+        lComplexity = GpiSetClipRegion(pHps->hps, hrgnCurrent, &hrgnOld);
+        SetLastError(ERROR_SUCCESS_W);
+        if (lComplexity != RGN_ERROR)
+            return lComplexity;
+   }
+   SetLastError(ERROR_SUCCESS_W);
+   return ERROR_W;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API GetClipBox(HDC hdc, PRECT lpRect)
+{
+ pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+ RECTL    rectl;
+ LONG     lComplexity;
+ int      rc;
+
+    if(!hdc || !lpRect || !pHps) {
+        dprintf(("GDI32: GetClipBox %x %x ERROR_INVALID_PARAMETER", hdc, lpRect));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return ERROR_W;
+    }
+    if(pHps->isPrinter)
+    {
+        lpRect->left   = 0;
+        lpRect->top    = 0;
+        lpRect->right  = GetDeviceCaps( hdc, HORZRES_W);
+        lpRect->bottom = GetDeviceCaps( hdc, VERTRES_W);
+        includeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
+        convertPMDeviceRectToWinWorldRect(pHps, &rectl);
+
+        rc = SIMPLEREGION_W;
+    }
+    else {
+        lComplexity = GpiQueryClipBox(pHps->hps, &rectl);
+        if(lComplexity == RGN_ERROR)
+        {
+            rc = ERROR_W;
+        }
+        else
+        if(lComplexity == RGN_NULL)
+        {
+            memset(lpRect, 0, sizeof(*lpRect));
+            rc = NULLREGION_W;
+        }
+        else {
+            //Convert including/including to including/excluding
+            includeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
+
+            lpRect->left   = rectl.xLeft;
+            lpRect->right  = rectl.xRight;
+            //No conversion required as GpiQueryClipBox is affected by
+            //the y-inversion of the window
+            //NOTE: YINVERSION dependancy
+            lpRect->top    = rectl.yBottom;
+            lpRect->bottom = rectl.yTop;
+
+            rc = (lComplexity == RGN_RECT) ? SIMPLEREGION_W : COMPLEXREGION_W;
+        }
+    }
+    dprintf(("GDI32: GetClipBox of %X returned %d\n", hdc, rc));
+    return rc;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API GetClipRgn(HDC hdc, HRGN hrgn)
+{
+   pDCData    pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+   BOOL       success;
+   LONG       lComplexity = RGN_RECT;
+   HRGN       hrgnClip = NULL, hrgnTemp;
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR || !pHps) {
+        dprintf(("WARNING: GetClipRgn %x %x invalid handle", hdc, hrgn));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return 0;
+    }
+
+    if(GpiSetClipRegion(pHps->hps, NULL, &hrgnClip) == RGN_ERROR) {
+        dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed! (%x)", WinGetLastError(0)));
+        SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
+        return 0;
+    }
+    if(hrgnClip) {
+        if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgnClip, pHps, NULL)) {
+                dprintf(("WARNING: GetClipRgn setWinDeviceRegionFromPMDeviceRegion failed!"));
+                GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp);
+                SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
+                return 0;
+        }
+        if(GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp) == RGN_ERROR )
+        {
+            dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed %x!", WinGetLastError(0)));
+            SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
+            return 0;
+        }
+    }
+    else lComplexity = RGN_NULL;
+
+    dprintf(("GetClipRgn %x %x returned %d", hdc, hrgn, lComplexity == RGN_NULL));
+    SetLastError(ERROR_SUCCESS_W);
+    if(lComplexity == RGN_NULL)
+         return 0;
+    else return 1;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API ExcludeClipRect(HDC hdc, int left, int top, int right, int bottom)
+{
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+    if(!pHps)
+    {
+        dprintf(("WARNING: ExcludeClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+
+    LONG   lComplexity;
+    RECTL  rectl = { left, bottom, right, top };
+
+    excludeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
+    if(rectl.yTop < rectl.yBottom) {
+        ULONG temp    = rectl.yBottom;
+        rectl.yBottom = rectl.yTop;
+        rectl.yTop    = temp;
+    }
+
+    dprintf(("ExcludeClipRgn %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
+    lComplexity = GpiExcludeClipRectangle(pHps->hps, &rectl);
+    if (lComplexity == RGN_ERROR) {
+        SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
+        return ERROR_W;
+    }
+
+    //todo metafile recording
+
+    SetLastError(ERROR_SUCCESS_W);
+    return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API IntersectClipRect(HDC hdc, int left, int top, int right, int bottom)
+{
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+    LONG      lComplexity;
+    BOOL      success;
+
+    if(!pHps) {
+        dprintf(("WARNING: IntersectClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+    RECTL rectl = { left, bottom, right, top };
+
+    excludeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
+    if(rectl.yTop < rectl.yBottom) {
+        ULONG temp    = rectl.yBottom;
+        rectl.yBottom = rectl.yTop;
+        rectl.yTop    = temp;
+    }
+
+    dprintf(("IntersectClipRgn %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
+    lComplexity = GpiIntersectClipRectangle(pHps->hps, &rectl);
+
+    //todo metafile recording
+
+    SetLastError(ERROR_SUCCESS_W);
+    return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API OffsetClipRgn(HDC hdc, int nXOffset, int nYOffset )
+{
+   BOOL      success;
+   pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+   LONG      lComplexity;
+
+   if(!pHps) {
+        dprintf(("OffsetClipRgn %x (%d,%d) invalid hdc", hdc, nXOffset, nYOffset));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+   }
+
+   dprintf(("OffsetClipRgn %x (%d,%d)", hdc, nXOffset, nYOffset));
+   POINTL  pointl = { nXOffset, nYOffset };
+   lComplexity = GpiOffsetClipRegion(pHps->hps, &pointl);
+
+   //todo metafile recording
+
+   SetLastError(ERROR_SUCCESS_W);
+   return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreatePolyPolygonRgn(const POINT * lppt, const int *pPolyCount, int nCount, int fnPolyFillMode)
+{
+ LONG  flMode;
+
+   switch(fnPolyFillMode)
+   {
+   case ALTERNATE_W:
+        flMode = POLYGON_ALTERNATE;
+        break;
+   case WINDING_W:
+        flMode = POLYGON_WINDING;
+        break;
+   default:
+        dprintf(("WARNING: CreatePolyPolygonRgn %x %x %d %d invalid parameter", lppt, pPolyCount, nCount, fnPolyFillMode));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+   }
+
+   if(nCount < 1)
+   {
+        dprintf(("WARNING: CreatePolyPolygonRgn %x %x %d %d invalid parameter", lppt, pPolyCount, nCount, fnPolyFillMode));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+   }
+
+   PPOLYGON pPolygon = new POLYGON[nCount];
+   if(!pPolygon) {
+        dprintf(("ERROR: CreatePolyPolygonRgn: out of memory!!"));
+        SetLastError(ERROR_OUTOFMEMORY_W);
+        return 0;
+   }
+   dprintf(("CreatePolyPolygonRgn %x %x %d %d", lppt, pPolyCount, nCount, fnPolyFillMode));
+
+   PPOINTL pPointl = (PPOINTL)lppt+1;     // skip first point
+   for (int x=0; x < nCount; x++) {
+        pPolygon[x].ulPoints = (x == 0) ? pPolyCount[x] - 1 : pPolyCount[x];
+        pPolygon[x].aPointl  = pPointl;
+        pPointl += pPolygon[x].ulPoints;
+   }
+   GpiMove(hpsRegion, (PPOINTL)lppt);
+   HRGN hrgn = GpiCreatePolygonRegion(hpsRegion, nCount, pPolygon, POLYGON_BOUNDARY | flMode);
+
+   delete[] pPolygon;
+
+   if(!hrgn) {
+        SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
+        return 0;
+   }
+
+   if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+        SetLastError(ERROR_OUTOFMEMORY_W);
+        return 0;
+   }
+   SetLastError(ERROR_SUCCESS_W);
+   return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreateRectRgn( int left, int top, int right, int bottom)
+{
+ HRGN   hrgn;
+ RECTL  rectl = { left, top < bottom ? top : bottom, right, top < bottom ? bottom : top };
+
+   hrgn = GpiCreateRegion(hpsRegion, 1, &rectl);
+   if(!hrgn) {
+        dprintf(("WARNING: CreateRectRgn: GpiCreateRectRegion failed! %x", WinGetLastError(0)));
+        SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
+        return 0;
+   }
+
+   if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+        SetLastError(ERROR_OUTOFMEMORY_W);
+        return 0;
+   }
+   dprintf(("CreateRectRegion (%d,%d)(%d,%d) returned %x", left, top, right, bottom, hrgn));
+   SetLastError(ERROR_SUCCESS_W);
+   return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreateRectRgnIndirect(const RECT *lprc)
+{
+   return CreateRectRgn(lprc->left, lprc->top, lprc->right, lprc->bottom);
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreateRoundRectRgn(int left, int top, int right, int bottom, int nWidthEllipse, int nHeightEllipse)
+{
+ HRGN   hrgn;
+ RECTL  rectl = { left, top < bottom ? top : bottom, right, top < bottom ? bottom : top };
+
+   PPOINTL pPointl = (PPOINTL)&rectl;
+
+   GpiMove(hpsRegion, &pPointl[0]);
+   hrgn = GpiCreateRoundRectRegion(hpsRegion, &pPointl[1], labs(nWidthEllipse), labs(nHeightEllipse));
+
+   if(!hrgn) {
+        SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
+        dprintf(("WARNING: CreateRoundRectRgn: GpiCreateRoundRectRegion failed! %x", WinGetLastError(0)));
+        return 0;
+   }
+
+   if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+        SetLastError(ERROR_OUTOFMEMORY_W);
+        return 0;
+   }
+   dprintf(("CreateRoundRectRegion (%d,%d)(%d,%d) (%d,%d) returned %x", left, top, right, bottom, nWidthEllipse, nHeightEllipse, hrgn));
+   SetLastError(ERROR_SUCCESS_W);
+   return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API ExtCreateRegion(const XFORM_W *pXform, DWORD count, const RGNDATA *pData)
+{
+   HRGN hrgn;
+
+    if(!pData || count < (sizeof(RGNDATAHEADER) +  pData->rdh.nCount * sizeof(RECT))) {
+        dprintf(("WARNING: ExtCreateRegion %x %d %x; invalid parameter", pXform, count, pData));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+    }
+
+    PRECTL  pRectl     = new RECTL[pData->rdh.nCount];
+    PRECT pDataRects = (PRECT)pData->Buffer;
+    for(int i=0; i < pData->rdh.nCount; i++) {
+        MapWin32ToOS2Rect(pDataRects[i], pRectl[i]);
+    }
+
+    BOOL doShear = pXform && (pXform->eM12 || pXform->eM21);
+    HPS  hpsTemp = NULLHANDLE;
+
+    dprintf(("ExtCreateRegion %x %d %x", pXform, count, pData));
+    if(doShear) {
+         hpsTemp = WinGetPS(HWND_DESKTOP);
+         GpiBeginPath(hpsTemp, 1);
+
+         MATRIXLF  matrixlf;
+         matrixlf.fxM11  = pXform->eM11 * (float)0x10000;
+         matrixlf.fxM12  = pXform->eM12 * (float)0x10000;
+         matrixlf.lM13   = 0;
+         matrixlf.fxM21  = pXform->eM21 * (float)0x10000;
+         matrixlf.fxM22  = pXform->eM22 * (float)0x10000;
+         matrixlf.lM23   = 0;
+         matrixlf.lM31   = pXform->eDx;
+         matrixlf.lM32   = pXform->eDy;
+         matrixlf.lM33   = 1;
+
+         GpiSetModelTransformMatrix(hpsTemp, 9, &matrixlf, TRANSFORM_REPLACE);
+    }
+
+    for(i=0; i < pData->rdh.nCount; i++)
+    {
+         LONG temp         = pRectl[i].yTop;
+         pRectl[i].yTop    = pRectl[i].yBottom;
+         pRectl[i].yBottom = temp;
+
+         if(pXform)
+         {
+            PPOINTL pPointl = ((PPOINTL)&pRectl[i]);
+
+            if (doShear) {
+                GpiMove(hpsTemp, pPointl);
+                GpiBox(hpsTemp, DRO_OUTLINE, pPointl+1, 0, 0);
+            }
+            else
+            {
+                for(int j=0; j < 2; j++) {
+                    pPointl[j].x = (pXform->eM11 * (float)pPointl[j].x) + (pXform->eM12 * (float)pPointl[j].y) + pXform->eDx;
+                    pPointl[j].y = (pXform->eM21 * (float)pPointl[j].x) + (pXform->eM22 * (float)pPointl[j].y) + pXform->eDy;
+                }
+
+                PRECTL pRectlT = (PRECTL)pPointl;
+                if (pRectlT->xLeft > pRectlT->xRight) {
+                    LONG temp       = pRectlT->xLeft;
+                    pRectlT->xLeft  = pRectlT->xRight;
+                    pRectlT->xRight = temp;
+                }
+                if (pRectlT->yBottom > pRectlT->yTop) {
+                    LONG temp         = pRectlT->yBottom;
+                    pRectlT->yBottom  = pRectlT->yTop;
+                    pRectlT->yTop     = temp;
+                }
+            }
+         }
+    }
+
+    if(doShear) {
+            GpiEndPath(hpsTemp);
+            hrgn = GpiPathToRegion(hpsTemp, 1, FPATH_WINDING);
+
+            if(pRectl)
+                delete[] pRectl;
+
+            if(hrgn == 0) {
+                dprintf(("WARNING: ExtCreateRegion GpiCreateRegion failed! (%x)", WinGetLastError(0)));
+                SetLastError(ERROR_INVALID_PARAMETER_W);
+                return 0;
+            }
+            WinReleasePS(hpsTemp);
+    }
+    else {
+            hrgn = GpiCreateRegion(hpsRegion, pData->rdh.nCount, pRectl);
+            if(pRectl)
+                delete[] pRectl;
+
+            if(hrgn == 0) {
+                dprintf(("WARNING: ExtCreateRegion GpiCreateRegion failed! (%x)", WinGetLastError(0)));
+                SetLastError(ERROR_INVALID_PARAMETER_W);
+                return 0;
+            }
+    }
+
+    if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+            SetLastError(ERROR_OUTOFMEMORY_W);
+            return 0;
+    }
+    SetLastError(ERROR_SUCCESS_W);
+    return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreateEllipticRgn(int left, int top, int right, int bottom)
+{
+ HRGN hrgn;
+
+    RECTL  rectl = { left,
+                     top < bottom ? top : bottom,
+                     right,
+                     top < bottom ? bottom : top };
+
+    dprintf(("CreateEllipticRgn (%d,%d)(%d,%d)", left, top, right, bottom));
+    hrgn = GpiCreateEllipticRegion(hpsRegion, &rectl);
+
+    if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+            SetLastError(ERROR_OUTOFMEMORY_W);
+            return 0;
+    }
+    SetLastError(ERROR_SUCCESS_W);
+    return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreateEllipticRgnIndirect(const RECT *pRect)
+{
+   return CreateEllipticRgn(pRect->left, pRect->top, pRect->right, pRect->bottom);
+}
+//******************************************************************************
+//******************************************************************************
+HRGN WIN32API CreatePolygonRgn(const POINT *lppt, int cPoints, int fnPolyFillMode)
+{
+    HRGN hrgn;
+    LONG flMode;
+
+    if(!lppt || cPoints < 2) {
+        dprintf(("WARNING: CreatePolygonRgn %x %d %d invalid parameter", lppt, cPoints, fnPolyFillMode));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+    }
+
+    switch (fnPolyFillMode)
+    {
+    case ALTERNATE_W :
+        flMode = POLYGON_ALTERNATE;
+        break;
+    case WINDING_W   :
+        flMode = POLYGON_WINDING;
+        break;
+    default:
+        dprintf(("WARNING: CreatePolygonRgn %x %d %d invalid parameter", lppt, cPoints, fnPolyFillMode));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+    }
+
+    dprintf(("CreatePolygonRgn %x %d %d", lppt, cPoints, fnPolyFillMode));
+
+    POLYGON  polygon;
+    polygon.ulPoints = cPoints - 1;
+    polygon.aPointl  = (PPOINTL)(lppt + 1);
+
+    GpiMove(hpsRegion, (PPOINTL)lppt);
+    hrgn = GpiCreatePolygonRegion(hpsRegion, 1, &polygon, POLYGON_BOUNDARY | flMode);
+
+    if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
+            SetLastError(ERROR_OUTOFMEMORY_W);
+            return 0;
+    }
+    SetLastError(ERROR_SUCCESS_W);
+    return hrgn;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API CombineRgn(HRGN hrgnDest, HRGN hrgnSrc1, HRGN hrgnSrc2, int combineMode)
+{
+    ULONG lComplexity;
+    LONG  mode;
+
+    switch(combineMode) {
+    case RGN_AND_W:
+        mode = CRGN_AND;
+        break;
+    case RGN_COPY_W:
+        mode = CRGN_COPY;
+        break;
+    case RGN_DIFF_W:
+        mode = CRGN_DIFF;
+        break;
+    case RGN_OR_W:
+        mode = CRGN_OR;
+        break;
+    case RGN_XOR_W:
+        mode = CRGN_XOR;
+        break;
+    default:
+        dprintf(("WARNING: CombineRgn %x %x %x %d; invalid mode!", hrgnDest, hrgnSrc1, hrgnSrc2, combineMode));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return ERROR_W;
+    }
+
+    hrgnDest = ObjGetHandleData(hrgnDest);
+    hrgnSrc1 = ObjGetHandleData(hrgnSrc1);
+    hrgnSrc2 = ObjGetHandleData(hrgnSrc2);
+    if(hrgnDest == HANDLE_OBJ_ERROR || hrgnSrc1 == HANDLE_OBJ_ERROR  || (hrgnSrc2 == HANDLE_OBJ_ERROR && combineMode != RGN_COPY_W)) {
+        dprintf(("WARNING: CombineRgn %x %x %x %d invalid region", hrgnDest, hrgnSrc1, hrgnSrc2, combineMode));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+
+    lComplexity = GpiCombineRegion(hpsRegion, hrgnDest, hrgnSrc1, hrgnSrc2, mode);
+    if(lComplexity == RGN_ERROR) {
+        dprintf(("WARNING: CombineRgn %x %x %x %d GpiCombineRegion failed (%x)", hrgnDest, hrgnSrc1, hrgnSrc2, mode, WinGetLastError(0)));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+    SetLastError(ERROR_SUCCESS_W);
+    return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API EqualRgn(HRGN hrgn1, HRGN hrgn2)
+{
+   LONG lEquality;
+
+   hrgn1 = ObjGetHandleData(hrgn1);
+   hrgn2 = ObjGetHandleData(hrgn2);
+   if(hrgn1 == HANDLE_OBJ_ERROR || hrgn2 == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: EqualRgn %x %x invalid region", hrgn1, hrgn2));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+   }
+   lEquality = GpiEqualRegion(hpsRegion, hrgn1, hrgn2);
+
+   dprintf(("EqualRgn %x %x = %d", hrgn1, hrgn2, lEquality));
+   SetLastError(ERROR_SUCCESS_W);
+
+   if(lEquality == EQRGN_EQUAL)
+        return TRUE;
+   else
+   if(lEquality == EQRGN_NOTEQUAL)
+        return FALSE;
+   else {
+        return FALSE;
+   }
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API SetRectRgn(HRGN hrgn, int left, int top, int right, int bottom)
+{
+   BOOL    result = FALSE;
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: SetRectRgn %x (%d,%d)(%d,%d) invalid region handle", hrgn, left, top, right, bottom));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return 0;
+    }
+    RECTL rectl = { left, top, right, bottom }; //reversed y coordinates
+    if(GpiSetRegion(hpsRegion, hrgn, 1, &rectl)) {
+        dprintf(("SetRectRgn %x (%d,%d)(%d,%d)", hrgn, left, top, right, bottom));
+        return TRUE;
+    }
+    dprintf(("WARNING: SetRectRgn %x (%d,%d)(%d,%d) GpiSetRegion failed %x", hrgn, left, top, right, bottom, WinGetLastError(0)));
+    return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+ULONG WIN32API GetRegionData(HRGN hrgn, ULONG count, PRGNDATA pData)
+{
+    if(!count && pData)
+    {
+        dprintf(("WARNING: GetRegionData %x %d %x; invalid parameter", hrgn, count, pData));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return 0;
+    }
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: GetRegionData %x %d %x; invalid region handle", hrgn, count, pData));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return 0;
+    }
+    RGNRECT rgnRect;
+    rgnRect.ircStart    = 1;
+    rgnRect.crc         = 0;
+    rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
+    if(!GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, NULL))
+    {
+        dprintf(("WARNING: GetRegionData %x %d %x: GpiQueryRegionRects failed! (%x)", hrgn, count, pData, WinGetLastError(0)));
+        return 0;
+    }
+
+    dprintf(("GetRegionData %x %d %x", hrgn, count, pData));
+
+    ULONG bufSizeNeeded = rgnRect.crcReturned * sizeof(RECT) + sizeof (RGNDATAHEADER);
+
+    if(pData && (count >= (sizeof(RGNDATAHEADER) + rgnRect.crcReturned * sizeof(RECT))))
+    {
+        //we actually need to flip the top & bottom values, but as the layout of the PM RECTL and
+        //Win32 RECT have exactly those two members reversed, we don't do this for the returned
+        //rectangles (more efficient)
+        PRECTL pRectl = (PRECTL)pData->Buffer;
+        rgnRect.crc   = rgnRect.crcReturned;
+        if(!GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, pRectl))
+        {
+            dprintf(("WARNING: GetRegionData: GpiQueryRegionRects failed! (%x)", WinGetLastError(0)));
+            return 0;
+        }
+
+        RECTL boundRect;
+        GpiQueryRegionBox(hpsRegion, hrgn, &boundRect);  // no need to check rc
+
+        pData->rdh.dwSize   = sizeof(pData->rdh);
+        pData->rdh.iType    = RDH_RECTANGLES_W;    // one and only possible value
+        pData->rdh.nCount   = rgnRect.crcReturned;
+        pData->rdh.nRgnSize = rgnRect.crcReturned * sizeof(RECTL);
+
+        //flip top & bottom for bounding rectangle (not really necessary; but cleaner coding)
+        LONG temp          = boundRect.yTop;
+        boundRect.yTop     = boundRect.yBottom;
+        boundRect.yBottom  = temp;
+        MapOS2ToWin32Rect(boundRect, pData->rdh.rcBound);
+    }
+
+    //return size needed
+    return bufSizeNeeded;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API GetRgnBox(HRGN hrgn, PRECT pRect)
+{
+   BOOL      success;
+   LONG      lComplexity;
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: GetRgnBox %x %x invalid region!", hrgn, pRect));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+
+    dprintf(("GetRgnBox %x %x", hrgn, pRect));
+
+    RECTL  rectl;
+    lComplexity = GpiQueryRegionBox(hpsRegion, hrgn, &rectl);
+    if(lComplexity != RGN_ERROR)
+    {
+            //no conversion required, just flip top & bottom
+            ULONG temp    = rectl.yBottom;
+            rectl.yBottom = rectl.yTop;
+            rectl.yTop    = temp;
+
+            MapOS2ToWin32Rect(rectl, *pRect);
+    }
+    else {
+            lComplexity = ERROR_W;
+            dprintf(("WARNING: GetRgnBox error in region!"));
+    }
+
+    SetLastError(ERROR_SUCCESS_W);
+    return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API InvertRgn(HDC hdc, HRGN hrgn)
+{
+    pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: InvertRgn %x %x invalid handle!", hdc, hrgn));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+    //todo metafile recording
+
+    dprintf(("InvertRgn %x %x", hdc, hrgn));
+
+    interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
+
+    LONG  lHits = GPI_ERROR;
+    HRGN  hrgnOld;
+    LONG  lComplexity ;
+    RECTL boundingRect;      // this gets a rectangle in world cordinates!
+
+    lComplexity = GpiQueryRegionBox(pHps->hps, pHps->hrgnHDC, &boundingRect);
+    if(lComplexity != RGN_ERROR)
+    {
+        lComplexity = GpiSetClipRegion(pHps->hps, pHps->hrgnHDC, &hrgnOld);
+        if(lComplexity != RGN_ERROR)
+        {
+            RECTL rectls[2];
+            rectls[0] = boundingRect;
+            rectls[1] = boundingRect;
+            lHits = GpiBitBlt(pHps->hps, NULL, 3, (PPOINTL)rectls,
+                              ROP_DSTINVERT, 0);
+
+            /* Restore the old region */
+            GpiSetClipRegion(pHps->hps, hrgnOld, &hrgnOld);
+        }
+    }
+
+    if(lHits == GPI_ERROR || lComplexity == RGN_ERROR)
+    {
+        dprintf(("WARNING: InvertRgn error during Gpi operation (%x) (%d,%d)", WinGetLastError(0), lHits, lComplexity));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API OffsetRgn(HRGN hrgn, int xOffset, int yOffset)
+{
+   LONG   lComplexity;
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: OffsetRgn %x %d %d invalid handle!", hrgn, xOffset, yOffset));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return ERROR_W;
+    }
+    dprintf(("OffsetRgn %x %d %d", hrgn, xOffset, yOffset));
+
+    POINTL   ptlOffset = {xOffset, yOffset};
+    GpiOffsetRegion(hpsRegion, hrgn, &ptlOffset);
+
+    RGNRECT  rgnRect;
+    rgnRect.ircStart    = 1;
+    rgnRect.crc         = 0;
+    rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;     // doesn't make a difference
+    if(GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, NULL))
+    {
+        switch (rgnRect.crcReturned) {
+        case 0:
+                lComplexity = NULLREGION_W;
+                break;
+        case 1:
+                lComplexity = SIMPLEREGION_W;
+                break;
+        default:
+                lComplexity = COMPLEXREGION_W;
+                break;
+        }
+   }
+   else {
+        lComplexity = ERROR_W;
+        dprintf(("WARNING: OffsetRgn error in region! (%x)", WinGetLastError(0)));
+   }
+
+   SetLastError(ERROR_SUCCESS_W);
+
+   return lComplexity;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API FrameRgn(HDC hdc, HRGN hrgn, HBRUSH hBrush, int width, int height)
+{
+    HBRUSH hbrushRestore = 0;
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: FrameRgn %x %x %x (%d,%d) invalid handle!", hdc, hrgn, hBrush, width, height));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+
+    width  = abs(width);
+    height = abs(height);
+
+    if(pHps->lastBrushHandle != (UINT)hBrush)
+    {
+        hbrushRestore = SelectObject(hdc, hBrush);
+        if(!hbrushRestore)
+        {
+            dprintf(("WARNING: FrameRgn %x %x %x (%d,%d) invalid brush!", hdc, hrgn, hBrush, width, height));
+            SetLastError(ERROR_INVALID_HANDLE_W);
+            return FALSE;
+        }
+    }
+    dprintf(("FrameRgn %x %x %x (%d,%d)", hdc, hrgn, hBrush, width, height));
+    interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
+
+    SIZEL  thickness = { width, height };
+    LONG   lHits = GpiFrameRegion(pHps->hps, pHps->hrgnHDC, &thickness);
+
+    SetLastError(ERROR_SUCCESS_W);
+
+    // Restore the brush if necessary
+    if(hbrushRestore)
+        SelectObject(hdc, hbrushRestore);
+
+    //todo metafile recording
+    return (lHits != GPI_ERROR);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API FillRgn(HDC hdc, HRGN hrgn, HBRUSH hBrush)
+{
+ BOOL   success;
+ HBRUSH hbrushRestore = 0;
+
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: FillRgn %x %x %x invalid handle!", hdc, hrgn, hBrush));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+
+    if(pHps->lastBrushHandle != (UINT)hBrush)
+    {
+        hbrushRestore = SelectObject(hdc, hBrush);
+        if (!hbrushRestore)
+        {
+            dprintf(("WARNING: FillRgn %x %x %x invalid brush!", hdc, hrgn, hBrush));
+            SetLastError(ERROR_INVALID_HANDLE_W);
+            return FALSE;
+        }
+    }
+    dprintf(("FillRgn %x %x %x", hdc, hrgn, hBrush));
+
+    interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
+
+    success = GpiPaintRegion(pHps->hps, pHps->hrgnHDC);
+
+    //todo metafile recording
+
+    /* Restore the brush if necessary */
+    if(hbrushRestore)
+        SelectObject(hdc, hbrushRestore);
+
+    return(success);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API PaintRgn(HDC hdc, HRGN hrgn)
+{
+   pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+   if(!pHps)
+   {
+      SetLastError(ERROR_INVALID_HANDLE_W);
+      return FALSE;
+   }
+
+   return FillRgn(hdc, hrgn, (HBRUSH) pHps->lastBrushHandle);
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API PtInRegion( HRGN hrgn, int x, int y)
+{
+   BOOL      success;
+   LONG      lInside;
+
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: PtInRgn %x (%d,%d) invalid region!", hrgn, x, y));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+
+    POINTL pointl = {x,y};
+    lInside = GpiPtInRegion(hpsRegion, hrgn, &pointl);
+    if(lInside == PRGN_ERROR) {
+         success = FALSE;
+    }
+    else success = TRUE;
+
+    SetLastError(ERROR_SUCCESS_W);
+
+    dprintf(("WARNING: PtInRgn %x (%d,%d) returned %d", hrgn, x, y, (success && lInside == PRGN_INSIDE) ? 1 : 0));
+
+    if(success && lInside == PRGN_INSIDE)
+        return TRUE;
+    else
+        return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API RectInRegion(HRGN hrgn, const RECT *pRect)
+{
+   BOOL      success;
+   LONG      lInside;
+
+    if(!pRect) {
+        dprintf(("WARNING: RectInRgn %x %x invalid parameter!", hrgn, pRect));
+        SetLastError(ERROR_INVALID_PARAMETER_W);
+        return FALSE;
+    }
+    hrgn = ObjGetHandleData(hrgn);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: RectInRgn %x %x invalid region", hrgn, pRect));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return FALSE;
+    }
+
+    RECTL rectl;
+    MapWin32ToOS2Rect(*pRect, rectl);
+    //switch bottom & top
+    UINT temp     = rectl.yBottom;
+    rectl.yBottom = rectl.yTop;
+    rectl.yTop    = temp;
+
+    lInside = GpiRectInRegion(hpsRegion, hrgn, &rectl);
+    if(lInside == RRGN_ERROR) {
+            success = FALSE;
+    }
+    else    success = TRUE;
+
+    SetLastError(ERROR_SUCCESS_W);
+
+    dprintf(("WARNING: RectInRgn %x %x returned %d", hrgn, pRect, (success && (lInside == RRGN_INSIDE || lInside == RRGN_PARTIAL)) ? 1 : 0));
+
+    if(success && (lInside == RRGN_INSIDE || lInside == RRGN_PARTIAL))
+        return TRUE;
+    else
+        return FALSE;
+}
+//******************************************************************************
+//Returned region in device coordinates (undocumented behaviour)
+//******************************************************************************
+HRGN WIN32API PathToRegion(HDC hdc)
+{
+    pDCData  pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+    if(!pHps)
+    {
+        dprintf(("WARNING: PathToRegion %x; invalid hdc!", hdc));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return NULLHANDLE;
+    }
+
+    HRGN hrgn, hrgnTemp, hrgnwin;
+
+    dprintf(("GDI32: PathToRegion %x", hdc));
+
+    hrgnTemp = GpiPathToRegion(pHps->hps, 1, (pHps->polyFillMode == ALTERNATE_W) ? FPATH_ALTERNATE : FPATH_WINDING);
+    if(hrgnTemp == NULLHANDLE)
+        goto error;
+
+    hrgnwin = CreateRectRgn(1, 1, 2, 2);
+    hrgn = ObjGetHandleData(hrgnwin);
+    if(hrgn == HANDLE_OBJ_ERROR) {
+        dprintf(("WARNING: PathToRegion invalid region", hrgnwin));
+        SetLastError(ERROR_INVALID_HANDLE_W);
+        return NULLHANDLE;
+    }
+
+    if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgnTemp, pHps, NULL))
+        goto error;
+
+    GpiDestroyRegion(pHps->hps, hrgnTemp);
+
+    return hrgnwin;
+
+error:
+    if(hrgnwin)
+        DeleteObject(hrgnwin);
+
+    SetLastError(ERROR_INVALID_HANDLE_W);       //todo right error
+    return NULLHANDLE;
+}
+//******************************************************************************
+//******************************************************************************
+void OSLibDeleteRegion(HANDLE hRegion)
+{
+    if(GpiDestroyRegion(hpsRegion, hRegion) == FALSE) {
+        dprintf(("WARNING: OSLibDeleteRegion %x; GpiDestroyRegion failed (%x)", hRegion, WinGetLastError(0)));
+    }
 }
 /*****************************************************************************
@@ -193,5 +1511,5 @@
 
 int WIN32API GetMetaRgn(HDC  hdc,
-                           HRGN hrgn)
+                        HRGN hrgn)
 {
   dprintf(("GDI32: GetMetaRgn(%08xh, %08xh) not implemented.\n",
@@ -199,4 +1517,5 @@
            hrgn));
 
+  SetLastError(ERROR_SUCCESS_W);
   return (0);
 }
@@ -221,6 +1540,7 @@
            hdc));
 
-  return (NULLREGION);
-}
-//******************************************************************************
-//******************************************************************************
+  SetLastError(ERROR_SUCCESS_W);
+  return (NULLREGION_W);
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/gdi32/region.h
===================================================================
--- trunk/src/gdi32/region.h	(revision 3705)
+++ trunk/src/gdi32/region.h	(revision 3705)
@@ -0,0 +1,9 @@
+//$Id: region.h,v 1.1 2000-06-14 13:17:51 sandervl Exp $
+#ifndef __REGION_H__
+#define __REGION_H__
+
+BOOL InitRegionSpace();
+
+void OSLibDeleteRegion(HANDLE hRegion);
+
+#endif //__REGION_H__
Index: trunk/src/user32/USER32.DEF
===================================================================
--- trunk/src/user32/USER32.DEF	(revision 3704)
+++ trunk/src/user32/USER32.DEF	(revision 3705)
@@ -1,3 +1,3 @@
-; $Id: USER32.DEF,v 1.33 2000-06-08 18:10:08 sandervl Exp $
+; $Id: USER32.DEF,v 1.34 2000-06-14 13:15:23 sandervl Exp $
 
 ;Created by BLAST for IBM's compiler
@@ -646,11 +646,5 @@
     _KEYBOARD_Enable@4                                           @2011
 
-    ;SvL: Belongs in GDI32, but put in dc.cpp to group similar apis
-    _GetClipBox@8                                                @2014
-    _GetClipRgn@8                                                @2015
-    _ExtSelectClipRgn@12                                         @2016
-    _ExcludeClipRect@20                                          @2017
-    _IntersectClipRect@20                                        @2018
-    _OffsetClipRgn@12                                            @2019
-    _SelectClipRgn@8                                             @2020
-
+    ;SvL: Used by GDI32
+    OSLibGetScreenHeight__Fv                                     @2013
+    OSLibGetScreenWidth__Fv                                      @2014
Index: trunk/src/user32/dcrgn.cpp
===================================================================
--- trunk/src/user32/dcrgn.cpp	(revision 3704)
+++ trunk/src/user32/dcrgn.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: dcrgn.cpp,v 1.1 2000-06-08 18:10:10 sandervl Exp $ */
+/* $Id: dcrgn.cpp,v 1.2 2000-06-14 13:15:24 sandervl Exp $ */
 
 /*
@@ -33,4 +33,6 @@
 #include "oslibmsg.h"
 #include <dcdata.h>
+#include <objhandle.h>
+#include <wingdi32.h>
 
 #define INCLUDED_BY_DC
@@ -42,113 +44,5 @@
 //******************************************************************************
 //******************************************************************************
-int WIN32API GetClipBox( HDC hdc, PRECT lpRect)
-{
- pDCData  pHps = (pDCData)GpiQueryDCData((HPS)hdc);
- RECTL    rectl;
- LONG     lComplexity;
- int      rc;
-
-    if(!hdc || !lpRect || !pHps) {
-    	dprintf(("GDI32: GetClipBox %x %x ERROR_INVALID_PARAMETER", hdc, lpRect));
-	SetLastError(ERROR_INVALID_PARAMETER_W);
-	return ERROR_W;
-    }
-    if(pHps->isPrinter)
-    {
-        lpRect->left   = 0;
-        lpRect->top    = 0;
-        lpRect->right  = GetDeviceCaps( hdc, HORZRES_W);
-        lpRect->bottom = GetDeviceCaps( hdc, VERTRES_W);
-
-        rc = SIMPLEREGION_W;
-    }
-    else {
-    	lComplexity = GpiQueryClipBox(pHps->hps, &rectl);
-    	if(lComplexity == RGN_ERROR) 
-    	{
-		rc = ERROR_W;
-    	}
-    	else
-	if(lComplexity == RGN_NULL) 
-    	{
-		memset(lpRect, 0, sizeof(*lpRect));
-		rc = NULLREGION_W;
-	}
-	else {
-		lpRect->left   = rectl.xLeft;
-		lpRect->right  = rectl.xRight;
-#if 0
-		lpRect->top    = pHps->height - rectl.yTop;
-		lpRect->bottom = pHps->height - rectl.yBottom;
-#else
-		//No conversion required as GpiQueryClipBox is affected by
-                //the y-inversion of the window
-		lpRect->top    = rectl.yBottom;
-		lpRect->bottom = rectl.yTop;
-#endif
-		//Convert including/including to including/excluding
-		if(lpRect->left != lpRect->right) {
-			lpRect->right++;
-		}
-		if(lpRect->top != lpRect->bottom) {
-			lpRect->bottom++;
-		}
-		rc = (lComplexity == RGN_RECT) ? SIMPLEREGION_W : COMPLEXREGION_W;
-    	}
-    }
-    dprintf(("GDI32: GetClipBox of %X returned %d\n", hdc, rc));
-    return rc;
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API GetClipRgn( HDC hdc, HRGN hRgn)
-{
- int rc;
-
-    rc = O32_GetClipRgn(hdc, hRgn);
-    dprintf(("GDI32: GetClipRgn %x %x returned %x", hdc, hRgn, rc));
-    return rc;
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API ExcludeClipRect( HDC arg1, int arg2, int arg3, int arg4, int  arg5)
-{
-    dprintf(("GDI32: ExcludeClipRect"));
-    return O32_ExcludeClipRect(arg1, arg2, arg3, arg4, arg5);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API IntersectClipRect(HDC arg1, int arg2, int arg3, int arg4, int  arg5)
-{
- int rc;
-
-  rc = O32_IntersectClipRect(arg1, arg2, arg3, arg4, arg5);
-  dprintf(("GDI32: IntersectClipRect returned %d\n", rc));
-  return(rc);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API ExtSelectClipRgn( HDC arg1, HRGN arg2, int  arg3)
-{
-    dprintf(("GDI32: ExtSelectClipRgn"));
-    return O32_ExtSelectClipRgn(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API OffsetClipRgn( HDC arg1, int arg2, int  arg3)
-{
-    dprintf(("GDI32: OffsetClipRgn"));
-    return O32_OffsetClipRgn(arg1, arg2, arg3);
-}
-//******************************************************************************
-//******************************************************************************
-int WIN32API SelectClipRgn( HDC hdc, HRGN hRgn)
-{
-    dprintf(("GDI32: SelectClipRgn %x %x", hdc, hRgn));
-    return O32_SelectClipRgn(hdc, hRgn);
-}
-//******************************************************************************
-//******************************************************************************
-BOOL WIN32API GetUpdateRect (HWND hwnd, LPRECT pRect, BOOL erase)
+BOOL WIN32API GetUpdateRect(HWND hwnd, LPRECT pRect, BOOL erase)
 {
    if (!hwnd)
@@ -228,29 +122,60 @@
 //******************************************************************************
 //******************************************************************************
-int WIN32API GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
-{
-   LONG Complexity;
-
+int WIN32API GetUpdateRgn(HWND hwnd, HRGN hrgn, BOOL erase)
+{
+   LONG lComplexity;
    Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
 
-   if (!wnd)
-   {
-      SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
-      return ERROR_W;
-   }
-
-   Complexity = O32_GetUpdateRgn (wnd->getOS2WindowHandle(), hrgn, FALSE);
-   if (erase && (Complexity > NULLREGION_W)) sendEraseBkgnd(wnd);
-
-   return Complexity;
-}
-//******************************************************************************
-//******************************************************************************
-INT WIN32API ExcludeUpdateRgn( HDC hDC, HWND  hWnd)
-{
-    dprintf(("USER32:  ExcludeUpdateRgn\n"));
-    hWnd = Win32BaseWindow::Win32ToOS2Handle(hWnd);
-
-    return O32_ExcludeUpdateRgn(hDC,hWnd);
+   hrgn = ObjWinToOS2Region(hrgn);
+   if(!wnd || !hrgn)
+   {
+	dprintf(("WARNING: GetUpdateRgn %x %x %d; invalid handle", hwnd, hrgn, erase));
+      	SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
+      	return ERROR_W;
+   }
+   lComplexity = WinQueryUpdateRegion(wnd->getOS2WindowHandle(), hrgn);
+   if(lComplexity == RGN_ERROR) {
+	dprintf(("WARNING: GetUpdateRgn %x %x %d; RGN_ERROR", hwnd, hrgn, erase));
+      	SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
+      	return ERROR_W;
+   }
+
+   if(lComplexity != RGN_NULL)
+   {
+      	if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgn, NULL, wnd->getOS2WindowHandle()))
+      	{
+		dprintf(("WARNING: GetUpdateRgn %x %x %d; setWinDeviceRegionFromPMDeviceRegion failed!", hwnd, hrgn, erase));
+      		SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
+      		return ERROR_W;
+      	}
+
+        if(erase) sendEraseBkgnd(wnd);
+   }
+
+   return lComplexity;
+}
+//******************************************************************************
+//TODO: Check
+//******************************************************************************
+INT WIN32API ExcludeUpdateRgn(HDC hdc, HWND hwnd)
+{
+   Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
+   pDCData          pHps = (pDCData)GpiQueryDCData((HPS)hdc);
+   LONG             lComplexity;
+
+   if(!wnd || !pHps)
+   {
+	dprintf(("WARNING: ExcludeUpdateRgn %x %x; invalid handle", hdc, hwnd));
+      	SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
+      	return ERROR_W;
+   }
+   dprintf(("USER32: ExcludeUpdateRgn %x %x", hdc, hwnd));
+
+   lComplexity = WinExcludeUpdateRegion(pHps->hps, wnd->getOS2WindowHandle());
+   if(lComplexity == RGN_ERROR) {
+	SetLastError(ERROR_INVALID_HANDLE_W); //todo: correct error
+   }
+   else	SetLastError(ERROR_SUCCESS_W); 
+   return lComplexity;      // windows and PM values are identical
 }
 /*****************************************************************************
Index: trunk/src/user32/oslibwin.cpp
===================================================================
--- trunk/src/user32/oslibwin.cpp	(revision 3704)
+++ trunk/src/user32/oslibwin.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: oslibwin.cpp,v 1.79 2000-06-07 14:51:26 sandervl Exp $ */
+/* $Id: oslibwin.cpp,v 1.80 2000-06-14 13:15:24 sandervl Exp $ */
 /*
  * Window API wrappers for OS/2
@@ -812,2 +812,14 @@
 //******************************************************************************
 //******************************************************************************
+ULONG OSLibGetScreenHeight()
+{
+  return ScreenHeight;
+}
+//******************************************************************************
+//******************************************************************************
+ULONG OSLibGetScreenWidth()
+{
+  return ScreenWidth;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/user32/pmwindow.cpp
===================================================================
--- trunk/src/user32/pmwindow.cpp	(revision 3704)
+++ trunk/src/user32/pmwindow.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: pmwindow.cpp,v 1.93 2000-06-08 18:10:10 sandervl Exp $ */
+/* $Id: pmwindow.cpp,v 1.94 2000-06-14 13:15:24 sandervl Exp $ */
 /*
  * Win32 Window Managment Code for OS/2
@@ -200,4 +200,7 @@
     case WM_CREATE:
     {
+        RestoreOS2TIB();
+	PMFrameWindowProc(hwnd, msg, mp1, mp2);
+  	SetWin32TIB();
 
         if(thdb->newWindow == 0)
@@ -213,7 +216,4 @@
             return (MRESULT)TRUE; //discontinue window creation
         }
-        RestoreOS2TIB();
-	PMFrameWindowProc(hwnd, msg, mp1, mp2);
-  	SetWin32TIB();
     createfail:
         RestoreOS2TIB();
@@ -235,5 +235,5 @@
         win32wnd->MsgDestroy();
         WinSetVisibleRegionNotify(hwnd, FALSE);
-	goto RunDefWndProc;
+	goto RunDefFrameProc;
 
     case WM_ENABLE:
@@ -450,7 +450,7 @@
         dprintf(("OS2: WM_ACTIVATE %x %x %x", hwnd, mp1, mp2));
 
+        WinSetWindowUShort(hwnd,QWS_FLAGS, SHORT1FROMMP(mp1) ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
         if(win32wnd->IsWindowCreated()) 
         {
-          WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
           win32wnd->MsgActivate((LOWORD(pWinMsg->wParam) == WA_ACTIVE_W) ? 1 : 0, HIWORD(pWinMsg->wParam), pWinMsg->lParam, (HWND)mp2);
 
@@ -463,6 +463,6 @@
           }
         }
-
-        break;
+        RestoreOS2TIB();
+        return 0;
     }
 
@@ -470,7 +470,6 @@
     {
         dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
-        break;
-    }
-
+        goto RunDefWndProc;
+    }
 
     case WM_MINMAXFRAME:
@@ -737,6 +736,6 @@
 
     case WM_FOCUSCHANGE:
-        dprintf(("OS2: WM_FOCUSCHANGE %x", win32wnd->getWindowHandle()));
-        goto RunDefWndProc;
+        dprintf(("OS2: WM_FOCUSCHANGE %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
+        goto RunDefFrameProc;  //partly responsible for activation of frame windows
 
     case WM_QUERYTRACKINFO:
Index: trunk/src/user32/win32wbase.cpp
===================================================================
--- trunk/src/user32/win32wbase.cpp	(revision 3704)
+++ trunk/src/user32/win32wbase.cpp	(revision 3705)
@@ -1,3 +1,3 @@
-/* $Id: win32wbase.cpp,v 1.200 2000-06-08 18:10:11 sandervl Exp $ */
+/* $Id: win32wbase.cpp,v 1.201 2000-06-14 13:15:25 sandervl Exp $ */
 /*
  * Win32 Window Base Class for OS/2
@@ -2053,5 +2053,7 @@
 
     dprintf(("ShowWindow %x %x", getWindowHandle(), nCmdShow));
-
+    if(getWindowHandle() == 0x68000030 && nCmdShow == 0) {
+	rc = 0;
+    }
     wasVisible = (getStyle() & WS_VISIBLE) != 0;
 
@@ -2386,5 +2388,4 @@
         else DebugInt3();
     }
-
     /* Hide the window */
     if(IsWindowVisible())
