⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overlap.c

📁 dos 1.0 其中包含quick basic源代码、内存管理himem emm386 发展历史
💻 C
📖 第 1 页 / 共 2 页
字号:

/*
	COW : Character Oriented Windows

	overlap.c  : Overlapping Window Support

*/


#define COW
#include <cow.h>

#define WINDOW
#include <uwindow.h>
#include <uevent.h>
#include <umenu.h>
#include <uisa.h>
#include <uscreen.h>
#include <vkey.h>
#include <kkeyboar.h>
#include <kinput.h>

#include "event.h"
#include "screen.h"
#include "util.h"
#include "dialog.h"
#include "window.h"
#include "shadow.h"
#include "overlap.h"


#ifdef WINDOW_OVERLAP	/* entire file */

extern void MemSetW(WORD, WORD, WORD, WORD);
extern PWND pwndClip;

/* forward */
STATIC VOID ThinkWindowAndSiblings(PWND);
STATIC BOOL FAllocDragSave(void);
STATIC VOID InitDragRrc(PWND);
STATIC VOID SaveDragRrc(void);
STATIC VOID RestoreDragRrc(void);
STATIC VOID DisplayDrag(void);
STATIC VOID EndDrag(void);
STATIC BOOL FAdjustDragRrc(int *, int *);


PRIVATE BOOL fDragging = FALSE;	/* am moving a window */
PRIVATE OWDS owds;		/* current window drag status */
				/* is valid only if fDragging == TRUE */
/*
  -- OWDF's contain the overlapping window drag flags
  -- rgowdf contains the initial settings for when a mouse clicks
          on the window.
  -- owdfKeyboardMove/Size contain the initial settings for keyboard
          moves and sizes
  -- format: { fMouse, fButton, fOutline, fXDrag, fYDrag, fEscapeMove, message}
*/
PRIVATE OWDF rgowdf[] =
	{
		{ 1, 1, 0, 0, 0, 0, WM_CLOSE },	/* top left corner */
		{ 1, 0, 1, 0, 0, 0, WM_MOVE },  /* top side */
		{ 1, 1, 0, 0, 0, 0, WM_ZOOM },	/* top right corner */
		{ 1, 0, 1, 0, 0, 0, WM_MOVE },	/* left side */
		{ 0, 0, 0, 0, 0, 0, 0 },	/* middle */
		{ 1, 0, 1, 1, 0, 0, WM_SIZE },	/* right side */
		{ 1, 0, 1, 0, 0, 0, WM_MOVE },	/* bottom left corner */
		{ 1, 0, 1, 0, 1, 0, WM_SIZE },	/* bottom side */
		{ 1, 0, 1, 1, 1, 0, WM_SIZE }	/* bottom right corner */
	};

PRIVATE OWDF owdfKeyboardMove = { 0, 0, 1, 0, 0, 0, WM_MOVE };
PRIVATE OWDF owdfKeyboardSize = { 0, 0, 1, 1, 1, 0, WM_SIZE };

PRIVATE PWND pwndCur;		/* current drawing window */
PRIVATE WORD psOverlap;		/* overlapping window table */

VOID FARPUBLIC
AddChildHead(pwndParent, pwndChild)
/*
  -- add child to head of child list
*/
PWND pwndParent, pwndChild;
	{
	StartPublic();

	Assert(pwndParent != NULL && pwndChild != NULL);

	pwndChild->pwndSibling = pwndParent->pwndChild;
	pwndChild->pwndParent = pwndParent;
	pwndParent->pwndChild = pwndChild;
	if (pwndParent->style & WS_CLIPOUT)
		{
		pwndChild->style |= WS_CLIPOUT;
		ClipoutWindowAndSiblings(pwndChild->pwndChild);
		}
	StopPublic();
	}

VOID FARPRIVATE
ClipoutWindowAndSiblings(pwnd)
/*
  -- pwnd inherits the clipout type along with its children
*/
PWND	pwnd;
	{

	while (pwnd != NULL)
		{
		pwnd->style |= WS_CLIPOUT;
		ClipoutWindowAndSiblings(pwnd->pwndChild);
		pwnd = pwnd->pwndSibling;
		}
	}



BOOL FARPUBLIC
FIsTopWindow(pwnd)
PWND	pwnd;
	{
	StartPublic();
	ReturnPublic(pwnd->pwndSibling == NULL, BOOL);
	}

PWND FARPUBLIC
PwndGetTopWindow(pwnd)
PWND	pwnd;
	{
	StartPublic();
	while (pwnd->pwndSibling != NULL)
		pwnd = pwnd->pwndSibling;
	ReturnPublic(pwnd, PWND);
	}

VOID FARPUBLIC
AddChildTail(pwndParent, pwndChild)
PWND pwndParent, pwndChild;
/*
  -- add child to tail of child list
*/
	{
	StartPublic();
	PWND pwndCur, pwndPrev;

	Assert(pwndParent != NULL && pwndChild != NULL);

	if ((pwndPrev = pwndParent->pwndChild) == NULL)
		pwndParent->pwndChild = pwndChild;
	else
		{
		while ((pwndCur = pwndPrev->pwndSibling) != NULL)
			pwndPrev = pwndCur;
		pwndPrev->pwndSibling = pwndChild;
		}
	pwndChild->pwndParent = pwndParent;
	if (pwndParent->style & WS_CLIPOUT)
		{
		pwndChild->style |= WS_CLIPOUT;
		ClipoutWindowAndSiblings(pwndChild->pwndChild);
		}
	StopPublic();
	}


VOID FARPRIVATE
DrawThisWndProc(pwnd)
REGISTER PWND pwnd;
/*
  -- sets the current window for clipping purposes
  -- NULL means no overlap clipping
*/
	{
	if (!(pwnd->style & WS_CLIPOUT) || !(psOverlap))
		{
		/* window isn't clipout type or there is no overlap table */
		pwndCur = NULL;
		return;
		}
	pwndCur = pwnd;
	}
	


STATIC VOID
ThinkWindowAndSiblings(pwnd)
REGISTER PWND pwnd;
/*
  -- fills the overlap table for pwnd and its children
  -- the overlap table is an array that maps screen positions onto the
	window that is in the foreground at a given position
  -- this is accomplished by walking through the tree and filling the
	table for each window.  hence the window that is lower in the
	tree has higher priority and overwrites window that are higher.
*/
	{
	while (pwnd != NULL)
		{
		WORD	off;			/* pointer to array position */
		AY	ay;
		ARC	arc;
		WORD	cwRow;			/* Count of words in each row */

		if ((pwnd->pwndParent != NULL) && (pwnd->style & WS_CLIPOUT))
			{
			if ((pwnd->style & WS_TYPE) == WS_SCROLL)
				{
				Assert(pwnd->pwndParent->pwndParent != NULL);
				IntersectRect((PRRC) &arc,
					 (PRRC) &pwnd->arcWindow, (PRRC)
				    &pwnd->pwndParent->pwndParent->arcClipping);
				}
			else
				{
				IntersectRect((PRRC) &arc,
					(PRRC) &pwnd->arcWindow,
					(PRRC) &pwnd->pwndParent->arcClipping);
				}
			}
		else
			arc = pwnd->arcWindow;

		off = (arc.ayTop * axMac + arc.axLeft) * sizeof(PWND);
		cwRow = arc.axRight - arc.axLeft;

		if (cwRow != 0)
			{
			/* Now simply work through each row */
			for (ay = arc.ayTop; ay < arc.ayBottom; ay++)
				{
				Assert(sizeof(PWND) == sizeof(WORD));
				/* otherwise this won't work */
				MemSetW(psOverlap, off,(WORD)pwnd,cwRow);
				off += axMac * sizeof(PWND);
				}
			}
		ThinkWindowAndSiblings(pwnd->pwndChild);
		pwnd = pwnd->pwndSibling;
		}
	}




VOID FARPUBLIC
RethinkDisplay()
/*
  -- recalculate overlap table
*/
	{
	StartPublic();

	/* first fill in base windows */
	if (psOverlap != 0)
		MemSetW(psOverlap, 0, NULL, axMac * ayMac);

	ThinkWindowAndSiblings(pwndRoot);

	StopPublic();
	}


VOID FARPUBLIC
RedrawDamagedRegions()
/*
  -- This function will redraw only the damaged regions of the screen
  -- Especially after a window has been moved/Deleted/ etc.
*/
	{
	StartPublic();

#ifdef LATER
    -- Put optimizer in here
#endif /* LATER */

	RethinkDisplay();   /* For now just rethink display on draw */
	DrawWindow(NULL);   /* All windows */

	StopPublic();
	}


VOID FARPUBLIC
DrawOverlapShadow(pwnd)
PWND	pwnd;
/*
  -- does a shadow for an overlapping window
*/
	{
	StartPublic();
	AX	daxShadowSave = daxShadow;

	Assert(pwnd->pwndParent != NULL);

	pwndClip = pwnd->pwndParent;
	DrawThisWnd(pwnd->pwndParent);
	ShadowArc(&pwnd->arcWindow);
	daxShadow /= 2;
	DrawThisWnd(NULL);
	ShadowArc(&pwnd->arcWindow);
	daxShadow = daxShadowSave;
	pwndClip = NULL;

	StopPublic();
	}


BOOL FARPUBLIC
FWindowToTop(pwnd)
PWND pwnd;
/*
  -- bring window to tail of child list
*/
	{
	StartPublic();
	PWND pwndParent = pwnd->pwndParent;
	PWND pwndOldTop = PwndGetTopWindow(pwnd);

	Assert(pwndParent != NULL && pwnd != NULL);

	if(SendMessage( pwndOldTop, WM_ACTIVATE, FALSE, 0L))
		{
		if(SendMessage(pwnd, WM_ACTIVATE, TRUE, 0L))
			{
			RemoveChild(pwnd);
			AddChildTail(pwndParent, pwnd);
			ThinkWindowAndSiblings(pwndOldTop);
			DrawWindow(pwndOldTop);
			DrawWindow(pwnd);
			UpdateCursor();
			ReturnPublic(TRUE,BOOL);
			}
		}

	ReturnPublic(FALSE,BOOL);
	}





BOOL FARPUBLIC
FMoveSizeWithKeyboard(pwnd,fMove)
PWND	pwnd;
BOOL	fMove;		/* true move false size */
/*
  -- Moves or sizes the window with the cursor
*/
	{
	StartPublic();
	MSG	msg;
	PWND	pwndRootOld = pwndRoot;
	PWND	pwndFocusOld = pwndFocus;
	PWND	pwndCaptureOld = pwndCapture;
	PFFN_FILTER	pfnFilterOld = pfnFilter;

	AssertSz(((pwnd->style & WS_CLIPOUT) && (pwnd->style & WS_OVERLAP)),
			"can only move overlap windows");

	Assert(!fDragging);

	if (!FIsTopWindow(pwnd))
		{
		if (!FWindowToTop(pwnd))
			ReturnPublic(FALSE,BOOL);
		}

	if (fMove)
		owds.owdf = owdfKeyboardMove;
	else
		owds.owdf = owdfKeyboardSize;

	owds.pwndMoving = pwnd;
	owds.pwndBackground = pwnd->pwndParent;

	if (!FAllocDragSave()) ReturnPublic(FALSE,BOOL);

	InitDragRrc(pwnd);
	fDragging = TRUE;	/* we are dragging and owds is valid */
	SaveDragRrc();
	DisplayDrag();

	pfnFilter = DummyFilter;
	pwndRoot = NULL;	/* set stuff to null so mouse input 
				   doesn't muck us up */
	pwndFocus = NULL;
	pwndCapture = NULL;
	UpdateCursor();

	/* we don't return control to the application until we're
	   done dragging */

	while(fDragging)
		{
		PollKeyboard();

		while (PeekMessage(&msg))
			DispatchMessage(&msg);
		}

	pfnFilter = pfnFilterOld;
	pwndRoot = pwndRootOld;
	pwndFocus = pwndFocusOld;
	pwndCapture = pwndCaptureOld;

	EndDrag();

	if (owds.owdf.fEscapeMove)
		{
		owds.owdf.fEscapeMove = 0;
		ReturnPublic(FALSE,BOOL);
		}

	UpdateCursor();
	ReturnPublic(TRUE,BOOL);
	}



BOOL PASCAL
OverlapFilter(pmsg)
PMSG	pmsg;
/*
  -- Does handling for overlapping windows
*/
	{
	AX		ax;		/* The Abs position of event */
	AY		ay;		/* The Abs position of event */
	short		iZoneX,iZoneY;	/* Location inside the window */
	PWND		pwnd = pmsg->pwnd;

	ax = LOBYTE(HIWORD(pmsg->lParam));        /* Get x, y position */
	ay = HIBYTE (HIWORD(pmsg->lParam));

	switch (pmsg->message)
		{
	case WM_LBUTTONDOWN:
		if (fDragging)
			return(FALSE);
		if (!(pwnd->style & WS_CLIPOUT))
			return(FALSE);

			/*
			 * find the overlapping window that we have
			 * clicked upon and then bring it to the top
			 * if it is not already there
			*/
			{
			PWND	pwndNewTop;

			pwndNewTop = pwnd;
			while (!(pwndNewTop->style & WS_OVERLAP)
					&&(pwndNewTop != NULL))
				pwndNewTop = pwndNewTop->pwndParent;
			if ((pwndNewTop == NULL) || (!pwndNewTop->fEnabled))
				 return(FALSE);
			if (!FIsTopWindow(pwndNewTop))
				{
				if (!FWindowToTop(pwndNewTop)) return(FALSE);
				}
			}

		if (!(pwnd->style & WS_OVERLAP))
			return(FALSE);

		/* (iZoneY * 3 + iZoneX) yields:
		 *  0 - Top left corner		*  1 - Top side

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -