Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

494 lines
10 KiB

/*=========================================================================
*
* Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
*
* File: winwatch.c
* Content: 16-bit window watch code
* History:
* Date By Reason
* ==== == ======
* 20-jun-95 craige split out of DCIMAN WINWATCH.C, tweaked
* 22-jun-95 craige re-worked for clipper stuff
* 02-jul-95 craige comment out clipper notify stuff
*
***************************************************************************/
#define _INC_DCIDDI
#include "ddraw16.h"
#undef _INC_DCIDDI
#ifdef CLIPPER_NOTIFY
static LPWINWATCH lpWWList;
static HHOOK hNextCallWndProc;
static BOOL bUnHook;
long FAR PASCAL _loadds CallWndProcHook(int hc, WPARAM wParam, LPARAM lParam);
extern HRGN FAR PASCAL InquireVisRgn(HDC hdc);
extern DWORD FAR PASCAL GetRegionData(HRGN hrgn, DWORD count, LPRGNDATA prd);
/*
* doNotify
*/
void doNotify(LPWINWATCH pww, DWORD code)
{
if( pww->lpCallback )
{
extern void DDAPI DD32_ClippingNotify( LPVOID, DWORD );
DD32_ClippingNotify( pww->self32, code );
}
} /* doNotify */
/*
* DD16_WWOpen
*/
void DDAPI DD16_WWOpen( LPWINWATCH ptr )
{
if( lpWWList == NULL )
{
DPF( 2, "Setting Windows Hook" );
hNextCallWndProc = (HHOOK) SetWindowsHook( WH_CALLWNDPROC,
(HOOKPROC) CallWndProcHook );
}
lpWWList = ptr;
} /* DD16_WWOpen */
/*
* DD16_WWClose
*/
void DDAPI DD16_WWClose( LPWINWATCH pww, LPWINWATCH newlist )
{
if( pww->prd16 != NULL )
{
LocalFree( (HLOCAL) pww->prd16 );
pww->prd16 = NULL;
}
if( newlist == NULL )
{
DPF( 3, "Flagging to Unhook" );
bUnHook = TRUE;
}
lpWWList = newlist;
} /* DD16_WWClose */
/*
* DD16_WWNotifyInit
*/
void DDAPI DD16_WWNotifyInit(
LPWINWATCH pww,
LPCLIPPERCALLBACK lpcallback,
LPVOID param )
{
doNotify( pww, WINWATCHNOTIFY_STOP );
pww->lpCallback = lpcallback;
pww->lpContext = param;
doNotify( pww, WINWATCHNOTIFY_START );
doNotify( pww, WINWATCHNOTIFY_CHANGED );
pww->fNotify = FALSE;
} /* DD16_WWNotifyInit */
/*
* getWindowRegionData
*/
static DWORD getWindowRegionData( HWND hwnd, DWORD size, RGNDATA NEAR * prd )
{
HDC hdc;
DWORD dw;
hdc = GetDCEx( hwnd, NULL, DCX_USESTYLE | DCX_CACHE );
dw = GetRegionData( InquireVisRgn( hdc ), size, prd );
ReleaseDC( hwnd, hdc );
return dw;
} /* getWindowRegionData */
/*
* DD16_WWGetClipList
*/
DWORD DDAPI DD16_WWGetClipList(
LPWINWATCH pww,
LPRECT prect,
DWORD rdsize,
LPRGNDATA prd )
{
DWORD dw;
DWORD size;
/*
* we have to see if the intersect rect has changed.
*/
if( prect )
{
if( !EqualRect(prect, &pww->rect) )
{
pww->fDirty = TRUE;
}
}
else
{
if( !IsRectEmpty( &pww->rect ) )
{
pww->fDirty = TRUE;
}
}
/*
* if we are not dirty just return the saved RGNDATA
*/
if( !pww->fDirty && pww->prd16 )
{
size = sizeof( *prd ) + (WORD) pww->prd16->rdh.nRgnSize;
if( prd == NULL )
{
return size;
}
if( rdsize < size )
{
size = rdsize;
}
_fmemcpy( prd, pww->prd16, (UINT) size );
return size;
}
/*
* get the RGNDATA, growing the memory if we have to
*/
dw = getWindowRegionData( (HWND) pww->hWnd, pww->dwRDSize, pww->prd16 );
if( dw > pww->dwRDSize )
{
DPF( 2, "GetClipList: growing RGNDATA memory from %ld to %ld",pww->dwRDSize, dw);
if( pww->prd16 != NULL )
{
LocalFree((HLOCAL)pww->prd16);
}
/*
* allocate new space plus some slop
*/
pww->dwRDSize = dw + 8*sizeof(RECTL);
pww->prd16 = (RGNDATA NEAR *) LocalAlloc(LPTR, (UINT)pww->dwRDSize);
if( pww->prd16 == NULL )
{
goto error;
}
dw = getWindowRegionData( (HWND) pww->hWnd, pww->dwRDSize, pww->prd16 );
if( dw > pww->dwRDSize )
{
goto error;
}
}
/*
* now intersect the region with the passed rect
*/
if( prect )
{
pww->rect = *prect;
DPF( 2, "GetClipList: intersect with [%d %d %d %d]", *prect);
ClipRgnToRect( (HWND) pww->hWnd, prect, pww->prd16 );
}
else
{
SetRectEmpty( &pww->rect );
}
pww->fDirty = FALSE;
size = sizeof( *prd ) + (WORD) pww->prd16->rdh.nRgnSize;
if( prd == NULL )
{
return size;
}
if( rdsize < size )
{
size = rdsize;
}
_fmemcpy( prd, pww->prd16, (UINT) size );
return size;
error:
pww->dwRDSize = 0;
return 0;
} /* DD16_WWGetClipList */
/****************************************************************************
* *
* ROUTINES TO HANDLE NOTIFICATION MESSAGES FOLLOW *
* *
****************************************************************************/
/*
* handleWindowDestroyed
*/
static void handleWindowDestroy( HWND hwnd )
{
LPWINWATCH pww;
DPF( 2, "*** handleWindowDestroy: hwnd=%08lx", hwnd );
again:
for( pww=lpWWList; pww; pww=pww->next16 )
{
if( (hwnd == NULL) || ((HWND)pww->hWnd == hwnd) )
{
extern void DDAPI DD32_WWClose( DWORD );
doNotify( pww, WINWATCHNOTIFY_DESTROY );
DD32_WWClose( (DWORD) pww->self32 );
goto again;
}
}
} /* handleWindowDestroy */
/*
* handleWindowPosChanged
*/
static void handleWindowPosChanged( HWND hwnd )
{
LPWINWATCH pww;
LPWINWATCH next;
RECT rect;
RECT rectT;
DPF( 20, "*** handleWindowPosChanged: hwnd=%08lx", hwnd );
/*
* get the screen rect that changed
*/
GetWindowRect( hwnd, &rect );
/*
* send message to each notify routine
*/
pww = lpWWList;
while( pww != NULL )
{
next = pww->next16;
GetWindowRect((HWND)pww->hWnd, &rectT);
if( IntersectRect( &rectT, &rectT, &rect ) )
{
pww->fNotify = TRUE;
pww->fDirty = TRUE;
}
if( pww->fNotify && pww->lpCallback )
{
DPF( 20, "clip changed %04X [%d %d %d %d]", (HWND)pww->hWnd, rectT);
doNotify( pww, WINWATCHNOTIFY_CHANGED );
pww->fNotify = FALSE;
}
pww = next;
}
} /* handleWindowPosChanged */
/*
* sendChanging
*/
static void sendChanging( LPRECT prect )
{
LPWINWATCH pww;
LPWINWATCH next;
RECT rectT;
pww = lpWWList;
while( pww != NULL )
{
next = pww->next16;
GetWindowRect( (HWND)pww->hWnd, &rectT );
if( IntersectRect(&rectT, &rectT, prect) )
{
pww->fDirty = TRUE;
if( pww->lpCallback )
{
DPF( 20, "clip changing %04X [%d %d %d %d]", (HWND)pww->hWnd, rectT);
doNotify( pww, WINWATCHNOTIFY_CHANGING );
pww->fNotify = TRUE;
pww->fDirty = TRUE;
}
}
pww = next;
}
} /* sendChanging */
/*
* handleWindowPosChanging
*/
static void handleWindowPosChanging( HWND hwnd, LPWINDOWPOS pwinpos )
{
RECT rect;
RECT rect_win;
int cx;
int cy;
/*
* get the current screen rect.
*/
DPF( 20, "*** handleWindowPosChanging: hwnd=%08lx", hwnd );
GetWindowRect( hwnd, &rect_win);
rect = rect_win;
if( pwinpos == NULL )
{
sendChanging( &rect );
return;
}
/*
* compute the new rect
*/
if( pwinpos->flags & SWP_NOSIZE )
{
cx = rect.right - rect.left;
cy = rect.bottom - rect.top;
}
else
{
cx = pwinpos->cx;
cy = pwinpos->cy;
}
if( !(pwinpos->flags & SWP_NOMOVE) )
{
rect.left = pwinpos->x;
rect.top = pwinpos->y;
if( GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD )
{
ClientToScreen(GetParent(hwnd), (LPPOINT)&rect);
}
}
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
/*
* only send changing if we are really changing... if the new
* rect is the same as the old rect, then check if something else
* interesting is happening...
*/
if( EqualRect( &rect, &rect_win ) )
{
if( !(pwinpos->flags & SWP_NOZORDER) )
{
sendChanging(&rect);
}
if( pwinpos->flags & (SWP_SHOWWINDOW|SWP_HIDEWINDOW) )
{
sendChanging(&rect);
}
}
else
{
sendChanging( &rect_win );
sendChanging( &rect );
}
} /* handleWindowPosChanging */
/*
* checkScreenLock
*/
static void checkScreenLock( void )
{
static BOOL bScreenLocked;
BOOL is_locked;
HDC hdc;
RECT rect;
hdc = GetDC(NULL);
is_locked = (GetClipBox(hdc, &rect) == NULLREGION);
ReleaseDC(NULL, hdc);
if( is_locked != bScreenLocked )
{
/*
* pretend the desktop window has moved, this will cause
* all WINWATCH handles to be set to dirty, and also be notified.
*/
handleWindowPosChanging( GetDesktopWindow(), NULL );
handleWindowPosChanged( GetDesktopWindow() );
bScreenLocked = is_locked;
}
} /* checkScreenLock */
/*
* CallWndProcHook
*/
long FAR PASCAL _loadds CallWndProcHook( int hc, WPARAM wParam, LPARAM lParam )
{
/* reversed MSG minus time and pt */
typedef struct
{
LONG lParam;
WORD wParam;
WORD message;
HWND hwnd;
} MSGR, FAR *LPMSGR;
LPMSGR lpmsg;
LPWINDOWPOS lpwinpos;
long rc;
if( hc == HC_ACTION )
{
lpmsg = (MSGR FAR *)lParam;
switch( lpmsg->message )
{
case WM_DESTROY:
handleWindowDestroy( lpmsg->hwnd );
break;
case WM_WINDOWPOSCHANGING:
lpwinpos = (LPWINDOWPOS) lpmsg->lParam;
handleWindowPosChanging( lpwinpos->hwnd, lpwinpos );
break;
case WM_WINDOWPOSCHANGED:
lpwinpos = (LPWINDOWPOS) lpmsg->lParam;
handleWindowPosChanged( lpwinpos->hwnd );
break;
case WM_EXITSIZEMOVE:
checkScreenLock();
break;
case WM_ENTERSIZEMOVE:
checkScreenLock();
break;
}
}
rc = DefHookProc(hc, wParam, lParam, &(HOOKPROC)hNextCallWndProc);
if( bUnHook )
{
DPF( 2, "Unhooking WindowsHook" );
UnhookWindowsHook( WH_CALLWNDPROC, (HOOKPROC)CallWndProcHook );
bUnHook = FALSE;
}
return rc;
} /* CallWndProcHook */
#endif