home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
SDWIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-04
|
21KB
|
765 lines
/*
sdwin.c
% sedwin_Class: The sed window class
C-scape 3.2
Copyright (c) 1988, by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History:
-----------------
8/09/88 jmd revised to use new object stuff
8/12/88 jmd added explode flag (not functional)
9/12/88 jmd Added in and out data to objects
11/15/88 jmd Added inner ptd clipping
11/19/88 jmd Added mouse stuff
11/20/88 jmd add ID to objects
11/22/88 jmd Changed unsigneds to ints
11/28/88 jmd reorganized headers
12/02/88 jmd added nextwin, SIZEREQ and MOVEREQ msgsw
12/06/88 jmd added jumpwin
12/07/88 jmd added clipping for negative offsets
12/09/88 ted tweaked up pix-to-char coordinate conversions
12/13/88 jmd added blank to PlotFields call
12/13/88 ted Extracted REQ message handlers
2/07/89 jmd Initialized mousecode to avoid warning
3/24/89 jmd Added sed_ macros
3/29/89 jmd converted seds to 'pure' objects
4/11/89 jmd added closing flag, release bob support
4/11/89 jmd added single field paint optimization
moved Plot code from sddisp
fixed field blanking
4/16/89 jmd Added WINM_CHILDCLOSE msg.
5/10/89 jmd changed to ptd_ClearFrame
5/23/89 jdc made menu_RemoveBob() private (sedpriv.h) not static
5/29/89 jmd simplified paint flags
6/14/89 jmd made one routine to paint text and fields or just fields
8/06/89 ted Removed explode function stuff to window layer.
8/08/89 jmd Added new win messages (size, top, position).
8/09/89 jdc Added field marking
8/16/89 jdc Fixed field marking
8/21/89 jdc Added bob_SetParent(bob, NULL) in menu_RemoveBob
8/23/89 jmd added more tests for menu == NULL
11/06/89 jmd removed DoRaw Macro
12/10/89 jmd removed GO message; it's now passed up to win_Class
12/11/89 jmd added field higlighting
12/12/89 ted Added IsParentMove test for SETPOS methods for child menus.
1/04/90 jmd removed jump window
1/27/90 jmd added SED_GETVALUE message for future C-cell interaction
2/03/90 jmd added SED_CLOSE message
2/14/90 jdc added SetAux to FNULL
3/03/90 ted/pmcm Added support for sed_FindField -2 return in case of protected fields.
3/17/90 jmd added employed test for Cache/Flush
3/28/90 jmd ansi-fied
4/19/90 jdc added NULL check for menu in CLOSE
4/19/90 jdc preened
5/11/90 jmd added OGLOBAL declaration
6/12/90 jmd fixed incorrect comment
7/29/90 jmd removed call to sed_SetAux in CLOSE msg
9/24/90 jmd put the GO message back
10/04/90 jmd removed SED_GETVALUE message, now done via aux function
*/
#include "sed.h"
#include "sedwinod.h"
#include "scancode.h" /* for MOU codes */
#include "tbpriv.h" /* for box_sort() */
OGLOBAL objreq_fptr sdwinreq_mousefptr = objreq_Null;
OGLOBAL objreq_fptr sdwinreq_loadfptr = objreq_Null;
OGLOBAL objreq_fptr sdwinreq_savefptr = objreq_Null;
OSTATIC int CSPRIV field_getattr(sed_type sed, int fld);
int sedwin_Class(VOID *objdata, int msg, VOID *indata, VOID *outdata)
/*
Dispatch function for sed windows.
*/
{
sedwin_od *sedwd;
ptd_struct *ptd;
ofont_type font;
opcoord sedx, sedy;
int flag;
sed_type sed;
win_type win;
bob_type bob;
byte attr;
opcoord oldx, dx, oldy, dy;
register int i;
sedwd = (sedwin_od *) objdata;
if (msg != OBJM_GETDATASIZE) { /* would be GP fault in this case (od is NULL) */
sed = sedod_GetSelf(sedwd);
}
switch (msg) {
case OBJM_LOAD:
return((*sdwinreq_loadfptr)(objdata, msg, indata, outdata));
case OBJM_SAVE:
return((*sdwinreq_savefptr)(objdata, msg, indata, outdata));
case OBJM_GETDATASIZE:
((ogds_struct *) outdata)->odsize = sizeof(sedwin_od);
((ogds_struct *) outdata)->xdsize = sizeof(sed_xd);
((ogds_struct *) outdata)->id = ID_SEDWIN;
break;
case OBJM_OPEN:
/* initialize sedwin_od to NULL */
sedwd->closing = 0;
sedwd->blank = -1;
/* initialize the xd */
sed_SetBaton(sed, 1);
sed_RedirectPrompt(sed, sed);
sed_SetPaintFlag(sed, SDPF_ALL);
sed_SetRegAttr(sed, ATTR_NORMAL);
sed_SetSelAttr(sed, ATTR_REVERSE);
sed_SetCtype(sed, CURSOR_NORMAL);
sed_SetHiColors(sed, ATTR_BOLD, ATTR_REVERSE);
/* ted stuff */
sed_SetMove(sed, default_move);
#ifdef OAK_NULLNOT0
sed_SetTrow(sed, 0);
sed_SetTcol(sed, 0);
sed_SetSpecial(sed, FNULL);
sed_SetAux(sed, FNULL);
sed_SetExit(sed, FALSE);
sed_SetActive(sed, FALSE);
sed_SetLabel(sed, 0);
sed_SetData(sed, NULL);
sed_SetExplode(sed, FNULL);
sed_SetYoffset(sed, 0);
sed_SetXoffset(sed, 0);
/* done by sed_Init */
sed_SetFieldNo(sed, -1);
sed_SetCurrField(sed, NULL);
sed_SetRecordPos(sed, NO_WRITEABLES);
#endif
/* pass OPEN to win superclass */
return(win_Class(&(sedwd->wd), OBJM_OPEN, indata, outdata));
case OBJM_CLOSE:
/* Turn on closing flag. This prevents CHILDCLOSE message
from working
*/
sedwd->closing = 1;
/* Close the sed's menu */
if (sed_GetMenu(sed) != NULL) {
menu_Destroy(sed_GetMenu(sed));
/* set our menu to NULL to avoid complications further
down the message chain
*/
sed_SetMenu(sed, NULL);
}
/* pass CLOSE to win superclass */
return(win_Class(&(sedwd->wd), OBJM_CLOSE, indata, outdata));
case OBJM_WHO:
/* Identify ourselves */
if (*((int *) indata) == ID_SEDWIN) {
return(TRUE);
}
return(win_Class(&(sedwd->wd), msg, indata, outdata));
case WINM_PAINTREQ:
/* repaint the sed and its bobs,
employ them if they are unemployed.
indata points to an unsigned containing sed paint masks,
(refer to sed_Draw comment)
if indata == NULL use default settings
*/
{
unsigned mode, bobmode;
disp_Cache();
if (indata == NULL) {
/* use default settings */
mode = WPD_BORDER | WPD_TEXT | WPD_FIELDS | WPD_SENTER;
}
else {
mode = *((unsigned *) indata);
}
if (!win_IsEmployed(sed)) {
/* pass up SENTER message and let win_Employ do the rest */
/* Do senters for us and our bobs */
bobmode = (mode & WPD_SENTER) ? WPD_SENTER : 0;
}
else {
bobmode = mode;
}
/* pass message up to all our dependent children (pass flag) */
/* don't pass up paint border only message */
if (bobmode != WPD_BORDER && bobmode != 0) {
sed_DoThemBobs(sed, WINM_PAINTREQ, &bobmode, NULL, SDTB_DEP);
}
/* call our senters if desired */
if (mode & WPD_SENTER) {
/* Send pre message to ox function */
sed_DoAux(sed, SED_PRESENTER, NULL, NULL);
/* Call sentry functions. */
for (i = 0; i < sed_GetFieldCount(sed); i++) {
sed_DoFieldSenter(sed, i);
}
/* Send post message to ox function */
sed_DoAux(sed, SED_POSTSENTER, NULL, NULL);
}
if (mode != WPD_SENTER && mode != 0) {
/* set paint flags */
if ((mode & WPD_TEXT)) {
sed_SetPaintFlag(sed, SDPF_ALL);
}
else if ((mode & WPD_FIELDS)) {
sed_SetPaintFlag(sed, SDPF_FIELDS);
}
else {
sed_SetPaintFlag(sed, SDPF_NONE);
}
/* filter out sed specific mode bits */
mode &= WPD_BORDER;
/* pass paint message up to window class */
win_Class(&(sedwd->wd), msg, &mode, outdata);
/* reset paint flag */
sed_SetPaintFlag(sed, SDPF_ALL);
}
disp_Flush();
break;
}
case WINM_CHILDCLOSE:
/* release the window (bob) attached to the sed
ignore if the closing flag is set.
Note: indata is a win.
*/
if (!sedwd->closing && sed_GetMenu(sed) != NULL) {
menu_RemoveBob(sed_GetMenu(sed), (win_type) indata);
}
break;
case WINM_SETPOS:
/* A request to move the sed */
if (win_IsEmployed(sed)) {
disp_Cache();
}
/* get old position */
oldx = win_GetXmin(sed);
oldy = win_GetYmin(sed);
/* First, pass up the message to win_Class to move the sed */
win_Class(&(sedwd->wd), msg, indata, outdata);
/* Then move the dependent bobs or framer dropdowns (if any) relatively */
if (sed_GetMenu(sed) != NULL) {
dx = win_GetXmin(sed) - oldx;
dy = win_GetYmin(sed) - oldy;
for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
if (bob_IsDepend(bob) || bob_IsParentMove(bob)) {
oldx = win_GetXmin(bob);
oldy = win_GetYmin(bob);
win_SetPixPosition(bob, oldx + dx, oldy + dy);
}
}
}
}
if (win_IsEmployed(sed)) {
disp_Flush();
}
break;
case WINM_SETSIZE:
/* A request to size the sed - round up instead of down */
if (win_IsEmployed(sed)) {
disp_Cache();
}
/* first, pass up the message to win_Class to resize the sed */
win_Class(&(sedwd->wd), msg, indata, outdata);
if (sed_GetMenu(sed) != NULL) {
/* now, repaint all our dependent children */
for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
if (bob_IsDepend(bob)) {
bord_Paint(bob);
}
}
}
}
if (win_IsEmployed(sed)) {
disp_Flush();
}
break;
case WINM_PUTUNDER:
/* A request to put the sed under (win_type) indata */
win = (win_type) indata;
disp_Cache();
/* Top the sed's children first, in reverse order */
if (sed_GetMenu(sed) != NULL) {
for (i = menu_GetBobCount(sed_GetMenu(sed)) - 1; i >= 0; i--) {
if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
if (bob_IsDepend(bob)) {
win_PutUnder(bob, win);
win = bob;
}
}
}
}
/* pass message up to win_Class */
win_Class(&(sedwd->wd), msg, win, outdata);
disp_Flush();
break;
case WINM_UNEMPLOY:
/* pop all the sed's bobs (both indy and dependent */
disp_Cache();
if (sed_GetMenu(sed) != NULL) {
for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
win_UnEmploy(bob);
}
}
}
/* pass message up to win_Class to pop ourselves */
win_Class(&(sedwd->wd), msg, indata, outdata);
disp_Flush();
break;
case WINM_SCROLLREQ:
/* pass message to request handler func, linked in by sedwin_ClassInit */
return((*sdwinreq_mousefptr)(objdata, msg, indata, outdata));
case WINM_GETINPOS:
{
inposdata_struct *ipd;
/* make sure menu is valid (we could be in the middle of being
loaded from a screen file)
*/
if (sed_GetMenu(sed) == NULL) {
return(win_Class(&(sedwd->wd), msg, indata, outdata));
}
/* get the menu size relative to the sed
so that borders can compute scroll lights
*/
ipd = (inposdata_struct *)outdata;
font = win_GetFont(ipd->win);
ipd->inbox.xmin = - (sed_GetXoffset(sed) * ofont_GetWidth(font));
ipd->inbox.xmax = ipd->inbox.xmin +
(sed_GetMenuVWidth(sed) * ofont_GetWidth(font));
ipd->inbox.ymin = - (sed_GetYoffset(sed) * ofont_GetHeight(font));
ipd->inbox.ymax = ipd->inbox.ymin +
(sed_GetMenuVHeight(sed) * ofont_GetHeight(font));
break;
}
case WINM_SHADOW:
/* reset paint flag to shadow paint */
ptd = (ptd_struct *)indata;
sed_SetPaintFlag(sed, SDPF_SHADOW);
/* set ptd data to indicate that we've taken care of the shadow */
ptd->emsgdata = (VOID *) 1;
/* no break; fall through to PAINT */
case WINM_PAINT:
{
ptd_struct inptd; /* for use in inner-coordinate computations */
opbox inbox; /* ditto; gets hooked in by ptd_SetInner */
opbox relbox;
/* Paint the sed window */
ptd = (ptd_struct *)indata;
win = ptd->win;
if (ptd_SetInner(ptd, &inptd, &inbox)) {
opbox_copy(&relbox, inptd.relboxp);
sedx = -(sed_GetXoffset(sed) * win_GetFontWidth(win));
sedy = -(sed_GetYoffset(sed) * win_GetFontHeight(win));
/* if flag >= 0, paint only that field */
if ((flag = sed_GetPaintFlag(sed)) >= 0) {
/* Paint field, if it isn't blanked (used by sleds) */
if (sedwd->blank < 0 || field_GetRow(sed_GetField(sed, flag)) < sedwd->blank) {
sd_plot_field(sed, sed_GetField(sed, flag), flag, &inptd);
}
}
else if (flag != SDPF_NONE) {
/* paint the sed's text and fields */
/* Clip if we're scrolled in the negative direction */
if (relbox.xmax > sedx && relbox.xmin < sedx) {
relbox.xmin = sedx;
}
if (relbox.ymax > sedy && relbox.ymin < sedy) {
relbox.ymin = sedy;
}
/* Test if we should paint the text */
inptd.relboxp = &relbox;
if (sedx < relbox.xmax && sedy < relbox.ymax) {
sed_Ploat(sed, &inptd, sedwd->blank);
}
/* Clear regions above (0, 0) if scrolled negative */
/* if shadow, use the window shadow attr for clear frame */
attr = (msg == WINM_SHADOW) ? win_GetShadowAttr(sed) : win_GetAttr(sed);
inptd.relboxp = &inbox;
ptd_ClearFrame(&inptd, sedx, sedy,
win_GetPixWidth(win) - sedx,
win_GetPixHeight(win) - sedy,
disp_GetAttrBgColor(attr));
}
}
/* pass message up to win superclass (for cursor and border paint) */
win_Class(&(sedwd->wd), msg, indata, outdata);
if (msg == WINM_SHADOW) {
/* reset paint flag */
sed_SetPaintFlag(sed, SDPF_ALL);
}
break;
}
case WINM_GO:
/* Call sed_ReallyGo to activate the sed */
/* indata: NULL, outdata: int * */
/* Don't pass this up to parent; no WINA_GO message sent by seds */
*((int *) outdata) = sed_ReallyGo(sed);
break;
case WINM_GETFLDPOS:
/* get current location within the sed (used by grid movement) */
{
ocbox *ocboxp;
boolean isabob, gotbox;
int row, col;
/* outdata is a (ocbox *) */
ocboxp = (ocbox *) outdata;
gotbox = FALSE;
if (sed_GetFieldCount(sed) > 0) {
isabob = FALSE;
if ((bob = sed_GetFieldBob(sed, sed_GetFieldNo(sed))) != NULL) {
isabob = bob_IsDepend(bob);
}
if (isabob) {
ocboxp->toprow = 0;
ocboxp->botrow = 0;
ocboxp->leftcol = 0;
ocboxp->rightcol = 0;
bob_Do(bob, WINM_GETFLDPOS, NULL, ocboxp);
gotbox = TRUE;
}
else if (menu_GetFieldBox(sed_GetMenu(sed), sed_GetFieldNo(sed), ocboxp)) {
gotbox = TRUE;
/* Translate box to sed coordinates */
ocboxp->toprow -= sed_GetYoffset(sed);
ocboxp->botrow -= sed_GetYoffset(sed);
ocboxp->leftcol -= sed_GetXoffset(sed);
ocboxp->rightcol -= sed_GetXoffset(sed);
}
}
if (!gotbox) {
/* default values */
ocboxp->toprow = 0;
ocboxp->botrow = sed_GetHeight(sed);
ocboxp->leftcol = 0;
ocboxp->rightcol = sed_GetWidth(sed);
}
/* Coords refer to the inner window box, translate to outer box */
ocboxp->toprow -= (row = bord_GetRowOff(sed));
ocboxp->botrow -= row;
ocboxp->leftcol -= (col = bord_GetColOff(sed));
ocboxp->rightcol -= col;
break;
}
case WINM_SETFLDPOS:
/* jump to the field closest to curpos (used by grid movement) */
{
winsfp_struct *winsfp;
ocbox *ocboxp;
int row, col, fld;
/* indata is a (winsfp_struct *) */
winsfp = (winsfp_struct *) indata;
ocboxp = winsfp->ocboxp;
/* Coords refer to the outer window box, translate to inner box */
ocboxp->toprow += (row = bord_GetRowOff(sed));
ocboxp->botrow += row;
ocboxp->leftcol += (col = bord_GetColOff(sed));
ocboxp->rightcol += col;
if ((fld = sed_FindField(sed, ocboxp, winsfp->pref)) >= 0) {
sed_GotoField(sed, fld);
}
break;
}
case WINM_GETCHILDNO:
/* get the child number of a window (indata),
-1 if window is not a child
*/
/* indata is a (bob_type), outdata is an (int *) */
{
int childno = -1;
menu_type menu;
bob_type bob;
bob = (bob_type) indata;
menu = sed_GetMenu(sed);
/* Find the field number */
for (i = 0; i < menu_GetBobCount(menu); i++) {
if (bob == menu_GetBob(menu, i)) {
childno = menu_GetBobFieldNo(menu, i);
break;
}
}
*((int *)outdata) = childno;
break;
}
case WINM_SETCURRCHILD:
/* set the window's current child: do a goto field */
/* indata is an (int *) */
sed_GotoField(sed, *((int *)indata));
break;
default:
win_Class(&(sedwd->wd), msg, indata, outdata);
break;
}
return(TRUE);
}
/*----------------------------------------------------------------------------*/
/*** Field Plotting Functions ***/
void sd_plot_field(sed_type sed, field_type field, int fldno, ptd_struct *ptd)
/*
Draws one field
Called by either sed_Ploat or directly by sedwin.
*/
{
int markattr;
byte attr, hiattr;
int hichar = -1; /* highlighted character */
int m, c;
/* determine color of field */
/* highlight the current field if we're in an active sed */
if (sed_GetPaintFlag(sed) == SDPF_SHADOW) {
attr = win_GetShadowAttr(sed);
}
else if ((markattr = field_getattr(sed, fldno)) != -1) {
attr = (byte) markattr;
}
else {
if (fldno == sed_GetFieldNo(sed) && sed_IsActive(sed)) {
if (field_GetMarked(field)) {
attr = field_GetSelAttr(field);
}
else {
attr = sed_GetSelAttr(sed);
hichar = field_IsHiCharOn(field) ? (int) field_GetHiChar(field) : (int) -1;
hiattr = sed_GetHiSelAttr(sed);
}
}
else {
if (field_GetMarked(field)) {
attr = field_GetRegAttr(field);
}
else {
attr = sed_GetRegAttr(sed);
hichar = field_IsHiCharOn(field) ? (int) field_GetHiChar(field) : (int) -1;
hiattr = sed_GetHiRegAttr(sed);
}
}
}
/* draw the field merge, letting the window clip it
* Get field coords relative to the sed
* paint the field in three chunks:
* 1) before the highlighted char
* 2) the highlighted char
* 3) after the highlighted char
*/
m = field_GetXoffset(field);
c = 0;
/* before */
if (hichar > field_GetXoffset(field)) {
ptd_DrawString(ptd,
(field_GetRow(field) - sed_GetYoffset(sed)),
(field_GetCol(field) - sed_GetXoffset(sed)),
(field_GetMerge(field) + field_GetXoffset(field)),
attr,
hichar - field_GetXoffset(field));
}
/* during */
if (hichar >= field_GetXoffset(field)) {
m = hichar + 1;
c = m - field_GetXoffset(field);
ptd_DrawString(ptd,
(field_GetRow(field) - sed_GetYoffset(sed)),
(field_GetCol(field) - sed_GetXoffset(sed) + hichar - field_GetXoffset(field)),
(field_GetMerge(field) + hichar),
hiattr,
1);
}
/* after (default case for no highlighting) */
ptd_DrawString(ptd,
(field_GetRow(field) - sed_GetYoffset(sed)),
(field_GetCol(field) - sed_GetXoffset(sed) + c),
(field_GetMerge(field) + m),
attr,
field_GetWidth(field) - c);
}
/*----------------------------------------------------------------------------*/
/*** Auxillary Functions ***/
void menu_RemoveBob(menu_type menu, win_type win)
/*
Removes the reference to a bob from a menu.
(does not close the bob)
*/
{
register int i;
int fldno;
bob_type bob;
/* find bob in list */
for (i = 0; i < menu->bobcount; i++) {
bob = menu_GetFieldBob(menu, (fldno = ia_Get(menu->boba, i)));
if (win == bob) {
field_SetBob(menu_GetField(menu, fldno), NULL);
bob_SetParent(bob, NULL);
/* slide remaining elements in bobarray */
for (; i < menu->bobcount; i++) {
fldno = ia_Get(menu->boba, i + 1);
ia_Put(menu->boba, i, fldno);
}
menu->bobcount--;
break;
}
}
}
/*----------------------------------------------------------------------------*/
static int CSPRIV field_getattr(sed_type sed, int fld)
/*
tests if a field is affected by text marking.
(needed primarily for Look & Feel)
returns -1 if the field is not text marked, else the
attribute of the field.
*/
{
int attr = -1, mark, frow, fcol, flcol;
ocbox mbox;
field_type field;
if ((mark = sed_GetTextbuf(sed)->mark) != TED_NOMARK) {
box_sort(&mbox, &(sed_GetTextbuf(sed)->markbox), (mark == TED_MARK) ? BOXSORT_ROW:BOXSORT_COL);
field = sed_GetField(sed, fld);
frow = field_GetRow(field);
fcol = field_GetCol(field);
flcol = field_GetLastCol(field);
if (field_GetWidth(field) == 0 || frow > mbox.botrow || frow < mbox.toprow) {
;
}
else if (mark == TED_MARK) {
if (frow == mbox.toprow && flcol < mbox.leftcol) {
;
}
else if (frow == mbox.botrow && fcol > mbox.rightcol) {
;
}
else {
attr = sed_GetSelAttr(sed);
}
}
else if (fcol <= mbox.rightcol && flcol >= mbox.leftcol) {
attr = sed_GetSelAttr(sed);
}
}
return(attr);
}
/*----------------------------------------------------------------------------*/
boolean bob_IsSed(bob_type bob)
/*
Returns TRUE if the object is a sed.
*/
{
int id = ID_SEDWIN;
return(bob_Do(bob, OBJM_WHO, &id, NULL));
}
/*----------------------------------------------------------------------------*/