magic/graphics/grLock.c

217 lines
6.3 KiB
C

/* grLock.c -
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*
* This file contains information related to the locking of windows.
* Windows are locked before any redisplay is done in them, and then
* unlocked afterwards. The procedures grSimpleLock and grSimpleUnlock
* are provided for device drivers that want to ingore the locking stuff --
* they can just point GrLockPtr and GrUnlockPtr to them. More sophisticated
* drivers (such as for the Sun 160) will want to do some of their own
* locking themselves.
*
* Locking sets up a clipping region (grCurClip and grCurObscure) that is
* used by the graphics drawing routines to clip things being displayed.
* It is an error to draw stuff without locking a window first, and device
* drivers should check for this case by using the macro GR_CHECK_LOCK().
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/graphics/grLock.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "windows/windows.h"
#include "graphics/graphics.h"
#include "textio/textio.h"
MagWindow *grLockedWindow = NULL; /* The window that we are redisplaying */
bool grLockScreen = FALSE; /* Full screen access? */
bool grTraceLocks = FALSE; /* For debugging */
bool grLockBorder; /* Redrawing the border of the window too? */
Rect grCurClip; /* Clip all output to this rectangle */
LinkedRect * grCurObscure; /* A list of obscuring areas */
/*
* ----------------------------------------------------------------------------
* grWindName --
*
* Return a string describing the window, either the window caption,
* or "NULL" for a null MagWindow pointer, or "FULL_SCREEN" when
* w is set to GR_LOCK_SCREEN.
*
* Results:
* A string representing the window or window caption
*
* Side effects:
* None.
* ----------------------------------------------------------------------------
*/
static char *
grWindName(w)
MagWindow *w;
{
if (w == NULL) return "<NULL>";
if (w == GR_LOCK_SCREEN) return "<FULL-SCREEN>";
return w->w_caption;
}
/*
* ----------------------------------------------------------------------------
* grSimpleLock & grSimpleUnlock --
*
* Handy procedures for device drivers.
*
* Lock a window so that we may safely write to it. Locking is
* required before any operation that may modify the window's pixels.
* Locking is slow and should be done around large blocks of code.
*
* Only one window may be locked at a time.
*
* Results:
* None.
*
* Side effects:
* Stores away the window and clipping info.
* ----------------------------------------------------------------------------
*/
void
grSimpleLock(w, inside)
MagWindow *w; /* The window to lock, or GR_LOCK_SCREEN if the
* whole screen.
*/
bool inside; /* If TRUE, clip to inside of window, otherwise clip
* to outside of window.
*/
{
ASSERT(w != NULL, "grSimpleLock");
grLockScreen = (w == GR_LOCK_SCREEN);
if (grTraceLocks) TxError("--- Lock %s\n", grWindName(w));
if (grLockScreen) {
grCurClip = GrScreenRect;
grCurObscure = NULL;
} else {
if (grLockedWindow != NULL) {
TxError("Magic error: Attempt to lock more than one window!\n");
TxError("Currently locked window is: '%s'\n",
grWindName(grLockedWindow));
TxError("Window to be locked is: '%s'\n", grWindName(w));
/* dump core here */
ASSERT(grLockedWindow == NULL, "grSimpleUnlock");
}
if (inside)
grCurClip = w->w_screenArea;
else
grCurClip = w->w_allArea;
grCurObscure = w->w_clipAgainst;
}
grLockBorder = !inside;
grLockedWindow = w;
GeoClip(&grCurClip, &GrScreenRect);
}
void
grSimpleUnlock(w)
MagWindow *w;
{
ASSERT(w != NULL, "grSimpleUnlock");
if (grTraceLocks) TxError("--- Unlock %s\n", grWindName(w));
if (w != grLockedWindow) {
TxError("Magic error: Attempt to unlock a window that wasn't locked\n");
TxError("Currently locked window is: '%s'\n",
grWindName(grLockedWindow));
TxError("Window to be unlocked is: '%s'\n", grWindName(w));
/* dump core here */
ASSERT(w == grLockedWindow, "grSimpleUnlock");
}
grLockedWindow = NULL;
grLockScreen = FALSE;
}
/*
* ----------------------------------------------------------------------------
* GrClipTo
*
* Further restrict the clipping area to a portion of a window.
*
* Results:
* None.
*
* Side effects:
* None.
* ----------------------------------------------------------------------------
*/
void
GrClipTo(r)
Rect *r;
{
if (grLockedWindow == NULL) return;
if (grLockScreen)
grCurClip = GrScreenRect;
else if (grLockBorder)
grCurClip = grLockedWindow->w_allArea;
else
grCurClip = grLockedWindow->w_screenArea;
GeoClip(&grCurClip, r);
GeoClip(&grCurClip, &GrScreenRect);
}
/*
* ----------------------------------------------------------------------------
* grNoLock
*
* We have encountered a bad lock.
*
* Results:
* None.
*
* Side effects:
* Complains or aborts.
* ----------------------------------------------------------------------------
*/
void
grNoLock()
{
TxError("Magic error: Attempt to draw graphics without a window lock.\n");
/*** ASSERT(FALSE, "grNoLock"); ***/
}
/*
* ----------------------------------------------------------------------------
* GrHaveLock()
*
* Do we have a window lock?
*
* Results:
* boolean.
*
* Side effects:
* none.
* ----------------------------------------------------------------------------
*/
bool
GrHaveLock()
{
return (grLockedWindow != NULL);
}