home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / WINOBJ.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-12  |  15.6 KB  |  555 lines

  1. /*
  2.     winobj.c
  3.  
  4.     % generic window object
  5.  
  6.     3/17/88 by Ted.
  7.  
  8.     OWL 1.1
  9.     Copyright (c) 1988, by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      6/16/88 Ted    revised to have inheritance and class factory functions.
  15.      8/09/88 jmd    revised to use new object stuff
  16.      9/02/88 ted    fixed graphics cursor scrolling
  17.      9/02/88 ted    moved non-object functions out to winfuncs.c
  18.      9/12/88 jmd    Added in and out data to objects
  19.     11/17/88 ted    Added WIN_GO & mouse control default methods.
  20.     11/20/88 jmd    Added ID to obj struct
  21.     11/22/88 jmd    Changed unsingeds to burnts!
  22.     12/02/88 ted    Added REQ message handling for bdmouse
  23.      3/24/89 ted    Moved attribute and curstype into xdata, added SETFONT msg.
  24.      3/24/89 ted    Made win's pure objects. Eliminated win_CreateWin,
  25.                      wmgr_Destroy win by folding them into win_Class.
  26.      4/14/89 ted    Added WINM_CHILDCLOSE msg.
  27.      5/01/89 ted    Added break case for WINM msgs not used at this level.
  28.      5/28/89 jmd    added Shadow support
  29.      7/07/89 gam    changed NULL to FNULL where necessary.
  30.      7/25/89 ted    Added explode function call.
  31.      8/06/89 ted    Commented out null inits to save time and code.
  32.      8/08/89 jmd    Added size, pos, and top support.
  33.      8/10/89 jmd    Killed bob, added new messages to windows.
  34.      8/12/89 jdc    Added win_Close function stuff here
  35.      8/12/89 jdc    Added INIT message, added WHO message
  36.      8/13/89 jmd    removed GETEXPLODE message
  37.      8/16/89 jmd    Added initialization for nullfont and resize flags.
  38.      9/12/89 jmd    Fixed Shadow Clear color
  39. */
  40.  
  41. #include "oakhead.h"
  42. #include "disppriv.h"
  43. #include "bordobj.h"
  44. #include "winod.h"
  45.  
  46. OGLOBAL objreq_fptr winreq_loadfptr = objreq_Null;
  47. OGLOBAL objreq_fptr winreq_savefptr = objreq_Null;
  48.  
  49. OSTATIC void OWLPRIV win_paintcursor(_arg1(win_type));
  50.  
  51. /* -------------------------------------------------------------------------- */
  52.  
  53. int win_Class(objdata, msg, indata, outdata)
  54.     VOID *objdata;            /* object instance data pointer */
  55.     int msg;                /* message */
  56.     VOID *indata;            /* message input data */
  57.     VOID *outdata;            /* message output data */
  58. /* 
  59.     win object dispatch function
  60. */
  61. {
  62.     win_od *wd;
  63.     win_type win;
  64.     win_xd *winxd;
  65.     ptd_struct *ptd;
  66.     ptd_struct inptd;    /* for use in inner-coordinate computations */
  67.     opbox inbox;        /* ditto; gets hooked in by ptd_SetInner */
  68.     opbox relbox;
  69.  
  70.     wd = (win_od *) objdata;
  71.     win = winod_GetSelf(wd); /* Note: no GP fault here because GETDATASIZE is never called */
  72.     winxd = win_getxd(win); oak_notused(winxd);/* Here for debugging reference */
  73.  
  74.     switch(msg) {
  75. /*    case OBJM_GETDATASIZE:    This class only exists to be inherited */
  76.  
  77.     case OBJM_WHO:
  78.         /* Identify ourselves */
  79.         return (*((int *) indata) == ID_WIN || *((int *) indata) == ID_BOB);
  80.  
  81.     case OBJM_OPEN:
  82.     /*
  83.         Open a new window in pixel coordinates, with a font spec.
  84.         Note: Called only from win_PixOpen, wmgr_Init, & wmgr_ListOpen which
  85.         is called from wmgr_Init. Therefore, it does not need to call
  86.         hard_Claim/Release for reentrancy protection because both of its
  87.         calling paths do it already.
  88.         Note: all inits to 0, FALSE, NULL, & FNULL are superfluous because
  89.         object structures are initted to 0's.
  90.     */
  91.     {
  92.         int i;
  93.  
  94.         /* Initialize win private object data */
  95.  
  96. #ifdef OAK_NULLNOT0
  97.         wd->current = FALSE;    /* init not current */
  98.         wd->curshide = 0;        /* init cursor showing */
  99.         wd->cursunder = NULL;    /* init cursor under-buffer */
  100.         wd->cudrawn = 0;
  101.         wd->cubox.xmin = 0; wd->cubox.ymin = 0;
  102.         wd->cubox.xmax = 0; wd->cubox.ymax = 0;
  103.  
  104.         /* Initialize win xdata */
  105.  
  106.         win_SetParent(win, NULL);
  107.  
  108.         win_inboxp(win)->xmin = 0; win_inboxp(win)->ymin = 0;
  109.         win_inboxp(win)->xmax = 0; win_inboxp(win)->ymax = 0;
  110.         win_pixboxp(win)->xmin = 0; win_pixboxp(win)->ymin = 0;
  111.         win_pixboxp(win)->xmax = 0; win_pixboxp(win)->ymax = 0;
  112.  
  113.         win_setemployed(win, FALSE);
  114.         win_setabove(win, NULL);
  115.         win_setbelow(win, NULL);
  116.  
  117.         win_setcursx(win, 0);
  118.         win_setcursy(win, 0);
  119.  
  120.         win_SetMouse(win, FNULL);
  121.         win_SetDebounced(win, FALSE);
  122.         win_SetNextWin(win, NULL);
  123.         win_SetExplode(win, FNULL);
  124.  
  125.         win_setbd(win, NULL);
  126.  
  127.         win_setshadowx(win, 0);
  128.         win_setshadowy(win, 0);
  129.         win_SetShadowAttr(win, 0x00);
  130. #endif
  131.         win_setnullfont(win, TRUE);
  132.         win_SetParentClip(win, TRUE);
  133.  
  134.         win_setattribute(win, ATTR_NORMAL);
  135.         win_setcurstype(win, CURSOR_NORMAL);
  136.  
  137.         win_setidmgr(win, disp_id());
  138.         win_SetCharSize(win, TRUE);
  139.         win_SetResize(win, TRUE);
  140.  
  141.         /* initialize LNF function handle array */
  142.         for (i = 0; i < WIN_FSYM_COUNT; i++) {
  143.             win_getxd(win)->handles[i] = -1;
  144.         }
  145.  
  146.         /* send OPEN to bob superclass */
  147.         return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
  148.     }
  149.  
  150.     case OBJM_INIT:
  151.     {
  152.         winopendata_struct *wod = (winopendata_struct *) indata;
  153.            opbox *boxp;
  154.         ofont_type dfont;
  155.         odim width, height;
  156.  
  157.         boxp = wod->boxp;
  158.         
  159.         if (!disp_TextFree()) {
  160.             dfont = disp_GetDefFont();
  161.             width  = opbox_GetWidth(boxp);
  162.             height = opbox_GetHeight(boxp);
  163.             opcoord_GridRound(&boxp->xmin, &boxp->ymin, dfont);
  164.             /* Round up instead of down */
  165.             boxp->xmax = boxp->xmin + width  + ofont_GetWidth(dfont) - 1;
  166.             boxp->ymax = boxp->ymin + height + ofont_GetHeight(dfont) - 1;
  167.             opcoord_GridRound(&boxp->xmax, &boxp->ymax, dfont);
  168.         }
  169.         opbox_copy(win_pixboxp(win), boxp);
  170.         win_inboxp(win)->xmax = opbox_GetWidth(boxp);
  171.         win_inboxp(win)->ymax = opbox_GetHeight(boxp);
  172.  
  173.         /* Set up the font, underbuffer, etc. */
  174.         if (!win_SetFont(win, wod->font)) {
  175.             return(FALSE);
  176.         }
  177.         /* Put window into unemployed list (at the top) */
  178.         if (wod->list != NULL) {
  179.             win_ListAdd(wod->list, win);
  180.         }
  181.         break;
  182.     }
  183.  
  184.     case OBJM_CLOSE:
  185.     /*
  186.         Note: Called only from wmgr_ListClose which is called from
  187.         wmgr_Wrapup and wmgr_Init. Therefore, it does not need to call
  188.         hard_Claim/Release for reentrancy protection because all three of its
  189.         calling paths do it already.
  190.     */
  191.     {
  192.         extern win_type vid_win;
  193.  
  194.         owl_Assert(win_Ok(win), OE_WC_WIN);
  195.  
  196.         hard_Claim();            /* Here for re-entrancy protection */
  197.  
  198.         /* Unemploy window first */
  199.         if (win_IsEmployed(win)) {
  200.             win_UnEmploy(win);
  201.         }
  202.         /* remove window from unemployed list */
  203.         win_ListRemove(win);
  204.  
  205.         /* Make sure vid_win ptr is NULL'ed out if vid_win is destroyed */
  206.         if (vid_win == win) {
  207.             vid_win = NULL;
  208.         }
  209.         /* Make sure backwin ptr is NULL'ed out if backwin is destroyed */
  210.         if (disp_GetBackWin() == win) {
  211.             wmgr_setbackwin(NULL);
  212.         }
  213.         /* Make sure the win is not still current after it is freed */
  214.         if (disp_GetCurrentWin() == win) {
  215.             win_MakeCurrent(NULL);
  216.         }
  217.         /* Close the window's border if it has one */
  218.         bord_Close(win);
  219.  
  220.         /* Kill the Window's cursor under-buffer and font reference. */
  221.         win_SetFont(win, NULL);
  222.  
  223.         /* Kill the window's dmgr id so win_Ok will now fail on this win ptr */
  224.         win_setidmgr(win, 0);
  225.  
  226.         /* Notify the window's parent window that its child is closed */
  227.         owl_Assert(((win_GetParent(win) == NULL) || win_Ok(win_GetParent(win))), OE_WC_PARENT);
  228.         win_Do(win_GetParent(win), WINM_CHILDCLOSE, win, NULL);
  229.  
  230.         hard_Release();
  231.  
  232.         /* send CLOSE to bob superclass */
  233.         return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
  234.     }
  235.  
  236.     case OBJM_LOAD:
  237.         return((*winreq_loadfptr)(objdata, msg, indata, outdata));
  238.  
  239.     case OBJM_SAVE:
  240.         return((*winreq_savefptr)(objdata, msg, indata, outdata));
  241.  
  242.     case WINM_SETFONT:
  243.     /* set new font and initialize the cursor under-buffer etc. if needed. */
  244.     {
  245.         ofont_type font = (ofont_type)indata;
  246.  
  247.         win_setfontptr(win, font);
  248.         win_setnullfont(win, font == NULL);
  249.  
  250.         pmap_Close(wd->cursunder);
  251.  
  252.         wd->cudrawn = 0;
  253.         wd->cubox.xmin = 0;
  254.         wd->cubox.ymin = 0;
  255.         if (font == NULL || disp_hardcursor()) {
  256.             wd->cubox.xmax = 0;
  257.             wd->cubox.ymax = 0;
  258.             wd->cursunder = NULL;
  259.         }
  260.         else {
  261.             wd->cubox.xmax = ofont_GetWidth(font);
  262.             wd->cubox.ymax = ofont_GetHeight(font);
  263.  
  264.             /* Allocate pixel map for saving under cursor */
  265.             wd->cursunder = pmap_Open(wd->cubox.xmax, wd->cubox.ymax);
  266.             if (wd->cursunder == NULL) {
  267.                 return(FALSE);
  268.             }
  269.         }
  270.         break;
  271.     }
  272.     case WINM_SHOWCURS:
  273.         if (wd->curshide == 1) {    /* first show */
  274.             wd->curshide--;
  275.             win_paintcursor((win_type)indata);
  276.             *((boolean *) outdata) = TRUE;    /* Return TRUE for did something */    
  277.         }
  278.         else  {
  279.             *((boolean *) outdata) = FALSE;
  280.         }
  281.         break;
  282.  
  283.     case WINM_HIDECURS:
  284.         if (wd->curshide == 0) {    /* first hide */
  285.             wd->curshide++;
  286.             win_paintcursor((win_type)indata);
  287.             *(boolean *) outdata = TRUE;    /* Return TRUE for did something */    
  288.         }
  289.         else *(boolean *) outdata = FALSE;
  290.         break;
  291.  
  292.     case WINM_SHADOW:
  293.         /* If the window subclass hasn't painted a shadow
  294.            clear the shadow area.
  295.         */
  296.         ptd = (ptd_struct *)indata;
  297.         if (ptd->emsgdata == NULL) {
  298.             ptd_Clear(ptd, disp_GetAttrBgColor(win_GetShadowAttr(ptd->win)));
  299.         }
  300.         /* no break: pass the message through to WINM_PAINT so it can  */
  301.         /*   take care of painting the border   */
  302.  
  303.     case WINM_DRAWCURSOR:    /* draw cursor if in this box */
  304.     case WINM_PAINT:
  305.     {
  306.         boolean dobord;    /* flag for whether to call border paint function. */
  307.  
  308.         ptd = (ptd_struct *)indata;
  309.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  310.             if (wd->current) {
  311.  
  312.                 win_GetCursorPixBox(win, &relbox);
  313.  
  314.                 if (opbox_clipbox(inptd.relboxp, &relbox)) {
  315.                     if (wd->curshide == 0) {
  316.                         if (wd->cursunder == NULL) {
  317.                             if (!wd->cudrawn) { /* Just draw text cursor */
  318.                                 ptd_DrawCursor(&inptd, win_GetCursorType(win));
  319.                             }
  320.                         }
  321.                         else { /* If graphics cursor, save under it before drawing it */
  322.                     /* Only save under & draw if cursor is not displayed - */
  323.                     /*   (was painted over or was not drawn) */
  324.                             if (!(msg == WINM_DRAWCURSOR && wd->cudrawn)) {
  325.                                 inptd.relboxp = &relbox;
  326.                                 ptd_ReadPixmap(&inptd, wd->cursunder, &wd->cubox);
  327.                                 inptd.relboxp = &inbox;    /* restore to other temp. box */
  328.  
  329.                                 ptd_DrawCursor(&inptd, win_GetCursorType(win));
  330.                             }
  331.                         }
  332.                         wd->cudrawn = TRUE;
  333.                     }
  334.                     else {    /* curshide != 0 */
  335.                 /* If graphics cursor, and this is PAINT msg, the char paint will */
  336.                 /* already have overwritten it, and this needs to do nothing */
  337.                 /* If a DRAWCURSOR msg, this pixmap restore will paint over it */
  338.                          if (wd->cursunder == NULL) {
  339.                         /* If hardware cursor, this will turn it off. */
  340.                             ptd_EraseCursor(&inptd);
  341.                         }
  342.                         else {
  343.                             if (msg == WINM_DRAWCURSOR && wd->cudrawn) {
  344.                                 inptd.relboxp = &relbox;
  345.                                 ptd_DrawPixmap(&inptd, wd->cursunder, &wd->cubox);
  346.                                 inptd.relboxp = &inbox;    /* restore to other temp. box */
  347.                             }
  348.                         }
  349.                         wd->cudrawn = FALSE;
  350.                     }
  351.                 }
  352.             }
  353.             /* If it was clipped, that means some of it hung over into border */
  354.             dobord = !opbox_equal(inptd.relboxp, ptd->relboxp);
  355.         }
  356.         /* If it wasn't in win box at all, it must be in border */
  357.         else {
  358.             dobord = TRUE;
  359.         }
  360.  
  361.         /* Paint border */
  362.         if (dobord) {
  363.             bord_Do(win, (msg == WINM_SHADOW) ? BDM_SHADOW : BDM_DRAW, indata, NULL);
  364.         }
  365.         break;
  366.     }
  367.     case WINM_SHADOWSAVE:
  368.     case WINM_SAVE:        /* hide cursor if in this box */
  369.         /* If hardware cursor, this will turn it off. */
  370.         /* If graphics cursor, it will get overwritten or it doesn't need */
  371.         /* to be erased and this does nothing */
  372.         if (wd->current && wd->curshide == 0) {
  373.             ptd = (ptd_struct *)indata;
  374.             if (ptd_SetInner(ptd, &inptd, &inbox)) {
  375.                 win_GetCursorPixBox(win, &relbox);
  376.                 if (opbox_clipbox(inptd.relboxp, &relbox)) {
  377.                      if (wd->cursunder == NULL) {
  378.                         ptd_EraseCursor(&inptd);
  379.                     }
  380.                     wd->cudrawn = FALSE;
  381.                 }
  382.             }
  383.         }
  384.         break;
  385.  
  386.     case WINM_SCROLL:
  387.     {
  388.         opcoord nx, ny;
  389.  
  390.         ptd = (ptd_struct *)indata;
  391.         nx = ( (opoint *)(ptd->emsgdata) )->x;
  392.         ny = ( (opoint *)(ptd->emsgdata) )->y;
  393.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  394.             opbox_copy(&relbox, inptd.relboxp);
  395.  
  396.             if (nx == 0) {
  397.                 if (ny == 0) {
  398.                     break;        /* Do nothing if no scroll called for */
  399.                 }
  400.                 else if (disp_vtscroll()) {        /* Vertical Scroll */
  401.                     if (opbox_ScrollVtIn(&relbox, ny)) {
  402.                         ptd_ScrollBoxVt(&inptd, ny);
  403.                     }
  404.                 }
  405.             }
  406.             else {
  407.                 if (ny == 0 && disp_hzscroll()) {    /* Horizontal Scroll */
  408.                     if (opbox_ScrollHzIn(&relbox, nx)) {
  409.                         ptd_ScrollBoxHz(&inptd, nx);
  410.                     }
  411.                 }
  412.             /*  else nx and ny not zero - just repaint the whole box */
  413.             }
  414.             /* Call the window's paint function on the remaining box portion */
  415.             inptd.relboxp = &relbox;
  416.             win_Do(win, WINM_PAINT, &inptd, NULL);
  417.         }
  418.         break;
  419.     }
  420.     case WINM_CLEAR:
  421.         ptd = (ptd_struct *)indata;
  422.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  423.             ptd_Clear(&inptd, *((opixval *)inptd.emsgdata));
  424.         }
  425.         break;
  426.  
  427.     case WINM_GETINPOS:        /* return inbox same as win box */
  428.     {
  429.         inposdata_struct *ipd = (inposdata_struct *)outdata;
  430.  
  431.         win_GetPixBox(ipd->win, &ipd->inbox);
  432.         break;
  433.     }
  434.     case WINM_STARTCUR:
  435.         if (wd->current != TRUE) {
  436.             wd->current = TRUE;
  437.             if (wd->curshide == 0) {    /* turn cursor on */
  438.                 win_paintcursor((win_type)indata);
  439.             }
  440.             *((boolean *) outdata) = TRUE;
  441.         }
  442.         else {
  443.             *((boolean *) outdata) = FALSE;
  444.         }
  445.         break;
  446.  
  447.     case WINM_STOPCUR:
  448.         if (wd->current != FALSE) {
  449.             if (wd->curshide == 0) {    /* turn cursor off */
  450.                 wd->curshide++;
  451.                 win_paintcursor((win_type)indata);
  452.                 wd->curshide--;
  453.             }
  454.             wd->current = FALSE;
  455.             *((boolean *) outdata) = TRUE;
  456.         }
  457.         else {
  458.             *((boolean *) outdata) = FALSE;
  459.         }
  460.         break;
  461.  
  462.     case WINM_EXPLODE:
  463.         if (win_GetExplodeFptr(win) != FNULL) {
  464.             return((*win_GetExplodeFptr(win))(objdata, msg, indata, outdata));
  465.         }
  466.         break;
  467.  
  468.     case WINM_SETPOS:
  469.         /* move the window to a new location */
  470.         win_ReallySetPixPosition(win, ((opoint *)indata)->x, ((opoint *)indata)->y);
  471.         break;
  472.  
  473.     case WINM_SETSIZE:
  474.         /* change the size of the window */
  475.         win_ReallySetPixSize(win, (odim) ((opoint *)indata)->x, (odim) ((opoint *)indata)->y);
  476.         break;
  477.  
  478.     case WINM_PUTUNDER:
  479.         /* indata in a win_type, put the window under it (if NULL put it on top) */
  480.         win_ReallyPutUnder(win, (win_type) indata);
  481.         break;
  482.  
  483.     case WINM_UNEMPLOY:
  484.         /* a request to unemploy the window */
  485.         win_ReallyUnEmploy(win);
  486.         break;
  487.  
  488.     case WINM_GOREQ:        /* request to be go'ed */
  489.         *((int *)outdata) = win_Go(win);
  490.         break;
  491.  
  492.     case WINM_GO:            /* default: quit (we didn't ask to be called) */
  493.         *((int *)outdata) = -1;
  494.         break;
  495.  
  496.     case WINM_PAINTREQ:
  497.         /* Paint a window (or employ it if it is unemployed) */
  498.         /* this is passed a bit flag via indata that tells
  499.            whether the border is to be painted or not.
  500.            indata can also be NULL which means paint the whole thing
  501.         */
  502.     
  503.         if (!win_IsEmployed(win)) {
  504.             if (indata == NULL || (*((unsigned *) indata) != WPD_SENTER)) {
  505.                 win_Employ(win);
  506.             }
  507.         }
  508.         else {
  509.             if (indata == NULL || (*((unsigned *) indata) & WPD_BORDER)) {
  510.                 bord_Paint(win);
  511.             }
  512.             else {
  513.                 win_Paint(win);
  514.             }
  515.         }
  516.         break;
  517.  
  518.     case WINM_GETFLDPOS:
  519.         /* get location of control within the window */
  520.         /* outdata is a (ocbox *) */
  521.         /* you should preset the ocbox before calling this message */
  522.         break;
  523.  
  524.     case WINM_SETFLDPOS:
  525.         /* pass control to location closest to curpos */
  526.         /* indata is a (winscp_struct *) */
  527.         break;
  528.  
  529.     case WINM_ISAVE:
  530.     case WINM_SCROLLREQ:
  531.     case WINM_ICONREQ:
  532.     case WINM_CHILDCLOSE:
  533.         break;    /* These messages are supported in a subclass or not at all */
  534.  
  535.     default:
  536.         /* pass other messages to bob superclass */
  537.         return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
  538.     }
  539.     return(TRUE);
  540. }
  541. /* -------------------------------------------------------------------------- */
  542.  
  543. static void OWLPRIV win_paintcursor(win)
  544.     win_type win;
  545. {
  546.     opbox cursbox;
  547.  
  548.     win_GetCursorPixBox(win, &cursbox);
  549.     if (win_clipbox(win, &cursbox)) {
  550.         win_ExposePixBox(win, &cursbox, WINM_DRAWCURSOR, NULL);
  551.     }
  552. }
  553. /* -------------------------------------------------------------------------- */
  554.  
  555.