home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 038.lha / MacGag / macgag.c < prev    next >
C/C++ Source or Header  |  1987-05-16  |  6KB  |  203 lines

  1. /* MacGAG.C - Copyright (c) 1987 John Hodgson
  2.  
  3.     Here's my attempt at spiffing up Intuition a little bit. Certain other
  4. graphic desktop environments perk up their screens by "blossoming" new windows
  5. just prior to display, and "withering" them just after closing. No reason why
  6. we can't do this as well; only "look and feel" issues are in question here!
  7.  
  8.     The idea is to intercept all calls to OpenWindow()/CloseWindow() and
  9. add some parasite code before or after the actual invocation of these routines.
  10. Keep in mind however, that this is a multitasking machine; since we're actually
  11. patching the ROM Kernel, parts of this code become a SHARED RESOURCE and better
  12. be reentrant. Also, any rubberband routines need to mutually exclude each other
  13. so we don't leave "snail trails" behind. The key to reentrancy is a local data
  14. area for each calling task; the stack pointer maintained by each task is ideal
  15. for this.
  16.  
  17.     Refer to the glue routines in SUPPORT.ASM to see how register
  18. preservation and parameter passing is accomplished between the zapped Exec
  19. library and C. This program MUST BE COMPILED under Aztec "C", 3.4 or later
  20. using the large code/data models, and run under KickStart 1.2 or later.
  21.  
  22.     P.S. This program will blossom/decay ALL windows, including potentially
  23. invisible BACKDROP and BORDERLESS ones. Feel free to modify this if you like.
  24. It also tips you off as to whether certain programs are using REQUESTERS
  25. (unaffected) or WINDOWS for their user input! -DJH
  26.  
  27. */
  28.  
  29. #define REV_1PT2 33
  30.  
  31. #define OWOFFSET (-0x00cc) /* OpenWindow() vector; see RKM : Exec */
  32. #define CWOFFSET (-0x0048) /* CloseWindow() vector; see RKM : Exec */
  33.  
  34. #define SPEED 4           /* blossoming speed, in pixels */
  35. #define BOXPATTERN 0xCCCC  /* rubberband box pattern */
  36. #define TAGPORT "gag.port" /* how we identify ourselves */
  37.  
  38. extern void NewOpenWindow(); /* 68K patch routines */
  39. extern void NewCloseWindow();
  40.  
  41. /* the following globals are constants; reentrant by nature */
  42.  
  43. void *GfxBase,*IntuitionBase,*LayersBase,*OldOpenWindow,*OldCloseWindow;
  44.  
  45. void BoxUp(NewWindowArg)
  46. struct NewWindow *NewWindowArg;
  47. {
  48.   struct Screen sc;
  49.   struct RastPort rp;
  50.   short x1,y1,x2,y2,minx,miny,maxx,maxy,poly[4*2];
  51.  
  52.   /* Make local copies of screens & rastports so we don't alter
  53.      the programs actually using these resources! */
  54.  
  55.   if (NewWindowArg->Type==CUSTOMSCREEN) sc=*(NewWindowArg->Screen);
  56.       else GetScreenData(&sc,sizeof(sc),WBENCHSCREEN,NULL);
  57.  
  58.   rp=sc.RastPort;
  59.  
  60.   minx=NewWindowArg->LeftEdge; maxx=minx+NewWindowArg->Width-1;
  61.   miny=NewWindowArg->TopEdge;  maxy=miny+NewWindowArg->Height-1;
  62.  
  63.   x1=x2=(minx+maxx)/2;
  64.   y1=y2=(miny+maxy)/2;
  65.  
  66.   SetDrMd(&rp,COMPLEMENT); /* XOR, great for rubberbanding */
  67.   SetDrPt(&rp,BOXPATTERN);     /* dithered bands for Mac fans */
  68.  
  69.   /* Starting from the window-to-be's midpoint, expand a rubberbanded
  70.      rectangle until it reaches the window's size. */
  71.  
  72.   while (x1>minx || y1>miny) {
  73.   
  74.     Move(&rp,x1,y1);
  75.  
  76.     poly[1]=y1;
  77.     poly[0]=poly[2]=x2;
  78.     poly[3]=poly[5]=y2;
  79.     poly[4]=poly[6]=x1;
  80.     poly[7]=y1+1;
  81.  
  82.     /* Make sure other graphics don't see our wickedness */
  83.  
  84.     LockLayers(&sc.LayerInfo);
  85.  
  86.     PolyDraw(&rp,4,&poly[0]); /* one dithered, XOR'd box, to go */
  87.  
  88.     WaitTOF(); /* give the user a chance to see */
  89.  
  90.     Move(&rp,x1,y1); PolyDraw(&rp,4,&poly[0]); /* erase box */
  91.  
  92.     UnlockLayers(&sc.LayerInfo);
  93.  
  94.     x1-=SPEED; x2+=SPEED;
  95.     y1-=SPEED; y2+=SPEED;
  96.  
  97.     if (x1<minx) x1=minx;
  98.     if (x2>maxx) x2=maxx;
  99.     if (y1<miny) y1=miny;
  100.     if (y2>maxy) y2=maxy;
  101.   }
  102. }
  103.  
  104. void BoxDown(window)
  105. struct Window *window;
  106. {
  107.   struct RastPort rp;
  108.   short x1,y1,x2,y2,midx,midy,poly[4*2];
  109.  
  110.   /* Duplicate rastport so we don't affect others using the real one */
  111.  
  112.   rp=window->WScreen->RastPort;
  113.  
  114.   x1=window->LeftEdge; x2=x1+window->Width-1;
  115.   y1=window->TopEdge;  y2=y1+window->Height-1;
  116.  
  117.   midx=(x1+x2)/2; midy=(y1+y2)/2;
  118.  
  119.   SetDrMd(&rp,COMPLEMENT); /* XOR, great for rubberbanding */
  120.   SetDrPt(&rp,BOXPATTERN);     /* dithered bands for Mac fans */
  121.  
  122.   /* shrink a box from window's edges to its midpoint */
  123.  
  124.   while (x1<midx || y1<midy) {
  125.   
  126.     Move(&rp,x1,y1);
  127.  
  128.     poly[1]=y1;
  129.     poly[0]=poly[2]=x2;
  130.     poly[3]=poly[5]=y2;
  131.     poly[4]=poly[6]=x1;
  132.     poly[7]=y1+1;
  133.  
  134.     /* Make sure other graphics don't see our wickedness */
  135.  
  136.     LockLayers(&window->WScreen->LayerInfo);
  137.  
  138.     PolyDraw(&rp,4,&poly[0]); /* one dithered, XOR'd box, to go */
  139.  
  140.     WaitTOF(); /* give the user a chance to see */
  141.  
  142.     Move(&rp,x1,y1); PolyDraw(&rp,4,&poly[0]); /* erase box */
  143.  
  144.     UnlockLayers(&window->WScreen->LayerInfo);
  145.  
  146.     x1+=SPEED; x2-=SPEED;
  147.     y1+=SPEED; y2-=SPEED;
  148.  
  149.     if (x1>midx) x1=midx;
  150.     if (x2<midx) x2=midx;
  151.     if (y1>midy) y1=midy;
  152.     if (y2<midy) y2=midy;
  153.   }
  154. }
  155.  
  156. main()
  157. {
  158.   struct Window *window;
  159.   struct NewWindow nw;
  160.   struct MsgPort *tagport;
  161.  
  162.   if (FindPort(TAGPORT)) exit(0); /* prevent multiple invocations */
  163.  
  164.   if (!(tagport=CreatePort(TAGPORT,0))) exit(0);
  165.  
  166.   GfxBase=OpenLibrary("graphics.library",0);
  167.   LayersBase=OpenLibrary("layers.library",0);
  168.  
  169.   /* quit if not running under 1.2 or later */
  170.  
  171.   if (!(IntuitionBase=OpenLibrary("intuition.library",REV_1PT2))) goto cleanup;
  172.  
  173.   /* Install new vectors, and save the originals for cleanup */
  174.  
  175.   OldOpenWindow=SetFunction(IntuitionBase,OWOFFSET,NewOpenWindow);
  176.   OldCloseWindow=SetFunction(IntuitionBase,CWOFFSET,NewCloseWindow);
  177.  
  178.   setmem(&nw,sizeof(nw),0);
  179.  
  180.   nw.Width=308; nw.Height=10;
  181.   nw.DetailPen=2; nw.BlockPen=3;
  182.   nw.IDCMPFlags=CLOSEWINDOW;
  183.   nw.Flags=WINDOWDEPTH|WINDOWCLOSE|WINDOWDRAG|SIMPLE_REFRESH;
  184.   nw.Title=(UBYTE *)"MacGAG (c) 1987 John Hodgson";
  185.   nw.Type=WBENCHSCREEN;
  186.  
  187.   if (window=OpenWindow(&nw)) {
  188.     WaitPort(window->UserPort); /* MacGAG in effect until WINDOWCLOSE */
  189.  
  190.     CloseWindow(window);
  191.   }
  192.  
  193.   SetFunction(IntuitionBase,OWOFFSET,OldOpenWindow); /* restore vectors */
  194.   SetFunction(IntuitionBase,CWOFFSET,OldCloseWindow);
  195.  
  196. cleanup:
  197.   DeletePort(tagport);
  198.  
  199.   CloseLibrary(IntuitionBase);
  200.   CloseLibrary(LayersBase);
  201.   CloseLibrary(GfxBase);
  202. }
  203.