mirror of https://github.com/lianthony/NT4.0
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.
424 lines
8.2 KiB
424 lines
8.2 KiB
/*
|
|
Enhanced NCSA Mosaic from Spyglass
|
|
"Guitar"
|
|
|
|
Copyright 1994 Spyglass, Inc.
|
|
All Rights Reserved
|
|
|
|
Author(s):
|
|
Jeff Hostetler [email protected]
|
|
Jim Seidman [email protected]
|
|
*/
|
|
|
|
/* w32wait.c -- code to manage WaitState while we're busy. */
|
|
|
|
#include "all.h"
|
|
#ifdef FEATURE_IAPI
|
|
#include "w32dde.h"
|
|
#endif
|
|
|
|
static int gPushCount = 0;
|
|
static int bWaitLock = FALSE; // TRUE if we're disallowing updates
|
|
|
|
void WAIT_SetStopButton(struct Mwin * tw, HWND hWndStop)
|
|
{
|
|
if (!tw)
|
|
return;
|
|
|
|
tw->hWndStop = hWndStop;
|
|
|
|
return;
|
|
}
|
|
|
|
static unsigned long x_ScaleTerm(struct AsyncWaitInfo * awi, unsigned long x)
|
|
{
|
|
if (!awi)
|
|
return 0;
|
|
|
|
XX_DMsg(DBG_WAIT, ("x_ScaleTerm: nThermStart=%d nThermEnd=%d x=%d nScalingDenominator=%d\n",
|
|
awi->nThermStart, awi->nThermEnd, x, awi->nScalingDenominator));
|
|
|
|
return ( awi->nThermStart
|
|
+ ( (awi->nThermEnd - awi->nThermStart)
|
|
* x
|
|
/ awi->nScalingDenominator));
|
|
}
|
|
|
|
static void x_SetRange(struct Mwin * tw, int nThermStart, int nThermEnd, int nScalingDenominator)
|
|
{
|
|
struct AsyncWaitInfo * awi;
|
|
struct AsyncWaitInfo * awiPrev;
|
|
|
|
/* we allow caller to define a range within our thermometer (0 to 25%,
|
|
for example) and a scaling term (nr of iterations thru loop, for example).
|
|
subsequent calls to ComeUpForAir will be scaled into this range. */
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_SetRange: %d %d %d\n", nThermStart, nThermEnd, nScalingDenominator));
|
|
|
|
if (!tw || !tw->awi)
|
|
return;
|
|
|
|
awi = tw->awi;
|
|
awiPrev = awi->prev;
|
|
|
|
awi->nThermStart = nThermStart;
|
|
if (awi->nThermStart < 0)
|
|
awi->nThermStart = 0;
|
|
else if (awi->nThermStart > 99)
|
|
awi->nThermStart = 99;
|
|
if (awiPrev)
|
|
awi->nThermStart = x_ScaleTerm(awiPrev,awi->nThermStart);
|
|
|
|
awi->nThermEnd = nThermEnd;
|
|
if ( (awi->nThermEnd < awi->nThermStart)
|
|
|| (awi->nThermEnd > 100))
|
|
awi->nThermEnd = 100;
|
|
#if 0 /* I removed this. EWS */
|
|
if (awiPrev)
|
|
awi->nThermEnd = x_ScaleTerm(awiPrev,awi->nThermEnd);
|
|
#endif
|
|
|
|
awi->nScalingDenominator = nScalingDenominator;
|
|
if (awi->nScalingDenominator == 0)
|
|
awi->nScalingDenominator = 1;
|
|
|
|
awi->nLastScalingNumerator = 0;
|
|
|
|
XX_DMsg(DBG_WAIT, ("nThermEnd=%d awi->nThermEnd=%d\n", nThermEnd, awi->nThermEnd));
|
|
|
|
return;
|
|
}
|
|
|
|
void WAIT_SetRange(struct Mwin * tw, int nThermStart, int nThermEnd, int nScalingDenominator)
|
|
{
|
|
if (!tw || !tw->awi)
|
|
return;
|
|
|
|
x_SetRange(tw,nThermStart,nThermEnd,nScalingDenominator);
|
|
UpdateThermometer(tw,x_ScaleTerm(tw->awi,tw->awi->nLastScalingNumerator));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
static void x_fixup_status(struct Mwin * tw)
|
|
{
|
|
if (!tw || !tw->awi)
|
|
{
|
|
/* turn off stuff */
|
|
|
|
UpdateThermometer(tw,-1);
|
|
BHBar_Update(tw);
|
|
|
|
if (tw->hWndStop)
|
|
TW_EnableButton(tw->hWndStop, FALSE);
|
|
|
|
TBar_SetGlobe(tw,FALSE);
|
|
}
|
|
else
|
|
{
|
|
/* turn on stuff */
|
|
|
|
UpdateThermometer(tw,x_ScaleTerm(tw->awi,tw->awi->nLastScalingNumerator));
|
|
if (tw->awi->ewt < waitNoInteract)
|
|
{
|
|
BHBar_Update(tw);
|
|
}
|
|
else
|
|
{
|
|
/* If we've gone into a non-interaction state, the previous
|
|
transient message must be invalid */
|
|
BHBar_SetStatusField(tw, "");
|
|
}
|
|
|
|
if (tw->hWndStop)
|
|
TW_EnableButton(tw->hWndStop, TRUE);
|
|
|
|
TBar_SetGlobe(tw,TRUE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void WAIT_Push(struct Mwin * tw, enum WaitType ewt, unsigned char * szMessage)
|
|
{
|
|
struct AsyncWaitInfo * awi;
|
|
|
|
#if 1 /* TODO fix me */
|
|
if (!tw)
|
|
{
|
|
XX_DMsg(DBG_WAIT, ("WAIT_Push: no tw\n"));
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_Push: '%s' (type %d)\n", szMessage, ewt));
|
|
|
|
/* If progress app has been specified in the tw structure, use DDE */
|
|
|
|
#ifdef FEATURE_IAPI
|
|
if (tw->szProgressApp[0] && (gPushCount == 0))
|
|
{
|
|
DDE_Issue_BeginProgress(tw->szProgressApp, szMessage);
|
|
DDE_Issue_SetProgressRange(tw->szProgressApp, 100);
|
|
}
|
|
#endif
|
|
|
|
gPushCount++;
|
|
|
|
awi = GTR_CALLOC(1,sizeof(struct AsyncWaitInfo));
|
|
if (!awi)
|
|
return;
|
|
|
|
/* if message given, use it. otherwise, use previous stack frames's message. */
|
|
|
|
if (!szMessage)
|
|
if (tw->awi && tw->awi->message)
|
|
szMessage = tw->awi->message;
|
|
if ( szMessage )
|
|
awi->message = GTR_MALLOC(strlen(szMessage)+1);
|
|
if (!awi->message)
|
|
{
|
|
GTR_FREE(awi);
|
|
return;
|
|
}
|
|
strcpy(awi->message,szMessage);
|
|
|
|
if (ewt == waitSameInteract)
|
|
{
|
|
if (tw->awi)
|
|
ewt = tw->awi->ewt;
|
|
else
|
|
ewt = waitFullInteract; /* same, but no previous */
|
|
}
|
|
else
|
|
{
|
|
if (tw->awi)
|
|
{
|
|
if (ewt < tw->awi->ewt)
|
|
{
|
|
XX_DMsg(DBG_WAIT, ("WAIT_Push: nested wait states must be more restrictive - changing to %d.", tw->awi->ewt));
|
|
ewt = tw->awi->ewt;
|
|
}
|
|
}
|
|
}
|
|
|
|
awi->ewt = ewt;
|
|
|
|
awi->prev = tw->awi;
|
|
tw->awi = awi;
|
|
|
|
if ( !awi->prev || (awi->prev->ewt != tw->awi->ewt) )
|
|
TBar_UpdateTBItems( tw );
|
|
|
|
#if 0
|
|
if (!awi->prev)
|
|
TBar_UpdateTBar(tw);
|
|
#endif
|
|
|
|
x_SetRange(tw,0,100,1);
|
|
TW_ForceHitTest(tw);
|
|
x_fixup_status(tw);
|
|
|
|
return;
|
|
}
|
|
|
|
void WAIT_Lock( BOOL bLock )
|
|
{
|
|
bWaitLock = bLock;
|
|
}
|
|
|
|
void WAIT_SetStatusBarIcon( struct Mwin * tw, enum StatusBarIconType StatusBarIcon )
|
|
{
|
|
if ( tw && tw->awi )
|
|
{
|
|
tw->awi->StatusBarIcon = StatusBarIcon;
|
|
BHBar_Update(tw);
|
|
}
|
|
}
|
|
|
|
BOOL WAIT_Pop(struct Mwin * tw)
|
|
{
|
|
struct AsyncWaitInfo * prev;
|
|
enum WaitType old_ewt;
|
|
|
|
if (!tw || !tw->awi)
|
|
{
|
|
XX_DMsg(DBG_WAIT, ("WAIT_Pop: no awi to pop\n"));
|
|
return( FALSE );
|
|
}
|
|
|
|
gPushCount--;
|
|
|
|
#ifdef FEATURE_IAPI
|
|
if (tw->szProgressApp[0] && (gPushCount == 0))
|
|
{
|
|
DDE_Issue_EndProgress(tw->szProgressApp);
|
|
tw->szProgressApp[0] = '\0';
|
|
}
|
|
#endif
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_Pop: '%s' (type %d)\n", tw->awi->message, tw->awi->ewt));
|
|
|
|
if (tw->awi->message)
|
|
GTR_FREE(tw->awi->message);
|
|
|
|
old_ewt = tw->awi->ewt;
|
|
prev = tw->awi->prev;
|
|
GTR_FREE(tw->awi);
|
|
tw->awi = prev;
|
|
|
|
if ( !tw->awi || (old_ewt != tw->awi->ewt) )
|
|
TBar_UpdateTBItems(tw);
|
|
|
|
#if 0
|
|
if (!tw->awi)
|
|
TBar_UpdateTBar(tw);
|
|
#endif
|
|
|
|
TW_ForceHitTest(tw);
|
|
x_fixup_status(tw);
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
void WAIT_Update(struct Mwin * tw, enum WaitType ewt, unsigned char * message)
|
|
{
|
|
if (!tw || !tw->awi)
|
|
return;
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_UpdateMessage: updating to '%s' (type %d)\n", message, ewt));
|
|
|
|
if ( bWaitLock )
|
|
{
|
|
XX_DMsg(DBG_WAIT, ("WAIT_UpdateMessage: Returning do to lock"));
|
|
return;
|
|
}
|
|
|
|
if (strlen(message) > strlen(tw->awi->message))
|
|
{
|
|
GTR_FREE(tw->awi->message);
|
|
tw->awi->message = GTR_MALLOC(strlen(message) + 1);
|
|
}
|
|
strcpy(tw->awi->message, message);
|
|
|
|
BHBar_Update(tw);
|
|
|
|
if (ewt != waitSameInteract)
|
|
{
|
|
enum WaitType old_ewt = tw->awi->ewt;
|
|
|
|
tw->awi->ewt = ewt;
|
|
if ( old_ewt != tw->awi->ewt )
|
|
TBar_UpdateTBItems(tw);
|
|
}
|
|
|
|
if (tw->awi->ewt < waitNoInteract)
|
|
{
|
|
TW_ForceHitTest(tw);
|
|
}
|
|
else
|
|
{
|
|
/* If we've gone into a non-interaction state, the previous
|
|
transient message must be invalid */
|
|
|
|
BHBar_SetStatusField(tw, "");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void WAIT_UpdateWaitStack(struct Mwin * tw, enum WaitType ewt, int nFrames)
|
|
{
|
|
struct AsyncWaitInfo * awi;
|
|
enum WaitType old_ewt;
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_UpdateWaitStack: updating %d frames to %d", nFrames, ewt));
|
|
|
|
if (!tw || !tw->awi)
|
|
return;
|
|
|
|
old_ewt = tw->awi->ewt;
|
|
|
|
for (awi=tw->awi; ((awi) && (nFrames)); awi=awi->prev, nFrames--)
|
|
awi->ewt = ewt;
|
|
|
|
|
|
if ( old_ewt != tw->awi->ewt )
|
|
TBar_UpdateTBItems(tw);
|
|
|
|
if (tw->awi->ewt < waitNoInteract)
|
|
{
|
|
BHBar_Update(tw);
|
|
}
|
|
else
|
|
{
|
|
/* If we've gone into a non-interaction state, the previous
|
|
transient message must be invalid */
|
|
BHBar_SetStatusField(tw, "");
|
|
}
|
|
|
|
TW_ForceHitTest(tw);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void WAIT_SetTherm(struct Mwin * tw, int nScalingNumerator)
|
|
{
|
|
int k1,k2;
|
|
|
|
if (!tw || !tw->awi)
|
|
return;
|
|
|
|
if ( tw->awi->nScalingDenominator < 10000 )
|
|
return;
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_SetTherm: updating to '%d (of %d)'\n",
|
|
nScalingNumerator, tw->awi->nScalingDenominator));
|
|
|
|
/* hack -- see if display would be affected */
|
|
|
|
k1 = x_ScaleTerm(tw->awi,tw->awi->nLastScalingNumerator);
|
|
k2 = x_ScaleTerm(tw->awi,nScalingNumerator);
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_SetTherm: k1=%d k2=%d\n", k1, k2));
|
|
|
|
if (k2 > k1)
|
|
{
|
|
/* If progress app has been specified, use DDE */
|
|
|
|
UpdateThermometer(tw,k2);
|
|
|
|
tw->awi->nLastScalingNumerator = nScalingNumerator;
|
|
|
|
XX_DMsg(DBG_WAIT, ("WAIT_SetTherm: DRAW\n"));
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
enum WaitType WAIT_GetWaitType(struct Mwin *tw)
|
|
{
|
|
enum WaitType wtResult;
|
|
|
|
if (!tw || !tw->awi)
|
|
{
|
|
wtResult = waitNotWaiting;
|
|
}
|
|
else
|
|
{
|
|
wtResult = tw->awi->ewt;
|
|
}
|
|
|
|
XX_Assert((wtResult >= waitNotWaiting && wtResult <= waitNoInteract), ("Illegal wait type found: %d", wtResult));
|
|
|
|
return wtResult;
|
|
}
|