home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / CSSRC / SDWIN.C < prev    next >
C/C++ Source or Header  |  1990-10-04  |  21KB  |  765 lines

  1. /*
  2.     sdwin.c
  3.  
  4.     % sedwin_Class: The sed window class
  5.  
  6.     C-scape 3.2
  7.     Copyright (c) 1988, by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12.      8/09/88 jmd    revised to use new object stuff
  13.      8/12/88 jmd    added explode flag (not functional)
  14.      9/12/88 jmd    Added in and out data to objects
  15.     11/15/88 jmd    Added inner ptd clipping
  16.     11/19/88 jmd    Added mouse stuff
  17.     11/20/88 jmd    add ID to objects
  18.     11/22/88 jmd    Changed unsigneds to ints
  19.     11/28/88 jmd    reorganized headers
  20.     12/02/88 jmd    added nextwin, SIZEREQ and MOVEREQ msgsw
  21.     12/06/88 jmd    added jumpwin
  22.     12/07/88 jmd    added clipping for negative offsets
  23.     12/09/88 ted    tweaked up pix-to-char coordinate conversions
  24.     12/13/88 jmd    added blank to PlotFields call
  25.     12/13/88 ted    Extracted REQ message handlers
  26.  
  27.      2/07/89 jmd    Initialized mousecode to avoid warning
  28.      3/24/89 jmd    Added sed_ macros
  29.      3/29/89 jmd    converted seds to 'pure' objects
  30.      4/11/89 jmd    added closing flag, release bob support
  31.      4/11/89 jmd    added single field paint optimization
  32.                     moved Plot code from sddisp
  33.                     fixed field blanking
  34.      4/16/89 jmd    Added WINM_CHILDCLOSE msg.
  35.  
  36.      5/10/89 jmd    changed to ptd_ClearFrame
  37.      5/23/89 jdc    made menu_RemoveBob() private (sedpriv.h) not static
  38.      5/29/89 jmd    simplified paint flags
  39.      6/14/89 jmd    made one routine to paint text and fields or just fields
  40.      8/06/89 ted    Removed explode function stuff to window layer.
  41.      8/08/89 jmd    Added new win messages (size, top, position).
  42.      8/09/89 jdc    Added field marking
  43.      8/16/89 jdc    Fixed field marking
  44.      8/21/89 jdc    Added bob_SetParent(bob, NULL) in menu_RemoveBob
  45.      8/23/89 jmd    added more tests for menu == NULL
  46.  
  47.     11/06/89 jmd    removed DoRaw Macro
  48.     12/10/89 jmd    removed GO message; it's now passed up to win_Class
  49.     12/11/89 jmd    added field higlighting
  50.     12/12/89 ted    Added IsParentMove test for SETPOS methods for child menus.
  51.      1/04/90 jmd    removed jump window
  52.      1/27/90 jmd    added SED_GETVALUE message for future C-cell interaction
  53.      2/03/90 jmd    added SED_CLOSE message
  54.      2/14/90 jdc    added SetAux to FNULL
  55.      3/03/90 ted/pmcm Added support for sed_FindField -2 return in case of protected fields.
  56.      3/17/90 jmd    added employed test for Cache/Flush
  57.      3/28/90 jmd    ansi-fied
  58.      4/19/90 jdc    added NULL check for menu in CLOSE
  59.      4/19/90 jdc    preened
  60.      5/11/90 jmd    added OGLOBAL declaration
  61.      6/12/90 jmd    fixed incorrect comment
  62.      7/29/90 jmd    removed call to sed_SetAux in CLOSE msg
  63.      9/24/90 jmd    put the GO message back
  64.     10/04/90 jmd    removed SED_GETVALUE message, now done via aux function
  65. */
  66.  
  67. #include "sed.h"
  68. #include "sedwinod.h"
  69.  
  70. #include "scancode.h"        /* for MOU codes */
  71. #include "tbpriv.h"            /* for box_sort() */
  72.  
  73. OGLOBAL objreq_fptr sdwinreq_mousefptr    = objreq_Null;
  74. OGLOBAL objreq_fptr sdwinreq_loadfptr   = objreq_Null;
  75. OGLOBAL objreq_fptr sdwinreq_savefptr   = objreq_Null;
  76.  
  77. OSTATIC int CSPRIV field_getattr(sed_type sed, int fld);
  78.  
  79. int sedwin_Class(VOID *objdata, int msg, VOID *indata, VOID *outdata)
  80. /*
  81.     Dispatch function for sed windows.
  82. */
  83. {
  84.     sedwin_od         *sedwd;
  85.     ptd_struct          *ptd;
  86.     ofont_type           font;
  87.     opcoord              sedx, sedy;
  88.     int                  flag;
  89.     sed_type          sed;
  90.     win_type          win;
  91.     bob_type          bob;
  92.     byte              attr;
  93.     opcoord              oldx, dx, oldy, dy;
  94.     register int      i;
  95.  
  96.     sedwd = (sedwin_od *) objdata;
  97.  
  98.     if (msg != OBJM_GETDATASIZE) {    /* would be GP fault in this case (od is NULL) */
  99.         sed = sedod_GetSelf(sedwd);
  100.     }
  101.  
  102.     switch (msg) {
  103.  
  104.     case OBJM_LOAD:
  105.         return((*sdwinreq_loadfptr)(objdata, msg, indata, outdata));
  106.     case OBJM_SAVE:
  107.         return((*sdwinreq_savefptr)(objdata, msg, indata, outdata));
  108.  
  109.     case OBJM_GETDATASIZE:
  110.         ((ogds_struct *) outdata)->odsize = sizeof(sedwin_od);
  111.         ((ogds_struct *) outdata)->xdsize = sizeof(sed_xd);
  112.         ((ogds_struct *) outdata)->id = ID_SEDWIN;
  113.         break;
  114.  
  115.     case OBJM_OPEN:
  116.         /* initialize sedwin_od to NULL */
  117.         sedwd->closing = 0;
  118.         sedwd->blank = -1;
  119.  
  120.         /* initialize the xd */
  121.         sed_SetBaton(sed, 1);
  122.         sed_RedirectPrompt(sed, sed);
  123.         sed_SetPaintFlag(sed, SDPF_ALL);
  124.         sed_SetRegAttr(sed, ATTR_NORMAL);
  125.         sed_SetSelAttr(sed, ATTR_REVERSE);
  126.         sed_SetCtype(sed, CURSOR_NORMAL);
  127.         sed_SetHiColors(sed, ATTR_BOLD, ATTR_REVERSE);
  128.  
  129.         /* ted stuff */
  130.         sed_SetMove(sed, default_move);
  131.  
  132. #ifdef OAK_NULLNOT0
  133.  
  134.         sed_SetTrow(sed, 0);
  135.         sed_SetTcol(sed, 0);
  136.         sed_SetSpecial(sed, FNULL);
  137.         sed_SetAux(sed, FNULL);
  138.         sed_SetExit(sed, FALSE);
  139.         sed_SetActive(sed, FALSE);
  140.         sed_SetLabel(sed, 0);
  141.         sed_SetData(sed, NULL);
  142.         sed_SetExplode(sed, FNULL);
  143.         sed_SetYoffset(sed, 0);
  144.         sed_SetXoffset(sed, 0);
  145.  
  146.         /* done by sed_Init */
  147.         sed_SetFieldNo(sed, -1);
  148.         sed_SetCurrField(sed, NULL);
  149.         sed_SetRecordPos(sed, NO_WRITEABLES);
  150. #endif
  151.  
  152.         /* pass OPEN to win superclass */
  153.         return(win_Class(&(sedwd->wd), OBJM_OPEN, indata, outdata));
  154.  
  155.     case OBJM_CLOSE:
  156.         /* Turn on closing flag.  This prevents CHILDCLOSE message
  157.            from working
  158.         */
  159.         sedwd->closing = 1;
  160.  
  161.         /* Close the sed's menu */
  162.         if (sed_GetMenu(sed) != NULL) {
  163.             menu_Destroy(sed_GetMenu(sed));
  164.  
  165.             /* set our menu to NULL to avoid complications further
  166.                down the message chain
  167.             */
  168.             sed_SetMenu(sed, NULL);
  169.         }
  170.  
  171.         /* pass CLOSE to win superclass */
  172.         return(win_Class(&(sedwd->wd), OBJM_CLOSE, indata, outdata));
  173.  
  174.     case OBJM_WHO:
  175.         /* Identify ourselves */
  176.         if (*((int *) indata) == ID_SEDWIN) {
  177.             return(TRUE);
  178.         }
  179.         return(win_Class(&(sedwd->wd), msg, indata, outdata));
  180.  
  181.     case WINM_PAINTREQ:
  182.         /* repaint the sed and its bobs,
  183.            employ them if they are unemployed.
  184.            indata points to an unsigned containing sed paint masks,
  185.            (refer to sed_Draw comment)
  186.             if indata == NULL use default settings
  187.         */
  188.     {
  189.         unsigned mode, bobmode;
  190.  
  191.         disp_Cache();
  192.         if (indata == NULL) {
  193.             /* use default settings */
  194.             mode = WPD_BORDER | WPD_TEXT | WPD_FIELDS | WPD_SENTER;
  195.         }
  196.         else {
  197.             mode = *((unsigned *) indata);
  198.         }
  199.  
  200.         if (!win_IsEmployed(sed)) {
  201.             /* pass up SENTER message and let win_Employ do the rest */
  202.             /* Do senters for us and our bobs */
  203.             bobmode = (mode & WPD_SENTER) ? WPD_SENTER : 0;
  204.         }
  205.         else {
  206.             bobmode = mode;
  207.         }
  208.  
  209.         /* pass message up to all our dependent children (pass flag) */
  210.         /* don't pass up paint border only message */
  211.         if (bobmode != WPD_BORDER && bobmode != 0) {
  212.             sed_DoThemBobs(sed, WINM_PAINTREQ, &bobmode, NULL, SDTB_DEP);
  213.         }
  214.  
  215.         /* call our senters if desired */
  216.         if (mode & WPD_SENTER) {
  217.             /* Send pre message to ox function */
  218.             sed_DoAux(sed, SED_PRESENTER, NULL, NULL);
  219.  
  220.             /* Call sentry functions. */
  221.             for (i = 0; i < sed_GetFieldCount(sed); i++) {
  222.                 sed_DoFieldSenter(sed, i);
  223.             }
  224.  
  225.             /* Send post message to ox function */
  226.             sed_DoAux(sed, SED_POSTSENTER, NULL, NULL);
  227.         }
  228.  
  229.         if (mode != WPD_SENTER && mode != 0) {
  230.             /* set paint flags */
  231.             if ((mode & WPD_TEXT)) {
  232.                 sed_SetPaintFlag(sed, SDPF_ALL);
  233.             }
  234.             else if ((mode & WPD_FIELDS)) {
  235.                 sed_SetPaintFlag(sed, SDPF_FIELDS);
  236.             }
  237.             else {
  238.                 sed_SetPaintFlag(sed, SDPF_NONE);
  239.             }
  240.  
  241.             /* filter out sed specific mode bits */
  242.             mode &= WPD_BORDER;
  243.  
  244.             /* pass paint message up to window class */
  245.             win_Class(&(sedwd->wd), msg, &mode, outdata);
  246.  
  247.             /* reset paint flag */
  248.             sed_SetPaintFlag(sed, SDPF_ALL);
  249.         }
  250.         disp_Flush();
  251.         break;
  252.     }
  253.  
  254.     case WINM_CHILDCLOSE:
  255.         /* release the window (bob) attached to the sed
  256.            ignore if the closing flag is set.
  257.            Note: indata is a win.
  258.         */
  259.         if (!sedwd->closing && sed_GetMenu(sed) != NULL) {
  260.             menu_RemoveBob(sed_GetMenu(sed), (win_type) indata);
  261.         }
  262.         break;
  263.  
  264.     case WINM_SETPOS:
  265.         /* A request to move the sed */
  266.  
  267.         if (win_IsEmployed(sed)) {
  268.             disp_Cache();
  269.         }
  270.         /* get old position */
  271.         oldx = win_GetXmin(sed);
  272.         oldy = win_GetYmin(sed);
  273.  
  274.         /* First, pass up the message to win_Class to move the sed */
  275.         win_Class(&(sedwd->wd), msg, indata, outdata);
  276.  
  277.         /* Then move the dependent bobs or framer dropdowns (if any) relatively */
  278.         if (sed_GetMenu(sed) != NULL) {
  279.             dx = win_GetXmin(sed) - oldx;
  280.             dy = win_GetYmin(sed) - oldy;
  281.  
  282.             for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
  283.                 if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
  284.                     if (bob_IsDepend(bob) || bob_IsParentMove(bob)) {
  285.                         oldx = win_GetXmin(bob);
  286.                         oldy = win_GetYmin(bob);
  287.                         win_SetPixPosition(bob, oldx + dx, oldy + dy);
  288.                     }
  289.                 }
  290.             }
  291.         }
  292.         if (win_IsEmployed(sed)) {
  293.             disp_Flush();
  294.         }
  295.         break;
  296.  
  297.     case WINM_SETSIZE:
  298.         /* A request to size the sed - round up instead of down */
  299.         if (win_IsEmployed(sed)) {
  300.             disp_Cache();
  301.         }
  302.  
  303.         /* first, pass up the message to win_Class to resize the sed */
  304.         win_Class(&(sedwd->wd), msg, indata, outdata);
  305.  
  306.         if (sed_GetMenu(sed) != NULL) {
  307.             /* now, repaint all our dependent children */
  308.             for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
  309.                 if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
  310.                     if (bob_IsDepend(bob)) {
  311.                         bord_Paint(bob);
  312.                     }
  313.                 }
  314.             }
  315.         }
  316.         if (win_IsEmployed(sed)) {
  317.             disp_Flush();
  318.         }
  319.         break;
  320.  
  321.     case WINM_PUTUNDER:
  322.         /* A request to put the sed under (win_type) indata */
  323.         win = (win_type) indata;
  324.  
  325.         disp_Cache();
  326.         /* Top the sed's children first, in reverse order */
  327.         if (sed_GetMenu(sed) != NULL) {
  328.             for (i = menu_GetBobCount(sed_GetMenu(sed)) - 1; i >= 0; i--) {
  329.                 if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
  330.  
  331.                     if (bob_IsDepend(bob)) {
  332.                         win_PutUnder(bob, win);
  333.                         win = bob;
  334.                     }
  335.                 }
  336.             }
  337.         }
  338.  
  339.         /* pass message up to win_Class */
  340.         win_Class(&(sedwd->wd), msg, win, outdata);
  341.  
  342.         disp_Flush();
  343.         break;
  344.  
  345.     case WINM_UNEMPLOY:
  346.         /* pop all the sed's bobs (both indy and dependent */
  347.         disp_Cache();
  348.         if (sed_GetMenu(sed) != NULL) {
  349.             for (i = 0; i < menu_GetBobCount(sed_GetMenu(sed)); i++) {
  350.                 if ((bob = menu_GetBob(sed_GetMenu(sed), i)) != NULL) {
  351.                     win_UnEmploy(bob);
  352.                 }
  353.             }
  354.         }
  355.  
  356.         /* pass message up to win_Class to pop ourselves */
  357.         win_Class(&(sedwd->wd), msg, indata, outdata);
  358.         disp_Flush();
  359.         break;
  360.  
  361.     case WINM_SCROLLREQ:
  362.         /* pass message to request handler func, linked in by sedwin_ClassInit */
  363.         return((*sdwinreq_mousefptr)(objdata, msg, indata, outdata));
  364.  
  365.     case WINM_GETINPOS:
  366.     {
  367.         inposdata_struct *ipd;
  368.  
  369.         /* make sure menu is valid (we could be in the middle of being
  370.                                     loaded from a screen file)
  371.         */
  372.  
  373.         if (sed_GetMenu(sed) == NULL) {
  374.             return(win_Class(&(sedwd->wd), msg, indata, outdata));
  375.         }
  376.  
  377.         /* get the menu size relative to the sed
  378.            so that borders can compute scroll lights
  379.         */
  380.         ipd = (inposdata_struct *)outdata;
  381.         font = win_GetFont(ipd->win);
  382.  
  383.         ipd->inbox.xmin = - (sed_GetXoffset(sed) * ofont_GetWidth(font));
  384.         ipd->inbox.xmax = ipd->inbox.xmin +
  385.                         (sed_GetMenuVWidth(sed) * ofont_GetWidth(font));
  386.         ipd->inbox.ymin = - (sed_GetYoffset(sed) * ofont_GetHeight(font));
  387.         ipd->inbox.ymax = ipd->inbox.ymin +
  388.                     (sed_GetMenuVHeight(sed) * ofont_GetHeight(font));
  389.         break;
  390.     }
  391.     case WINM_SHADOW:
  392.         /* reset paint flag to shadow paint */
  393.         ptd = (ptd_struct *)indata;
  394.  
  395.         sed_SetPaintFlag(sed, SDPF_SHADOW);
  396.  
  397.         /* set ptd data to indicate that we've taken care of the shadow */
  398.         ptd->emsgdata = (VOID *) 1;
  399.  
  400.         /* no break; fall through to PAINT */
  401.  
  402.     case WINM_PAINT:
  403.     {
  404.         ptd_struct           inptd;    /* for use in inner-coordinate computations */
  405.         opbox               inbox;    /* ditto; gets hooked in by ptd_SetInner */
  406.         opbox               relbox;
  407.  
  408.         /* Paint the sed window */
  409.         ptd = (ptd_struct *)indata;
  410.         win = ptd->win;
  411.  
  412.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  413.  
  414.             opbox_copy(&relbox, inptd.relboxp);
  415.             sedx = -(sed_GetXoffset(sed) *  win_GetFontWidth(win));
  416.             sedy = -(sed_GetYoffset(sed) *  win_GetFontHeight(win));
  417.  
  418.             /* if flag >= 0, paint only that field */
  419.             if ((flag = sed_GetPaintFlag(sed)) >= 0) {
  420.  
  421.                 /* Paint field, if it isn't blanked (used by sleds) */
  422.                 if (sedwd->blank < 0 || field_GetRow(sed_GetField(sed, flag)) < sedwd->blank) {
  423.  
  424.                     sd_plot_field(sed, sed_GetField(sed, flag), flag, &inptd);
  425.                 }
  426.             }
  427.             else if (flag != SDPF_NONE) {
  428.                 /* paint the sed's text and fields */
  429.                 /* Clip if we're scrolled in the negative direction */
  430.                 if (relbox.xmax > sedx && relbox.xmin < sedx) {
  431.                     relbox.xmin = sedx;
  432.                 }
  433.  
  434.                 if (relbox.ymax > sedy && relbox.ymin < sedy) {
  435.                      relbox.ymin = sedy;
  436.                 }
  437.  
  438.                 /* Test if we should paint the text */
  439.                 inptd.relboxp = &relbox;
  440.                 if (sedx < relbox.xmax && sedy < relbox.ymax) {
  441.                     sed_Ploat(sed, &inptd, sedwd->blank);
  442.                 }
  443.  
  444.                 /* Clear regions above (0, 0) if scrolled negative */
  445.                 /* if shadow, use the window shadow attr for clear frame */
  446.                 attr = (msg == WINM_SHADOW) ? win_GetShadowAttr(sed) : win_GetAttr(sed);
  447.  
  448.                 inptd.relboxp = &inbox;
  449.                 ptd_ClearFrame(&inptd, sedx, sedy,
  450.                     win_GetPixWidth(win) - sedx,
  451.                     win_GetPixHeight(win) - sedy,
  452.                     disp_GetAttrBgColor(attr));
  453.             }
  454.         }
  455.  
  456.         /* pass message up to win superclass (for cursor and border paint) */
  457.         win_Class(&(sedwd->wd), msg, indata, outdata);
  458.  
  459.         if (msg == WINM_SHADOW) {
  460.             /* reset paint flag */
  461.             sed_SetPaintFlag(sed, SDPF_ALL);
  462.         }
  463.         break;
  464.     }
  465.  
  466.     case WINM_GO:
  467.         /* Call sed_ReallyGo to activate the sed */
  468.         /* indata: NULL,        outdata: int * */
  469.         /* Don't pass this up to parent; no WINA_GO message sent by seds */
  470.  
  471.         *((int *) outdata) = sed_ReallyGo(sed);
  472.         break;
  473.  
  474.     case WINM_GETFLDPOS:
  475.     /* get current location within the sed (used by grid movement) */
  476.     {
  477.         ocbox     *ocboxp;
  478.         boolean     isabob, gotbox;
  479.         int         row, col;
  480.  
  481.         /* outdata is a (ocbox *) */
  482.         ocboxp = (ocbox *) outdata;
  483.  
  484.         gotbox = FALSE;
  485.  
  486.         if (sed_GetFieldCount(sed) > 0) {
  487.             isabob = FALSE;
  488.             if ((bob = sed_GetFieldBob(sed, sed_GetFieldNo(sed))) != NULL) {
  489.                 isabob = bob_IsDepend(bob);
  490.             }
  491.  
  492.             if (isabob) {
  493.                 ocboxp->toprow = 0;
  494.                 ocboxp->botrow = 0;
  495.                 ocboxp->leftcol = 0;
  496.                 ocboxp->rightcol = 0;
  497.  
  498.                 bob_Do(bob, WINM_GETFLDPOS, NULL, ocboxp);
  499.                 gotbox = TRUE;
  500.             }
  501.             else if (menu_GetFieldBox(sed_GetMenu(sed), sed_GetFieldNo(sed), ocboxp)) {
  502.                 gotbox = TRUE;
  503.                 /* Translate box to sed coordinates */
  504.                 ocboxp->toprow -= sed_GetYoffset(sed);
  505.                 ocboxp->botrow -= sed_GetYoffset(sed);
  506.                 ocboxp->leftcol -= sed_GetXoffset(sed);
  507.                 ocboxp->rightcol -= sed_GetXoffset(sed);
  508.             }
  509.         }
  510.  
  511.         if (!gotbox) {
  512.             /* default values */
  513.             ocboxp->toprow = 0;
  514.             ocboxp->botrow = sed_GetHeight(sed);
  515.             ocboxp->leftcol = 0;
  516.             ocboxp->rightcol = sed_GetWidth(sed);
  517.         }
  518.  
  519.         /* Coords refer to the inner window box, translate to outer box */
  520.         ocboxp->toprow -= (row = bord_GetRowOff(sed));
  521.         ocboxp->botrow -= row;
  522.         ocboxp->leftcol -= (col = bord_GetColOff(sed));
  523.         ocboxp->rightcol -= col;
  524.  
  525.         break;
  526.     }
  527.     case WINM_SETFLDPOS:
  528.     /* jump to the field closest to curpos (used by grid movement) */
  529.     {
  530.         winsfp_struct *winsfp;
  531.         ocbox     *ocboxp;
  532.         int        row, col, fld;
  533.  
  534.         /* indata is a (winsfp_struct *) */
  535.         winsfp = (winsfp_struct *) indata;
  536.         ocboxp = winsfp->ocboxp;
  537.  
  538.         /* Coords refer to the outer window box, translate to inner box */
  539.         ocboxp->toprow += (row = bord_GetRowOff(sed));
  540.         ocboxp->botrow += row;
  541.         ocboxp->leftcol += (col = bord_GetColOff(sed));
  542.         ocboxp->rightcol += col;
  543.  
  544.         if ((fld = sed_FindField(sed, ocboxp, winsfp->pref)) >= 0) {
  545.             sed_GotoField(sed, fld);
  546.         }
  547.         break;
  548.     }
  549.      case WINM_GETCHILDNO:
  550.         /* get the child number of a window (indata),
  551.            -1 if window is not a child
  552.         */
  553.         /* indata is a (bob_type), outdata is an (int *) */
  554.     {
  555.         int childno = -1;
  556.         menu_type menu;
  557.         bob_type bob;
  558.  
  559.         bob = (bob_type) indata;
  560.         menu = sed_GetMenu(sed);
  561.  
  562.         /* Find the field number */
  563.         for (i = 0; i < menu_GetBobCount(menu); i++) {
  564.             if (bob == menu_GetBob(menu, i)) {
  565.                 childno = menu_GetBobFieldNo(menu, i);
  566.                 break;
  567.             }
  568.         }
  569.  
  570.         *((int *)outdata) = childno;
  571.  
  572.         break;
  573.     }
  574.     case WINM_SETCURRCHILD:
  575.         /* set the window's current child: do a goto field */
  576.         /* indata is an (int *) */
  577.         sed_GotoField(sed, *((int *)indata));
  578.         break;
  579.  
  580.     default:
  581.         win_Class(&(sedwd->wd), msg, indata, outdata);
  582.         break;
  583.     }
  584.     return(TRUE);
  585. }
  586.  
  587. /*----------------------------------------------------------------------------*/
  588.  
  589. /*** Field Plotting Functions ***/
  590.  
  591. void sd_plot_field(sed_type sed, field_type field, int fldno, ptd_struct *ptd)
  592. /*
  593.       Draws one field
  594.     Called by either sed_Ploat or directly by sedwin.
  595. */
  596. {
  597.     int  markattr;
  598.     byte attr, hiattr;
  599.     int  hichar = -1;        /* highlighted character */
  600.     int  m, c;
  601.  
  602.     /* determine color of field */
  603.     /* highlight the current field if we're in an active sed */
  604.     if (sed_GetPaintFlag(sed) == SDPF_SHADOW) {
  605.         attr = win_GetShadowAttr(sed);
  606.     }
  607.     else if ((markattr = field_getattr(sed, fldno)) != -1) {
  608.         attr = (byte) markattr;
  609.     }
  610.     else {
  611.         if (fldno == sed_GetFieldNo(sed) && sed_IsActive(sed)) {
  612.             if (field_GetMarked(field)) {
  613.                 attr = field_GetSelAttr(field);
  614.             }
  615.             else {
  616.                 attr = sed_GetSelAttr(sed);
  617.                 hichar = field_IsHiCharOn(field) ? (int) field_GetHiChar(field) : (int) -1;
  618.                 hiattr = sed_GetHiSelAttr(sed);
  619.             }
  620.         }
  621.         else {
  622.             if (field_GetMarked(field)) {
  623.                 attr = field_GetRegAttr(field);
  624.             }
  625.             else {
  626.                 attr = sed_GetRegAttr(sed);
  627.                 hichar = field_IsHiCharOn(field) ? (int) field_GetHiChar(field) : (int) -1;
  628.                 hiattr = sed_GetHiRegAttr(sed);
  629.             }
  630.         }
  631.     }
  632.  
  633.     /* draw the field merge, letting the window clip it
  634.      * Get field coords relative to the sed
  635.      * paint the field in three chunks:
  636.      *    1) before the highlighted char
  637.      *    2) the highlighted char
  638.      *    3) after the highlighted char
  639.      */
  640.  
  641.     m = field_GetXoffset(field);
  642.     c = 0;
  643.  
  644.     /* before */
  645.     if (hichar > field_GetXoffset(field)) {
  646.         ptd_DrawString(ptd,
  647.              (field_GetRow(field) - sed_GetYoffset(sed)),
  648.              (field_GetCol(field) - sed_GetXoffset(sed)),
  649.              (field_GetMerge(field) + field_GetXoffset(field)),
  650.               attr,
  651.               hichar - field_GetXoffset(field));
  652.     }
  653.  
  654.     /* during */
  655.     if (hichar >= field_GetXoffset(field)) {
  656.         m = hichar + 1;
  657.         c = m - field_GetXoffset(field);
  658.  
  659.         ptd_DrawString(ptd,
  660.              (field_GetRow(field) - sed_GetYoffset(sed)),
  661.              (field_GetCol(field) - sed_GetXoffset(sed) + hichar - field_GetXoffset(field)),
  662.              (field_GetMerge(field) + hichar),
  663.               hiattr,
  664.               1);
  665.     }
  666.  
  667.     /* after (default case for no highlighting) */
  668.  
  669.     ptd_DrawString(ptd,
  670.              (field_GetRow(field) - sed_GetYoffset(sed)),
  671.              (field_GetCol(field) - sed_GetXoffset(sed) + c),
  672.              (field_GetMerge(field) + m),
  673.               attr,
  674.               field_GetWidth(field) - c);
  675. }
  676.  
  677. /*----------------------------------------------------------------------------*/
  678. /*** Auxillary Functions ***/
  679.  
  680. void menu_RemoveBob(menu_type menu, win_type win)
  681. /*
  682.     Removes the reference to a bob from a menu.
  683.     (does not close the bob)
  684. */
  685. {
  686.     register int     i;
  687.     int         fldno;
  688.     bob_type bob;
  689.  
  690.     /* find bob in list */
  691.     for (i = 0; i < menu->bobcount; i++) {
  692.         bob = menu_GetFieldBob(menu, (fldno = ia_Get(menu->boba, i)));
  693.  
  694.         if (win == bob) {
  695.             field_SetBob(menu_GetField(menu, fldno), NULL);
  696.              bob_SetParent(bob, NULL);
  697.  
  698.             /* slide remaining elements in bobarray */
  699.             for (; i < menu->bobcount; i++) {
  700.                 fldno = ia_Get(menu->boba, i + 1);
  701.                 ia_Put(menu->boba, i, fldno);
  702.             }
  703.  
  704.             menu->bobcount--;
  705.             break;
  706.         }
  707.     }
  708. }
  709. /*----------------------------------------------------------------------------*/
  710.  
  711. static int CSPRIV field_getattr(sed_type sed, int fld)
  712. /*
  713.     tests if a field is affected by text marking.
  714.     (needed primarily for Look & Feel)
  715.     returns -1 if the field is not text marked, else the
  716.     attribute of the field.
  717. */
  718. {
  719.     int attr = -1, mark, frow, fcol, flcol;
  720.     ocbox mbox;
  721.     field_type field;
  722.  
  723.     if ((mark = sed_GetTextbuf(sed)->mark) != TED_NOMARK) {
  724.         box_sort(&mbox, &(sed_GetTextbuf(sed)->markbox), (mark == TED_MARK) ? BOXSORT_ROW:BOXSORT_COL);
  725.  
  726.         field = sed_GetField(sed, fld);
  727.         frow = field_GetRow(field);
  728.         fcol = field_GetCol(field);
  729.         flcol = field_GetLastCol(field);
  730.  
  731.         if (field_GetWidth(field) == 0 || frow > mbox.botrow || frow < mbox.toprow) {
  732.             ;
  733.         }
  734.         else if (mark == TED_MARK) {
  735.             if (frow == mbox.toprow && flcol < mbox.leftcol) {
  736.                 ;
  737.             }
  738.             else if (frow == mbox.botrow && fcol > mbox.rightcol) {
  739.                 ;
  740.             }
  741.             else {
  742.                 attr = sed_GetSelAttr(sed);
  743.             }
  744.         }
  745.         else if (fcol <= mbox.rightcol && flcol >= mbox.leftcol) {
  746.             attr = sed_GetSelAttr(sed);
  747.         }
  748.     }
  749.  
  750.     return(attr);
  751. }
  752. /*----------------------------------------------------------------------------*/
  753.  
  754. boolean bob_IsSed(bob_type bob)
  755. /*
  756.     Returns TRUE if the object is a sed.
  757. */
  758. {
  759.     int id = ID_SEDWIN;
  760.  
  761.     return(bob_Do(bob, OBJM_WHO, &id, NULL));
  762. }
  763. /*----------------------------------------------------------------------------*/
  764.  
  765.