magic/oa/oa.c

193 lines
6.4 KiB
C

/*--------------------------------------------------------------*/
/* oa.c -- */
/* OpenAccess database support for magic */
/* */
/* Written by R. Timothy Edwards 4/22/04 */
/* Open Circuit Design, Inc. for */
/* MultiGiG, Inc. */
/*--------------------------------------------------------------*/
#ifdef MAGIC_WRAPPER
#ifdef OPENACCESS
#include "tcltk/tclmagic.h"
#include "utils/geometry.h"
#include "utils/magic.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "oa/oa.h"
/*
*-----------------------------------------------------------------------------
*
* OAInit --
*
* Initialize variables required by the OpenAccess module.
*
*-----------------------------------------------------------------------------
*/
void
OAInit()
{
/* This generates the TCL commands for magicoa */
Magicoa_Init(magicinterp);
}
/*
*-----------------------------------------------------------------------------
*
* OACellSearch --
*
* The OpenAccess equivalent of DBTreeSrCells. This function is called by
* DBTreeSrCells when the cell def has the flag CDOPENACCESS set.
*
* The procedure should be of the following form:
* int
* func(scx, cdarg)
* SearchContext *scx;
* ClientData cdarg;
* {
* }
*
* In the above, the transform scx->scx_trans is from coordinates of
* the def of scx->scx_use to the "root". The array indices
* scx->scx_x and scx->scx_y identify this element if it is a
* component of an array. Func normally returns 0. If func returns
* 1, then the search is aborted. If func returns 2, then all
* remaining elements of the current array are skipped, but the
* search is not aborted.
*
* Each element of an array is returned separately.
*
* Results:
* 0 is returned if the search terminated normally. 1 is
* returned if it was aborted.
*
* Side effects:
* Whatever side effects are brought about by applying the
* procedure supplied.
*
* Warnings:
* The OpenAccess routines should only be used when (*func)()
* is read-only; that is, the function should not attempt to
* alter the cell structure.
*-----------------------------------------------------------------------------
*/
int
OACellSearch(scx, xMask, func, cdarg)
SearchContext *scx; /* Pointer to search context specifying a cell use to
* search, an area in the coordinates of the cell's
* def, and a transform back to "root" coordinates.
*/
int xMask; /* All subcells are visited recursively until we
* encounter uses whose flags, when anded with
* xMask, are not equal to xMask. Func is called
* for these cells. A zero mask means all cells in
* the root use are considered not to be expanded,
* and hence are passed to func.
*/
int (*func)(); /* Function to apply to each qualifying cell */
ClientData cdarg; /* Client data for above function */
{
TreeContext context;
TreeFilter filter;
char *instname;
filter.tf_xmask = xMask;
filter.tf_func = func;
filter.tf_arg = cdarg;
context.tc_scx = scx;
context.tc_filter = &filter;
/* Get the name of the instance, which should have been set by */
/* rexlite when the OpenAccess database was opened under magic. */
instname = scx->scx_use->cu_id;
/* Query the OpenAccess database. For each cell overlapping the
* area scx->scx_area, call the function (*func)() with client
* data cdarg. Currently, xMask is not used (assumed to be 0).
*/
/* The rexlite function is tentatively called REXSearchInstances(): */
/* REXSearchInstances(name, func, arg) { */
/* char *name; */
/* (int)(*func)(); */
/* ClientData arg; */
/* */
/* This function should return 0 normally, 1 in case of error. */
/* For each cell instance which is in the hierarchy of "instname", */
/* REXSearchInstances() should call "func" with arguments: */
/* */
/* (int)(*func)(char *iname, char *dname, int llx, int lly, */
/* int urx, int urx, ClientData arg); */
/* */
/* where "iname" is the name of the instance, "dname" is the name */
/* of the master cell, and "llx", "lly", "urx", and "ury" are the */
/* bounding box coordinates. "arg" is passed on from above. */
/* If func() returns 0, then the database search should continue. */
/* If func() returns 1, then the database search should stop and */
/* REXSearchInstances() should return 1. */
/* return REXSearchInstances(instname, oaTreeCellSrFunc, (ClientData)&context); */
return 0; /* placeholder */
}
/*
* Callback function called from REXSearchInstances() for each instance
* encountered in the cell search.
*
* For the time being, we pass back a minimal amount of information: The
* instance name and the bounding box. The bounding box will be compared
* against the search area to check for overlap, and the function buried
* in the TreeContext structure (passed as a generic client data pointer)
* will be called.
*/
int
oaTreeCellSrFunc(instname, defname, llx, lly, urx, ury, cdarg)
char *instname;
char *defname;
int llx, lly, urx, ury;
ClientData cdarg;
{
TreeContext *context = (TreeContext *)cdarg;
TreeFilter *filter = context->tc_filter;
SearchContext newscx, *scx = context->tc_scx;
int fres;
Rect r, *area = &scx->scx_area;
CellUse newuse;
/* Check for area overlap */
r.r_xbot = llx;
r.r_xtop = urx;
r.r_ybot = lly;
r.r_ytop = ury;
/* Transform---for now, assuming that llx, etc., are relative to */
/* the top-level coordinate system. */
/* Check for area overlap */
if (!GEO_OVERLAP(area, &r))
return 0; /* Don't call function but keep the search going */
newuse.cu_id = instname;
newuse.cu_bbox = r;
/* Need to fill in more of the CellUse structure! */
newscx.scx_use = &newuse;
newscx.scx_area = scx->scx_area;
/* Need to fill in more of the SearchContext structure! */
/* Call the function */
fres = (*(filter->tf_func))(newscx, (ClientData)filter->tf_arg);
return fres; /* keep the search going */
}
#endif /* OPENACCESS */
#endif /* MAGIC_WRAPPER */