home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / CMWIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-03  |  8.9 KB  |  315 lines

  1. /*
  2.     cmwin.c    3/11/88
  3.  
  4.     % Character map window object.
  5.     By Ted.
  6.  
  7.     OWL 1.2
  8.     Copyright (c) 1988, by Oakland Group, Inc.
  9.     ALL RIGHTS RESERVED.
  10.  
  11.     Revision History:
  12.     -----------------
  13.      6/16/88 Ted    revised to have inheritance and class factory functions.
  14.      8/09/88 jmd    revised to use new object stuff
  15.      8/15/88 jmd    OPEN now takes a winopen_struct
  16.      9/12/88 jmd    Added in and out data to objects
  17.     11/20/88 jmd    Added ID to obj struct
  18.     12/13/88 jmd    Added cmap = NULL to cmwin_GetCmap (removes LC warning)
  19.  
  20.      1/18/89 Ted    changed call to PlotText for simplified interface.
  21.      6/24/89 jmd    added shadow support
  22.      8/12/89 jmd    improved shadow support
  23.      8/12/89 jdc    Added INIT and WHO message
  24.      8/13/89 jmd    Added test for NULL cmap in INPOS message
  25.  
  26.     11/06/89 jmd    removed DoRaw macros
  27.  
  28.     Questions...  *** Answers 7/05/89 ted.
  29.     1) why is cmwin made current during ISAVE message?
  30.         Because the ISAVE message is only sent during disp_Init to the
  31.         background window, and this allows the vid_win to display its cursor.
  32.     2) read loop in cmwin_Plot looks like it could be better.
  33.         Since this is a rarely used feature I optimized for code size and
  34.         simplicity.
  35.     3) Spaces plotting should be optimized.
  36.         Go ahead.
  37.  
  38.      1/08/89 ted    Added arg to win_MakeCurrent.
  39.      3/28/90 jmd    ansi-fied
  40.      4/21/90 ted    Deactivated PlotBox ClearFrame for READBOX case.
  41.      5/03/90 ted    Added cmap resizing feature inspired by Robert Decuir.
  42. */
  43.  
  44. #include "oakhead.h"
  45. #include "disppriv.h"
  46. #include "cmwinobj.h"
  47. #include "cmwinod.h"
  48.  
  49. OGLOBAL objreq_fptr cmwinreq_mousefptr =  objreq_Null;
  50.  
  51. OSTATIC void OWLPRIV cmwin_PlotBox(ptd_struct *ptd, cmwin_od *cmwd, int plot);
  52. OSTATIC void OWLPRIV ptd_ReadCharAttrbuf(ptd_struct *ptd, opcoord x, opcoord y, char *charbuf, byte *attrbuf, int slen);
  53.  
  54. #define CMWIN_READBOX    0
  55. #define CMWIN_PLOTBOX    1
  56. #define CMWIN_SHADOW    2
  57. /* -------------------------------------------------------------------------- */
  58.  
  59. int cmwin_Class(VOID *objdata, int msg, VOID *indata, VOID *outdata)
  60. /* 
  61.     cmap window object dispatch function
  62. */
  63. {
  64.     cmwin_od     *cmwd;
  65.     win_type    win;
  66.     cmap_type     cmap;
  67.     ofont_type  font;
  68.     ptd_struct     *ptd;
  69.     ptd_struct  inptd;        /* for use in inner-coordinate computations */
  70.     opbox         inbox;        /* ditto; gets hooked in by ptd_SetInner */
  71.     winopendata_struct *wod;
  72.     inposdata_struct *ipd;
  73.  
  74.     cmwd = (cmwin_od *) objdata;
  75.     if (msg != OBJM_GETDATASIZE) {    /* would be GP fault in this case */
  76.         win = cmwinod_GetSelf(cmwd);
  77.     }
  78.     switch(msg) {
  79.     case OBJM_GETDATASIZE:
  80.         ((ogds_struct *) outdata)->odsize = sizeof(cmwin_od);
  81.         ((ogds_struct *) outdata)->xdsize = sizeof(cmwin_xd);
  82.         ((ogds_struct *) outdata)->id = ID_CMWIN;
  83.         break;
  84.  
  85.     case OBJM_INIT:
  86.         wod = (winopendata_struct *) indata;
  87.  
  88.         if (wod->font == NULL) {
  89.             return(FALSE);
  90.         }
  91.  
  92.         /* Allocate character map */
  93.         if ((cmap = cmap_Open(opbox_GetHeight(wod->boxp)/ofont_GetHeight(wod->font),
  94.             opbox_GetWidth(wod->boxp)/ofont_GetWidth(wod->font))) == NULL) {
  95.  
  96.             return(FALSE);
  97.         }
  98.         cmwin_SetCmap(win, cmap);
  99.  
  100.         return(win_Class(&(cmwd->wd), msg, indata, outdata));
  101.  
  102.     case OBJM_OPEN:
  103.         /* Initialize cmap data */
  104.         cmwin_SetCmap(win, NULL);
  105.         cmwin_SetRowoffs(win, 0);    /* offsets for scrolling cmap within window */
  106.         cmwin_SetColoffs(win, 0);
  107.  
  108.         /* send OPEN message to win superclass */
  109.         return(win_Class(&(cmwd->wd), msg, indata, outdata));
  110.  
  111.     case OBJM_CLOSE:
  112.         /* close character map */
  113.         if (cmwin_GetCmap(win) != NULL) {
  114.             cmap_Close(cmwin_GetCmap(win));
  115.         }
  116.         /* No break, pass CLOSE msg to win superclass */
  117.     default:
  118.         /* pass other messages to win superclass */
  119.         return(win_Class(&(cmwd->wd), msg, indata, outdata));
  120.  
  121.     case OBJM_WHO:
  122.         /* Identify ourselves */
  123.         if (*((int *) indata) == ID_CMWIN) {
  124.             return(TRUE);
  125.         }
  126.         return(win_Class(&(cmwd->wd), msg, indata, outdata));
  127.  
  128.     case WINM_SHADOW:
  129.         ptd = (ptd_struct *)indata;
  130.  
  131.         /* set ptd data to indicate that we've taken care of the shadow */
  132.         ptd->emsgdata = (VOID *) 1;
  133.  
  134.         /* no break; fall through to PAINT */
  135.  
  136.     case WINM_PAINT:
  137.         ptd = (ptd_struct *)indata;
  138.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  139.             cmwin_PlotBox(&inptd, cmwd, (msg == WINM_PAINT) ? CMWIN_PLOTBOX : CMWIN_SHADOW);
  140.         }
  141.         return(win_Class(&(cmwd->wd), msg, indata, outdata));
  142.  
  143.     case WINM_ISAVE:
  144.         ptd = (ptd_struct *)indata;
  145.  
  146.     /* This is background cmwin; make it current */
  147.         win_MakeCurrent(ptd->win, NULL);
  148.  
  149.     /*  Get the characters from the display into the cmap */
  150.         if (ptd_SetInner(ptd, &inptd, &inbox)) {
  151.             cmwin_PlotBox(ptd, cmwd, CMWIN_READBOX);
  152.         }
  153.         break;
  154.  
  155.     case WINM_GETINPOS:
  156.         ipd = (inposdata_struct *) outdata;
  157.         font = win_GetFont(ipd->win);
  158.  
  159.         /* make sure cmap is valid (we could be in the middle of being 
  160.                                     loaded from a screen file)
  161.         */
  162.         if (cmwin_GetCmap(win) == NULL) {
  163.             return(win_Class(&(cmwd->wd), msg, indata, outdata));
  164.         }
  165.  
  166.         ipd->inbox.xmin = -cmwin_GetColoffs(win) * ofont_GetWidth(font);
  167.         ipd->inbox.xmax = ipd->inbox.xmin + 
  168.                         (cmap_GetWidth(cmwin_GetCmap(win)) * ofont_GetWidth(font));
  169.         ipd->inbox.ymin = -cmwin_GetRowoffs(win) * ofont_GetHeight(font);
  170.         ipd->inbox.ymax = ipd->inbox.ymin + 
  171.                         (cmap_GetHeight(cmwin_GetCmap(win)) * ofont_GetHeight(font));
  172.         break;
  173.  
  174.     case WINM_SCROLLREQ:
  175.         return((*cmwinreq_mousefptr)(cmwd, msg, indata, outdata));
  176.  
  177.     case WINM_SETSIZE:
  178.     {
  179.         cmap_type newcm, oldcm;
  180.  
  181.         if (win_Class(&(cmwd->wd), msg, indata, outdata) && cmwin_GetResize(win)) {
  182.             newcm = cmap_Open(win_GetHeight(win), win_GetWidth(win));
  183.             if (newcm != NULL) {
  184.                 oldcm = cmwin_GetCmap(win);
  185.                 cmap_Copy(newcm, oldcm, win_GetAttr(win));
  186.                 cmwin_SetCmap(win, newcm);
  187.                 cmap_Close(oldcm);
  188.             }
  189.         }
  190.         break;
  191.     }
  192.     }
  193.     return(TRUE);
  194. }
  195. /* -------------------------------------------------------------------------- */
  196.  
  197. static void OWLPRIV cmwin_PlotBox(ptd_struct *ptd, cmwin_od *cmwd, int plot)
  198. /*
  199.     Plots a region of a cmap window to the display.
  200.     'plot' is a flag to plot, shadow,  or read.
  201. */
  202. {
  203.     win_type win;
  204.     cmap_type cmap;
  205.     ocbox     relcbox;
  206.     opcoord xpix, ypix;
  207.     int     row;
  208.     char   *charbuf;
  209.     byte   *attrbuf;
  210.     opcoord fwidth, fheight;
  211.     int     cwidth;
  212.     int     i, last;
  213.     byte     lasta, attr;
  214.     ofont_type font;
  215.  
  216.     win = cmwinod_GetSelf(cmwd);
  217.     cmap = cmwin_GetCmap(win);
  218.     font = win_GetFont(ptd->win);
  219.     fheight = ofont_GetHeight(font);
  220.     fwidth  = ofont_GetWidth(font);
  221.  
  222.     opbox_charcoords(ptd->relboxp, font, &relcbox);
  223.     ocbox_trans(&relcbox, cmwin_GetRowoffs(win), cmwin_GetColoffs(win));
  224.  
  225.     /* Clear out the parts of the box not occupied by cmap, if any */
  226.     attr = (plot == CMWIN_SHADOW) ? win_GetShadowAttr(win) : win_GetAttr(win);
  227.  
  228.     if (plot != CMWIN_READBOX) {
  229.         ptd_ClearFrame(ptd, -cmwin_GetColoffs(win) * fwidth, -cmwin_GetRowoffs(win) * fheight,
  230.                         cmwin_GetCmap(win)->ncols * fwidth, cmwin_GetCmap(win)->nrows * fheight,
  231.                         disp_GetAttrBgColor(attr));
  232.     }
  233.     /* Plot the text from the window */
  234.     if (cmap_clipcbox(cmap, &relcbox)) {
  235.  
  236.         charbuf = cmap_charbuf(cmap, relcbox.toprow, relcbox.leftcol);
  237.         attrbuf = cmap_attrbuf(cmap, relcbox.toprow, relcbox.leftcol);
  238.  
  239.         ocbox_trans(&relcbox, -cmwin_GetRowoffs(win), -cmwin_GetColoffs(win));
  240.  
  241.         ypix = (relcbox.toprow + 1) * fheight;
  242.         xpix = (relcbox.leftcol) * fwidth;
  243.         cwidth = ocbox_GetWidth(&relcbox);
  244.  
  245.         row = ocbox_GetHeight(&relcbox);
  246.         if (plot == CMWIN_PLOTBOX) {        /* plotting (for paint message) */
  247.             for (;;) {
  248.                 last = 0;
  249.                 lasta = attrbuf[last];
  250.                 for (i = 0; i <= cwidth; i++) {
  251.                     if (i == cwidth) {
  252.                         ptd_PlotTextbuf(ptd, xpix + last*fwidth, ypix,
  253.                                         charbuf+last, lasta, i-last);
  254.                         break;
  255.                     }
  256.                     if (attrbuf[i] != lasta) {
  257.                         ptd_PlotTextbuf(ptd, xpix + last*fwidth, ypix,
  258.                                         charbuf+last, lasta, i-last);
  259.                         last = i;
  260.                         lasta = attrbuf[last];
  261.                     }
  262.                 }
  263.                 if (row <= 1) {
  264.                     break;
  265.                 }
  266.  
  267.                 ypix += fheight;
  268.                 charbuf += cmap->ncols;
  269.                 attrbuf += cmap->ncols;
  270.                 row--;
  271.             }
  272.         }
  273.         else if (plot == CMWIN_SHADOW) {        /* plotting (for shadow message) */
  274.             for (;row > 0; row--) {
  275.                 ptd_PlotTextbuf(ptd, xpix, ypix, charbuf, 
  276.                         win_GetShadowAttr(win), cwidth);
  277.  
  278.                 ypix += fheight;
  279.                 charbuf += cmap->ncols;
  280.                 attrbuf += cmap->ncols;
  281.             }
  282.         }
  283.         else {        /* reading (for isave message) */
  284.             for (;;) {
  285.                 ptd_ReadCharAttrbuf(ptd, xpix, ypix, charbuf, attrbuf, cwidth);
  286.                 if (row <= 1) {
  287.                     break;
  288.                 }
  289.  
  290.                 ypix += fheight;
  291.                 charbuf += cmap->ncols;
  292.                 attrbuf += cmap->ncols;
  293.                 row--;
  294.             }
  295.         }
  296.     }
  297. }
  298. /* -------------------------------------------------------------------------- */
  299.  
  300. static void OWLPRIV ptd_ReadCharAttrbuf(ptd_struct *ptd, opcoord x, opcoord y, char *charbuf, byte *attrbuf, int slen)
  301. {
  302.     ptarg_struct pta;
  303.  
  304.     pta.ptd = ptd;
  305.     pta.x = x;
  306.     pta.y = y;
  307.     pta.charbuf = charbuf;
  308.     pta.attrbuf = attrbuf;
  309.     pta.slen = slen;
  310.  
  311.     disp_Control(DC_READCHARATTR, &pta, NULL);
  312. }
  313. /* -------------------------------------------------------------------------- */
  314.  
  315.