Files
msword/src/Opus/wproc.c
T
2026-08-06 13:49:53 -07:00

3634 lines
88 KiB
C

/* W P R O C . C */
#ifdef DEBUG
/*#define SHOWAPPMSG*/
/*#define SHOWDSKMSG*/
/*#define SHOWDOCMSG*/
/*#define SHOWPNEMSG*/
#endif /* DEBUG */
#define RSHDEFS
#define NOVHGDIS
#define NOKEYSTATE
#define NOICON
#define NOBRUSH
#define NOCREATESTRUCT
#define NODRAWTEXT
#define NOMINMAX
#define NOPEN
#define NOREGION
#define NOSOUND
#define NOTEXTMETRIC
#define NOWNDCLASS
#define NOCOMM
#include "word.h"
DEBUGASSERTSZ /* WIN - bogus macro for assert string */
#include "version.h"
#include "heap.h"
#include "layout.h"
#include "file.h"
#define NOIFK
#define USEBCM
#include "cmd.h"
#include "keys.h"
#include "doc.h"
#include "disp.h"
#include "props.h"
#include "sel.h"
#include "screen.h"
#include "print.h"
#include "ch.h"
#include "format.h"
#include "status.h"
#include "wininfo.h"
#include "menu2.h"
#include "dde.h"
#include "help.h"
#include "debug.h"
#include "field.h"
#include "cmdtbl.h"
#include "fkp.h"
#include "prm.h"
#include "prompt.h"
#include "message.h"
#include "idle.h"
#include "error.h"
#include "iconbar.h"
#include "sdmdefs.h"
#include "sdmver.h"
#include "sdm.h"
#include "sdmtmpl.h"
#include "sdmparse.h"
#include "scc.h"
#include "resource.h"
#include "rareflag.h"
#include "recorder.h"
#ifdef DEBUG
#include "rerr.h"
#endif
#define WPROC
#include "core.h"
/* globals */
#ifdef DEBUG
int cHpFreeze = 0;
#endif /* DEBUG */
struct CHP vchpFetch;
struct CHP vchpStc;
struct PAP vpapStc;
struct TAP vtapStc;
struct PAP vpapFetch;
struct SEP vsepFetch;
BOOL vfFliMunged; /* returned from cachepage */
int vised;
int vipgd;
struct CA caPara;
struct CA caPage;
struct CA caSect;
struct CA caTable;
#ifdef OPUS_X64
extern struct FTI vfti;
extern char (**vhgrpchr)[];
extern int vbchrMac;
#endif
extern struct FCB **mpfnhfcb[];
extern int vfnPreload;
extern int vcPreload;
struct CA caTcxCache;
int vdocFetch;
int vdocFetchPic;
CP vcpFetch;
char HUGE *vhpchFetch;
int vccpFetch;
/* signals cpMac reached */
BOOL vfEndFetch;
CP vcpFirstTablePara;
CP vcpFirstTableCell;
/* used to avoid AdjustCp's while inserting from the keyboard */
char rgchInsert[cchInsertMax];
int ichInsert; /* Number of chars used in rgchInsert */
int fnFetch; /* last run was in this fn */
/* fc corresponding to vcpFetch. If fnLast == fnInsert, fc is an index
into rgchInsert, still corresponding to vcpFetch */
FC fcFetch;
int fcmFetch;
int prmFetch; /* prm of ipcdFetch */
int vdocPapLast = docNil;
int vfnPapLast = fnNil;
int vpnPapLast = 0;
int vbpapxPapLast = cbSector + 1;
/* number of cp's remaining in last chp run, piece, page in file */
/* following three quantities must be in order (hand-nat requirement) */
CP ccpChp, ccpPcd;
int ccpFile;
int ipcdFetch; /* index of the piece corresponding to vcpFetch */
int vstcpMapStc; /* last stcp calculated by MapStc */
char rgchCaps[ichCapsMax];
int vfAwfulNoise;
int vssc; /* secondary selection (move, copy, copy looks) mode */
int vfInitializing = TRUE;
int vwwSelect;
/* means idle should normalize to the selection and then reset the flag */
BOOL vfSeeSel;
/* flags are set fTrue when prefix key is encountered. Thus, the next
keystroke is interpreted as part of a 2 key sequence. */
int vgrpfKeyPrefix;
int vxwCursor; /* preferred column for up-down cursor movement */
int flashID = 0; /* timer ID for flashing before we put up a messagebox when we are not the active app */
MSG vmsgLast; /* last message received */
HANDLE vhSysMenu; /* handle to system (toaster) menu */
HWND vhwndApp; /* handle to parent ww (created in
interface module) */
HWND vhwndStartup; /* handle to start up monologue */
HANDLE vhInstance; /* handle to memory module instance */
HMENU vhMenu; /* handle to current top level menu */
HMENU vhMenuLongFull; /* full menu*/
int viMenu = -2; /* current menu number */
CHAR *vpDlgBuf; /* pointer to buffer for dialog boxes */
BOOL vfSingleApp; /* if true, running with runtime windows */
HBRUSH vhbrWhite; /* various brushes used for pattern fills */
HBRUSH vhbrBlack;
HBRUSH vhbrGray;
HBRUSH vhbrLtGray;
HBRUSH vhbrDkGray;
/* bitmaps used for drawing vertical and horizontal lines */
HBITMAP vhbmPatVert;
HBITMAP vhbmPatHorz;
int vfFocus = FALSE; /* Whether we have the input focus */
int vfMouseExist = fFalse; /* fTrue if mouse hardware is installed */
int vfInLongOperation = fFalse; /* fTrue if we are still in a long operation
so that the cursor should stay hourglass */
int vfDeactByOtherApp=fFalse; /* We were deactivated by another app */
HWND vhwndSizeBox; /* handle to the size box */
HWND vhwndMsgBoxParent; /* current parent to use for message boxes */
HWND vhwndDeskTop; /* handle to desktop window, area that contains doc windows */
#ifdef DEBUG
int **vhgdis = hNil;
#endif /* DEBUG */
int vgrpfKeyBoardState = 0; /* current keyboard state */
BOOL vfOvertypeMode = fFalse;
BOOL vfExtendSel = fFalse; /* true if extend to next typed character and survive in search and goto */
BOOL vfBlockSel = fFalse; /* true if in block selection state */
BOOL vfDoubleClick = FALSE; /* whether click is double click */
BOOL vfRightClick = FALSE; /* whether click is right button */
HCURSOR vhcHourGlass; /* handle to hour glass cursor */
HCURSOR vhcIBeam; /* handle to i-beam cursor */
HCURSOR vhcArrow; /* handle to arrow cursor */
HCURSOR vhcBarCur; /* handle to back arrow cursor */
HCURSOR vhcSplit; /* handle to split cursor */
HCURSOR vhcStyWnd; /* handle to style name window cursor */
HCURSOR vhcRecorder;
HCURSOR vhcHelp; /* handle to ? cursor for help */
HCURSOR vhcOtlCross;
HCURSOR vhcOtlHorz;
HCURSOR vhcOtlVert;
HCURSOR vhcColumn;
HCURSOR vhcPrvwCross = NULL;
HICON vhiWord; /* winword icon */
/* This is how we tell if NewCurWw is being called as a result of
returning from a message box mamong other things (we disable
coming back from a messagebox or dialog if we were in a message box
too. They can nest, e.g., at ExitWindows time bz
*/
int vcInMessageBox = 0;
/* USAGE: caAdjust is a temporary CA which can be used by anyone if they
want a caTemp that will be adjusted whenever AdjustCp is called. The
only constraint is that you must call AcquireCaAdjust() before using
it and ReleaseCaAdjust() when you're done, to ensure that noone else
is using it at the time. Actually these are macros that will go away
when DEBUG is undefined, but we should catch these conflicts now.
*/
struct CA caAdjust = {
0, 0, docNil };
struct CA caAdjustL = {
cp0, cp0, docNil };
#ifdef DEBUG
int cCaAdjust = 0;
int cCaAdjustL = 0;
#endif
#ifdef RSH
#ifdef NOASM
NATIVE IScanLprgw( int far *, WORD, int ); /* DECLARATION ONLY */
#endif /* NOASM */
/* this table is used to record sys commands (SC_) in the research version */
csconst int rgscRsh[] =
{
SC_SIZE,
SC_MOVE,
SC_MINIMIZE,
SC_MAXIMIZE,
SC_NEXTWINDOW,
SC_PREVWINDOW,
SC_CLOSE,
SC_VSCROLL,
SC_HSCROLL,
SC_MOUSEMENU,
SC_KEYMENU,
SC_RESTORE
};
#define iscMax sizeof(rgscRsh)/sizeof(int)
/* this table is used to record interesting messages (WM_) in the research version */
csconst int rgwmRsh[] =
{
WM_QUERYENDSESSION,
WM_ENDSESSION,
WM_ACTIVATEAPP,
WM_NCLBUTTONDOWN,
WM_NCRBUTTONDOWN,
WM_NCLBUTTONDBLCLK,
WM_NCRBUTTONDBLCLK,
WM_LBUTTONDOWN,
WM_RBUTTONDOWN,
WM_LBUTTONDBLCLK,
WM_RBUTTONDBLCLK,
WM_CLOSE,
WM_VSCROLL,
WM_HSCROLL
};
#define iwmMax sizeof(rgwmRsh)/sizeof(int)
#endif /* RSH */
extern int vpisPrompt;
extern int flashID;
extern ENV *penvMem;
extern BOOL vfDdeIdle;
extern BOOL vfRecording;
extern BOOL vfRecordNext;
extern CMR **vhcmr;
extern FARPROC vlppFWHChain;
extern int vfInitializing;
extern struct MWD **hmwdCur;
extern int mwCur;
extern int mwMac; /* mac of child window */
extern int wwMac;
extern HMENU vhMenuNoMwd;
extern int vfLargeFrameEMS;
extern HMENU vhMenuShort;
extern HMENU vhMenuWithMwd;
extern struct MWD **mpmwhmwd[];
extern struct SCI vsci;
extern struct PRI vpri;
extern struct FLI vfli;
extern struct PREF vpref;
extern CHAR szApp[];
extern HANDLE vhInstance;
extern HWND vhwndApp; /* handle to parent's window */
extern HWND vhwndDeskTop;
extern HWND vhwndPrompt;
extern HWND vhwndPromptHidden;
extern HWND vhwndRibbon;
extern HWND vhwndCBT;
extern int vcxtHelp; /* help context id */
extern BOOL vfHelp; /* whether we're in Help Mode */
extern long vcmsecHelp;
#ifdef OPUS_X64
extern WPARAM vwParamHelp;
extern LPARAM vlParamHelp;
#else
extern WORD vwParamHelp;
extern LONG vlParamHelp;
#endif
extern HCURSOR vhcHourGlass;
extern HCURSOR vhcIBeam;
extern HCURSOR vhcArrow;
extern HCURSOR vhcBarCur;
extern HCURSOR vhcRecorder;
extern HCURSOR vhcHelp;
extern HCURSOR vhcStyWnd;
extern HMENU vhMenu;
extern HWND vhwndAppModalFocus;
extern HWND vhwndStatLine;
extern BOOL vfExtendSel;
extern struct STTB **vhsttbOpen;
extern BOOL vfBlockSel;
extern MSG vmsgLast;
extern struct WWD **mpwwhwwd[];
extern struct WWD **hwwdCur;
extern int mwCreate;
extern BOOL vfInLongOperation;
extern int wwCur;
extern struct SEL selCur;
extern struct SEL selDotted;
extern int vfDeactByOtherApp;
extern HWND vhwndMsgBoxParent;
extern struct PPR **vhpprPRPrompt;
extern int vlm;
extern int vssc;
extern struct MERR vmerr;
extern int vfFocus;
extern BOOL vfDoubleClick;
extern BOOL vfRightClick;
extern int vfSysMenu;
extern MUD ** vhmudUser;
extern MUD ** vhmudBase;
extern KMP ** vhkmpUser;
extern KMP ** hkmpCur;
extern KMP ** hkmpBase;
extern CP vcpFetch;
extern int vfSeeSel;
extern int vcConseqScroll;
extern int sbScroll;
extern int sbScrollLast;
extern IDF vidf;
extern int cLongOpCount;
extern int vfMouseExist;
extern BOOL fElActive;
extern struct RF vrf;
extern BOOL vfInCommit;
extern int cbMemChunk;
extern struct BPTB vbptbExt;
#ifdef OPUS_X64
extern int vibp;
extern int vibpProtect;
#endif
extern int vgrfMenuKeysAreDirty;
extern BOOL vfEmptyMenu;
BOOL vfChildSysMenu = fFalse;
BOOL fRecordMove=fFalse;
BOOL fRecordSize=fFalse;
BOOL fCdlScrollSet=fFalse;
struct MERR vmerr;
extern BOOL vfRestPmtOnInput;
extern long vusecTimeoutPrompt;
extern int vcchStatLinePrompt;
extern int docCur;
extern struct DRF *vpdrfHead;
extern struct DRF *vpdrfHeadUnused;
extern int vfNoInval;
void MwdVertScroll( int, WORD, int );
void MwdHorzScroll( int, WORD, int );
void WwPaneMouse( int, unsigned, WORD, POINT );
#ifdef OPUS_X64
LRESULT LMenuChar(HWND, WPARAM, LPARAM);
void DrawMenuHelp(HMENU, UINT_PTR, int);
void SaveMenuHelpContext(WPARAM, LPARAM, int);
/*
* Opus used the sign bit of a Win16 WORD-sized int to distinguish its
* command ids from the SC_* values in WM_SYSCOMMAND. A Win64 int is 32
* bits, so casting WPARAM to int makes every SC_* value positive and causes
* Word to swallow window move/size/close commands as application commands.
*/
#define FOpusCommandWParam(wParam) ((short) LOWORD(wParam) >= 0)
#define BcmFromWParam(wParam) ((WORD) LOWORD(wParam))
#define WM_OPUS_X64_QUERY_SELECTION (WM_APP + 0x351)
#else
LONG LMenuChar(HWND, WORD, LONG);
#define FOpusCommandWParam(wParam) ((int) (wParam) >= 0)
#define BcmFromWParam(wParam) (wParam)
#endif
#ifdef DEBUG
ENV *penvBase;
BYTE fCoverWasActive;
#endif /* DEBUG */
#ifdef HYBRID
BOOL vfShowSwapping;
#endif /* HYBRID */
/************************************************************************/
/* WinMain -- Windows' equivalent of "main()" in standard C */
/************************************************************************/
/* %%Function:WinMain %%Owner:peterj */
#ifdef OPUS_X64
EXPORT int PASCAL OpusOriginalWinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
#else
EXPORT int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
#endif
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
int wMsg;
#ifdef DEBUG
ENV env;
extern BYTE fCoverActive;
#endif /* DEBUG */
#ifdef HYBRID
extern BYTE fCoverActive;
#endif
InitApploader();
#ifdef DEBUG
FInitCover(0);
fCoverWasActive = fCoverActive;
fCoverActive = fFalse;
#endif
#ifdef HYBRID
FInitCover(0);
fCoverActive &= GetProfileInt(szApp, SzShared("HybridfCoverActive"), 0);
#endif
/* Initialize our huge pointer info
** IMPORTANT FInitSegTable before GlobalMemInit, else GlobalMemInit may
cause our code being moved and WINDOW does not know that our segment
table has to be updated.
*/
if (!FInitSegTable( sbMax ))
{
ReportSz("FinitSegTable failure");
return fFalse; /* Could not initialize; exit the program */
}
#ifdef DEBUG
/* initialize SetJmp/DoJmp for out of memory errors */
penvBase = &env;
if (SetJmp (penvMem = penvBase))
{
Assert (fFalse);
}
#endif /* DEBUG */
#ifdef HYBRID
vfShowSwapping = GetProfileInt((LPSTR)szApp,
(LPSTR)SzFrameKey("HybridShowSwapping",HybridShowSwapping), 0);
if (vfShowSwapping) InstallInt3FHandler();
#endif /* HYBRID */
/* initialize structures, create initial windows, etc. */
if (!FInitWinInfo( hInstance, hPrevInstance, lpszCmdLine, cmdShow ))
{
CleanUpForExit();
return fFalse; /* Could not initialize; exit the program */
}
for (;;)
{
BOOL fHaveMsg = fFalse;
#ifdef DEBUG
{
extern BOOL vfAllocGuaranteed, vfInCmd, vfInDebug;
extern int vnErrorLevel;
Assert(vfAllocGuaranteed == 0);
vfAllocGuaranteed = 0;
Assert(vfInCmd == 0);
vfInCmd = 0;
Assert(vfInDebug == 0);
vfInDebug = 0;
vnErrorLevel = 0;
}
#endif /* DEBUG */
if (cLongOpCount > 0)
EndLongOp(fTrue);
while (!fHaveMsg)
/* wait for a message */
{
TopOfMainLoop();
/* iconbar dialog uses its own message loop */
if (vidf.fIBDlgMode)
{
Assert (!vidf.fDead);
IBDlgLoop();
}
/* idle if there are not messages ready */
else if (PeekMessage((LPMSG)&vmsgLast, NULL, NULL, NULL, PM_REMOVE))
/* we have a message */
fHaveMsg = fTrue;
else
{
BOOL fYield = fFalse;
if (!vfDeactByOtherApp && !vidf.fNotLive)
/* Neither an icon nor a dying ember -- perform background
tasks like screen update, showing selection, etc. */
fYield = !FIdle(); /* true if interrupted */
/* perform background DDE processes, if any (esp when deact, icon or dead) */
else if (vfDdeIdle)
DoDdeIdle ();
else
WaitMessage();
if (vmerr.mat == matFont || vmerr.mat == matDisp)
FlushPendingAlerts();
vmerr.mat = matNil;/* don't report errors in bkgnd processes */
vmerr.fHadMemAlert = fFalse;/* in case we already did */
if (fYield)
Yield();
}
}
if ((wMsg = vmsgLast.message) == WM_QUIT)
{
QuitExit();
Assert( fFalse );
}
/* If the prompt line wants to be cleared on input, vfRestPmtOnInput is
set. */
if (vfRestPmtOnInput && ((wMsg == WM_SYSCOMMAND)||
(wMsg == WM_KEYDOWN) ||
(wMsg == WM_LBUTTONDOWN) || (wMsg == WM_RBUTTONDOWN)
|| (wMsg == WM_COMMAND)))
{
BOOL fMsgForPrompt = vmsgLast.hwnd == vhwndPrompt;
RestorePrompt();
/* if the message was destined for the prompt and the prompt was
destroyed by RestorePrompt, don't try to send it on! */
fHaveMsg = !fMsgForPrompt || vhwndPrompt != NULL;
}
if (fHaveMsg)
{
/* keyboard processing */
if (!FIsKeyMessage((LPMSG) &vmsgLast))
{
/* messages not fully processed */
DispatchMessage((LPMSG)&vmsgLast);
}
if (vfChildSysMenu)
{
Assert(!vfSysMenu);
if (hwwdCur != hNil)
{
SendMessage((*hwwdCur)->hwnd, WM_SYSCOMMAND,
SC_KEYMENU, (DWORD) '-');
}
vfChildSysMenu = fFalse;
}
}
/* This means we got a WM_CBTTERM from CBT and waited to clean up
until they are no longer on our stack (since we free their
library as part of our cleanup) */
if (vrf.fMustStopCBT && !vfDeactByOtherApp)
{
StopCBT();
vrf.fMustStopCBT = fFalse;
}
} /* for (;;) */
Assert( fFalse );
}
/* performes standard actions between all commands */
/* %%Function:TopOfMainLoop %%Owner:peterj */
TopOfMainLoop()
{
int ww;
Assert (vfNoInval == 0);
vfNoInval = 0;
Assert (vpdrfHead == NULL);
vpdrfHead = NULL;
Assert (vpdrfHeadUnused == NULL);
Debug(vpdrfHeadUnused = NULL);
if (vidf.fDead)
return;
if (vmerr.fKillRulRib) /* take down before messages appear */
EndIbdlg();
if (vmerr.mat != matNil && !vidf.fNotLive)
FlushPendingAlerts();
/* if set, we should have had a mat set, so Flush... should have cleared this. bz */
Assert (vmerr.fHadMemAlert == fFalse || vidf.fNotLive);
vmerr.fHadMemAlert = fFalse;
vmerr.fErrorAlert = fFalse;
vmerr.fDiskAlert = fFalse;
vmerr.fDiskWriteErr = fFalse;
vmerr.fFmtFailed = fFalse;
vmerr.fCompressFailed = fFalse;
/* some document has overflown size we are capable of saving */
if (vmerr.fWarnDocTooBig)
{
ErrorEid(eidDocTooBigToSave, "WinMain");
vmerr.fWarnDocTooBig = fFalse;
}
/* if a nestable progress report was left active, deactivate it */
if (vhpprPRPrompt)
StopProgressReport(hNil, pdcRestore);
/* make sure no AbortChecks were left active */
Assert(vpisPrompt == pisNormal);
vpisPrompt = pisNormal;
/* check for no-dr case which will want to bag windows out of PageView */
if (vmerr.fNoDrs)
UpdateAllWws(fFalse);
Assert(cHpFreeze==0);
if (vmerr.hrgwEmerg3 == 0)
vmerr.hrgwEmerg3 = HAllocateCw(cwEmerg3);
if (vmerr.hrgwEmerg2 == 0)
vmerr.hrgwEmerg2 = HAllocateCw(cwEmerg2);
if (vmerr.hrgwEmerg1 == 0)
vmerr.hrgwEmerg1 = HAllocateCw(cwEmerg1);
vmerr.mat = matNil; /* Do not report errors from above allocations */
/* if we're in a memory emergency, pop all ww's out of page view */
if (vmerr.hrgwEmerg1 ==0 || vmerr.hrgwEmerg2 == 0 || vmerr.hrgwEmerg3 == 0)
{
for (ww = wwDocMin; ww < wwMac; ww++)
if (mpwwhwwd[ww] != hNil && PwwdWw(ww)->fPageView)
{
if (ww == wwCur)
/* go through FExecCmd so that special modes get terminated.
Undo, repeat, recording are also taken care of. FLegalBcm
will allow PageView if current window is already in page view */
FExecCmd(bcmPageView);
else
CmdPageViewOff(ww);
}
}
for (ww = wwDocMin; ww < wwMac; ww++)
{
struct WWD *pwwd;
if (mpwwhwwd[ww] !=hNil && (pwwd = PwwdWw(ww))->fOutline &&
PdodDoc(PmwdWw(ww)->doc)->hplcpad == hNil)
{
/* For various reasons, we do not restore
rulers in this case. */
pwwd->fHadRuler = fFalse;
FToggleOutline(ww);
}
}
/* from printer change message */
if (vrf.fCkPgMarg)
{
SetFlm( flmRepaginate );
FCheckPageAndMargins(selCur.doc, fTrue, fFalse, NULL);
vrf.fCkPgMarg = fFalse;
}
/* handle postponed system messages (from print, pictures) */
if (vpri.wmm)
CheckEnvPending();
/* close any files on floppies so we are not hosed if the user
removes/changes floppies */
CloseEveryFn(fFalse);
}
/* FInitWinInfo - initialise the world, this routine simply calls two
* other initialisation routines making sure their code modules get
* swapped out after use. It is reason for being (rather than have the
* code in line in WinMain, is to declare the command line buffers shared
* between FInitPart1 and FInitPart2.
*/
/* %%Function:FInitWinInfo %%Owner:peterj */
int FInitWinInfo( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
int ipchArgMac;
BOOL fOpenUntitled = fTrue;
BOOL fTutorial = fFalse;
CHAR rgchCmdLine [ichMaxCmdLine+1];
CHAR *rgpchArg [ipchArgMax];
extern int far pascal initwin_q();
extern int far pascal init2_q();
if (!FInitPart1( hInstance, hPrevInstance, lpszCmdLine,
rgchCmdLine, rgpchArg, &ipchArgMac, &fOpenUntitled, &fTutorial))
return fFalse;
/* get it out of memory */
#ifndef OPUS_X64
GlobalDiscard(GetCodeHandle((FARPROC)initwin_q));
#endif
if (!FInitPart2(cmdShow, rgchCmdLine, rgpchArg, ipchArgMac, fOpenUntitled, fTutorial))
return fFalse;
/* get it out of memory */
#ifndef OPUS_X64
GlobalDiscard(GetCodeHandle((FARPROC)init2_q));
#endif
return fTrue;
}
/* NOTE: Messages bound for this WndProc are filtered in wprocn.asm */
/* %%Function:AppWndProc %%Owner:peterj */
#ifdef OPUS_X64
LRESULT CALLBACK AppWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#else
long EXPORT FAR PASCAL AppWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
#endif
{
static int fEnteredIdle=fTrue;
static HMENU hMenu;
#ifdef OPUS_X64
static UINT_PTR bcm;
#else
static int bcm;
#endif
static int mf;
int cxt;
#ifdef OPUS_X64
LRESULT AppWndProcRare(HWND, UINT, WPARAM, LPARAM);
LRESULT AppWndProcAct(HWND, UINT, WPARAM, LPARAM);
#else
long AppWndProcRare();
long AppWndProcAct();
#endif
struct RC rc;
#ifdef SHOWAPPMSG
ShowMsg ("ap", hwnd, message, wParam, lParam);
#endif /* SHOWAPPMSG */
#ifdef RSH
/* BLOCK - log message */
{
int iwm = IScanLprgw((int far *)rgwmRsh,message,iwmMax);
if (iwm >= 0 && iwm < iwmMax)
LogUa(uaAppMessage+iwm);
}
#endif /* RSH */
switch (message)
{
default:
return AppWndProcRare( hwnd, message, wParam,lParam );
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
return AppWndProcAct( hwnd, message, wParam,lParam );
case WM_MOUSEACTIVATE:
/* this keeps us from beeping unnecessarly when the application
is reactivated by a mouse click if a window is app modal */
if (vhwndAppModalFocus != hNil && vfDeactByOtherApp)
return (LONG) MA_ACTIVATEANDEAT;
else
goto LDefProc;
case WM_COMMAND:
/* Ignore command messages posted while in a message box (this
can happen when our app is activated by clicking on an icon
bar button while a message box is waiting to come up). BAC */
if (vcInMessageBox)
return 0L;
/* CBT hook must be the first thing we do under WM_COMMAND */
if (vhwndCBT && !SendMessage(vhwndCBT, WM_CBTSEMEV, smvCommand,
MAKELONG(CxtFromBcm(BcmFromWParam(wParam)), 0 /* from menu */)))
{
return (0L);
}
/* CBT returned TRUE; do normal handling */
EnsureFocusInPane();
SetOurKeyState(); /* we don't get a key-up for Alt! */
/* dyadic stuff handled at command level now */
RestorePrompt();
if (BcmFromWParam(wParam) == bcmNil) /* menu empty */
return (0L);
Assert(FOpusCommandWParam(wParam));
vcxtHelp = cxtNil;
FExecCmd(BcmFromWParam(wParam));
break;
case WM_SYSCOMMAND:
#ifdef RSH
/* BLOCK - log command */
{
int isc = IScanLprgw((int far *)rgscRsh,wParam,iscMax);
if (isc >= 0 && isc < iscMax)
LogUa(uaAppCommand+isc);
}
#endif /* RSH */
if (vfHelp || vhwndCBT)
cxt = CxtAppSysMenu(wParam);
/* Must notify CBT before processing the message */
/* undocumented Windows fact: wParam & 0x000F is non-zero if
WM_SYSCOMMAND was generated from clicking in title bar or
sizing borders, and zero otherwise */
if (vhwndCBT && (!(wParam & 0x000F) || wParam == bcmControlRun))
{
switch (wParam)
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MINIMIZE:
case SC_RESTORE:
case SC_CLOSE:
case bcmControlRun:
#ifdef DEBUG
if (wParam == bcmControlRun)
Assert(cxt == CxtFromBcm(bcmControlRun));
#endif
if (!SendMessage(vhwndCBT, WM_CBTSEMEV, smvCommand,
MAKELONG(cxt, 0 /* from menu */)))
{
return (0L);
}
break;
#ifdef INEFFICIENT
case SC_NEXTWINDOW:
case SC_PREVWINDOW:
case SC_VSCROLL:
case SC_HSCROLL:
case SC_MOUSEMENU:
case SC_KEYMENU:
case SC_ARRANGE:
break;
#endif
}
}
if (vfHelp)
{
if (cxt == cxtNil)
goto LDefProc; /* pressed Alt, or clicked to drop down a menu */
GetHelp(cxt);
return fTrue;
}
else
{
Profile(vpfi == pfiMenu ? StartProf(30) : 0);
EnsureFocusInPane();
vcxtHelp = cxtNil;
if (FOpusCommandWParam(wParam))
{
CmdExecBcmKc(BcmFromWParam(wParam), kcNil);
}
else
{
if (vfRecording)
RecordAppSysCmd(wParam);
switch (wParam & 0xfff0)
{
case SC_MOVE:
fRecordMove = fTrue;
break;
case SC_SIZE:
fRecordMove = fTrue;
fRecordSize = fTrue;
break;
}
goto LDefProc;
}
}
break;
case WM_INITMENUPOPUP:
/* setup the pull down menu before being drawn */
/* wParam is the popup menu handle */
/* LOWORD(lParam) = index of popup in main menu */
/* HIWORD(lParam) = 1 if system menu, 0 if application main menu */
EndLongOp(fTrue /* fAll */);
if (HIWORD(lParam) == 0)
{ /* we care for the application main menu only */
/* for the zorn menu in the menu bar HIWORD(lParam) is still 0 */
SetAppMenu((HMENU) wParam, lParam);
}
/* Turn on the cursor so we can see where it is */
if (!selCur.fOn && selCur.fIns)
{
/* Bug Fix BL 9/13/88: be sure window is up to date first */
UpdateWw( selCur.ww, fFalse /*fAbortOK*/ );
ToggleSel( &selCur, selCur.cpFirst, selCur.cpFirst );
selCur.fHidden = fFalse;
}
break;
case WM_MENUCHAR:
{
LONG lRet = LMenuChar(hwnd, wParam, lParam);
if (lRet != 0)
return lRet;
}
LDefProc:
return(DefWindowProc(hwnd, message, wParam, lParam));
case WM_SETCURSOR:
if (vfHelp | vfInLongOperation)
{
OurSetCursor(NULL); /* will set according to the vf's */
return fTrue;
}
goto LDefProc;
case WM_MENUSELECT:
SaveMenuHelpContext(wParam, lParam, cxtAppMenuSelect);
if (vhwndStatLine)
{
#ifdef OPUS_X64
hMenu = (HMENU) lParam;
mf = HIWORD(wParam);
bcm = (mf & MF_POPUP) && hMenu != NULL ?
(UINT_PTR) GetSubMenu(hMenu, LOWORD(wParam)) :
(UINT_PTR) LOWORD(wParam);
#else
hMenu = HIWORD(lParam);
bcm = wParam;
mf = LOWORD(lParam );
#endif
if (hMenu == 0 && fEnteredIdle)
DrawMenuHelp(hMenu, bcm, mf);
fEnteredIdle = fFalse;
if (!vwParamHelp && !vlParamHelp && !vcxtHelp) /* exit menu */
RestorePrompt();
}
break;
case WM_SYSKEYDOWN:
/* received when no window has the input focus */
if (wParam == VK_F1 && !vfControlKey && !vfOptionKey)
{
if (vfShiftKey)
CmdHelpContext(NULL);
else
CmdHelp(NULL);
break;
}
goto LDefProc;
case WM_ENTERIDLE:
/* received from Windows code when idle in menu or dialog.
Now is the time to really paint status line menu help
NOTE: we don't use windows dialogs, bug libraries we call may
(esp. conv-wrd.dll).
wParam==MSGF_MENU indicates idle in menu, we should put up menuhelp
*/
Profile( vpfi == pfiMenu ? StopProf() : 0 );
Assert(wParam == MSGF_MENU || wParam == MSGF_DIALOGBOX); /* documentation said so */
if (wParam == MSGF_MENU && !fEnteredIdle && vhwndStatLine)
{
fEnteredIdle = fTrue;
DrawMenuHelp(hMenu, bcm, mf);
}
#ifdef DCORELOAD
CommSz(SzShared("."));
#endif /* DCORELOAD */
FAbortNewestCmg(cmgDlgNew, fTrue, fTrue);
break;
}
/* A window proc should always return something */
return(0L);
}
/* NOTE: Messages bound for this WndProc are filtered in wprocn.asm */
/* %%Function:MwdWndProc %%Owner:peterj */
#ifdef OPUS_X64
LRESULT CALLBACK MwdWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#else
long EXPORT FAR PASCAL MwdWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
#endif
{
extern int mwCreate;
static int fEnteredIdle=fTrue;
static HMENU hMenu;
#ifdef OPUS_X64
static UINT_PTR bcm;
#else
static int bcm;
#endif
static int mf;
#ifdef OPUS_X64
LRESULT MwdWndProcRare(HWND, UINT, WPARAM, LPARAM);
#else
long MwdWndProcRare();
#endif
int ww;
PAINTSTRUCT ps;
#ifdef SHOWDOCMSG
ShowMsg ("dc", hwnd, message, wParam, lParam);
#endif /* SHOWDOCMSG */
#ifdef RSH
/* BLOCK - log message */
{
int iwm = IScanLprgw((int far *)rgwmRsh,message,iwmMax);
if (iwm >= 0 && iwm < iwmMax)
LogUa(uaMwdMessage+iwm);
}
#endif /* RSH */
switch (message)
{
default:
return MwdWndProcRare( hwnd, message, wParam,lParam );
case WM_VSCROLL:
case WM_HSCROLL:
/* Vertical/Horizontal scroll bar input. wParam contains the
** scroll code. For the thumb movement codes, the low
** word of lParam contain the new scroll position.
** Possible values for wParam are: SB_LINEUP, SB_LINEDOWN,
** SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, SB_THUMBTRACK
** Hiword of lParam contains the window handle of the
** scroll bar. */
EnsureFocusInPane();
Assert(hwwdCur);
#ifdef RSH
SetUatMode(uamNavigation);
StopUatTimer();
#endif /* RSH */
#ifdef OPUS_X64
{
WORD code = LOWORD(wParam);
int dqThumb = HIWORD(wParam);
HWND hwndScroll = (HWND) lParam;
if (message == WM_HSCROLL)
MwdHorzScroll(wwCur, code, dqThumb);
else
MwdVertScroll(((*hwwdCur)->hwndVScroll == hwndScroll) ?
wwCur : WwOther(wwCur), code, dqThumb);
if (vfRecording)
RecordScroll(message, code, dqThumb);
}
#else
if (message == WM_HSCROLL)
MwdHorzScroll( wwCur, wParam, (int)lParam);
else
MwdVertScroll(((*hwwdCur)->hwndVScroll == HIWORD(lParam)) ?
wwCur : WwOther(wwCur), wParam, (int)lParam);
if (vfRecording)
RecordScroll(message, wParam, LOWORD(lParam));
#endif
break;
case WM_MOUSEACTIVATE:
{
int iRet =
#ifdef OPUS_X64
MA_ACTIVATE;
#else
0;
#endif
if (vhwndAppModalFocus != hNil)
if (!vfDeactByOtherApp)
return (LONG) MA_NOACTIVATE;
else
goto DefaultProc;
if (hmwdCur != hNil && (*hmwdCur)->hwnd != hwnd)
{
switch (LOWORD(lParam))
{
/* We eat HTCLIENT, HTSYSMENU, and HTMENU */
/* NOTE: HTSIZE, HTHSCROLL, and HTVSCROLL have no affect
because our scroll bars and size box are in our client
area and are therefore not considered by Windows to be
"real" scroll bars and size boxes. (BAC) */
case HTREDUCE:
case HTZOOM:
case HTCAPTION:
case HTSIZE:
case HTHSCROLL:
case HTVSCROLL:
case HTLEFT:
case HTRIGHT:
case HTTOP:
case HTTOPLEFT:
case HTTOPRIGHT:
case HTBOTTOM:
case HTBOTTOMLEFT:
case HTBOTTOMRIGHT:
iRet = MA_NOACTIVATE;
break;
case HTCLIENT:
NewCurWw( PmwdMw(MwFromHwndMw(hwnd))->wwActive, fFalse /*fDoNotSelect*/);
/* fall through */
default:
#ifdef OPUS_X64
/* Modern USER can activate and deliver this click without the
* Win16 re-entrancy workaround. Eating it makes the first click
* after switching documents disappear. */
iRet = MA_ACTIVATE;
#else
iRet = MA_ACTIVATEANDEAT;
#endif
break;
}
}
return(iRet);
}
case WM_CHILDACTIVATE:
NewCurWw( PmwdMw(MwFromHwndMw(hwnd))->wwActive, fFalse /*fDoNotSelect*/);
break;
case WM_MENUCHAR:
{
LONG lRet = LMenuChar(hwnd, wParam, lParam);
if (lRet == 0)
goto DefaultProc;
else
return lRet;
}
case WM_SYSCOMMAND:
if (vfSysMenu)
/* don't really want to be here */
{
SendMessage(vhwndApp, message, wParam, lParam);
return fTrue;
}
#ifdef RSH
/* BLOCK - log command */
{
int isc = IScanLprgw((int far *)rgscRsh,wParam,iscMax);
if (isc >= 0 && isc < iscMax)
LogUa(uaMwdCommand+isc);
}
#endif /* RSH */
if (vhwndCBT)
{
switch (wParam)
{
case bcmRestoreWnd:
/* should get this here if doc window maximized;
would come through AppWndProc */
Assert (fFalse);
/* fall thru just in case */
case bcmMoveWnd:
case bcmSizeWnd:
case bcmZoomWnd:
case bcmSplit:
case bcmCloseWnd:
if (!SendMessage(vhwndCBT, WM_CBTSEMEV, smvCommand,
MAKELONG(CxtFromBcm(wParam), 0 /* from menu */)))
{
return (0L);
}
break;
}
}
if (vfHelp)
{
int cxt;
if ((cxt = CxtDocSysMenu(wParam)) == cxtNil)
goto DefaultProc; /* Probably clicked to drop down sys menu */
GetHelp(cxt);
return fTrue;
}
EnsureFocusInPane();
if (FOpusCommandWParam(wParam))
return CmdExecBcmKc(BcmFromWParam(wParam), kcNil) == cmdOK;
switch (wParam & 0xfff0)
{
case SC_MAXIMIZE:
fRecordMove = fFalse;
fRecordSize = fFalse;
CmdExecBcmKc(bcmZoomWnd, kcNil);
return fTrue;
case SC_MINIMIZE: /* not allowed! */
return fFalse;
case SC_SIZE:
if (vpref.fZoomMwd) /* not allowed if maximized! */
return fFalse;
fRecordMove = fTrue;
fRecordSize = fTrue;
break;
case SC_MOVE:
if (vpref.fZoomMwd) /* not allowed if maximized! */
return fFalse;
fRecordMove = fTrue;
}
if (vfRecording)
RecordDocSysCmd(wParam);
goto DefaultProc;
case WM_INITMENUPOPUP:
lParam |= 0x10000; /* Windows lies the first time! */
vgrfMenuKeysAreDirty = 0xffff;/* force update of accelerator keys */
SetAppMenu((HMENU) wParam, lParam);
break;
case WM_MENUSELECT:
SaveMenuHelpContext(wParam, lParam, cxtDocMenuSelect);
if (vhwndStatLine)
{
#ifdef OPUS_X64
hMenu = (HMENU) lParam;
mf = HIWORD(wParam);
bcm = (mf & MF_POPUP) && hMenu != NULL ?
(UINT_PTR) GetSubMenu(hMenu, LOWORD(wParam)) :
(UINT_PTR) LOWORD(wParam);
#else
hMenu = HIWORD(lParam);
bcm = wParam;
mf = LOWORD(lParam );
#endif
if (hMenu == 0 && fEnteredIdle)
DrawMenuHelp(hMenu, bcm, mf);
fEnteredIdle = fFalse;
if (!vwParamHelp && !vlParamHelp && !vcxtHelp) /* exit menu */
RestorePrompt();
}
break;
case WM_ENTERIDLE:
/* received from Windows code when idle in menu or dialog.
Now is the time to really paint status line menu help
NOTE: we don't use windows dialogs, bug libraries we call may
(esp. conv-wrd.dll).
wParam==MSGF_MENU indicates idle in menu, we should put up menuhelp
*/
Assert(wParam == MSGF_MENU || wParam == MSGF_DIALOGBOX); /* documentation said so */
if (wParam == MSGF_MENU && !fEnteredIdle && vhwndStatLine)
{
fEnteredIdle = fTrue;
DrawMenuHelp(hMenu, bcm, mf);
}
#ifdef DCORELOAD
CommSz(SzShared("."));
#endif /* DCORELOAD */
FAbortNewestCmg(cmgDlgNew, fTrue, fTrue);
break;
}
/* A window proc should always return something */
return(0L);
DefaultProc: /* All messages not processed come here. */
return (DefWindowProc(hwnd, message, wParam, lParam));
}
/* S A V E M E N U H E L P C O N T E X T - */
/* Since we do not want to compute the help context every time the
user pulls down a menu, we will just save the wParam and lParam.
If the user hits F1, and vcxtHelp has not yet been set to something
else, we can compute the context from these saved values.
*/
/* %%Function:SaveMenuHelpContext %%Owner:rosiep */
#ifdef OPUS_X64
void SaveMenuHelpContext(WPARAM wParam, LPARAM lParam, int cxt)
#else
SaveMenuHelpContext(wParam,lParam,cxt)
WORD wParam;
LONG lParam;
int cxt;
#endif
{
Assert(cxt == cxtAppMenuSelect || cxt == cxtDocMenuSelect);
/* if we're exiting Menu Mode, no more help context */
#ifdef OPUS_X64
if (lParam == 0 && HIWORD(wParam) == 0xffff)
#else
if (HIWORD(lParam) == 0 || wParam == 0)
#endif
{
vwParamHelp = 0;
vlParamHelp = 0;
vcxtHelp = cxtNil;
}
else
{
vwParamHelp = wParam;
vlParamHelp = lParam;
vcxtHelp = cxt;
}
}
#ifdef REFERENCE /* most of these are now in UpdateWindowWw */
/* U P D A T E I N V A L I D W W */
/* Find out what Windows considers to be the invalid range of
the passed window. Mark it invalid in WWD & blank the area on the screen */
/* %%Function:UpdateInvalidWw %%Owner:NOTUSED */
UpdateInvalidWw(ww)
int ww;
{
struct RC rc, rcwAboveYwMin;
struct WWD **hwwd;
int ypTop;
/* First, get the update rect for the parent. This will do necessary background
erasure and border validation, the returned rectangle is ignored.
Test for wwCur assures we only do this once per UpdateWindows */
if (ww == wwCur)
GetUpdateRect( vhwndApp, (LPRECT) &rc, fTrue /* fErase */ );
if ((hwwd = mpwwhwwd [ww]) == hNil || (*hwwd)->wk == wkClipboard)
return;
/* Now, do the same for the document window, except that this time we use the
rect to update the invalid band stored in the WWD structure */
Assert( (*hwwd)->hwnd != NULL );
GetUpdateRect( (*hwwd)->hwnd, (LPRECT) &rc, fTrue /* fErase */);
if (FSectRc( PrcSet( &rcwAboveYwMin, 0, 0,
(*hwwd)->xwMac, (*hwwd)->ywMin ),
&rc, &rcwAboveYwMin ))
PatBltRc( (*hwwd)->hdc, &rcwAboveYwMin, vsci.ropErase );
if (vidf.fDead)
{
/* If we are in the process of shutting down, we DONT want to repaint,
but we DO want to erase the bkgrnd and validate the border */
PatBltRc( (*hwwd)->hdc, &rc, vsci.ropErase );
return;
}
/* draw portion of style name window border that extends above ypMin */
/* This is the only drawing/invalidation that we have to do in this area */
if ((*hwwd)->xwSelBar)
PaintStyStub( ww, &rc );
rc.ypTop = max( (*hwwd)->ywMin, rc.ypTop );
if (rc.ypTop < rc.ypBottom)
InvalWwRc(ww, &rc );
/* Since we have found out the invalid rect, and marked it invalid
in our structures, we don't want to hear about it again,
so we tell windows that we have made everything valid */
ValidateRect( (*hwwd)->hwnd, (LPRECT) NULL );
}
#endif /* REFERENCE */
/* NOTE: Messages bound for this WndProc are filtered in wprocn.asm */
/* %%Function:WwPaneWndProc %%Owner:peterj */
#ifdef OPUS_X64
LRESULT CALLBACK WwPaneWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#else
long EXPORT FAR PASCAL WwPaneWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
#endif
{
int ww;
struct RC rc;
#ifdef OPUS_X64
LRESULT RareWwPaneWndProc(HWND, UINT, WPARAM, LPARAM);
#else
long RareWwPaneWndProc();
#endif
#ifdef SHOWPNEMSG
ShowMsg ("pn", hwnd, message, wParam, lParam);
#endif /* SHOWPNEMSG */
#ifdef RSH
/* BLOCK - log message */
{
int iwm = IScanLprgw((int far *)rgwmRsh,message,iwmMax);
if (iwm >= 0 && iwm < iwmMax)
LogUa(uaWwdMessage+iwm);
}
#endif /* RSH */
switch (message)
{
default:
return RareWwPaneWndProc( hwnd, message, wParam,lParam );
#ifdef OPUS_X64
case WM_OPUS_X64_QUERY_SELECTION:
switch (LOWORD(wParam))
{
case 0: return (LRESULT) selCur.cpFirst;
case 1: return (LRESULT) selCur.cpLim;
case 2: return (LRESULT) selCur.fIns;
case 3: return (LRESULT) selCur.sty;
case 4: return (LRESULT) selCur.xw;
case 5: return (LRESULT) vfDoubleClick;
case 6: return (LRESULT) selCur.sk;
case 7: return (LRESULT) selCur.yw;
case 8: return (LRESULT) selCur.dyp;
case 9: return (LRESULT) selCur.fOn;
case 10: return (LRESULT) selCur.fHidden;
case 11: return (LRESULT) selCur.xpFirst;
case 12: return (LRESULT) selCur.xpLim;
case 13: return (LRESULT) vfli.cpMin;
case 14: return (LRESULT) vfli.cpMac;
case 15: return (LRESULT) vfli.xpLeft;
case 16: return (LRESULT) vfli.xpRight;
case 17: return (LRESULT) vfli.ichMac;
case 18: return (LRESULT) vfli.rgdxp[0];
case 19: return (LRESULT) vfli.rgdxp[
vfli.ichMac == 0 ? 0 : vfli.ichMac - 1];
case 24: return (LRESULT) sizeof(struct CHR);
case 25: return (LRESULT) sizeof(struct CHRT);
case 26: return (LRESULT) sizeof(struct CHRV);
case 27: return (LRESULT) sizeof(struct CHRF);
case 28: return (LRESULT) sizeof(struct CHRDF);
case 29: return (LRESULT) sizeof(struct CHRFG);
case 30:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return (LRESULT) IMacPlc(pdr->hplcedl);
}
case 31:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return (LRESULT) CpPlc(pdr->hplcedl, (int) lParam);
}
case 32:
case 33:
case 34:
case 35:
{
struct EDL edl;
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
GetPlc(pdr->hplcedl, (int) lParam, &edl);
if (LOWORD(wParam) == 32) return (LRESULT) edl.ypTop;
if (LOWORD(wParam) == 33) return (LRESULT) edl.dyp;
if (LOWORD(wParam) == 34) return (LRESULT) edl.dcp;
return (LRESULT) edl.fDirty;
}
case 36:
case 37:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return LOWORD(wParam) == 36 ?
(LRESULT) pdr->cpFirst : (LRESULT) pdr->cpLim;
}
case 38: return (LRESULT) sizeof(struct EDL);
case 39:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return (LRESULT) pdr->fDirty;
}
case 40:
return (LRESULT) PwwdWw(WwFromHwnd(hwnd))->fDirty;
case 41: return (LRESULT) CpMacDocEdit(selCur.doc);
case 42:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return (LRESULT) pdr->dyl;
}
case 43:
return (LRESULT) DyOfRc(&PwwdWw(WwFromHwnd(hwnd))->rcwDisp);
case 44:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
return (LRESULT) pdr->dxl;
}
case 45:
return (LRESULT) DxOfRc(&PwwdWw(WwFromHwnd(hwnd))->rcwDisp);
case 46: return (LRESULT) CpMacDoc(selCur.doc);
case 47:
case 48:
{
struct EDL edl;
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
GetPlc(pdr->hplcedl, (int) lParam, &edl);
return LOWORD(wParam) == 47 ?
(LRESULT) edl.dlk : (LRESULT) edl.fEnd;
}
case 49: return (LRESULT) selCur.chp.ftc;
case 50: return (LRESULT) selCur.chp.hps;
case 51:
case 52:
{
CP cp = (CP) lParam;
if (cp < cp0 || cp >= CpMacDocEdit(selCur.doc))
return (LRESULT) -1;
FetchCp(selCur.doc, cp, fcmProps);
return LOWORD(wParam) == 51 ?
(LRESULT) vchpFetch.ftc : (LRESULT) vchpFetch.hps;
}
case 53:
return (LRESULT) IbstFontFromFtcDoc(selCur.chp.ftc,
selCur.doc);
case 54:
{
union FCID fcid;
fcid.lFcid = 0L;
fcid.ibstFont = (int)lParam;
return (LRESULT) fcid.ibstFont;
}
case 58:
return (LRESULT) sizeof(union FCID);
case 55:
case 56:
case 57:
InvalFli();
FormatLine(selCur.ww, selCur.doc, (CP)lParam);
if (LOWORD(wParam) == 55)
return (LRESULT) vfli.dypLine;
if (LOWORD(wParam) == 56)
return (LRESULT) vfti.fcid.hps;
return (LRESULT) (vfti.dypAscent + vfti.dypDescent);
case 59:
case 60:
case 61:
case 62:
{
int bchr = 0;
int cchp = 0;
int hpsChpMax = 0;
int hpsFcidMax = 0;
int ichMax = 0;
InvalFli();
FormatLine(selCur.ww, selCur.doc, (CP)lParam);
while (bchr < vbchrMac)
{
struct CHR *pchr =
(struct CHR *)&(**vhgrpchr)[bchr];
int cb = CbFromChrm(pchr->chrm);
if (cb <= 0 || cb > vbchrMac - bchr)
break;
if (pchr->chrm == chrmChp)
{
++cchp;
hpsChpMax = max(hpsChpMax,
(int)pchr->chp.hps);
hpsFcidMax = max(hpsFcidMax,
(int)pchr->fcid.hps);
ichMax = max(ichMax,
(int)(unsigned char)pchr->ich);
}
bchr += cb;
}
if (LOWORD(wParam) == 59) return (LRESULT) hpsChpMax;
if (LOWORD(wParam) == 60) return (LRESULT) hpsFcidMax;
if (LOWORD(wParam) == 61) return (LRESULT) cchp;
return (LRESULT) ichMax;
}
case 63:
InvalFli();
FormatLine(selCur.ww, selCur.doc, cp0);
if ((int)lParam < 0 || (int)lParam >= vfli.ichMac)
return (LRESULT) -1;
return (LRESULT) vfli.rgdxp[(int)lParam];
case 64:
case 65:
case 66:
case 67:
{
struct DR *pdr = PdrGalley(PwwdWw(WwFromHwnd(hwnd)));
CP cp = CpPlc(pdr->hplcedl, 0);
InvalFli();
FormatLineDr(selCur.ww, cp, pdr);
if (LOWORD(wParam) == 64)
{
if ((int)lParam < 0 || (int)lParam >= vfli.ichMac)
return (LRESULT) -1;
return (LRESULT) vfli.rgdxp[(int)lParam];
}
if (LOWORD(wParam) == 65) return (LRESULT) vfli.dxsInch;
if (LOWORD(wParam) == 66) return (LRESULT) vfli.dxuInch;
return (LRESULT) vfti.dxpInch;
}
case 68:
{
int ich = (int)HIWORD(wParam);
InvalFli();
FormatLine(selCur.ww, selCur.doc, (CP)lParam);
if (ich < 0 || ich >= vfli.ichMac)
return (LRESULT)-1;
return (LRESULT)(unsigned char)vfli.rgch[ich];
}
case 69:
{
CP cp = (CP)lParam;
if (cp < cp0 || cp >= CpMacDoc(selCur.doc))
return (LRESULT)-1;
FetchCp(selCur.doc, cp, fcmChars);
if (vccpFetch <= 0 || vhpchFetch == NULL)
return (LRESULT)-1;
return (LRESULT)(unsigned char)*vhpchFetch;
}
case 70:
{
CP cp = (CP)lParam;
if (cp < cp0 || cp >= CpMacDoc(selCur.doc))
return (LRESULT)-1;
FetchCp(selCur.doc, cp,
fcmChars + fcmProps + fcmParseCaps);
if (vccpFetch <= 0 || vhpchFetch == NULL)
return (LRESULT)-1;
return (LRESULT)(unsigned char)*vhpchFetch;
}
case 71:
{
CP cp = (CP)lParam;
if (cp < cp0 || cp >= CpMacDoc(selCur.doc))
return (LRESULT)-1;
FetchCp(selCur.doc, cp,
fcmChars + fcmProps + fcmParseCaps);
return (LRESULT)MAKELONG((WORD)vibpProtect,
(WORD)vibp);
}
}
return (LRESULT) -1;
#endif
case WM_SETFOCUS:
/* The window is getting the focus. wParam contains the window
** handle of the window that previously had the focus. */
WwPaneGetFocus(hwnd, (HWND)wParam);
break;
case WM_KILLFOCUS:
/* The window is losing the focus. wParam contains the window
** handle of the window about to get the focus, or NULL. */
if (vidf.fDead)
break;
Debug(vdbs.fShakeHeap ? ShakeHeap() : 0);
WwPaneLoseFocus(hwnd, (HWND)wParam);
break;
case WM_MOUSEACTIVATE:
{ /* reset the wwActivePane of its parent */
int fSscClick = fFalse;
if ((vhwndAppModalFocus != hNil) && !vfHelp)
if (!vfDeactByOtherApp)
return (LONG) MA_NOACTIVATE;
else
goto DefaultProc;
if (vfHelp || (GetMessageTime() < vcmsecHelp))
return(fTrue);
if (GetFocus() != hwnd)
{
int ww = WwFromHwnd(hwnd);
/* we want to gain focus */
if (HIWORD(lParam) == WM_RBUTTONDOWN)
vfRightClick = fTrue;
if (fSscClick = FSscClick())
{
int eid = eidInvalidSelection;
/* Note: Ssc click will do a quickmove/copy
unless selCur.fIns or in dyadic mode or a few
other cases. In those cases cancel the operation.
Better to do it now before we change the activation.
*/
if ( FOutlineEmpty(ww, fFalse) ||
(eid = EidMouseAction()) != eidNil )
{
ErrorEid(eid, "WwPaneWndProc");
return (LONG) MA_NOACTIVATE;
}
else
{
/* a value which is not sscNil. This will keep
NewCurWw from changing selCur.
*/
vssc = sscMouse;
}
}
/* Kludge Alert! Windows has a re-entrancy problem with MA_ACTIVATEANDEAT
such that we cannot call PeekMessage while nested in a WM_MOUSEACTIVATE
message to which we plan to return MA_ACTIVATEANDEAT. If we do, the
message will stay on the queue. NewCurWw can cause FMsgPresent to be
called indirectly. rp - 1/4/89
Dyadic copy formatting, which does some extra NewCurWw calls had a similar
problem with the MOUSEACTIVATE message not getting cleared. Setting the
flag so FMsgPresent will return solved the problem, though I am not sure
why, since the details are a little different that Rosie describes in
Opus bug 5810. bz 4-27-89
Moved setting of flag, now counter, to NewCurWw itself bz 5/10/89 */
NewCurWw(ww, fFalse /*fDoNotSelect*/);
if (fSscClick)
{
/* leave vssc as sscMouse so PselActive will use selDotted */
return(MA_ACTIVATE); /* cause click msg to do dyadic move */
}
else
{
#ifdef OPUS_X64
/* The Win16 eat-on-activate workaround makes the next
* physical click look like a double-click on modern USER.
* Let the activating click position the caret immediately. */
return(MA_ACTIVATE);
#else
return(MA_ACTIVATEANDEAT);
#endif
}
}
DefaultProc: /* All messages not processed come here. */
return (DefWindowProc(hwnd, message, wParam, lParam));
}
case WM_MENUCHAR:
{
LONG lRet = LMenuChar(hwnd, wParam, lParam);
if (lRet != 0)
return lRet;
goto DefaultProc;
}
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU)
{
if (vfSysMenu || LOWORD(lParam != '-'))
return SendMessage(vhwndApp, message, wParam, lParam);
else if (vlm == lmPreview)
/* prevent Menu From Nowhere from popping up over the
Preview window */
return (0L);
}
#ifdef RSH
/* BLOCK - log command */
{
int isc = IScanLprgw((int far *)rgscRsh,wParam,iscMax);
if (isc >= 0 && isc < iscMax)
LogUa(uaMwdCommand+isc);
}
#endif /* RSH */
goto DefaultProc;
case WM_PAINT:
/* Time for the window to draw itself. */
UpdateWindowWw(WwFromHwnd(hwnd));
break;
/* For each of following mouse window messages, wParam contains
** bits indicating whether or not various virtual keys are down,
** and lParam is a POINT containing the mouse coordinates. The
** keydown bits of wParam are: MK_LBUTTON (set if Left Button is
** down); MK_RBUTTON (set if Right Button is down); MK_SHIFT (set
** if Shift Key is down); MK_ALTERNATE (set if Alt Key is down);
** and MK_CONTROL (set if Control Key is down). */
case WM_SETCURSOR:
return 0L;
case WM_MOUSEMOVE:
ForceCursorChange(hwnd, &lParam, vidf.fInIdle/*fExact*/);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
#ifdef RSH
{
int w = 0;
if (GetKeyState(VK_SHIFT) < 0) w |= 1;
if (GetKeyState(VK_MENU) < 0) w |= 2;
if (GetKeyState(VK_CONTROL) < 0) w |= 4;
LogUa(uaKeyState + w);
}
#endif /* RSH */
ww = WwFromHwnd( hwnd );
Assert( ww != wwNil );
WwPaneMouse(ww, message, wParam, MAKEPOINT(lParam));
}
/* A window proc should always return something */
return(0L);
}
/* %%Function:WwPaneMouse %%Owner:peterj */
void WwPaneMouse(ww, message, wParam, pt)
int ww;
unsigned message;
WORD wParam;
POINT pt;
{
BOOL fShift;
BOOL fInStyleName = fFalse;
if ((ww != wwCur) && !vfHelp)
return;
if (vfRecording)
{
#ifdef OPUS_X64
MessageBeep(MB_OK);
#else
Beep();
#endif
return;
}
Assert( message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
message == WM_LBUTTONDBLCLK );
vfDoubleClick = (message == WM_LBUTTONDBLCLK);
vfRightClick = (message == WM_RBUTTONDOWN);
Assert(hwwdCur != hNil);
if (vfDoubleClick && (GetMessageTime() < vcmsecHelp))
return;
/* styname area? */
if ((*hwwdCur)->xwSelBar > 0)
{
/* styname border? */
if (pt.x <= ((*hwwdCur)->xwSelBar + (vsci.dxpBorder << 1)))
if (vfHelp)
{
GetHelp(cxtStyleArea);
return;
}
else
{
fInStyleName = fTrue;
if (FXpNearStyWndBorder(pt.x, hwwdCur))
{
if (!vhwndCBT || SendMessage(vhwndCBT, WM_CBTSEMEV,
smvTrackStyWnd, 0L))
{
TrackStyWndCursor(pt);
}
return;
}
}
}
fShift = vgrpfKeyBoardState & wKbsShiftMask;
if (vfHelp)
{
GetHelp(CxtFromWwPt(ww, pt));
return;
}
/* the fCommand parameter for Mac is used as fControl in Win */
DoContentHit( pt, fShift, fFalse /* fOption */, vfControlKey /* fCommand */ );
if (!vfBlockSel && vfDoubleClick && fInStyleName)
{
if (!vhwndCBT || SendMessage(vhwndCBT, WM_CBTSEMEV, smvCommand,
MAKELONG(CxtFromBcm(bcmApplyStyleDlg), 2 /* dbl click */)))
{
CmdExecBcmKc(bcmApplyStyleDlg, kcNil);
}
}
return;
}
/* %%Function:ClearAbortKeyState %%Owner:peterj */
ClearAbortKeyState()
{
GetAsyncKeyState(VK_ESCAPE);
GetAsyncKeyState(VK_CANCEL);
GetAsyncKeyState(VK_MENU);
}
/* SetOurKeyState
This function is called when ever there is likely to have been
a change in the state of the keyboard. This function updates
vgrpfKeyBoardState which contains the state of:
Keys:
Shift Key wKbsShiftMask
Control Key wKbsControlMask
Alt/Option/menu Key wKbsOptionMask
Capslock key wKbsCapsLckMask
Note that Extend Mode and Block Selection are not purely toggle key
because it could be turned off by switching windows or executing
certain commands.
*/
/* %%Function:SetOurKeyState %%Owner:peterj */
void SetOurKeyState()
{
#ifdef INTL
extern int vwWinVersion, vkRightBracket;
#endif /* INTL */
extern int vgrpfKeyBoardState;
int grpfT = vgrpfKeyBoardState;
vgrpfKeyBoardState = (GetKeyState(VK_SHIFT) < 0) ? wKbsShiftMask : 0;
vgrpfKeyBoardState |= (GetKeyState(VK_MENU) < 0) ? wKbsOptionMask : 0;
vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0) ? wKbsControlMask : 0;
#ifdef CAPSLOCKSFIX /* for intl only */
/* localized pre-Win3.0 keyboards don't toggle the caps-lock key! */
/* We detect localalized keyboards by looking at the vk for the ']'. */
/* Only for German and French (defined CAPSLOCKSFIX) */
if (vwWinVersion < 0x300 && vkRightBracket >= 0x600)
vgrpfKeyBoardState |= (GetKeyState(VK_CAPITAL) < 0) ? wKbsCapsLckMask : 0;
else
#endif /* CAPSLOCKSFIX */
/* VK_CAPITAL is a toggle key, hence we check if it's toggled, not
if it's down */
vgrpfKeyBoardState |= (GetKeyState(VK_CAPITAL) & 1) ? wKbsCapsLckMask : 0;
vgrpfKeyBoardState |= (GetKeyState(VK_NUMLOCK) & 1) ? wKbsNumLckMask : 0;
if (vhwndStatLine != NULL &&
(grpfT & (wKbsCapsLckMask + wKbsNumLckMask)) !=
(vgrpfKeyBoardState & (wKbsCapsLckMask + wKbsNumLckMask)))
{
UpdateStatusLine(usoToggles);
}
}
/* %%Function:FXpNearStyWndBorder %%Owner:peterj */
FXpNearStyWndBorder(xp, hwwd)
int xp;
struct WWD **hwwd;
{
int xpStyWndBorder = (*hwwd)->xwSelBar;
return( xp <= xpStyWndBorder &&
xp >= xpStyWndBorder - (vsci.dxpBorder << 1));
}
/* F W H K E Y */
/* Note: wParam is no longer used.
wCode, if >= 0 will be one of the MSGF_* codes, otherwise
we MUST pass it on to DefHookProc.
HC_'s no longer exist (except internally)
The Windows people are very confused about this too, and it took
me a while to figure it out with Bob Gunderson.
*/
/* %%Function:FWHKey %%Owner:peterj */
EXPORT long FAR PASCAL FWHKey(wCode, wParam, lpmsg)
int wCode, wParam;
LPMSG lpmsg;
{
int wm;
if (lpmsg != 0L && (wm = lpmsg->message) == WM_QUIT)
{
bltbx(lpmsg, (LPMSG)&vmsgLast, sizeof(MSG));
QuitExit();
Assert(fFalse);
}
switch (wCode)
{
case MSGF_DIALOGBOX:
Assert (lpmsg != 0L);
SetOurKeyState(); /* we don't get a key-up for Alt */
/* We will get this for non-SDM (printer driver) dialog boxes */
if (wm == WM_KEYDOWN && lpmsg->wParam == VK_F1
&& !vfControlKey && !vfOptionKey)
{
GetHelp(vcxtHelp);
}
break;
case MSGF_MESSAGEBOX:
Assert (lpmsg != 0L);
/* GetCapture will return NULL in a message box unless a
key is held down, in which case we don't want to process
a second key. Excel does this trick, which is where I
got it. This is to fix a bug where we'd crash if you
pressed a key to dismiss the message box and then
pressed F1 while the first key was still down. (rp)
*/
if (GetCapture())
break;
#ifdef DEBUG
if (!FCheckToggleKeyMessage(lpmsg) &&
wm == WM_KEYDOWN &&
FProcessDbgKey(KcModified(lpmsg->wParam)))
/* special debugging key processing */
return fTrue;
#endif /* DEBUG */
/* FALL THROUGH */
case MSGF_MENU:
Assert (lpmsg != 0L);
/** This code will call the help application if the user
* selects something from a menu with the keyboard. Mouse
* selection is handled elsewhere (in the wndproc). **/
SetOurKeyState();
/** return immediately if it's not the right message **/
if (wm != WM_KEYDOWN && wm != WM_SYSKEYDOWN)
break;
if (vfEmptyMenu && lpmsg->wParam == VK_UP)
return fTrue;
/** Two possible cases: (1) the user selects something from
* a menu, then presses F1. (2) The user is already in help
* mode, selects something from a menu, presses return. **/
if ((lpmsg->wParam == VK_F1 && !vfControlKey && !vfOptionKey)
|| (lpmsg->wParam == kcReturn && vfHelp))
{
CmdHelp(NULL);
return fTrue;
}
} /* end of switch (wCode) */
return DefHookProc(wCode, wParam, lpmsg, (FARPROC FAR *) &vlppFWHChain);
}
#ifdef NOTUSED
/* %%Function:ChFromKc %%Owner:NOTUSED */
ChFromKc(kc)
int kc;
{
CHAR ch;
switch (kc)
{
case kcPageBreak:
ch = chSect;
break;
case kcColumnBreak:
ch = chColumnBreak;
break;
case kcNonBreakSpace:
ch = chNonBreakSpace;
break;
case kcNonReqHyphen:
ch = chNonReqHyphen;
break;
case kcNonBreakHyphen:
ch = chNonBreakHyphen;
break;
case kcNewLine:
ch = chCRJ;
break;
default:
ch = kc;
}
return (ch);
}
#endif /* NOTUSED */
/* F C H E C K T O G G L E K E Y M E S S A G E */
/* If the passed message is an up- or down- transition of a
keyboard toggle key (e.g. shift), update our global flags & return
fTrue; if not, return fFalse */
/* %%Function:FCheckToggleKeyMessage %%Owner:peterj */
FCheckToggleKeyMessage(lpmsg)
LPMSG lpmsg;
{
switch (lpmsg->message)
{
case WM_SYSKEYDOWN: /* we'll get WM_SYSKEY messages if no
window has the focus */
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
switch (lpmsg->wParam)
{
case VK_NUMLOCK:
case VK_CAPITAL:
case VK_CONTROL:
case VK_SHIFT:
/* FUTURE: SetOurKeyState will not work in win3 if the msg
is just peeked at and not removed. We had to add calls
to do that in the callers, and should remove this call
once we agree it is safe bz
*/
/* case VK_MENU:*/
SetOurKeyState();
return fTrue;
/* Following returns fFalse iff Alt key is down */
/* return !(lpmsg->lParam & 0x20000000);*/
}
}
return fFalse;
}
/* S p e c i a l S e l M o d e E n d */
/* cancel special selection modes. Check globals to avoid bringing
in code in the very common case when this routine has nothing to do. */
/* %%Function:SpecialSelModeEnd %%Owner:peterj */
SpecialSelModeEnd()
{
extern int vfBlockSel;
extern int vfExtendSel;
extern int vssc;
if (vfBlockSel)
BlockModeEnd();
if (vfExtendSel)
ExtendSelEnd();
if (vssc != sscNil)
CancelDyadic();
}
/* O U R S E T C U R S O R */
/* %%Function:OurSetCursor %%Owner:peterj */
EXPORT PASCAL OurSetCursor(hc)
HCURSOR hc;
{
if (vfHelp)
hc = vhcHelp;
else if (vfInLongOperation)
hc = vhcHourGlass;
if (!vfMouseExist && hc != vhcHourGlass)
hc = NULL;
#ifdef DEBUG
else
Assert (hc != NULL || vhcHourGlass == NULL);
#endif /* DEBUG */
SetCursor(hc);
}
/* these are here for swap-tuning purposes */
/* RestorePrompt
Remove the currently displayed prompt. If there is some other prompt that
should be displayed (based on the programs global mode) display that
prompt.
*/
/* %%Function:RestorePrompt %%Owner:peterj */
RestorePrompt ()
{
#ifdef RSH
StopSubTimer(uasMenu);
#endif /* RSH */
/* the following code should check the state of the program and assign to
pmt the new prompt to display. */
vfRestPmtOnInput = fFalse;
vusecTimeoutPrompt = 0;
if (vssc != sscNil)
SetPromptVssc();
else
{
if (vcchStatLinePrompt)
DisplayStatLinePrompt(pdcRestore);
}
if (vhwndPrompt != NULL)
HidePromptWindow();
if (vhwndStatLine)
UpdateWindow(vhwndStatLine);
else
UpdateWindow(vhwndDeskTop);
}
/* %%Function:HidePromptWindow %%Owner:peterj */
HidePromptWindow()
{
Assert(vhpprPRPrompt == hNil);
/* don't really destroy, just hide! */
SetWindowPos(vhwndPrompt, NULL, 0,0,0,0,
SWP_HIDEWINDOW|SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOMOVE);
Assert(vhwndPromptHidden == vhwndPrompt);
vhwndPrompt = NULL;
}
/* SetPromptRestore
Set the "restore prompt" information according to pdc.
*/
/* %%Function:SetPromptRestore %%Owner:peterj */
SetPromptRestore (pdc)
int pdc;
{
vusecTimeoutPrompt = 0;
vfRestPmtOnInput = fFalse;
if (pdc & pdcmRestore)
{
RestorePrompt();
return;
}
if (pdc & pdcmRestOnInput)
/* restore on input */
vfRestPmtOnInput = fTrue;
if (pdc & pdcmTimeout)
/* restore on timeout */
{
vusecTimeoutPrompt = GetTickCount() + usecPromptTimeout;
if (!vusecTimeoutPrompt)
vusecTimeoutPrompt++;
}
/* else: don't restore */
}
/* E n s u r e F o c u s I n P a n e */
/* This is called by the recipients of some messages which may arrive
while the user is in a ribbon or ruler combo box. It moves the
focus back to the pane, closing the combo, if necessary */
/* %%Function:EnsureFocusInPane %%Owner:peterj */
EnsureFocusInPane()
{
HWND hwnd;
if (!vfDeactByOtherApp && wwCur != wwNil &&
(hwnd = PwwdWw(wwCur)->hwnd) != GetFocus())
{
if (vidf.fIBDlgMode)
TermCurIBDlg(fFalse); /* escapes without doing action */
SetFocus(hwnd);
}
}
/* F I S K E Y M E S S A G E */
/* General key message handler. Pass messages to this and it will return
fTrue if it dealt with it, fFalse otherwise. This function knows about
insert mode. */
/* %%Function:FIsKeyMessage %%Owner:peterj */
BOOL FIsKeyMessage(lpmsg)
LPMSG lpmsg;
{
extern BOOL vfInsertMode;
extern KME vkme;
#ifdef COMING_SOON_TO_A_WORD_PROCESSOR_NEAR_YOU
/* and when is does, this flag should be part of vrf for
efficient DS usage */
static BOOL fIconBarPending = fFalse;
#endif
int wm, kc;
wm = lpmsg->message;
kc = lpmsg->wParam; /* key code or char */
#ifdef COMING_SOON_TO_A_WORD_PROCESSOR_NEAR_YOU
/* This is currently commented out due to the fact that Windows seems to
have a bug where they do not tell us when keys are released always... */
ShowMsg("KM", lpmsg->hwnd, wm, kc, lpmsg->lParam);
CommSz(SzShared("\r\n"));
/* Deal with Alt+Shift for IconBarMode */
/*CommSzNum(SzShared("f is "), fIconBarPending);*/
/* What it does: start icon bar mode when Alt and Shift are pressed
and released.
How it works: fIconBarPending is set whenever both the Alt and
Shift keys are down and reset when any other key is pressed.
When both the Alt and Shift keys have been released,
fIconBarPending is checked. If it is set, IconBarMode is
entered. */
if (wm == WM_KEYDOWN || wm == WM_SYSKEYDOWN)
{
fIconBarPending = ((kc == VK_MENU || kc == VK_SHIFT) &&
(GetKeyState(VK_MENU) & 0x8000) &&
(GetKeyState(VK_SHIFT) & 0x8000));
/*CommSzNum(SzShared("set f to "), fIconBarPending);*/
}
else if (fIconBarPending && (!(GetKeyState(VK_MENU) & 0x8000) &&
!(GetKeyState(VK_SHIFT) & 0x8000)))
{
CommSz(SzShared("Chaining...\r\n"));
ChainCmd(bcmIconBarMode);
fIconBarPending = fFalse;
}
#endif /* COMING_SOON___ */
/* FUTURE: TRASH THIS!!! (BAC) */
if (FCheckToggleKeyMessage(lpmsg))
goto LTranslate;
switch (wm)
{
case WM_CHAR:
/* this must come first! */
if (vhwndCBT && !SendMessage(vhwndCBT, WM_CBTSEMEV,
smvWmChar, MAKELONG(kc, 0)))
{
/* if CBT doesn't like it, kill it */
GetMessage(lpmsg, NULL, 0, 0);
return fTrue;
}
if (vlm == lmPreview)
return fTrue;
if (vfInsertMode)
{
GetMessage(lpmsg, NULL, 0, 0);
/* indicate we have a char to insert */
lpmsg->wParam |= 0x8000;
return fTrue;
}
LInsert:
if (hwwdCur != hNil && lpmsg->hwnd == (*hwwdCur)->hwnd)
{
if (vfExtendSel) /* catch the extend to alpha case */
{
if (kc != kcBackSpace)
{
ExtendSelToCh(kc);
return fTrue;
}
else
{
/* terminate Extend Mode before going into the insert code */
/* cannot simply add these keys as terminate mode keys in the keymap
because we still want the backspace and delete to be performed */
ExtendSelEnd();
}
}
/* don't allow typing with 2nd sel active */
if (vssc != sscNil)
#ifdef OPUS_X64
MessageBeep(MB_OK);
#else
Beep();
#endif
else
InsertLoopCh(kc, bcmNil);
return fTrue;
}
break;
case WM_SYSKEYDOWN:
if (kc == VK_MENU)
{
if (vfInsertMode)
return fFalse;
goto LTranslate;
}
case WM_KEYDOWN:
/* Get Alt key state from message, as vfOptionKey cannot
be trusted. */
if ((lpmsg->lParam & 0x20000000) != 0)
{
vgrpfKeyBoardState |= wKbsOptionMask;
if ((uns)(kc - VK_F1) <= (VK_F2 - VK_F1))
kc += 10; /* assumes VK_Fn's are contiguous */
}
else
{
vgrpfKeyBoardState &= ~wKbsOptionMask;
}
/* Get current Ctrl key state; OurGetKeyState cannot be trusted
(sez bradch(rp)) */
vgrpfKeyBoardState |= (GetKeyState(VK_CONTROL)<0) ? wKbsControlMask : 0;
/* FUTURE: cursor keys will be in keymap someday... */
/* but because they're not, need to special case preview */
if (vlm != lmPreview && FCursKey(kc, !vfInsertMode /*fDoIt*/ ))
return !vfInsertMode;
kc = KcModified(kc); /* Apply Shift, Ctrl, etc. */
if (vfInsertMode)
{
extern KME * PkmeOfKcInChain();
KME * pkme;
#ifdef DEBUG /* special debug key processing */
if (FProcessDbgKey(kc))
{
/* message has been dealt with, throw away! */
GetMessage(lpmsg, NULL, 0, 0);
return fTrue;
}
#endif /* DEBUG */
if ((pkme = PkmeOfKcInChain(kc)) == 0)
{
/* key not in table, try to translate */
GetMessage(lpmsg, NULL, 0, 0);
/* Ctrl+ keys are not translated so we do
not have to deal with the CHAR message. */
#ifdef INTL
if (!TranslateMessage(lpmsg)) /* no beep on Ctrl+Alt */
#else
if ((FCtrlKc(kc) && !FAltKc(kc)) || !TranslateMessage(lpmsg))
#endif
#ifdef OPUS_X64
MessageBeep(MB_OK);
#else
Beep();
#endif
}
else if (pkme->kt == ktInsert)
{
/* key is special insert type */
GetMessage(lpmsg, NULL, 0, 0);
/* indicate we have a char to insert */
lpmsg->wParam = pkme->ch | 0x8000;
}
else
{
/* command key not handled yet, tell
insert loop to stop */
return fFalse;
}
}
else /* !vfInsertMode */
{
if (!FExecKc(kc) && vkme.kt == ktInsert)
{
kc = vkme.ch;
goto LInsert;
}
}
return fTrue;
/* FUTURE: trash this when SetOurKeyState() is trashed (BAC) */
case WM_MOUSEMOVE:
if (vfInsertMode)
return fFalse;
/* Windows doesn't give us the shift KEYUP message if
mouse button is down!! */
SetOurKeyState();
/* FALL THROUGH */
case WM_SYSKEYUP:
case WM_KEYUP:
LTranslate:
if (vfInsertMode)
GetMessage(lpmsg, NULL, 0, 0);
SetOurKeyState(); /* must be done after msg removed for win3 */
TranslateMessage(lpmsg);
DispatchMessage(lpmsg);
return fTrue;
}
return fFalse;
}
/*************************************************************************/
/********************** CODE LRU MANIPULATIONS *************************/
/*************************************************************************/
#define cparaStrip (55*64)
/* sizes to request/get back */
csconst int mpsascpara[sasMin+1] =
{
/*sas, swap area >= */
/*0*/ 210*64, /* what we really want */
/*1*/ 175*64, /* enough for SDM */
/*2*/ 150*64, /* acceptable (won't load SDM) */
/*3*/ 128*64, /* lowest "good" amount - get warning & lose fonts below here */
/*4*/ 115*64,
/*5*/ 100*64,
/*6*/ 90*64,
/*7*/ 60*64,
/*8*/ cparaStrip
}; /* number of elements MUST equal mpsaseid in init2.c! */
int vsasCur = sasMin;
int vcShrinkSwapArea = 0;
int vfNoCoreLoad;
int vcparaReserve;
/* REVIEW ship(pj): do i really want this to stay around? */
int vcparaMaxReqLast = 0;
int vcparaRequestLast = 0;
int vcparaSwapLast = 0;
/* O U R S E T S A S */
/* Set Opus's SwapAreaSize according to sas */
/* %%Function:OurSetSas %%Owner:peterj */
EXPORT OurSetSas(sas)
int sas;
{
int cparaSwap;
Assert(sas >= 0 && sas <= sasMin);
if (vfNoCoreLoad Debug(|| vdbs.fNoCoreLoad))
{
vsasCur = sasMin;
return;
}
if (vcShrinkSwapArea != 0)
/* someome is counting on the fact that we are using min swap area */
sas = sasMin;
/* block - compute amount to ask for */
{
int cparaMaxReq = CpMin(SetSwapAreaSize(0) + (GlobalCompact(0)/16)
- vcparaReserve, 0x00007fffL);
int cparaRequest = min(mpsascpara[sas], max(cparaStrip, cparaMaxReq));
Assert(vfLargeFrameEMS == 0 || vfLargeFrameEMS == 1);
cparaSwap = SetSwapAreaSize(cparaRequest);
/* for use by AppInfo$() */
vcparaMaxReqLast = cparaMaxReq;
vcparaRequestLast = cparaRequest;
vcparaSwapLast = cparaSwap;
#ifdef DCORELOAD
CommSzNum(SzShared("sas = "), sas);
CommSzNum(SzShared("cparaRequest = "), cparaRequest);
CommSzNum(SzShared("cparaSwap = "), cparaSwap);
#endif /* DCORELOAD */
}
/* given how much swap area we now have, what can we do with it? */
for (vsasCur = sas; vsasCur < sasMin; vsasCur++)
{
if (mpsascpara[vsasCur] <= cparaSwap)
break;
}
#ifdef DCORELOAD
CommSzNum (SzShared("\t\tvsasCur = "), vsasCur);
CommSzNum (SzShared("\t\tSwap Area Available (K)= "), cparaSwap/64);
#endif /* DCORELOAD */
}
/* C O R E N E W E S T */
/* Makes newest (or loads) the Opus core. Also loads portions of Windows
needed for our "core" functionality. Pays some attention to how much
memory is available when loading. Interruptable when loading.
*/
/* %%Function:CoreNewest %%Owner:peterj */
CoreNewest(fLoad)
BOOL fLoad;
{
int ihcd;
extern int vsasCur;
if (hmwdCur == hNil || vfDeactByOtherApp)
return;
#ifdef DCORELOAD
if (fLoad)
CommSz(SzShared(" {"));
#endif /* DCORELOAD */
/* SDM - all (just Newest it) */
if (FAbortNewestCmg(cmgCoreSdmAll, fFalse, fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* windows code for scroll bars */
if ((vpref.fHorzScrollBar || vpref.fVertScrollBar) &&
FAbortNewestCmg(cmgCoreWinScroll, (fLoad && vsasCur <= 2), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* windows core */
if (FAbortNewestCmg(cmgCoreWindows, (fLoad && vsasCur <= 2), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* optional core */
if (vpref.fBkgrndPag &&
FAbortNewestCmg(cmgCoreLayout, (fLoad && vsasCur <= 3), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
if ((vhwndRibbon || (hmwdCur != hNil && (*hmwdCur)->hwndRuler != NULL))
&& FAbortNewestCmg(cmgCoreRibbon, (fLoad && vsasCur <= 4), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
if (vhwndStatLine &&
FAbortNewestCmg(cmgCoreStatline, (fLoad && vsasCur <= 4), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* SDM - startup portion */
if (FAbortNewestCmg(cmgDlgNew, (fLoad && vsasCur <= 1), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* semi optional portion of core */
if (FAbortNewestCmg(cmgCore1, (fLoad && vsasCur <= 5), fTrue))
goto LDone;
if (FMsgPresent(mtyIdle))
goto LDone;
/* not really optional core */
FAbortNewestCmg(cmgCore2, (fLoad && vsasCur <= 6), fTrue);
if (FMsgPresent(mtyIdle))
goto LDone;
/* not really optional core */
FAbortNewestCmg(cmgCore3, (fLoad && vsasCur <= 7), fTrue);
LDone:
;
#ifdef DCORELOAD
if (fLoad)
{
static int cLoad = 0;
CommSz(SzShared("} "));
if (!(++cLoad & 15))
CommSz(SzShared("\r\n"));
}
#endif /* DCORELOAD */
}
/* F A B O R T N E W E S T C M G */
/* Makes Code Module Group identified by cmg newest. If fLoad will force
them to be loaded. May be interrupted if fAbortOk. Returns fTrue if
interrupted, otherwise fFalse.
See core.h for structures etc.
*/
/* %%Function:FAbortNewestCmg %%Owner:peterj */
FAbortNewestCmg (cmg, fLoad, fAbortOk)
int cmg;
BOOL fLoad, fAbortOk;
{
HANDLE hcd;
int iihcd = 0;
int ihcd;
#ifdef HYBRID
if (vfShowSwapping)
return fFalse;
#endif /* HYBRID */
#ifdef DEBUG
if (vdbs.fNoCoreLoad)
return fFalse;
#endif /* DEBUG */
if (vfNoCoreLoad || vhwndCBT != NULL)
return fFalse;
/* so we don't kick them out on their way in! */
if (fLoad && FAbortNewestCmg(cmg, fFalse, fAbortOk))
return fTrue;
while ((ihcd = mpcmgrgihcd [cmg][iihcd++]) != ihcdEnd)
{
MSG msg;
if (fAbortOk &&
PeekMessage(&msg, NULL, NULL, NULL, PM_NOYIELD|PM_NOREMOVE))
{
#ifdef DCORELOAD
CommSz(SzShared("FAbortNewestCmg aborted\r\n"));
#endif /* DCORELOAD */
return fTrue;
}
if (fLoad || (hcd = rghcdModules [ihcd]) == NULL)
{
StartUMeas (umGetCodeHandle);
hcd = rghcdModules[ihcd] = GetCodeHandle(mpihcdpfnModules[ihcd]);
StopUMeas (umGetCodeHandle);
}
StartUMeas (umGlobalLru);
GlobalLruNewest (hcd);
StopUMeas (umGlobalLru);
}
return fFalse;
}
/* O L D E S T C M G */
/* makes modules in cmg oldest.
*/
/* %%Function:OldestCmg %%Owner:peterj */
OldestCmg (cmg)
int cmg;
{
int iihcd = 0;
int ihcd;
HANDLE hcd;
while ((ihcd = mpcmgrgihcd [cmg][iihcd++]) != ihcdEnd)
{
if ((hcd = rghcdModules[ihcd]) == NULL)
continue;
StartUMeas (umGlobalLru);
GlobalLruOldest (hcd);
StopUMeas (umGlobalLru);
}
}
/* G E T N E X T H C D */
/* Finds the next NULL entry in rghcdModules and obtains the module handle
for it.
*/
/* %%Function:GetNextHcd %%Owner:peterj */
GetNextHcd()
{
int ihcd;
for (ihcd = 0; ihcd < ihcdQuietlyLoadMax; ihcd++)
{
if (rghcdModules[ihcd] == NULL)
{
rghcdModules[ihcd] = GetCodeHandle(mpihcdpfnModules[ihcd]);
Assert(rghcdModules[ihcd] != NULL);
break;
}
}
#ifdef DCORELOAD
if (ihcd == ihcdQuietlyLoadMax)
{
static int fReported = fFalse;
if (!fReported)
CommSz(SzShared("All desired handles in rghcd obtained\r\n"));
fReported = fTrue;
}
#endif /* DCORELOAD */
}
/*
Return true if the window is not visible */
/* %%Function:FWindowHidden %%Owner:peterj */
FWindowHidden(ww)
int ww;
{
Assert(ww);
return !IsWindowVisible(PwwdWw(ww)->hwnd);
}
#ifdef DEBUG /* debug routines that we would like to be in the core */
/* D u m m y */
/* A Do-nothing function useful for breakpointing in the middle of
long routines */
/* %%Function:Dummy %%Owner:peterj */
Dummy()
{
}
/* %%Function:NatDummy %%Owner:peterj */
NATIVE NatDummy() /* WINIGNORE - DEBUG only */
{
}
ARG_RAREEVENTS RareEvent[RareEventMax];
/* F R A R E P R O C */
/* this procedure returns true if the selected rare event has
occured the selected number of times
wEventNumber identifier of event
wRepetitions current repetition count
wRepetitionsMac stop repetition count
fOn count on/off flag
These variables will be typically set from the debugger or other debug
routines.
*/
/* %%Function:FRareProc %%Owner:peterj */
NATIVE FRareProc(n) /* WINIGNORE - DEBUG only */
int n;
{
int i;
int fRetVal;
fRetVal = fFalse;
for (i=0; i < RareEventMax; i++)
{
if (RareEvent[i].fOn && (RareEvent[i].wEventNumber == n))
if (RareEvent[i].wRepetitions < RareEvent[i].wRepetitionsMac)
if (++RareEvent[i].wRepetitions == RareEvent[i].wRepetitionsMac)
fRetVal = fTrue;
}
return(fRetVal);
}
/* %%Function:FRareNULL %%Owner:peterj */
NATIVE FRareNULL(re,w) /* WINIGNORE - DEBUG only */
int re;
int w;
{
int i;
int fRetVal;
fRetVal = w;
if (!fRetVal)
return NULL;
for (i=0; i < RareEventMax; i++)
{
if (RareEvent[i].fOn && (RareEvent[i].wEventNumber == re))
if (RareEvent[i].wRepetitions < RareEvent[i].wRepetitionsMac)
if (++RareEvent[i].wRepetitions == RareEvent[i].wRepetitionsMac)
fRetVal = NULL;
}
return(fRetVal);
}
/* A s s e r t H S z L n */
/* If H is not a valid, nonfree handle, report an Assertion failure
in file szFile, line line */
/* %%Function:AssertHSzLn %%Owner:peterj */
AssertHSzLn( h, szFile, line )
VOID **h;
CHAR szFile[];
int line;
{
struct DRF *pdrfList;
extern struct SCC vsccAbove;
for (pdrfList = vpdrfHead; pdrfList != NULL; pdrfList = pdrfList->pdrfNext)
if (pdrfList->dr.hplcedl == h)
{
if (!(*((struct PLC **)h))->fExtBase)
break;
Assert (pdrfList->dr.hplcedl == &pdrfList->pplcedl);
Assert (pdrfList->pplcedl == &pdrfList->dr.plcedl);
return;
}
if (!FCheckHandle (sbDds, h))
{
if (!(h == vsccAbove.hplcedl || *h == &vsccAbove))
AssertProc(szFile, line );
}
}
#endif /* DEBUG */
/* %%Function:ForceCursorChange %%Owner:peterj */
ForceCursorChange(hwnd, ppt, fExact)
HWND hwnd;
struct PT * ppt;
BOOL fExact;
{
HCURSOR hc = NULL;
struct WWD *pwwd;
BOOL fOtlEmpty;
extern struct SEL selCur;
extern int vfInLongOperation;
extern int mwCur;
extern HWND vhwndPgPrvw;
extern struct WWD **mpwwhwwd[];
extern HCURSOR vhcArrow, vhcRecorder, vhcIBeam, vhcBarCur,
vhcHelp, vhcStyWnd, vhcOtlCross, vhcColumn;
extern BOOL vfHelp, vfRecording;
extern struct WWD **hwwdCur;
vidf.fCorrectCursor = fFalse;
if (vfHelp)
hc = vhcHelp;
else if (vfInLongOperation)
hc = vhcHourGlass;
else if (hwnd == NULL || vhwndPgPrvw != NULL)
hc = vhcArrow;
else if (vfRecording)
hc = vhcRecorder;
if (hc != NULL)
goto lblSet;
hc = vhcArrow;
if (hwwdCur != hNil && hwnd == (pwwd = *hwwdCur)->hwnd)
{
int ww = wwCur;
int xw = ppt->xw;
int dxp = vsci.dxpBorder << 1;
Assert(ww != wwNil);
Assert(wwCur == GetWindowWord(hwnd, IDWWW));
Assert(mwCur == pwwd->mw);
if (pwwd->xwSelBar && xw < pwwd->xwSelBar + dxp)
{
Assert(!pwwd->fPageView);
if (xw <= pwwd->xwSelBar &&
xw >= pwwd->xwSelBar - dxp /* fNearSty */)
{
if (vhcStyWnd == NULL && !FAssureIrcds(ircdsStyWnd))
hc = vhcArrow;
else
hc = vhcStyWnd;
}
else
hc = vhcBarCur;
}
else if (ppt->yw >= pwwd->ywMin)
{
if (fExact)
{
int idr;
int dl;
struct PLDR **hpldr;
struct PT ptT;
struct SPT spt;
ptT = *ppt;
if ((fOtlEmpty = FOutlineEmpty(ww, fFalse)) ||
(dl = DlWherePt(ww, &ptT, &hpldr, &idr, &spt, fTrue, fTrue))
== dlNil)
goto lblSet;
if (spt.fWholeColumn)
hc = vhcColumn;
else if (spt.fSelBar)
{
hc = vhcBarCur;
dl = DlWherePt(ww, &ptT, &hpldr, &idr, &spt, fFalse, fFalse);
if ((*hwwdCur)->fOutline && !fOtlEmpty && dl != dlNil &&
FXwInBullet(ww, dl, ppt->xw))
{
int yp, ywBottom;
struct EDL edl;
GetPlc(PdrGalley(PwwdWw(ww))->hplcedl, dl, &edl);
yp = edl.ypTop + edl.dyp;
ywBottom = YwFromYp(((edl.hpldr != hNil) ?
edl.hpldr : HwwdWw(ww)), 0, yp);
if (ppt->yw <= ywBottom)
hc = vhcOtlCross;
}
}
else
{
hc = (selCur.fGraphics ? vhcArrow : vhcIBeam);
}
}
else
{
vidf.fCorrectCursor = fTrue;
hc = vhcIBeam;
}
}
}
lblSet:
SetCursor( hc );
}
/* L M E N U C H A R */
/*
Handle WM_MENUCHAR messages. Returns 0 if message should be
passed to DefWindowProc(). Non-0 return values should be returned
by the window proc receiving the message.
*/
/* %%Function:LMenuChar %%Owner:peterj */
#ifdef OPUS_X64
LRESULT LMenuChar(HWND hwnd, WPARAM wParam, LPARAM lParam)
#else
LONG LMenuChar(hwnd, wParam, lParam)
HWND hwnd;
WORD wParam;
LONG lParam;
#endif
{
if (vhwndAppModalFocus != NULL)
return MAKELONG(0, 1);
#ifdef OPUS_X64
if (LOWORD(wParam) == '-' && !(HIWORD(wParam) & MF_POPUP) &&
hwwdCur != hNil)
#else
if (wParam == '-' && !(LOWORD(lParam) & MF_POPUP) && hwwdCur != hNil)
#endif
{
if (vfSysMenu)
{
if (hwnd == vhwndApp)
return MAKELONG(0,2);
PostMessage(vhwndApp, WM_MENUCHAR, wParam, lParam);
return MAKELONG(0, 1);
}
if (hwnd == vhwndApp)
{
vfChildSysMenu = fTrue;
return MAKELONG(0, 1);
}
return MAKELONG(0, 2);
}
return 0;
}
/* I N H I B I T R E C O R D E R */
/*
Called to inhibit or allow recording operation for the subsequent
actions. Inhibits when fInhibit is true. The state of both vfRecording
and vfRecordNext are saved in *pwsave, so the saved value should not
used by any other function. The saved value will either be 0 if
neither flag was on, 1 if vfRecording if on, or 2 if both flags are on.
Note that vfRecordNext cannot be on if vfRecording is not on, so we can
simply add the flags to give a numerical value of 0, 1, or 2.
/*
/* %%Function:InhibitRecorder %%Owner:tonykr */
InhibitRecorder(pwSav, fInhibit)
BOOL *pwSav, fInhibit;
{
Assert(fTrue == 1 && fFalse == 0);
Assert(vfRecording == fTrue || vfRecording == fFalse);
Assert(vfRecordNext == fTrue || vfRecordNext == fFalse);
Assert((2 == 2) == 1);
if (fInhibit)
{
*pwSav = vfRecording + vfRecordNext;
Assert(*pwSav != 1 || !vfRecordNext);
vfRecording = fFalse;
vfRecordNext = fFalse;
}
else
{
if (vhcmr == hNil && !vfRecordNext && *pwSav != 2)
{
vfRecording = fFalse;
vfRecordNext = fFalse;
}
else
{
vfRecordNext = ((*pwSav == 2 || vfRecordNext) && vhcmr == hNil);
vfRecording = (*pwSav != 0 || vfRecording);
}
selCur.fUpdateStatLine = fTrue; /* force a stat line update in Idle */
}
}
#ifdef DEBUG
extern struct PLSBHI ** vhplsbhi;
BOOL vfBogusHeapState = fFalse;
/* R E P O R T H E A P */
/* %%Function:ReportHeapSz %%Owner:peterj */
ReportHeapSz (sz, cbDiff)
CHAR *sz;
int cbDiff;
{
static uns cbHeapLast = 0;
static uns cbTotalLast = 0;
static long cbFarLast = 0L;
if (vfBogusHeapState)
return;
{
uns cbHeap = CbAvailHeap(sbDds);
uns dcbDS = cbMaxSbDds - CbSizeSb(sbDds);
uns cbTotal = cbHeap + dcbDS;
long cbFarUsed=MemUsed(1)-CbSizeSb(sbDds);
long cbFarAvail=LcbUnusedEmm();
long cbEmmUsed=MemUsed(2)-((long)vbptbExt.ibpMax*cbSector)-cbFarAvail;
long dcbFar;
long cbEmm = smtMemory==smtLIM ? CbFreeEmm() : 0L;
CHAR rgch [100], *pch = rgch;
dcbFar = cbFarUsed + cbEmmUsed - cbFarLast;
if (abs(cbHeap-cbHeapLast)>=cbDiff || abs(cbTotal-cbTotalLast)>=cbDiff
|| dcbFar >= cbDiff || -dcbFar >= cbDiff)
{
SetBytes(rgch, ' ', 100);
CchPchToPpch(sz, &pch);
pch = max (pch, rgch+13);
CchPchToPpch(SzShared(" local="), &pch);
CchUnsToPpch(cbHeap, &pch);
*pch++ = '+';
CchUnsToPpch(dcbDS, &pch);
*pch++ = '=';
*pch++ = ' ';
CchUnsToPpch(cbTotal, &pch);
pch = max (pch, rgch+33);
CchPchToPpch(SzShared(" farUsed="), &pch);
CchLongToPpch(cbFarUsed, &pch);
if (smtMemory==smtLIM)
{
*pch++='+';
CchLongToPpch(cbEmmUsed, &pch);
}
if (smtMemory==smtLIM)
{
pch = max (pch, rgch+59);
CchPchToPpch(SzShared(" emm="), &pch);
CchLongToPpch(cbEmm, &pch);
*pch++='+';
CchLongToPpch(cbFarAvail, &pch);
}
*pch++ = '\r';
*pch++ = '\n';
*pch = 0;
CommSz(rgch);
cbHeapLast = cbHeap;
cbTotalLast = cbTotal;
cbFarLast = cbFarUsed+cbEmmUsed;
}
}
}
BOOL vfAllocGuaranteed; /* alloc should succeed unconditionally */
BOOL vfInDebug; /* in debug code, don't force failures */
/* R E P O R T F A I L C A L L S */
/* %%Function:ReportFailCalls %%Owner:peterj */
ReportFailCalls()
{
if (vdbs.cWinCalls || vdbs.cLmemCalls)
{
CHAR rgch[cchMaxSz], *pch = rgch;
CchPchToPpch(SzShared("\r\nMem calls = "), &pch);
CchUnsToPpch(vdbs.cLmemCalls, &pch);
CchPchToPpch(SzShared(" Win calls = "), &pch);
CchUnsToPpch(vdbs.cWinCalls, &pch);
*pch++ = '\r';
*pch++ = '\n';
*pch = 0;
CommSz(rgch);
vdbs.cLmemCalls = 0;
vdbs.cWinCalls = 0;
}
}
/* F F A I L L M E M O P U S */
/* Return fTrue to cause lmem allocation to fail, fFalse to allow them to
succeed.
*/
/* %%Function:FFailLmemOpus %%Owner:peterj */
EXPORT FFailLmemOpus (merr, sb, cbNew, cRetry)
WORD merr;
SB sb;
WORD cbNew;
WORD cRetry;
{
extern BOOL vfInitializing;
extern BOOL vfInCmd;
if (vfBogusHeapState)
return fFalse;
if (!vfInitializing)
{
#ifdef DLMEM
int rgw [5];
rgw[0] = merr;
rgw[1] = sb;
rgw[2] = cbNew;
rgw[3] = CbSizeSb(sb);
rgw[4] = CbAvailHeap(sb);
CommSzRgNum(SzShared("FFailLmemOpus (merr,sb,cbNew,cbSb,cbAvail): "), rgw, 5);
#endif /* DLMEM */
if (vdbs.fReportHeap)
ReportHeapSz(SzShared("memory usage."), 200);
}
Assert (vdbs.cLmemSucceed >= 0 && vdbs.cLmemFail >= 0);
Assert (cHpFreeze == 0 || sb != sbDds);
if (vfAllocGuaranteed || vfInDebug)
return fFalse;
Assert(!vfInCommit);
if (vdbs.fOutsideCmd || vfInCmd)
{
if (vdbs.fHeapAct)
CommSz(SzShared("h"));
vdbs.cLmemCalls++;
if (vdbs.cLmemSucceed)
{
if (vdbs.fHeapAct)
CommSz(SzShared("s "));
vdbs.cLmemSucceed--;
return fFalse;
}
if (vdbs.cLmemFail)
{
if (vdbs.fHeapAct)
CommSz(SzShared("f "));
vdbs.cLmemFail--;
if (vdbs.fBreakOnFail)
DebugBreak(1);
if (sb == sbDds)
FreePh(&vmerr.hrgwEmerg1);
return fTrue;
}
if (vdbs.fHeapAct)
CommSz(SzShared(" "));
}
return fFalse;
}
#endif /* DEBUG */
#ifdef DEBUG
/* %%Function:CkFarHeaps %%Owner:peterj */
CkFarHeaps()
{
struct SBHI *psbhi = PInPl(vhplsbhi, 0);
struct SBHI *psbhiMac = psbhi + (*vhplsbhi)->isbhiMac;
VOID **ppv;
int ch;
while (psbhi < psbhiMac)
{
if (psbhi->fHasHeap)
{
CheckHeap(psbhi->sb);
if (vdbs.fShakeHeap)
ShakeHeapSb(psbhi->sb);
ch = 0;
ppv = NULL;
for (;;)
if ((ppv = PpvWalkHeap(psbhi->sb, ppv)) == NULL)
break;
else
ch++;
Assert(ch == psbhi->ch);
}
else
{
Assert(CbSizeSb(psbhi->sb) > cbMinBig-dcbBigSmall);
Assert(psbhi->ch == 1);
Assert(!psbhi->fHasFixed);
}
/* other checks */
Assert(psbhi->ch || psbhi->fHasFixed);
psbhi++;
}
}
#endif /* DEBUG */
#ifdef DEBUG
/* %%Function:SbMgrError %%Owner:peterj */
SbMgrError(sberr, sb)
int sberr;
SB sb;
{
extern BOOL fElActive;
IdPromptBoxSz(SzShared("SB Manager interface error"),MB_TROUBLE);
if (fElActive)
{
FlagRtError(rerrInternalError);
}
}
#endif /* DEBUG */
int vfMsg=fFalse; /* tell caller whether msg arrived */
/* F S t i l l D o w n R e p l a y */
/* %%Function:FStillDownReplay %%Owner:peterj */
FStillDownReplay( ppt, fRightButton )
struct PT *ppt;
BOOL fRightButton;
{ /* This is roughly equivalent to a Mac routine that returns whether
the mouse button is down. We look for one mouse message from our
window's queue, and return FALSE if it is a BUTTONUP. We return the
point at which the mouse event occurred through a pointer. If no
message occurred, we return whether the left button is down
and do not store into the pointer
Note that we specifically do not return the state of the right button;
our right button processing is handled at the top of DoContentHit, and
we don't want to deal with dragging that button in this loop. (bz).
*/
MSG msg;
/* Since re-entrancy can move the heap sometimes, shake it */
Debug(vdbs.fShakeHeap ? ShakeHeap() : 0);
if ( (vfMsg = PeekMessage( (LPMSG)&msg, (HWND)NULL, NULL, NULL, TRUE )) )
{
switch (msg.message)
{
default:
TranslateMessage( (LPMSG)&msg );
DispatchMessage( (LPMSG)&msg );
break;
case WM_RBUTTONUP:
case WM_LBUTTONUP:
if (fRightButton != (msg.message == WM_RBUTTONUP))
break;
ppt->xp = MAKEPOINT( msg.lParam ).x;
ppt->yp = MAKEPOINT( msg.lParam ).y;
return fFalse;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_MOUSEMOVE:
/* A Mouse Move, Mouse Down, or Mouse Up is waiting */
ppt->xp = MAKEPOINT(msg.lParam).x;
ppt->yp = MAKEPOINT(msg.lParam).y;
break;
}
}
#ifdef OPUS_X64
/*
* The Win16 loop could rely on GetKeyState's queue snapshot while nested
* inside the button-down dispatch. On modern Windows that snapshot can
* lag the physical/SENDINPUT transition and prematurely end a drag before
* the corresponding button-up reaches this replay loop.
*/
return ((GetAsyncKeyState(fRightButton ? VK_RBUTTON : VK_LBUTTON) &
0x8000) != 0);
#else
return (GetKeyState( fRightButton ? VK_RBUTTON : VK_LBUTTON ) < 0);
#endif
}
/* %%Function:CloseEveryFn %%Owner:peterj */
CloseEveryFn( fHardToo )
{ /* Close all files we have open. Close only files on removable media
if fHardToo is FALSE; ALL files if fHardToo is TRUE */
extern int fnMac;
int fn;
struct FCB **hfcb;
for ( fn = 0; fn < fnMac; fn++ )
if ((hfcb = mpfnhfcb [fn]) != NULL)
{
struct FCB *pfcb = *hfcb;
int osfn = pfcb->osfn;
if (osfn != osfnNil)
{
if (fHardToo || !pfcb->ofh.fFixedDisk)
{
/* Close may fail if windows already closed the file for us, but that's OK */
FCloseDoshnd( osfn );
pfcb->osfn = osfnNil;
}
}
}
}
/* E N A B L E P R E L O A D */
/* Make subsequent accesses to fn load large chunks.
Does not guarantee that preloading will be done for fn (if a
preload is already in progress, this one is ignored).
*/
/* %%Function:EnablePreload %%Owner:peterj */
EnablePreload(fn)
int fn;
{
if (!vcPreload++)
{
Assert(vfnPreload == fnNil);
vfnPreload = fn;
}
}
/* %%Function:DisablePreload %%Owner:peterj */
DisablePreload()
{
if (--vcPreload == 0)
vfnPreload = fnNil;
Assert(vcPreload >= 0);
}
#ifdef PROFILE
/* P C O D E S T A R T P R O F I L E R */
/* %%Function:PcodeStartProfiler %%Owner:peterj */
PcodeStartProfiler()
{
}
/* P C O D E S T O P P R O F I L E R */
/* %%Function:PcodeStopProfiler %%Owner:peterj */
PcodeStopProfiler()
{
}
#endif /* PROFILE */
#ifdef PROFILE
/* this is here so that appended native code does not appear in previous
function in pcode profiles. */
Wproc_Last(){}
#endif /* PROFILE */
/* ADD NEW CODE *ABOVE* Wproc_Last() */