对于前面提到的后台自动运行的持续的DRC检查器,也是在DRCcontin.c
中实现的,核心方法为DRCContinuous
,由WindDispatch()
调用,这个函数会一直运行,检查当前窗口中是否有待DRC的区域,如果有则就会使用恰当的方式进行检查。当用户键入了一个新的命令后,这个函数会以最快的方式进入中断。
void
DRCContinuous()
{
#ifndef MAGIC_WRAPPER
Rect drc_orig_bbox; /* Area of DRC def that changed. */
#endif
if (DRCHasWork == FALSE)
{
#ifdef MAGIC_WRAPPER
DRCStatus = DRC_NOT_RUNNING;
#endif
return;
}
#ifdef MAGIC_WRAPPER
if (DRCStatus != DRC_NOT_RUNNING) return; /* Avoid infinitely recursive loop */
GrFlush();
DRCStatus = DRC_IN_PROGRESS;
Tcl_EvalEx(magicinterp, "after idle magic::drcstate busy", -1, 0);
if (TxInputRedirect != TX_INPUT_REDIRECTED) TxSetPrompt(']');
/* fprintf(stderr, "Starting DRC\n"); fflush(stderr); */
#endif
UndoDisable(); /* Don't want to undo error info. */
drc_orig_bbox = DRCdef->cd_bbox;
while (DRCPendingRoot != (DRCPendingCookie *) NULL)
{
/* DBSrPaintArea() returns 1 if drcCheckTile()
* returns 1, meaning that a CHECK tile
* was found and processed.
*/
while ((DRCPendingRoot != (DRCPendingCookie *)NULL) &&
DBSrPaintArea ((Tile *) NULL,
DRCPendingRoot->dpc_def->cd_planes[PL_DRC_CHECK],
&TiPlaneRect, &DBAllButSpaceBits, drcCheckTile, (ClientData) NULL))
{
/* check for new user command (without blocking) */
#ifdef MAGIC_WRAPPER
/* Execute pending Tcl events, so the DRC process doesn't block. */
/* NOTE: Exclude file events, or else "drc catchup" will not work */
/* in batch mode. */
UndoEnable();
while (Tcl_DoOneEvent(TCL_DONT_WAIT))
{
if (DRCStatus == DRC_BREAK_PENDING)
{
/* fprintf(stderr, "DRC exiting loop. .