home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / Devices / modules / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-21  |  11.3 KB  |  413 lines

  1. /* screen.c - 2.0 screen module for Display
  2.  * based on scdemo, oscandemo, looki
  3.  */
  4.  
  5. /*
  6. Copyright (c) 1989, 1990 Commodore-Amiga, Inc.
  7.  
  8. Executables based on this information may be used in software
  9. for Commodore Amiga computers. All other rights reserved.
  10. This information is provided "as is"; no warranties are made.
  11. All use is at your own risk, and no liability or responsibility
  12. is assumed.
  13. */
  14.  
  15. #include "iffp/ilbmapp.h"
  16.  
  17. BOOL   VideoControlTags(struct ColorMap *,ULONG tags, ...);
  18.  
  19. extern struct Library *GfxBase;
  20. extern struct Library *IntuitionBase;
  21.  
  22. struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, };
  23. UWORD  penarray[] = {~0};
  24.  
  25. /* default new window if none supplied in ilbm->nw */
  26. struct   NewWindow      defnw = {
  27.    0, 0,                                  /* LeftEdge and TopEdge */
  28.    0, 0,                                /* Width and Height */
  29.    -1, -1,                                /* DetailPen and BlockPen */
  30.    VANILLAKEY|MOUSEBUTTONS,               /* IDCMP Flags with Flags below */
  31.    BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP,
  32.    NULL, NULL,                            /* Gadget and Image pointers */
  33.    NULL,                                  /* Title string */
  34.    NULL,                                  /* Screen ptr null till opened */
  35.    NULL,                                  /* BitMap pointer */
  36.    50, 20,                                /* MinWidth and MinHeight */
  37.    0 , 0,                                 /* MaxWidth and MaxHeight */
  38.    CUSTOMSCREEN                           /* Type of window */
  39.    };
  40.  
  41.  
  42. /* opendisplay - passed ILBMInfo, dimensions, modeID
  43.  *
  44.  *    Attempts to open correct 2.0 modeID screen and window,
  45.  *    else an old 1.3 mode screen and window.
  46.  *
  47.  * Returns *window or NULL.
  48.  */
  49.  
  50. struct Window *opendisplay(struct ILBMInfo *ilbm,
  51.                SHORT wide, SHORT high, SHORT deep,
  52.                ULONG mode)
  53.     {
  54.     struct NewWindow newwin, *nw;
  55.  
  56.     closedisplay(ilbm);
  57.     if(ilbm->scr = openidscreen(ilbm, wide, high, deep, mode))
  58.     {
  59.     nw = &newwin;
  60.     if(ilbm->windef) *nw = *(ilbm->windef);
  61.     else *nw = *(&defnw);
  62.     nw->Screen    = ilbm->scr;
  63.  
  64.     D(bug("sizes: scr= %ld x %ld  passed= %ld x %ld\n",
  65.         ilbm->scr->Width,ilbm->scr->Height,wide,high)); 
  66.  
  67.     nw->Width    = wide;
  68.     nw->Height    = high;
  69.     if (!(ilbm->win = OpenWindow(nw)))
  70.         {
  71.         closedisplay(ilbm);
  72.         D(bug("Failed to open window."));
  73.         }
  74.     else
  75.         {
  76.         if(ilbm->win->Flags & BACKDROP)
  77.         {
  78.         ShowTitle(ilbm->scr, FALSE);
  79.         ilbm->TBState = FALSE;
  80.         }
  81.         }
  82.     }
  83.  
  84.     if(ilbm->scr)    /* nulled out by closedisplay if OpenWindow failed */
  85.     {
  86.     ilbm->vp  = &ilbm->scr->ViewPort;
  87.     ilbm->srp = &ilbm->scr->RastPort;
  88.     ilbm->wrp = ilbm->win->RPort;
  89.     }
  90.     return(ilbm->win);
  91.     }
  92.  
  93.  
  94. void closedisplay(struct ILBMInfo *ilbm)
  95.     {
  96.     if(ilbm)
  97.     {
  98.         if (ilbm->win)    CloseWindow(ilbm->win), ilbm->win = NULL;
  99.         if (ilbm->scr)    CloseScreen(ilbm->scr), ilbm->scr = NULL;
  100.         ilbm->vp  = NULL;
  101.         ilbm->srp = ilbm->wrp = NULL;
  102.     }
  103.     }
  104.  
  105.  
  106.  
  107. /* openidscreen - ILBMInfo, dimensions, modeID
  108.  *
  109.  *    Attempts to open correct 2.0 modeID screen with centered
  110.  *    overscan based on user's prefs,
  111.  *    else old 1.3 mode screen.
  112.  *
  113.  * If ilbm->stype includes CUSTOMBITMAP, ilbm->brbitmap will be
  114.  *       used as the screen's bitmap.
  115.  * If ilbm->stags is non-NULL, these tags will be added to the
  116.  *    end of the taglist.
  117.  *
  118.  * Returns *screen or NULL.
  119.  */
  120.  
  121. struct Screen *openidscreen(struct ILBMInfo *ilbm,
  122.                 SHORT wide, SHORT high, SHORT deep,
  123.                 ULONG mode)
  124.     {
  125.     struct NewScreen ns;            /* for old style OpenScreen */
  126.     struct Rectangle spos, dclip, txto, stdo, maxo, uclip;  /* display rectangles */
  127.     struct Rectangle *uclipp;
  128.     struct Screen   *scr = NULL;
  129.     LONG   error, trynew;
  130.     ULONG  bitmaptag, passedtags;
  131.     BOOL   vctl;
  132.  
  133.     if (trynew = ((((struct Library *)GfxBase)->lib_Version >= 36)&&
  134.           (((struct Library *)IntuitionBase)->lib_Version >= 36)))
  135.     {
  136.         /* if >= v36, see if mode is available */
  137.     if(error = ModeNotAvailable(mode))
  138.         {
  139.         D(bug("Mode $%08lx not available, error=%ld:\n",mode,error));
  140.         /* if not available, try fall back mode */
  141.         mode = modefallback(mode,wide,high,deep);
  142.         error = ModeNotAvailable(mode);
  143.  
  144.         D(bug("$%08lx ModeNotAvailable=%ld:\n",mode,error));
  145.         }
  146.  
  147.     if(error) trynew = FALSE;
  148.     else trynew=((QueryOverscan(mode,&txto,OSCAN_TEXT))&&
  149.             (QueryOverscan(mode,&stdo,OSCAN_STANDARD))&&
  150.                 (QueryOverscan(mode,&maxo,OSCAN_MAX)));
  151.     }
  152.  
  153.     D(bug("\nILBM: w=%ld, h=%ld, d=%ld, mode=0x%08lx\n",
  154.         wide,high,deep,mode));    
  155.     D(bug("OPEN: %s.\n",
  156.         trynew    ? "Is >= 2.0 and mode available, trying OpenScreenTags"
  157.         : "Not 2.0, doing old OpenScreen"));
  158.  
  159.     if(trynew)
  160.     {
  161.     /* If user clip type specified and available, use it */
  162.     if(ilbm->Video) ilbm->ucliptype = OSCAN_VIDEO;
  163.     if((ilbm->ucliptype)&&(QueryOverscan(mode,&uclip,ilbm->ucliptype)))
  164.         uclipp = &uclip;
  165.     else uclipp = NULL;
  166.  
  167.     clipit(wide,high,&spos,&dclip,&txto,&stdo,&maxo,uclipp);
  168.  
  169.     D(bug("Using dclip  %ld,%ld  to  %ld,%ld... width=%ld height=%ld\n",
  170.             dclip.MinX,dclip.MinY,dclip.MaxX,dclip.MaxY,
  171.             dclip.MaxX-dclip.MinX+1,dclip.MaxY-dclip.MinY+1));
  172.     D(bug("spos->minx = %ld, spos->miny = %ld\n",spos.MinX,spos.MinY));
  173.     D(bug("DEBUG: About to attempt OpenScreenTags\n"));
  174.  
  175.     bitmaptag = ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP)) ?
  176.         SA_BitMap : TAG_IGNORE;
  177.     passedtags = ilbm->stags ? TAG_MORE : TAG_IGNORE;
  178.  
  179.     scr=(struct Screen *)OpenScreenTags((struct NewScreen *)NULL,
  180.         SA_DisplayID,    mode,
  181.         SA_Type,    ilbm->stype,
  182.         SA_Behind,    TRUE,
  183.         SA_Top,        spos.MinY,
  184.         SA_Left,    spos.MinX,
  185.         SA_Width,    wide,
  186.         SA_Height,    high,
  187.         SA_Depth,    deep,
  188.         SA_DClip,    &dclip,
  189.         SA_AutoScroll,    ilbm->Autoscroll ? TRUE : FALSE,
  190.         SA_Title,    ilbm->stitle,
  191.         SA_Font,    &SafeFont,
  192.         SA_Pens,    penarray,
  193.         SA_ErrorCode,    &error,
  194.         bitmaptag,    ilbm->brbitmap,
  195.         passedtags,    ilbm->stags,
  196.         TAG_DONE
  197.         );
  198.  
  199.         D(bug("DEBUG: OpenScreenTags scr at 0x%lx\n",scr));
  200.  
  201.         if(scr)
  202.         {
  203.         if(ilbm->Notransb)
  204.             {
  205.             vctl=VideoControlTags(scr->ViewPort.ColorMap,
  206.                 VTAG_BORDERNOTRANS_SET, TRUE,
  207.                 TAG_DONE);
  208.  
  209.     D(bug("VideoControl to set bordernotrans, error = %ld\n",vctl));
  210.  
  211.             MakeScreen(scr);
  212.             RethinkDisplay();
  213.             }
  214.         }
  215.         else modeErrorMsg(mode,error);
  216.         }
  217.  
  218.     if(!scr)
  219.     {
  220.     /* ns initialization for 1.3 old style OpenScreen only
  221.          */
  222.     ns.LeftEdge = ns.TopEdge = 0;   
  223.     ns.Width     =    wide;
  224.     ns.Height     =    high;
  225.     ns.Depth    =    deep;
  226.     ns.ViewModes    =     modefallback(mode,wide,high,deep);
  227.     ns.DetailPen    =    0;
  228.     ns.BlockPen    =    1;
  229.     ns.Gadgets    =    NULL;
  230.     ns.CustomBitMap    =    ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP))
  231.                     ? ilbm->brbitmap : NULL;
  232.     ns.Font        =    &SafeFont;
  233.     ns.DefaultTitle =     ilbm->stitle;
  234.     ns.Type        =    ilbm->stype & 0x01FF;  /* allow only 1.3 types */
  235.  
  236.     scr=(struct Screen *)OpenScreen(&ns);
  237.  
  238.     D(bug("DEBUG: ns.ViewModes=0x%lx, vp->Modes=0x%lx\n",
  239.                  ns.ViewModes,scr->ViewPort.Modes));
  240.     D(bug("DEBUG: non-extended scr at 0x%lx (0=failure)\n",scr));
  241.     }
  242.     return(scr);
  243.     }
  244.  
  245.  
  246. /*
  247.  * modefallback - passed a mode id, attempts to provide a
  248.  *                suitable old mode to use instead
  249.  */
  250.  
  251. /* for old 1.3 screens */
  252. #define MODE_ID_MASK (LACE|HIRES|HAM|EXTRA_HALFBRITE)
  253.  
  254. ULONG modefallback(ULONG mode, SHORT wide, SHORT high, SHORT deep)
  255. {
  256. ULONG newmode;
  257.  
  258.     /* For now, simply masks out everything but old mode bits.
  259.      * This is just a cheap way to get some kind of display open
  260.      *   and may be totally invalid for future modes.
  261.      * Should search the display database for a suitable mode
  262.      * based on the specific needs of your application.
  263.      */
  264.     newmode = mode & MODE_ID_MASK;
  265.  
  266.     D(bug("Try 0x%08lx instead of 0x%08lx\n",newmode,mode));
  267.     return(newmode);
  268. }
  269.  
  270.  
  271. /*
  272.  * clipit - passed width and height of a display, and the text, std, and
  273.  *          max overscan rectangles for the mode, clipit fills in the
  274.  *          spos (screen pos) and dclip rectangles to use in centering.
  275.  *          Centered around smallest containing user-editable oscan pref,
  276.  *          with dclip confined to legal maxoscan limits.
  277.  *          Screens which center such that their top is below text
  278.  *          oscan top, will be moved up.
  279.  *          If a non-null uclip is passed, that clip is used instead.
  280.  */
  281. void clipit(SHORT wide, SHORT high,
  282.         struct Rectangle *spos, struct Rectangle *dclip,
  283.         struct Rectangle *txto, struct Rectangle *stdo,
  284.         struct Rectangle *maxo, struct Rectangle *uclip)
  285. {
  286. struct  Rectangle *besto;
  287. SHORT    minx, maxx, miny, maxy;
  288. SHORT    txtw, txth, stdw, stdh, maxw, maxh, bestw, besth;
  289.  
  290.     /* get the txt, std and max widths and heights */
  291.     txtw = txto->MaxX - txto->MinX + 1;
  292.     txth = txto->MaxY - txto->MinY + 1;
  293.     stdw = stdo->MaxX - stdo->MinX + 1;
  294.     stdh = stdo->MaxY - stdo->MinY + 1;
  295.     maxw = maxo->MaxX - maxo->MinX + 1;
  296.     maxh = maxo->MaxY - maxo->MinY + 1;
  297.  
  298.     if((wide <= txtw)&&(high <= txth))
  299.     {
  300.     besto = txto;
  301.     bestw = txtw;
  302.     besth = txth;
  303.  
  304.     D(bug("Best clip is txto\n"));
  305.     }
  306.     else
  307.     {
  308.     besto = stdo;
  309.     bestw = stdw;
  310.     besth = stdh;
  311.  
  312.     D(bug("Best clip is stdo\n"));
  313.     }
  314.  
  315.     D(bug("TXTO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  316.         txto->MinX,txto->MinY,txto->MaxX,txto->MaxY,txtw,txth));
  317.     D(bug("STDO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  318.         stdo->MinX,stdo->MinY,stdo->MaxX,stdo->MaxY,stdw,stdh));
  319.     D(bug("MAXO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  maxw=%ld maxh=%ld\n",
  320.         maxo->MinX,maxo->MinY,maxo->MaxX,maxo->MaxY,maxw,maxh));
  321.  
  322.     if(uclip)
  323.     {
  324.     *dclip = *uclip;
  325.         spos->MinX = uclip->MinX;
  326.     spos->MinY = uclip->MinY;
  327.  
  328.     D(bug("UCLIP: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  329.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  330.     }
  331.     else
  332.     {
  333.     /* CENTER the screen based on best oscan prefs
  334.      * but confine dclip within max oscan limits
  335.      *
  336.      * FIX MinX first */
  337.     spos->MinX = minx = besto->MinX - ((wide - bestw) >> 1);
  338.     maxx = wide + minx - 1;
  339.     if(maxx > maxo->MaxX)  maxx = maxo->MaxX;    /* too right */
  340.     if(minx < maxo->MinX)  minx = maxo->MinX;    /* too left  */
  341.  
  342.     D(bug("DCLIP: minx adjust from %ld to %ld\n",spos->MinX,minx));
  343.  
  344.     /* FIX MinY */
  345.     spos->MinY = miny = besto->MinY - ((high - besth) >> 1);
  346.     /* if lower than top of txto, move up */
  347.     spos->MinY = miny = MIN(spos->MinY,txto->MinY);
  348.     maxy = high + miny - 1;
  349.     if(maxy > maxo->MaxY)  maxy = maxo->MaxY;    /* too down  */
  350.     if(miny < maxo->MinY)  miny = maxo->MinY;    /* too up    */
  351.  
  352.     D(bug("DCLIP: miny adjust from %ld to %ld\n",spos->MinY,miny));
  353.  
  354.     /* SET up dclip */
  355.     dclip->MinX = minx;
  356.     dclip->MinY = miny;
  357.     dclip->MaxX = maxx;
  358.     dclip->MaxY = maxy;
  359.  
  360.     D(bug("CENTER: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  361.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  362.     }
  363. }
  364.  
  365.  
  366. void modeErrorMsg(ULONG mode, ULONG errorcode)
  367.    {
  368.    UBYTE *s=NULL;
  369.  
  370.     D(bug("DEBUG: Can't open mode ID 0x%08lx screen: ",mode));
  371.  
  372.         switch ( errorcode )
  373.     {
  374.     case OSERR_NOMEM:
  375.         s="Not enough memory.";
  376.         break;
  377.     case OSERR_NOCHIPMEM:
  378.         s="Not enough chip memory.";
  379.         break;
  380. #ifdef DEBUG
  381.     case OSERR_NOMONITOR:
  382.         s="monitor not available.";
  383.         break;
  384.  
  385.     case OSERR_NOCHIPS:
  386.         s="new chipset not available.";
  387.         break;
  388.  
  389.     case OSERR_PUBNOTUNIQUE:
  390.         s="public screen already open.";
  391.         break;
  392.     case OSERR_UNKNOWNMODE:
  393.         s="mode ID is unknown.";
  394.         break;
  395.     default:
  396.         message("unknown mode error %ld\n",errorcode);
  397. #endif
  398.     }
  399.     if(s) message("%s\n",s);
  400.     }
  401.  
  402.  
  403. /*----------------------------------------------------------------------*/
  404.  
  405. BOOL VideoControlTags(struct ColorMap *cm, ULONG tags, ...)
  406.     {
  407.     return (VideoControl(cm, (struct TagItem *)&tags));
  408.     }
  409.  
  410.  
  411. /*----------------------------------------------------------------------*/
  412.  
  413.