Author: jimtabor
Date: Fri Sep 7 16:21:26 2007
New Revision: 28918
URL:
http://svn.reactos.org/svn/reactos?rev=28918&view=rev
Log:
- Reordered IntGdiGet/SetDCState and separated the copy sections.
- When creating DCE for window handles, allocate a DC structure for the default window
DC.
- Return Dhpdev if not zero for NtGdiOpenDCW.
- Reordered the DC object.
Modified:
trunk/reactos/subsystems/win32/win32k/include/dc.h
trunk/reactos/subsystems/win32/win32k/include/intgdi.h
trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
trunk/reactos/subsystems/win32/win32k/objects/dc.c
Modified: trunk/reactos/subsystems/win32/win32k/include/dc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/dc.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/dc.h Fri Sep 7 16:21:26 2007
@@ -59,37 +59,42 @@
typedef struct _DC
{
- HDC hSelf;
- HDC hNext;
- PDC_ATTR pDc_Attr;
- INT DC_Type;
- INT DC_Flags;
- DHPDEV PDev;
- HSURF FillPatternSurfaces[HS_DDI_MAX];
- PGDIINFO GDIInfo;
- PDEVINFO DevInfo;
- HDEV GDIDevice;
+ HGDIOBJ hHmgr;
+ PVOID pvEntry;
+ ULONG lucExcLock;
+ ULONG Tid;
+
+ DHPDEV PDev;
+ INT DC_Type;
+ INT DC_Flags;
+ PDC_ATTR pDc_Attr;
+ DC_ATTR Dc_Attr;
+
+ HDC hSelf;
+ HDC hNext;
+ HSURF FillPatternSurfaces[HS_DDI_MAX];
+ PGDIINFO GDIInfo;
+ PDEVINFO DevInfo;
+ HDEV GDIDevice;
DRIVER_FUNCTIONS DriverFunctions;
UNICODE_STRING DriverName;
- HANDLE DeviceDriver;
+ HANDLE DeviceDriver;
- CLIPOBJ *CombinedClip;
+ CLIPOBJ *CombinedClip;
- XLATEOBJ *XlateBrush;
- XLATEOBJ *XlatePen;
+ XLATEOBJ *XlateBrush;
+ XLATEOBJ *XlatePen;
- INT saveLevel;
- BOOL IsIC;
+ INT saveLevel;
+ BOOL IsIC;
- HPALETTE PalIndexed;
+ HPALETTE PalIndexed;
- WIN_DC_INFO w;
- DC_ATTR Dc_Attr;
+ WIN_DC_INFO w;
- HANDLE hFile;
+ HANDLE hFile;
LPENHMETAHEADER emh;
-
} DC, *PDC;
typedef struct _GDIPOINTER /* should stay private to ENG */
@@ -151,6 +156,8 @@
HDC FASTCALL DC_GetNextDC (PDC pDC);
VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC);
VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
+VOID FASTCALL IntGdiCopyFromSaveState(PDC, PDC);
+VOID FASTCALL IntGdiCopyToSaveState(PDC, PDC);
VOID FASTCALL DC_UpdateXforms(PDC dc);
BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/intgdi.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h Fri Sep 7 16:21:26 2007
@@ -159,7 +159,7 @@
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
- PUNICODE_STRING Output,
+ PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c Fri Sep 7 16:21:26 2007
@@ -39,7 +39,7 @@
/* NOTE - I think we should store this per window station (including gdi objects) */
static PDCE FirstDce = NULL;
-static HDC defaultDCstate = NULL;
+static PDC defaultDCstate = NULL;
//static INT DCECount = 0;
#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
@@ -126,12 +126,16 @@
ExFreePoolWithTag(pDce, TAG_PDCE);
return NULL;
}
-
+//
+// If NULL, first time through! Build the default window dc!
+//
if (NULL == defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this.
- // But, due to the right way of creating gdi handles there is no choice.
- defaultDCstate = IntGdiGetDCState(pDce->hDC);
- DC_SetOwnership( defaultDCstate, NULL);
+ PDC dc = DC_LockDc ( pDce->hDC );
+ defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
+ RtlZeroMemory(defaultDCstate, sizeof(DC));
+ IntGdiCopyToSaveState(dc, defaultDCstate);
+ DC_UnlockDc( dc );
}
pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
@@ -144,8 +148,7 @@
KeLeaveCriticalRegion();
if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
- {
- DC_SetOwnership(pDce->hDC, PsGetCurrentProcess());
+ { // Process should already own it.
pDce->pProcess = PsGetCurrentProcess();
}
else
@@ -248,13 +251,8 @@
/* make the DC clean so that SetDCState doesn't try to update the vis rgn */
IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
- if( dce->pProcess ) // Attempt to fix Dc_Attr problem.
- DC_SetOwnership( defaultDCstate, dce->pProcess);
- else
- DC_SetOwnership( defaultDCstate, PsGetCurrentProcess());
-
- IntGdiSetDCState(dce->hDC, defaultDCstate);
- DC_SetOwnership( defaultDCstate, NULL); // Return default dc state to inaccessible
mode.
+ PDC dc = DC_LockDc ( dce->hDC );
+ IntGdiCopyFromSaveState(dc, defaultDCstate); // Was SetDCState.
dce->DCXFlags &= ~DCX_DCEBUSY;
if (dce->DCXFlags & DCX_DCEDIRTY)
Modified: trunk/reactos/subsystems/win32/win32k/objects/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dc.c Fri Sep 7 16:21:26 2007
@@ -809,7 +809,7 @@
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
- PUNICODE_STRING Output,
+ PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC)
{
@@ -909,6 +909,7 @@
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
+ if(pUMdhpdev) pUMdhpdev = NewDC->PDev;
NewDC->GDIDevice = (HDEV)&PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->w.hBitmap = PrimarySurface.Handle;
@@ -963,6 +964,7 @@
{
UNICODE_STRING SafeDevice;
DEVMODEW SafeInitData;
+ PVOID Dhpdev;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
@@ -970,6 +972,12 @@
{
_SEH_TRY
{
+ if (pUMdhpdev)
+ {
+ ProbeForWrite(pUMdhpdev,
+ sizeof(PVOID),
+ 1);
+ }
ProbeForRead(InitData,
sizeof(DEVMODEW),
1);
@@ -1002,10 +1010,12 @@
Ret = IntGdiCreateDC(NULL == Device ? NULL : &SafeDevice,
NULL,
- NULL,
+ NULL == pUMdhpdev ? NULL : &Dhpdev,
NULL == InitData ? NULL : &SafeInitData,
(BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
+ if (pUMdhpdev) pUMdhpdev = Dhpdev;
+
return Ret;
}
@@ -1281,29 +1291,11 @@
return oldColor;
}
-HDC STDCALL
-IntGdiGetDCState(HDC hDC)
-{
- PDC newdc, dc;
- HDC hnewdc;
-
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- hnewdc = DC_AllocDC(NULL);
- if (hnewdc == NULL)
- {
- DC_UnlockDc(dc);
- return 0;
- }
- newdc = DC_LockDc( hnewdc );
- /* FIXME - newdc can be NULL!!!! Don't assert here!!! */
- ASSERT( newdc );
-
+
+VOID
+FASTCALL
+IntGdiCopyToSaveState(PDC dc, PDC newdc)
+{
newdc->w.flags = dc->w.flags | DC_SAVED;
newdc->Dc_Attr.hpen = dc->Dc_Attr.hpen;
newdc->Dc_Attr.hbrush = dc->Dc_Attr.hbrush;
@@ -1344,7 +1336,6 @@
newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
newdc->w.xformVport2World = dc->w.xformVport2World;
newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
- DCU_UpdateUserXForms(newdc,
WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
newdc->Dc_Attr.ptlWindowOrg.x = dc->Dc_Attr.ptlWindowOrg.x;
newdc->Dc_Attr.ptlWindowOrg.y = dc->Dc_Attr.ptlWindowOrg.y;
newdc->Dc_Attr.szlWindowExt.cx = dc->Dc_Attr.szlWindowExt.cx;
@@ -1354,7 +1345,6 @@
newdc->Dc_Attr.szlViewportExt.cx = dc->Dc_Attr.szlViewportExt.cx;
newdc->Dc_Attr.szlViewportExt.cy = dc->Dc_Attr.szlViewportExt.cy;
- newdc->hSelf = hnewdc;
newdc->saveLevel = 0;
newdc->IsIC = dc->IsIC;
@@ -1370,6 +1360,136 @@
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
+}
+
+
+VOID
+FASTCALL
+IntGdiCopyFromSaveState(PDC dc, PDC dcs)
+{
+ HDC hDC = dc->hSelf;
+
+ dc->w.flags = dcs->w.flags & ~DC_SAVED;
+
+ dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
+
+#if 0
+ dc->w.hDevice = dcs->w.hDevice;
+#endif
+
+ dc->w.totalExtent = dcs->w.totalExtent;
+ dc->Dc_Attr.jROP2 = dcs->Dc_Attr.jROP2;
+ dc->Dc_Attr.jFillMode = dcs->Dc_Attr.jFillMode;
+ dc->Dc_Attr.jStretchBltMode = dcs->Dc_Attr.jStretchBltMode;
+ dc->Dc_Attr.lRelAbs = dcs->Dc_Attr.lRelAbs;
+ dc->Dc_Attr.jBkMode = dcs->Dc_Attr.jBkMode;
+ dc->Dc_Attr.crBackgroundClr = dcs->Dc_Attr.crBackgroundClr;
+ dc->Dc_Attr.crForegroundClr = dcs->Dc_Attr.crForegroundClr;
+ dc->Dc_Attr.ptlBrushOrigin.x = dcs->Dc_Attr.ptlBrushOrigin.x;
+ dc->Dc_Attr.ptlBrushOrigin.y = dcs->Dc_Attr.ptlBrushOrigin.y;
+ dc->Dc_Attr.lTextAlign = dcs->Dc_Attr.lTextAlign;
+ dc->Dc_Attr.lTextExtra = dcs->Dc_Attr.lTextExtra;
+ dc->Dc_Attr.cBreak = dcs->Dc_Attr.cBreak;
+ dc->Dc_Attr.lBreakExtra = dcs->Dc_Attr.lBreakExtra;
+ dc->Dc_Attr.iMapMode = dcs->Dc_Attr.iMapMode;
+ dc->Dc_Attr.iGraphicsMode = dcs->Dc_Attr.iGraphicsMode;
+#if 0
+/* Apparently, the DC origin is not changed by [GS]etDCState */
+ dc->w.DCOrgX = dcs->w.DCOrgX;
+ dc->w.DCOrgY = dcs->w.DCOrgY;
+#endif
+ dc->Dc_Attr.ptlCurrent.x = dcs->Dc_Attr.ptlCurrent.x;
+ dc->Dc_Attr.ptlCurrent.y = dcs->Dc_Attr.ptlCurrent.y;
+ dc->w.ArcDirection = dcs->w.ArcDirection;
+
+ dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
+ dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
+ dc->w.xformVport2World = dcs->w.xformVport2World;
+ dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
+ dc->Dc_Attr.ptlWindowOrg.x = dcs->Dc_Attr.ptlWindowOrg.x;
+ dc->Dc_Attr.ptlWindowOrg.y = dcs->Dc_Attr.ptlWindowOrg.y;
+ dc->Dc_Attr.szlWindowExt.cx = dcs->Dc_Attr.szlWindowExt.cx;
+ dc->Dc_Attr.szlWindowExt.cy = dcs->Dc_Attr.szlWindowExt.cy;
+ dc->Dc_Attr.ptlViewportOrg.x = dcs->Dc_Attr.ptlViewportOrg.x;
+ dc->Dc_Attr.ptlViewportOrg.y = dcs->Dc_Attr.ptlViewportOrg.y;
+ dc->Dc_Attr.szlViewportExt.cx = dcs->Dc_Attr.szlViewportExt.cx;
+ dc->Dc_Attr.szlViewportExt.cy = dcs->Dc_Attr.szlViewportExt.cy;
+ dc->PalIndexed = dcs->PalIndexed;
+
+ if (!(dc->w.flags & DC_MEMORY))
+ {
+ dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
+ }
+
+#if 0
+ if (dcs->w.hClipRgn)
+ {
+ if (!dc->w.hClipRgn)
+ {
+ dc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+ }
+ NtGdiCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
+ }
+ else
+ {
+ if (dc->w.hClipRgn)
+ {
+ NtGdiDeleteObject( dc->w.hClipRgn );
+ }
+ dc->w.hClipRgn = 0;
+ }
+ {
+ int res;
+ res = CLIPPING_UpdateGCRegion( dc );
+ ASSERT ( res != ERROR );
+ }
+ DC_UnlockDc ( dc );
+#else
+ IntGdiExtSelectClipRgn(dc, dcs->w.hClipRgn, RGN_COPY);
+ DC_UnlockDc ( dc );
+#endif
+
+ NtGdiSelectObject( hDC, dcs->w.hBitmap );
+ NtGdiSelectObject( hDC, dcs->Dc_Attr.hbrush );
+ NtGdiSelectObject( hDC, dcs->Dc_Attr.hlfntNew );
+ NtGdiSelectObject( hDC, dcs->Dc_Attr.hpen );
+
+ NtGdiSetBkColor( hDC, dcs->Dc_Attr.crBackgroundClr);
+ NtGdiSetTextColor( hDC, dcs->Dc_Attr.crForegroundClr);
+
+ NtUserSelectPalette( hDC, dcs->w.hPalette, FALSE );
+
+#if 0
+ GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
+#endif
+}
+
+HDC STDCALL
+IntGdiGetDCState(HDC hDC)
+{
+ PDC newdc, dc;
+ HDC hnewdc;
+
+ dc = DC_LockDc(hDC);
+ if (dc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ hnewdc = DC_AllocDC(NULL);
+ if (hnewdc == NULL)
+ {
+ DC_UnlockDc(dc);
+ return 0;
+ }
+ newdc = DC_LockDc( hnewdc );
+ /* FIXME - newdc can be NULL!!!! Don't assert here!!! */
+ ASSERT( newdc );
+
+ newdc->hSelf = hnewdc;
+ IntGdiCopyToSaveState( dc, newdc);
+
DCU_SyncDcAttrtoUser(newdc, -1);
DC_UnlockDc( newdc );
DC_UnlockDc( dc );
@@ -1391,105 +1511,16 @@
{
if ( dcs->w.flags & DC_SAVED )
{
- dc->w.flags = dcs->w.flags & ~DC_SAVED;
-
- dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
-
-#if 0
- dc->w.hDevice = dcs->w.hDevice;
-#endif
-
- dc->w.totalExtent = dcs->w.totalExtent;
- dc->Dc_Attr.jROP2 = dcs->Dc_Attr.jROP2;
- dc->Dc_Attr.jFillMode = dcs->Dc_Attr.jFillMode;
- dc->Dc_Attr.jStretchBltMode = dcs->Dc_Attr.jStretchBltMode;
- dc->Dc_Attr.lRelAbs = dcs->Dc_Attr.lRelAbs;
- dc->Dc_Attr.jBkMode = dcs->Dc_Attr.jBkMode;
- dc->Dc_Attr.crBackgroundClr = dcs->Dc_Attr.crBackgroundClr;
- dc->Dc_Attr.crForegroundClr = dcs->Dc_Attr.crForegroundClr;
- dc->Dc_Attr.ptlBrushOrigin.x = dcs->Dc_Attr.ptlBrushOrigin.x;
- dc->Dc_Attr.ptlBrushOrigin.y = dcs->Dc_Attr.ptlBrushOrigin.y;
- dc->Dc_Attr.lTextAlign = dcs->Dc_Attr.lTextAlign;
- dc->Dc_Attr.lTextExtra = dcs->Dc_Attr.lTextExtra;
- dc->Dc_Attr.cBreak = dcs->Dc_Attr.cBreak;
- dc->Dc_Attr.lBreakExtra = dcs->Dc_Attr.lBreakExtra;
- dc->Dc_Attr.iMapMode = dcs->Dc_Attr.iMapMode;
- dc->Dc_Attr.iGraphicsMode = dcs->Dc_Attr.iGraphicsMode;
-#if 0
- /* Apparently, the DC origin is not changed by [GS]etDCState */
- dc->w.DCOrgX = dcs->w.DCOrgX;
- dc->w.DCOrgY = dcs->w.DCOrgY;
-#endif
- dc->Dc_Attr.ptlCurrent.x = dcs->Dc_Attr.ptlCurrent.x;
- dc->Dc_Attr.ptlCurrent.y = dcs->Dc_Attr.ptlCurrent.y;
- dc->w.ArcDirection = dcs->w.ArcDirection;
-
- dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
- dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
- dc->w.xformVport2World = dcs->w.xformVport2World;
- dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
- DCU_UpdateUserXForms(dc,
WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
- dc->Dc_Attr.ptlWindowOrg.x = dcs->Dc_Attr.ptlWindowOrg.x;
- dc->Dc_Attr.ptlWindowOrg.y = dcs->Dc_Attr.ptlWindowOrg.y;
- dc->Dc_Attr.szlWindowExt.cx = dcs->Dc_Attr.szlWindowExt.cx;
- dc->Dc_Attr.szlWindowExt.cy = dcs->Dc_Attr.szlWindowExt.cy;
- dc->Dc_Attr.ptlViewportOrg.x = dcs->Dc_Attr.ptlViewportOrg.x;
- dc->Dc_Attr.ptlViewportOrg.y = dcs->Dc_Attr.ptlViewportOrg.y;
- dc->Dc_Attr.szlViewportExt.cx = dcs->Dc_Attr.szlViewportExt.cx;
- dc->Dc_Attr.szlViewportExt.cy = dcs->Dc_Attr.szlViewportExt.cy;
- dc->PalIndexed = dcs->PalIndexed;
-
- if (!(dc->w.flags & DC_MEMORY))
- {
- dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
- }
-
-#if 0
- if (dcs->w.hClipRgn)
- {
- if (!dc->w.hClipRgn)
- {
- dc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
- }
- NtGdiCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
- }
- else
- {
- if (dc->w.hClipRgn)
- {
- NtGdiDeleteObject( dc->w.hClipRgn );
- }
-
- dc->w.hClipRgn = 0;
- }
- {
- int res;
- res = CLIPPING_UpdateGCRegion( dc );
- ASSERT ( res != ERROR );
- }
- DC_UnlockDc ( dc );
-#else
- IntGdiExtSelectClipRgn(dc, dcs->w.hClipRgn, RGN_COPY);
- DC_UnlockDc ( dc );
-#endif
-
- NtGdiSelectObject( hDC, dcs->w.hBitmap );
- NtGdiSelectObject( hDC, dcs->Dc_Attr.hbrush );
- NtGdiSelectObject( hDC, dcs->Dc_Attr.hlfntNew );
- NtGdiSelectObject( hDC, dcs->Dc_Attr.hpen );
- NtGdiSetBkColor( hDC, dcs->Dc_Attr.crBackgroundClr);
- NtGdiSetTextColor( hDC, dcs->Dc_Attr.crForegroundClr);
-
- NtUserSelectPalette( hDC, dcs->w.hPalette, FALSE );
-
-#if 0
- GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
-#endif
- } else {
+ IntGdiCopyFromSaveState( dc, dcs);
+ }
+ else
+ {
DC_UnlockDc(dc);
}
DC_UnlockDc ( dcs );
- } else {
+ }
+ else
+ {
DC_UnlockDc ( dc );
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
@@ -2607,7 +2638,6 @@
{
PDC DC;
-// DC_FreeDcAttr(hDC, NULL);
GDIOBJ_SetOwnership(GdiHandleTable, hDC, Owner);
DC = DC_LockDc(hDC);
if (NULL != DC)
@@ -2626,7 +2656,6 @@
}
DC_UnlockDc(DC);
}
-// DC_AllocateDcAttr(hDC, Owner);
}
BOOL FASTCALL