home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / MultiDesktop / wall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-27  |  10.3 KB  |  449 lines

  1. /* Wallpaper-Verwaltung */
  2. #include "multiwindows.h"
  3. #include "iff-ilbm.h"
  4.  
  5. extern struct MultiWindowsBase *MultiWindowsBase;
  6. extern struct ExecBase         *SysBase;
  7.  
  8. BOOL LoadBODY();
  9. BOOL SetWindowWallpaper();
  10. void ShowWallpaperRastPort();
  11.  
  12. /* ---- Wallpaper im Fenster darstellen */
  13. void ShowWallpaperWindow(win,wp)
  14.  struct Window    *win;
  15.  struct Wallpaper *wp;
  16. {
  17.  int innerLeftEdge,innerTopEdge,
  18.      innerWidth,innerHeight;
  19.  
  20.  if(wp==NULL) return;
  21.  
  22.  innerTopEdge=win->BorderTop;
  23.  innerLeftEdge=win->BorderLeft;
  24.  innerWidth=win->Width-win->BorderLeft-win->BorderRight;
  25.  innerHeight=win->Height-win->BorderTop-win->BorderBottom;
  26.  ShowWallpaperRastPort(win->RPort,wp,innerLeftEdge,innerTopEdge,innerWidth,innerHeight);
  27. }
  28.  
  29. /* ---- Wallpaper im RastPort darstellen */
  30. void ShowWallpaperRastPort(rp,wp,innerLeftEdge,innerTopEdge,innerWidth,innerHeight)
  31.  struct RastPort  *rp;
  32.  struct Wallpaper *wp;
  33.  int               innerLeftEdge,innerTopEdge,
  34.                    innerWidth,innerHeight;
  35. {
  36.  int               x,y;
  37.  int               x1,y1,x2,y2,w,h;
  38.  
  39.  if(wp==NULL) return;
  40.  x2=innerWidth+innerLeftEdge;
  41.  y2=innerHeight+innerTopEdge;
  42.  for(x=0;x<innerWidth;x+=wp->Width)
  43.   {
  44.    for(y=0;y<innerHeight;y+=wp->Height)
  45.     {
  46.      x1=x+innerLeftEdge;
  47.      y1=y+innerTopEdge;
  48.      w=wp->Width;
  49.      if(x1+w>x2) w=x2-x1;
  50.      h=wp->Height;
  51.      if(y1+h>y2) h=y2-y1;
  52.      BltBitMapRastPort(&wp->BitMap,0,0,rp,x1,y1,w,h,0xc0);
  53.     }
  54.   }
  55. }
  56.  
  57. /* ---- Wallpaper entfernen */
  58. void UnLoadWallpaper(wp)
  59.  struct Wallpaper *wp;
  60. {
  61.  int i;
  62.  
  63.  if(wp)
  64.   {
  65.    i=0;
  66.    Forbid();
  67.    wp->UserCount--;
  68.    if(wp->UserCount==0) {
  69.      if(wp->Node.ln_Succ!=NULL)
  70.        { Remove(wp); MultiWindowsBase->WallpaperCount--; i=1; }}
  71.    Permit();
  72.  
  73.    if(i==1)
  74.     {
  75.      for(i=0;i<8;i++)
  76.       {
  77.        if(wp->BitMap.Planes[i])
  78.          FreeRaster(wp->BitMap.Planes[i],wp->Width,wp->Height);
  79.       }
  80.      FreeVec(wp);
  81.     }
  82.   }
  83. }
  84.  
  85. /* ---- Wallpaper laden */
  86. struct Wallpaper *LoadWallpaper(name)
  87.  UBYTE *name;
  88. {
  89.  struct Wallpaper  *wp;
  90.  struct FileLock   *lock,*syslock;
  91.  struct FileHandle *fh;
  92.  struct BMHD        bmhd;
  93.  BOOL               HasBMHD,HasBODY,okay;
  94.  UBYTE              id[60];
  95.  ULONG              size,res;
  96.  int                i;
  97.  
  98.  for(i=0;i<strlen(name);i++)
  99.    id[i]=tolower(name[i]);
  100.  id[i]=0x00;
  101.  Forbid();
  102.  wp=FindName(&MultiWindowsBase->WallpaperList,&id);
  103.  if(wp) wp->UserCount++;
  104.  Permit();
  105.  if(wp) return(wp);
  106.  
  107.  lock=Lock(MultiWindowsBase->WallpaperDir,ACCESS_READ);
  108.  if(lock) syslock=CurrentDir(lock); else syslock=NULL;
  109.  fh=Open(name,MODE_OLDFILE);
  110.  if(syslock) CurrentDir(syslock);
  111.  if(lock) UnLock(lock);
  112.  if(fh==NULL) return(NULL);
  113.  
  114.  wp=AllocVec(sizeof(struct Wallpaper)+strlen(name)+2,MEMF_CLEAR|MEMF_PUBLIC);
  115.  if(wp!=NULL)
  116.   {
  117.    wp->UserCount=1;
  118.    strcpy(&wp->Name,&id);
  119.    wp->Node.ln_Name=&wp->Name;
  120.  
  121.    Read(fh,&id,4L);
  122.    if(!(strncmp(&id,"FORM",4L)))
  123.     {
  124.      Read(fh,&size,4L);
  125.      Read(fh,&id,4L);
  126.      if(!(strncmp(&id,"ILBM",4L)))
  127.       {
  128.        HasBMHD=HasBODY=FALSE;
  129.        res=Read(fh,&id,4L);
  130.        while((res==4)&&(HasBODY==FALSE))
  131.         {
  132.          Read(fh,&size,4L);
  133.          if(!(strncmp(&id,"BMHD",4L)))
  134.           {
  135.            Read(fh,&bmhd,sizeof(struct BMHD));
  136.            Seek(fh,-sizeof(struct BMHD),OFFSET_CURRENT);
  137.            if((size % 2)==1) size++;
  138.            Seek(fh,size,OFFSET_CURRENT);
  139.            HasBMHD=TRUE;
  140.           }
  141.          else if(!(strncmp(&id,"BODY",4L)))
  142.            HasBODY=TRUE;
  143.          else
  144.           {
  145.            if((size % 2)==1) size++;
  146.            Seek(fh,size,OFFSET_CURRENT);
  147.           }
  148.  
  149.          res=Read(fh,&id,4L);
  150.         }
  151.        Seek(fh,-4,OFFSET_CURRENT);
  152.  
  153.        if((HasBODY)&&(HasBMHD))
  154.         {
  155.          if(bmhd.Compression<=1)
  156.           {
  157.            if(bmhd.Depth>8) bmhd.Depth=8;
  158.            wp->Width=bmhd.Width;
  159.            wp->Height=bmhd.Height;
  160.            okay=TRUE;
  161.            for(i=0;i<bmhd.Depth;i++)
  162.             {
  163.              wp->BitMap.Planes[i]=AllocRaster(wp->Width,wp->Height);
  164.              if(wp->BitMap.Planes[i]==NULL) okay=FALSE;
  165.             }
  166.            if(okay)
  167.             {
  168.              InitBitMap(&wp->BitMap,bmhd.Depth,wp->Width,wp->Height);
  169.              okay=LoadBODY(fh,wp,size,bmhd.Compression);
  170.              if(okay==FALSE)
  171.               {
  172.                ErrorL(1023,"LoadWallpaper():\nUnable to allocate temporary buffer!");
  173.                UnLoadWallpaper(wp);
  174.                wp=NULL;
  175.               }
  176.             }
  177.            else
  178.             {
  179.              ErrorL(1028,"LoadWallpaper():\nNot enough chip memory!");
  180.              UnLoadWallpaper(wp);
  181.              wp=NULL;
  182.             }
  183.           }
  184.          else
  185.           {
  186.            ErrorL(1024,"LoadWallpaper():\nUnknown ILBM compression!");
  187.            UnLoadWallpaper(wp);
  188.            wp=NULL;
  189.           }
  190.         }
  191.        else
  192.         {
  193.          ErrorL(1025,"LoadWallpaper():\nInvalid ILBM file!");
  194.          UnLoadWallpaper(wp);
  195.          wp=NULL;
  196.         }
  197.       }
  198.      else
  199.       {
  200.        ErrorL(1026,"LoadWallpaper():\nNo IFF-ILBM file!");
  201.        UnLoadWallpaper(wp);
  202.        wp=NULL;
  203.       }
  204.     }
  205.    else
  206.     {
  207.      ErrorL(1027,"LoadWallpaper():\nNo IFF file format!");
  208.      UnLoadWallpaper(wp);
  209.      wp=NULL;
  210.     }
  211.   }
  212.  else
  213.   {
  214.    ErrorL(0,0);
  215.    UnLoadWallpaper(wp);
  216.    wp=NULL;
  217.   }
  218.  
  219.  Close(fh);
  220.  if(wp)
  221.   {
  222.    Forbid();
  223.    AddTail(&MultiWindowsBase->WallpaperList,wp);
  224.    MultiWindowsBase->WallpaperCount++;
  225.    Permit();
  226.   }
  227.  return(wp);
  228. }
  229.  
  230. void CopyByte(a,b)
  231.  UBYTE *a,*b;
  232. { b[0]=a[0]; }
  233.  
  234. BOOL LoadBODY(fh,wp,size,compression)
  235.  struct FileHandle *fh;
  236.  struct Wallpaper  *wp;
  237.  ULONG              size;
  238.  UBYTE              compression;
  239. {
  240.  ULONG           bb;
  241.  UBYTE          *dest;
  242.  UBYTE           ch1,ch2;
  243.  REGISTER ULONG  body;
  244.  REGISTER UWORD  y,b,i,byteCount,bpr;
  245.  
  246.  bb=body=AllocMem(size,MEMF_ANY);
  247.  if(body==NULL) return(FALSE);
  248.  Read(fh,body,size);
  249.  
  250.  bpr=wp->BitMap.BytesPerRow;
  251.  for(y=0;y<wp->Height;y++)
  252.   {
  253.    for(b=0;b<wp->BitMap.Depth;b++)
  254.     {
  255.      byteCount=0;
  256.      dest=(UBYTE *) ( (ULONG)wp->BitMap.Planes[b]+((ULONG)y*(ULONG)bpr) );
  257.  
  258.      if(compression==0)
  259.       {
  260.        CopyMem(body,dest,bpr); body+=bpr;
  261.       }
  262.      else
  263.       {
  264.        while(byteCount<bpr)
  265.         {
  266.          CopyByte(body,&ch1); body++;
  267.          if(ch1<128)
  268.           {
  269.            CopyMem(body,(UBYTE *)dest+(UBYTE *)byteCount,ch1+1);
  270.            body+=ch1+1;
  271.            byteCount+=ch1+1;
  272.           }
  273.          if(ch1>128)
  274.           {
  275.            CopyByte(body,&ch2); body++;
  276.            for(i=byteCount;i<(byteCount+(257-ch1));i++)
  277.              { *(dest+(UBYTE *)i) = ch2; }
  278.            byteCount+=257-ch1;
  279.           }
  280.         }
  281.       }
  282.     }
  283.   }
  284.  FreeMem(bb,size);
  285.  return(TRUE);
  286. }
  287.  
  288. /* ---- Wallpaper benutzen */
  289. void UseWallpaper(we,wp)
  290.  struct WindowEntry *we;
  291.  struct Wallpaper   *wp;
  292. {
  293.  struct Node     *node;
  294.  struct MWGadget *gad;
  295.  
  296.  we->Wallpaper=wp;
  297.  if(we->Iconify) return;
  298.  
  299.  if(wp)
  300.    ShowWallpaperWindow(we->Window,wp);
  301.  else
  302.   {
  303.    BackupRP(we);
  304.    SetAPen(we->RastPort,0);
  305.    RectFill(we->RastPort,we->InnerLeftEdge,we->InnerTopEdge,
  306.             we->InnerLeftEdge+we->InnerWidth,we->InnerTopEdge+we->InnerHeight);
  307.    RestoreRP(we);
  308.   }
  309.  
  310.   BackupRP(we);
  311.   SetAPen(we->RastPort,0);
  312.   for(node=we->GadgetList.lh_Head;node!=&we->GadgetList.lh_Tail;node=node->ln_Succ)
  313.    {
  314.     gad=node;
  315.     RectFill(we->RastPort,
  316.              gad->NewGadget.ng_LeftEdge,
  317.              gad->NewGadget.ng_TopEdge,
  318.              gad->NewGadget.ng_LeftEdge+gad->NewGadget.ng_Width-1,
  319.              gad->NewGadget.ng_TopEdge+gad->NewGadget.ng_Height-1);
  320.    }
  321.   RestoreRP(we);
  322.  
  323.  if(we->Window->FirstGadget)
  324.    RefreshGList(we->Window->FirstGadget,we->Window,NULL,-1L);
  325.  RefreshSGadgets(we);
  326.  GTRefreshWindow(we->Window,NULL);
  327. }
  328.  
  329. /* ---- Wallpaper laden und im aktuellen Fenster darstellen */
  330. BOOL Wallpaper(name)
  331.  UBYTE *name;
  332. {
  333.  struct WindowEntry *we;
  334.  
  335.  WE;
  336.  if(we==NULL) return(FALSE);
  337.  return(SetWindowWallpaper(we->WindowID,name));
  338. }
  339.  
  340. /* ---- Wallpaper laden und in einem Fenster darstellen */
  341. BOOL SetWindowWallpaper(windowID,name)
  342.  UBYTE  windowID;
  343.  UBYTE *name;
  344. {
  345.  struct WindowEntry *we;
  346.  struct Wallpaper   *wp;
  347.  
  348.  we=FindWindowEntry(windowID);
  349.  if(we==NULL) return(FALSE);
  350.  
  351.  wp=LoadWallpaper(name);
  352.  if(wp)
  353.   {
  354.    UseWallpaper(we,wp);
  355.    if(we->SysWPAddress) UnLoadWallpaper(we->SysWPAddress);
  356.    we->SysWPAddress=wp;
  357.    return(TRUE);
  358.   }
  359.  return(FALSE);
  360. }
  361.  
  362. /* ---- Wallpaper laden und in einem Screen-Backdrop darstellen */
  363. BOOL SetScreenWallpaper(screenID,name)
  364.  UBYTE  screenID;
  365.  UBYTE *name;
  366. {
  367.  struct ScreenEntry *se;
  368.  struct Wallpaper   *wp;
  369.  
  370.  se=FindScreenEntry(screenID);
  371.  if(se==NULL) return(FALSE);
  372.  
  373.  wp=LoadWallpaper(name);
  374.  if(wp)
  375.   {
  376.    if(se->BgWindow==NULL) InitBackdrop(se);
  377.    if(se->BgWindow!=NULL) ShowWallpaperWindow(se->BgWindow,wp);
  378.    if(se->BgWallpaper) UnLoadWallpaper(se->BgWallpaper);
  379.    se->BgWallpaper=wp;
  380.    return(TRUE);
  381.   }
  382.  return(FALSE);
  383. }
  384.  
  385. /* ---- Hintergrund wiederherstellen */
  386. void RestoreBackground(we,x,y,w,h)
  387.  struct WindowEntry *we;
  388.  UWORD               x,y,w,h;
  389. {
  390.  struct Wallpaper *wp;
  391.  struct RastPort  *rp;
  392.  int               xa,ya,xs,ys,xp,yp;
  393.  int               x1,y1,x2,y2;
  394.  int               x3,y3,x4,y4;
  395.  UBYTE             pen;
  396.  
  397.  BackupRP(we);
  398.  rp=we->RastPort;
  399.  wp=we->Wallpaper;
  400.  
  401.  if(wp==NULL)
  402.   {
  403.    SetDrMd(rp,JAM1);
  404.    SetAPen(rp,0);
  405.    x1=x;
  406.    y1=y;
  407.    x2=x+w;
  408.    y2=y+h;
  409.    if(x1>we->Window->Width) x1=we->Window->Width;
  410.    if(x2>we->Window->Width) x2=we->Window->Width;
  411.    if(y1>we->Window->Height) y1=we->Window->Height;
  412.    if(y2>we->Window->Height) y2=we->Window->Height;
  413.    RectFill(rp,x1,y1,x2,y2);
  414.   }
  415.  else
  416.   {
  417.    xs=((x-we->InnerLeftEdge)/wp->Width)*wp->Width+we->InnerLeftEdge;
  418.    ys=((y-we->InnerTopEdge)/wp->Height)*wp->Height+we->InnerTopEdge;
  419.    xp=((((x-we->InnerLeftEdge)+w)/wp->Width)+1)*wp->Width+we->InnerLeftEdge;
  420.    yp=((((y-we->InnerTopEdge)+h)/wp->Height)+1)*wp->Height+we->InnerTopEdge;
  421.  
  422.    for(xa=xs;xa<xp;xa+=wp->Width)
  423.     {
  424.      for(ya=ys;ya<yp;ya+=wp->Height)
  425.       {
  426.        x1=xa; y1=ya; x2=x1+wp->Width; y2=y1+wp->Height;
  427.        /* ------------------------------------------ */
  428.  
  429.        if(x>x1)   x3=x;   else x3=x1;
  430.        if(y>y1)   y3=y;   else y3=y1;
  431.        if(x+w<x2) x4=x+w; else x4=x2;
  432.        if(y+h<y2) y4=y+h; else y4=y2;
  433.  
  434.        if(!((x4-x3)<=0)) {
  435.          if(!((y4-y3)<=0)) {
  436.            BltBitMapRastPort(&wp->BitMap,
  437.                 (x3-we->InnerLeftEdge) % wp->Width,
  438.                 (y3-we->InnerTopEdge) % wp->Height,
  439.                 rp,x3,y3,x4-x3,y4-y3,0xc0);
  440.          }}
  441.  
  442.        /* ------------------------------------------ */
  443.       }
  444.     }
  445.   }
  446.  RestoreRP(we);
  447. }
  448.  
  449.