home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / nieuûytki / workbench95 / main.c < prev    next >
C/C++ Source or Header  |  1977-12-31  |  21KB  |  936 lines

  1. /*
  2.  *    ++++++++++++++++++++++++++++++++
  3.  *    +++ W*ndows95 BOOPSI Gadgets +++
  4.  *    ++++++++++++++++++++++++++++++++
  5.  *
  6.  *    Windows95 is a registered trademark of Microsoft Inc.
  7.  *    I don't know if the image design of the window-control
  8.  *    buttons is also a registered trademark of billy, please
  9.  *    tell me if so!
  10.  *
  11.  *    btw. visit www.micros0ft.com and all the other hate&fuck sites!
  12.  *
  13.  *    this hack was "developed" by Daniel Balster
  14.  */
  15.  
  16. #include <exec/exec.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/classes.h>
  19. #include <intuition/classusr.h>
  20. #include <intuition/cghooks.h>
  21. #include <intuition/gadgetclass.h>
  22. #include <intuition/imageclass.h>
  23. #include <intuition/icclass.h>
  24. #include <intuition/screens.h>
  25. #include <graphics/text.h>
  26. #include <utility/tagitem.h>
  27. #include <clib/alib_protos.h>
  28.  
  29. #include <proto/exec.h>
  30. #include <proto/dos.h>
  31. #include <proto/intuition.h>
  32. #include <proto/graphics.h>
  33. #include <proto/utility.h>
  34. #include <proto/diskfont.h>
  35.  
  36. #include <string.h>
  37.  
  38. //#define DEBUG
  39.  
  40. #ifdef DEBUG
  41. void kprintf(UBYTE *fmt,...);
  42. #define bug kprintf
  43. #define D(X) X
  44. #else
  45. #define D(X)
  46. #endif
  47.  
  48. #if defined(__SASC)
  49. #define SAVEDS        __saveds
  50. #define ASM        __asm
  51. #define REG(x)        register __ ## x
  52. #define REGISTER    register
  53. #else
  54. #error hehehe
  55. #endif
  56.  
  57. typedef enum { false=0, true=~(false) } bool;
  58.  
  59. #define ifn(x) if(!(x))
  60.  
  61. /*******************************************************/
  62.  
  63. /* OpenWindowTagList */
  64. #define VEC1 -0x25e
  65. #define LIB1 (struct Library*) IntuitionBase
  66.  
  67. /* CloseWindow */
  68. #define VEC2 -0x48
  69. #define LIB2 (struct Library*) IntuitionBase
  70.  
  71. extern APTR NewVector1;
  72. extern APTR OldVector1;
  73. extern APTR NewVector2;
  74. extern APTR OldVector2;
  75.  
  76. // Feel Free To Send Me Flowers On My Birthday,
  77. // The Magic Cookie!
  78. //
  79. #define MAGIC_ID 0x30121971
  80.  
  81. struct W95Gadgets
  82. {
  83.     struct TagItem Tags [3];
  84.     
  85.     ULONG  MagicID;
  86.     Object *CloseImg;
  87.     Object *DepthImg;
  88.     Object *ZoomImg;
  89.     Object *CloseGad;
  90.     Object *DepthGad;
  91.     Object *ZoomGad;
  92.     Object *DragGad;    // absolute madness... ;-)
  93.     Object *DragImg;
  94.     
  95.     struct Gadget *LastOne;
  96.     
  97.     STRPTR WindowTitle;
  98.     
  99.     WORD    Selected, Normal;
  100.  
  101.     struct Window *win;    
  102. };
  103.  
  104. //// P·R·O·T·O·T·Y·P·E·S
  105.  
  106. SAVEDS ASM ULONG DispatchW95Img (REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg);
  107. SAVEDS ASM ULONG DispatchW95Gad (REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg);
  108. ULONG DrawImage95 (Class *cl, Object *o, struct impDraw *msg);
  109. struct W95Gadgets *InstallWindows95 (int mode);
  110. struct BitMap *GetDrawer(WORD openclose, ULONG *width, ULONG *height);
  111. VOID RemapDrawer(struct Screen *scr, struct GadgetInfo *gplinfo);
  112.  
  113. //// G·L·O·B·A·L V·A·R·I·A·B·L·E·S
  114.  
  115. Class *W95ImageClass;
  116. Class *W95GadgetClass;
  117.  
  118. // the nice and small 'drawer' logo
  119.  
  120. Object *Picture1, *Picture2, *Picture3, *Picture4;
  121. struct Screen *OldScreen = NULL;
  122.  
  123. // global new font
  124.  
  125. struct TextFont *tf;
  126.  
  127. struct TextAttr ta =
  128. {
  129.     "Helvetica.font",13,FPF_DISKFONT,FS_NORMAL
  130. };
  131.  
  132. STATIC UBYTE vers[] = "$VER: Workbench95 3.11 (1/31/96)";
  133.  
  134. #define TEMPL "IMG1,IMG2,IMG3,IMG4,FONTNAME/K,FONTSIZE/N/K,FONTSTYLE/N/K,PATCHDOPUS/S"
  135.  
  136. struct {
  137.     STRPTR    img1,img2,img3,img4;
  138.     STRPTR    fontname;
  139.     ULONG    *fontsize;
  140.     ULONG    *fontstyle;
  141.     ULONG    dopus;
  142. } args = {0};
  143.  
  144. /*    NewOpenWindowTagList
  145. **
  146. **    If the calling task is "Workbench", the following gadgets
  147. **    will be removed from the delivered parameter-lists:
  148. **
  149. **    CLOSEGADGET, DRAGBAR, DEPTHGADGET, ZOOMGADGET.
  150. **
  151. **    After that, we will call "InstallWindows95()" ;-)
  152. **
  153. */
  154.  
  155. struct TagItem ASM *Before_OpenWindow (REG(a0) struct NewWindow *nw, REG(a1) struct TagItem *ti)
  156. {
  157.     struct Process *pr = (struct Process*) FindTask(0);
  158.     STRPTR tname = pr->pr_Task.tc_Node.ln_Name;
  159.     WORD sel=0,norm=1,patch=0;
  160.  
  161.     if (!strcmp(tname,"Workbench"))
  162.         { sel=0; norm=1; goto skip; }
  163.  
  164.     // continue only if the user wants to have dopus patched.
  165.     if (!args.dopus) return ti;
  166.  
  167.     if (!strncmp(tname,"dopus_",6))
  168.         { sel=2; norm=2; patch=1; goto skip; }
  169.     if (!strncmp(tname,"config_",6))
  170.         { sel=3; norm=3; patch=1; goto skip; }
  171.     if (!strncmp(tname,"button_",6))
  172.         { sel=2; norm=2; patch=1; goto skip; }
  173.     if (!strncmp(tname,"function_",8))
  174.         { sel=3; norm=3; patch=1; goto skip; }
  175.     if (!strncmp(tname,"class_",5))
  176.         { sel=3; norm=3; patch=1; goto skip; }
  177.     if (!strncmp(tname,"filetype_",9))
  178.         { sel=3; norm=3; patch=1; goto skip; }
  179.  
  180.     return ti;
  181. skip:
  182.     {
  183.         struct W95Gadgets *W95;
  184.         int mode = 0;
  185.  
  186.         // now we will scan the taglists.
  187.         // don't try to understand why I do all these checks.
  188.         
  189.  
  190.         if (ti)
  191.         {
  192.             struct TagItem *tags, *HH=0;
  193.             struct Gadget *where=0;
  194.  
  195.             mode = 0;
  196.             
  197.             for (tags=ti;tags->ti_Tag;tags++)
  198.             {
  199.                 switch (tags->ti_Tag)
  200.                 {
  201.                     case WA_DragBar:
  202.                         tags->ti_Data = FALSE;
  203.                         mode |= 1;
  204.                         break;
  205.                     case WA_DepthGadget:
  206.                         tags->ti_Data = FALSE;
  207.                         mode |= 1;
  208.                         break;
  209.                     case WA_CloseGadget:
  210.                         tags->ti_Data = FALSE;
  211.                         mode |= 1;
  212.                         break;
  213.                     case WA_Zoom:
  214.                         tags->ti_Tag = TAG_IGNORE;
  215.                     case WA_SizeGadget:
  216.                         mode |= 2;
  217.                         break;
  218.                     case WA_Flags:
  219.                         tags->ti_Data &=~ (WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR);
  220.                         mode |= 1;
  221.                         break;
  222.                     case WA_Gadgets:
  223.                         tags->ti_Tag = TAG_IGNORE;
  224.                         where = tags->ti_Data;
  225.                         mode |= 1;
  226.                         break;
  227.                     case WA_Height:
  228.                         HH = tags;
  229.                         break;
  230.                     case WA_Borderless:
  231.                         if (tags->ti_Data) mode |= 0x80;
  232.                         break;
  233.                 }
  234.             }
  235.  
  236.             if ( !(mode & 0x80) && (mode) )
  237.             if (W95 = InstallWindows95(mode-1))
  238.             {
  239.                 struct Gadget *g = W95->CloseGad, *gg;
  240.             
  241.                 W95->Normal    = norm;
  242.                 W95->Selected    = sel;
  243.             
  244.                 if (patch)
  245.                 if (HH) HH->ti_Data += 4;
  246.  
  247.                 W95->LastOne->NextGadget = where;
  248.  
  249.                 if (gg = where)
  250.                 {
  251.                     while (gg->NextGadget)
  252.                     {
  253.                         if (gg->GadgetType == GTYP_PROPGADGET)
  254.                         {
  255.                             if (gg->Activation & GACT_RIGHTBORDER)
  256.                             {
  257.                                 gg->Height  -= -g->TopEdge+tf->tf_YSize+8;
  258.                                 gg->TopEdge = tf->tf_YSize+8;
  259.                             }
  260.                         }
  261.                         gg = gg->NextGadget;
  262.                     }
  263.                 }
  264.  
  265.  
  266.                 W95->Tags[0].ti_Tag        = WA_Gadgets;
  267.                 W95->Tags[0].ti_Data    = g;
  268.                 W95->Tags[1].ti_Tag        = TAG_MORE;
  269.                 W95->Tags[1].ti_Data    = ti;
  270.  
  271.                 // make sure nw doesn't contain any flags
  272.                 if (nw) nw->Flags &= ~(WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR);
  273.  
  274.                 // ..BIT OR "1" ??
  275.                 // tricky: I need a bit returned to the asm-stub
  276.                 // telling it that the result is modified.
  277.                 // well, you cannot allocate any ODD structures.
  278.                 // that's it!
  279.                 return (struct TagItem*) (((int)W95) | 1);
  280.             }
  281.         }
  282.  
  283.         if (nw)
  284.         {
  285.             if (nw->Flags & WFLG_CLOSEGADGET)    mode |= 1;
  286.             if (nw->Flags & WFLG_DEPTHGADGET)    mode |= 1;
  287.             if (nw->Flags & WFLG_DRAGBAR)        mode |= 1;
  288.             if (nw->Flags & WFLG_SIZEGADGET)    mode |= 2;
  289.             if (nw->Flags & WFLG_BORDERLESS)    mode = 0;
  290.  
  291.             if (nw->Title && mode)
  292.             {
  293.                 if (W95 = InstallWindows95(mode-1))
  294.                 {
  295.                     struct Gadget *g;
  296.  
  297.                     W95->Normal    = norm;
  298.                     W95->Selected    = sel;
  299.  
  300.                     W95->Tags[0].ti_Tag        = TAG_MORE;
  301.                     W95->Tags[0].ti_Data    = ti;
  302.  
  303.                     nw->Flags &= ~(WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR);
  304.  
  305.                     W95->WindowTitle = nw->Title;
  306.                 
  307.                     // parse through the list and 'patch'
  308.                     // badly programmed rightborders.
  309.                     // i.e. Workbench ;-)
  310.                     
  311.                     if (g = nw->FirstGadget)
  312.                     {
  313.                         while (g->NextGadget)
  314.                         {
  315.                             if (g->GadgetType == GTYP_PROPGADGET)
  316.                             {
  317.                                 if (g->Activation & GACT_RIGHTBORDER)
  318.                                 {
  319.                                     g->Height  -= -g->TopEdge+tf->tf_YSize+8;
  320.                                     g->TopEdge = tf->tf_YSize+8;
  321.                                 }
  322.                             }
  323.                             g = g->NextGadget;
  324.                         }
  325.                     }
  326.                     
  327.                 
  328.                     if (patch)    
  329.                     nw->Height += 4;
  330.                     
  331.                     W95->LastOne->NextGadget = nw->FirstGadget;
  332.                     nw->FirstGadget = W95->CloseGad;
  333.  
  334.                     return (struct TagItem*) (((int)W95) | 1);
  335.                 }
  336.             }
  337.         }
  338.  
  339.     }
  340.     
  341.     return ti;
  342. }
  343.  
  344. VOID ASM After_OpenWindow (REG(a0) struct Window *win, REG(a1) struct W95Gadgets *W95)
  345. {
  346.     win->ExtData = W95;
  347.  
  348. //    if (W95) if (W95->MagicID == MAGIC_ID) ??
  349. }
  350.  
  351.  
  352. struct W95Gadgets* ASM Before_CloseWindow (REG(a0) struct Window *win)
  353. {
  354.     if (win->ExtData)
  355.     {
  356.         if (((struct W95Gadgets*)win->ExtData)->MagicID == MAGIC_ID)
  357.         {
  358.             struct W95Gadgets* W95 = win->ExtData;
  359.             win->ExtData = NULL;
  360.             
  361.             return W95;
  362.         }
  363.         else return 0;
  364.     }
  365. }
  366.  
  367. VOID ASM After_CloseWindow (REG(a0) struct W95Gadgets *W95)
  368. {
  369.     if (((int)W95) &~1l )
  370.     {
  371.         if (W95->MagicID == MAGIC_ID)
  372.         {
  373.  
  374.         // DisposeObject(obj) causes a GURU here, why ??
  375.  
  376.             DoMethod(W95->DragGad,OM_DISPOSE,0,0,0);
  377.             DoMethod(W95->DepthGad,OM_DISPOSE,0,0,0);
  378.             DoMethod(W95->ZoomGad,OM_DISPOSE,0,0,0);
  379.             DoMethod(W95->CloseGad,OM_DISPOSE,0,0,0);
  380.             DoMethod(W95->CloseImg,OM_DISPOSE,0,0,0);
  381.             DoMethod(W95->ZoomImg,OM_DISPOSE,0,0,0);
  382.             DoMethod(W95->DepthImg,OM_DISPOSE,0,0,0);
  383.             DoMethod(W95->DragImg,OM_DISPOSE,0,0,0);
  384.         }
  385.     }
  386. }
  387.  
  388. SAVEDS ASM ULONG DispatchW95Img (REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg)
  389. {
  390.     switch (msg->MethodID)
  391.     {
  392.         case IM_DRAW:
  393.             return DrawImage95(cl,o,msg);
  394.             break;
  395.         case OM_DISPOSE:
  396.             return DoSuperMethodA(cl,o,msg);
  397.             break;
  398.         default:
  399.             return DoSuperMethodA(cl,o,msg);
  400.             break;
  401.     }
  402. }
  403.  
  404. SAVEDS ASM ULONG DispatchW95Gad (REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg)
  405. {
  406.     switch (msg->MethodID)
  407.     {
  408.         case OM_DISPOSE:
  409.             return DoSuperMethodA(cl,o,msg);
  410.             break;
  411.         case GM_LAYOUT:
  412.         case GM_RENDER:
  413.         case GM_HITTEST:
  414.         case GM_GOACTIVE:
  415.         case GM_GOINACTIVE:
  416.             {    struct gpLayout *gpl = (struct gpLayout*) msg;
  417.                 struct Gadget *g = (struct Gadget *) o;
  418.                 struct W95Gadgets *W95;
  419.  
  420.                 if (gpl->gpl_GInfo->gi_Window)
  421.                 {
  422.                     g->Width = gpl->gpl_GInfo->gi_Window->Width-(int)g->UserData;
  423.                 
  424.                     SetAttrs(g->GadgetRender,IA_Width,g->Width,TAG_DONE);
  425.                     GetAttr(IA_Data,g->GadgetRender,&W95);
  426.                     if (gpl->gpl_GInfo->gi_Window->Title) W95->WindowTitle = gpl->gpl_GInfo->gi_Window->Title;
  427.                     gpl->gpl_GInfo->gi_Window->Title = NULL;
  428.                 
  429.                     W95->win = gpl->gpl_GInfo->gi_Window;
  430.                 
  431.                     RemapDrawer(gpl->gpl_GInfo->gi_Window->WScreen,gpl->gpl_GInfo);
  432.                 }
  433.             }
  434.         default:
  435.             return DoSuperMethodA(cl,o,msg);
  436.             break;
  437.     }
  438. }
  439.  
  440. ULONG DrawImage95 (Class *cl, Object *o, struct impDraw *msg)
  441. {
  442.     struct Image *IMG = (struct Image*) o;
  443.  
  444.     WORD X,Y,W,H,TT,openclose;
  445.  
  446.     BYTE white=2,black=1,dark=4,fill=5;
  447.     BYTE nrmbar,nrmtxt,selbar,seltxt;
  448.     BYTE barpen, textpen;
  449.  
  450.     struct RastPort *RP = msg->imp_RPort;
  451.     struct W95Gadgets *W95 = IMG->ImageData;
  452.  
  453.     if (msg->imp_DrInfo)
  454.     {
  455.         white = msg->imp_DrInfo->dri_Pens[HIGHLIGHTTEXTPEN];
  456.         fill     = msg->imp_DrInfo->dri_Pens[SHINEPEN];
  457.         black = msg->imp_DrInfo->dri_Pens[TEXTPEN];
  458.         dark  = msg->imp_DrInfo->dri_Pens[SHADOWPEN];
  459.  
  460.         selbar = msg->imp_DrInfo->dri_Pens[FILLPEN];
  461.         seltxt = msg->imp_DrInfo->dri_Pens[FILLTEXTPEN];
  462.         nrmbar = msg->imp_DrInfo->dri_Pens[SHADOWPEN];
  463.         nrmtxt = msg->imp_DrInfo->dri_Pens[SHINEPEN];
  464.     }
  465.  
  466.     X = IMG->LeftEdge + msg->imp_Offset.X;
  467.     Y = IMG->TopEdge + msg->imp_Offset.Y;
  468.     W = IMG->Width-1 - (2*IMG->LeftEdge);
  469.     H = IMG->Height-1 - (2*IMG->TopEdge);
  470.  
  471.     if (IM_FGPEN(IMG)==8)
  472.     {
  473.         struct BitMap *bmp;
  474.  
  475.         switch (msg->imp_State)
  476.         {
  477.             case IDS_INACTIVENORMAL:
  478.                 barpen    = nrmbar;
  479.                 textpen    = nrmtxt;
  480.                 openclose = W95->Selected;
  481.                 break;
  482.             case IDS_NORMAL:
  483.                 barpen    = selbar;
  484.                 textpen    = seltxt;
  485.                 openclose = W95->Normal;
  486.                 break;
  487.         }
  488.         
  489.         SetAPen(RP,barpen);
  490.         RectFill(RP,X+1,Y+1,X+W-1,Y+H-1);
  491.  
  492.         SetAPen(RP,black);
  493.         Move(RP,X+1,Y+H);
  494.         Draw(RP,X+16,Y+H);
  495.         Move(RP,X+W+1,Y+H);
  496.         Draw(RP,X+W+100,Y+H);
  497.     
  498.         {
  499.             ULONG w=0,h=0;
  500.             if (bmp = GetDrawer(openclose,&w,&h))
  501.             {
  502.                 BltBitMapRastPort(bmp,0,0,RP,3,3,w,h,0xC0);
  503.             }
  504.  
  505.             if (W95->WindowTitle)
  506.             {
  507.                 struct TextExtent te1;
  508.             
  509.                 SetABPenDrMd(RP,textpen,barpen,JAM2);
  510.                 SetFont(RP,tf);
  511.                 SetSoftStyle(RP,ta.ta_Style,ta.ta_Style);
  512.                 Move (RP,X+1+w+6,Y+RP->TxBaseline+1+((IMG->Height-RP->TxHeight)>>1));
  513.                 Text (RP,W95->WindowTitle,TextFit(RP,W95->WindowTitle,strlen(W95->WindowTitle),&te1,0,1,X+W-1-8-w,1000));
  514.             }
  515.         }
  516.  
  517.         return 1;
  518.     }
  519.  
  520.     switch (msg->imp_State)
  521.     {
  522.         case IDS_INACTIVENORMAL:
  523.             barpen = nrmbar;
  524.             goto skip1;
  525.         case IDS_NORMAL:
  526.             barpen = selbar;
  527.     skip1:    SetAPen(RP,white);
  528.             Move(RP,X,Y+H-1);
  529.             Draw(RP,X,Y);
  530.             Draw(RP,X+W-1,Y);
  531.             SetAPen(RP,black);
  532.             Move(RP,X+W,Y);
  533.             Draw(RP,X+W,Y+H);
  534.             Draw(RP,X,Y+H);
  535.             SetAPen(RP,dark);
  536.             Move(RP,X+W-1,Y+1);
  537.             Draw(RP,X+W-1,Y+H-1);
  538.             Draw(RP,X+1,Y+H-1);
  539.             SetAPen(RP,fill);
  540.             RectFill(RP,X+1,Y+1,X+W-2,Y+H-2);
  541.             TT=0;
  542.             break;
  543.         case IDS_INACTIVESELECTED:
  544.             barpen = nrmbar;
  545.             goto skip2;
  546.         case IDS_SELECTED:
  547.             barpen = selbar;
  548.     skip2:    SetAPen(RP,black);
  549.             Move(RP,X,Y+H);
  550.             Draw(RP,X,Y);
  551.             Draw(RP,X+W,Y);
  552.             SetAPen(RP,white);
  553.             Move(RP,X+W,Y+1);
  554.             Draw(RP,X+W,Y+H);
  555.             Draw(RP,X+1,Y+H);
  556.             SetAPen(RP,dark);
  557.             Move(RP,X+1,Y+H-1);
  558.             Draw(RP,X+1,Y+1);
  559.             Draw(RP,X+W-1,Y+1);
  560.             SetAPen(RP,fill);
  561.             RectFill(RP,X+2,Y+2,X+W-1,Y+H-1);
  562.             TT=1;
  563.             break;
  564.     }
  565.     
  566.     SetAPen(RP,barpen);
  567.     RectFill(RP,X,Y-IMG->TopEdge,X+W,Y-1);
  568.     RectFill(RP,X,Y+H+1,X+W,Y+H+IMG->TopEdge);
  569.     
  570.     // Pass IA_Data with the desired image number.
  571.     // No defines yet, sorry
  572.     switch (IM_FGPEN(IMG))
  573.     {
  574.         case 1:    // CLOSE, this draws a X
  575.             SetAPen(RP,black);
  576.             Move(RP,X+4+TT,Y+3+TT);
  577.             Draw(RP,X+W-5+TT,Y+H-4+TT);
  578.             Move(RP,X+5+TT,Y+3+TT);
  579.             Draw(RP,X+W-4+TT,Y+H-4+TT);
  580.             Move(RP,X+4+TT,Y+H-4+TT);
  581.             Draw(RP,X+W-5+TT,Y+3+TT);
  582.             Move(RP,X+5+TT,Y+H-4+TT);
  583.             Draw(RP,X+W-4+TT,Y+3+TT);
  584.             SetAPen(RP,barpen);
  585.             RectFill(RP,X-IMG->LeftEdge,Y-IMG->TopEdge,X-1,Y+H+IMG->TopEdge);
  586.             RectFill(RP,X+W+1,Y-IMG->TopEdge,X+W+IMG->LeftEdge,Y+H+IMG->TopEdge);
  587.             break;
  588.         case 3:    // ZOOM, this draws a entitled box
  589.             {
  590.                 // Shit! this is delayed! dont know how to fix it.
  591.             
  592.                 if (W95->win->Flags & WFLG_ZOOMED)
  593.                 {
  594.                     // Zoomed-State Image
  595.                 
  596.                     SetAPen(RP,black);
  597.                     RectFill(RP,X+3+TT,Y+2+3+TT,X+W-4-2+TT,Y+3+3+TT);
  598.                     RectFill(RP,X+3+2+TT,Y+2+TT,X+W-4+TT,Y+3+TT);
  599.                     Move(RP,X+3+TT,Y+4+3+TT);
  600.                     Draw(RP,X+3+TT,Y+H-3+TT);
  601.                     Draw(RP,X+W-4-2+TT,Y+H-3+TT);
  602.                     Draw(RP,X+W-4-2+TT,Y+4+3+TT);
  603.                     Move(RP,X+3+2+TT,Y+4+TT);
  604.                     Draw(RP,X+3+2+TT,Y+4+2+TT);
  605.                     Move(RP,X+W-4+TT,Y+4+TT);
  606.                     Draw(RP,X+W-4+TT,Y+H-3-3+TT);
  607.                     Draw(RP,X+W-4-2+TT,Y+H-3-3+TT);
  608.                 }
  609.                 else
  610.                 {
  611.                     // Unzoomed-State Image
  612.             
  613.                     SetAPen(RP,black);
  614.                     RectFill(RP,X+3+TT,Y+2+TT,X+W-4+TT,Y+3+TT);
  615.                     Move(RP,X+3+TT,Y+4+TT);
  616.                     Draw(RP,X+3+TT,Y+H-3+TT);
  617.                     Draw(RP,X+W-4+TT,Y+H-3+TT);
  618.                     Draw(RP,X+W-4+TT,Y+4+TT);
  619.                 }
  620.             }
  621.             break;
  622.         case 2:    // ICONIFY, this draws an underscore
  623.             SetAPen(RP,black);
  624.             RectFill(RP,X+4+TT,Y+H+TT-4,X+W-6+TT,Y+H+TT-3);
  625.             break;
  626.         default:
  627.             break;
  628.     }
  629.  
  630.     return 1;
  631. }
  632.  
  633.  
  634. SAVEDS struct W95Gadgets *InstallWindows95 (int mode)
  635. {
  636.     struct W95Gadgets *W95;
  637.     WORD width, height;
  638.  
  639.     if (W95 = AllocVec(sizeof(*W95),MEMF_PUBLIC|MEMF_CLEAR))
  640.     {
  641.         struct Gadget *last;
  642.     
  643.         W95->MagicID = MAGIC_ID;
  644.  
  645.         height    = tf->tf_YSize+1;
  646.         width    = height+2;
  647.  
  648.         W95->DragImg = NewObject(W95ImageClass,NULL,
  649.             IA_Data        , W95,
  650.             IA_FGPen        , 8,
  651.             IA_Height        , height+6,
  652.             TAG_DONE);
  653.         W95->CloseImg = NewObject(W95ImageClass,NULL,
  654.             IA_Left        , 2,
  655.             IA_Top        , 2,
  656.             IA_Width        , width+4,
  657.             IA_Height        , height+4,
  658.             IA_Data        , W95,
  659.             IA_FGPen        , 1,
  660.             TAG_DONE);
  661.     if (mode)
  662.     {
  663.         W95->DepthImg = NewObject(W95ImageClass,NULL,
  664.             IA_Left        , 0,
  665.             IA_Top        , 2,
  666.             IA_Width        , width,
  667.             IA_Height        , height+4,
  668.             IA_Data        , W95,
  669.             IA_FGPen        , 2,
  670.             TAG_DONE);
  671.     }
  672.     if (mode)
  673.     {
  674.         W95->ZoomImg = NewObject(W95ImageClass,NULL,
  675.             IA_Left        , 0,
  676.             IA_Top        , 2,
  677.             IA_Width        , width,
  678.             IA_Height        , height+4,
  679.             IA_Data        , W95,
  680.             IA_FGPen        , 3,
  681.             TAG_DONE);
  682.     }
  683.  
  684.         W95->CloseGad = NewObject(NULL,"buttongclass",
  685.             GA_RelRight    , -width-4,
  686.             GA_ID        , MAGIC_ID,
  687.             GA_Top        , 1,
  688.             GA_Width        , width+4,
  689.             GA_Height        , height+4,
  690.             GA_Image        , W95->CloseImg,
  691.             GA_RelVerify    , TRUE,
  692.             GA_EndGadget    , TRUE,
  693.             GA_TopBorder    , TRUE,
  694.             GA_SysGType    , GTYP_CLOSE,
  695.             TAG_DONE); last = W95->CloseGad;
  696.     if (mode)
  697.     {
  698.         W95->ZoomGad = NewObject(NULL,"buttongclass",
  699.             GA_RelRight    , -2*(width)-4,
  700.             GA_ID        , MAGIC_ID+1,
  701.             GA_Top        , 1,
  702.             GA_Width        , width,
  703.             GA_Height        , height+4,
  704.             GA_Image        , W95->ZoomImg,
  705.             GA_RelVerify    , TRUE,
  706.             GA_TopBorder    , TRUE,
  707.             GA_SysGType    , GTYP_WZOOM,
  708.             GA_Previous    , last,
  709.             TAG_DONE); last = W95->ZoomGad;
  710.     }
  711.     if (mode)
  712.     {
  713.         W95->DepthGad = NewObject(NULL,"buttongclass",
  714.             GA_RelRight    , -3*(width)-4,
  715.             GA_ID        , MAGIC_ID+2,
  716.             GA_Top        , 1,
  717.             GA_Width        , width,
  718.             GA_Height        , height+4,
  719.             GA_Image        , W95->DepthImg,
  720.             GA_RelVerify    , TRUE,
  721.             GA_TopBorder    , TRUE,
  722.             GA_SysGType    , GTYP_WDEPTH,
  723.             GA_Previous    , last,
  724.             TAG_DONE); last = W95->DepthGad;
  725.     }
  726.         W95->DragGad = NewObject(W95GadgetClass,NULL,
  727.             GA_TopBorder    , TRUE,
  728.             GA_ID        , MAGIC_ID+3,
  729.             GA_SysGType    , GTYP_WDRAGGING,
  730.             GA_RelWidth    , TRUE,
  731.             GA_UserData    , (ULONG) mode ? (3*(width)+4) : (width+4),
  732.             GA_Image        , W95->DragImg,
  733.             GA_Previous    , last,
  734.             TAG_DONE); last = W95->DragGad;
  735.  
  736.         W95->LastOne = W95->DragGad;
  737.  
  738.         if (mode)
  739.         {
  740.             if (W95->CloseImg && W95->ZoomImg && W95->DepthImg && W95->CloseGad && W95->ZoomGad && W95->DepthGad && W95->DragGad && W95->DragImg) return W95;
  741.         }
  742.         else
  743.         {
  744.             if (W95->CloseImg && W95->CloseGad && W95->DragGad && W95->DragImg) return W95;
  745.         }
  746.  
  747.         // whoops, at this point something went wrong.
  748.         // kill and destroy all!
  749.  
  750.         DisposeObject(W95->CloseGad);
  751.         DisposeObject(W95->ZoomGad);
  752.         DisposeObject(W95->DepthGad);
  753.         DisposeObject(W95->DragGad);
  754.  
  755.         DisposeObject(W95->CloseImg);
  756.         DisposeObject(W95->ZoomImg);
  757.         DisposeObject(W95->DepthImg);
  758.         DisposeObject(W95->DragImg);
  759.         FreeVec (W95);
  760.     }
  761.     return NULL;
  762. }
  763.  
  764. int LoadDrawer(VOID)
  765. {
  766.     Picture1 = NewDTObject(args.img1,
  767.         DTA_SourceType        , DTST_FILE,
  768.         DTA_GroupID        , GID_PICTURE,
  769.         PDTA_Remap        , TRUE,
  770.         OBP_Precision        , PRECISION_IMAGE,
  771.         TAG_DONE);
  772.     Picture2 = NewDTObject(args.img2,
  773.         DTA_SourceType        , DTST_FILE,
  774.         DTA_GroupID        , GID_PICTURE,
  775.         PDTA_Remap        , TRUE,
  776.         OBP_Precision        , PRECISION_IMAGE,
  777.         TAG_DONE);
  778.     Picture3 = NewDTObject(args.img3,
  779.         DTA_SourceType        , DTST_FILE,
  780.         DTA_GroupID        , GID_PICTURE,
  781.         PDTA_Remap        , TRUE,
  782.         OBP_Precision        , PRECISION_IMAGE,
  783.         TAG_DONE);
  784.     Picture4 = NewDTObject(args.img4,
  785.         DTA_SourceType        , DTST_FILE,
  786.         DTA_GroupID        , GID_PICTURE,
  787.         PDTA_Remap        , TRUE,
  788.         OBP_Precision        , PRECISION_IMAGE,
  789.         TAG_DONE);
  790.  
  791.     // it is now no more required to specify any image
  792.     // that will lead into image-less window titles.
  793.     return (int) 1;
  794.  
  795. //    return (int) (Picture1 && Picture2 && Picture3 && Picture4);
  796.  
  797. }
  798.  
  799. VOID UnloadDrawer(VOID)
  800. {
  801.     DisposeDTObject(Picture1);
  802.     DisposeDTObject(Picture2);
  803.     DisposeDTObject(Picture3);
  804.     DisposeDTObject(Picture4);
  805.     
  806.     Picture1 = Picture2 = Picture3 = Picture4 = 0;
  807. }
  808.  
  809. /*
  810. **    This is the function that makes me mad.
  811. **    I'm not sure about the PROCLAYOUT msg to send,
  812. **    because sometimes dt.lib freezes the system.
  813. **    If I send a gplinfo instead of NULL, remapping
  814. **    is done without freeze but in the wrong pens.
  815. **
  816. **    why ? please tell me, I have not enough informations
  817. **    about that!
  818. */
  819.  
  820. VOID RemapDrawer(struct Screen *scr, struct GadgetInfo *gplinfo)
  821. {
  822.     struct BitMap *bmp;
  823.  
  824.     if (scr == OldScreen) return;
  825.  
  826.     OldScreen = scr;
  827.  
  828.     if (OldScreen)
  829.     {
  830.         if (Picture1)
  831.         {
  832.             SetDTAttrs(Picture1,PDTA_Remap,TRUE,PDTA_Screen,OldScreen,TAG_DONE);
  833.             DoMethod(Picture1,DTM_PROCLAYOUT,gplinfo,1);
  834.         //    DoMethod(Picture1,DTM_PROCLAYOUT,NULL,1);
  835.         }
  836.         if (Picture2)
  837.         {
  838.             SetDTAttrs(Picture2,PDTA_Remap,TRUE,PDTA_Screen,OldScreen,TAG_DONE);
  839.             DoMethod(Picture2,DTM_PROCLAYOUT,gplinfo,1);
  840.         //    DoMethod(Picture2,DTM_PROCLAYOUT,NULL,1);
  841.         }
  842.         if (Picture3)
  843.         {
  844.             SetDTAttrs(Picture3,PDTA_Remap,TRUE,PDTA_Screen,OldScreen,TAG_DONE);
  845.             DoMethod(Picture3,DTM_PROCLAYOUT,gplinfo,1);
  846.         //    DoMethod(Picture3,DTM_PROCLAYOUT,NULL,1);
  847.         }
  848.         if (Picture4)
  849.         {
  850.             SetDTAttrs(Picture4,PDTA_Remap,TRUE,PDTA_Screen,OldScreen,TAG_DONE);
  851.             DoMethod(Picture4,DTM_PROCLAYOUT,gplinfo,1);
  852.         //    DoMethod(Picture4,DTM_PROCLAYOUT,NULL,1);
  853.         }
  854.     }
  855. }
  856.  
  857. struct BitMap *GetDrawer(WORD openclose, ULONG *width, ULONG *height)
  858. {
  859.     struct BitMap *bmp=NULL;
  860.     Object *o;
  861.  
  862.     switch (openclose)
  863.     {
  864.         case 0: o = Picture2; break;
  865.         case 1: o = Picture1; break;
  866.         case 2: o = Picture3; break;
  867.         case 3: o = Picture4; break;
  868.     }
  869.  
  870.     if (o)
  871.     {
  872.         GetDTAttrs(o,PDTA_DestBitMap,&(bmp),TAG_DONE);
  873.     //    if (!bmp) GetDTAttrs(o,PDTA_DestBitMap,&(bmp),TAG_DONE);
  874.  
  875.         if (bmp)
  876.         {
  877.             *width    = GetBitMapAttr(bmp,BMA_WIDTH);
  878.             *height    = GetBitMapAttr(bmp,BMA_HEIGHT);
  879.         }
  880.     }
  881.  
  882.     return bmp;
  883. }
  884.  
  885. int main ()
  886. {
  887.     struct RDArgs *rda;
  888.     
  889.     ifn (rda=ReadArgs(TEMPL,(long*)&args,NULL)) return 20;
  890.  
  891.     if (args.fontname)    ta.ta_Name = args.fontname;
  892.     if (args.fontsize)    ta.ta_YSize = *args.fontsize;
  893.     if (args.fontstyle)    ta.ta_Style = *args.fontstyle;
  894.  
  895.     if (tf = OpenDiskFont (&ta))
  896.     {
  897.     if (W95ImageClass = MakeClass (NULL,"imageclass",0,0,0))
  898.     {    W95ImageClass->cl_Dispatcher.h_Entry = DispatchW95Img;
  899.     if (W95GadgetClass = MakeClass (NULL,"buttongclass",0,0,0))
  900.     {    W95GadgetClass->cl_Dispatcher.h_Entry = DispatchW95Gad;
  901.  
  902.         if (LoadDrawer())
  903.         {
  904.             Disable();
  905.             OldVector1 = SetFunction (LIB1,VEC1,(ULONG(*)())&(NewVector1));
  906.             OldVector2 = SetFunction (LIB2,VEC2,(ULONG(*)())&(NewVector2));
  907.             CacheClearU();
  908.             Enable();
  909.  
  910.             Wait (SIGBREAKF_CTRL_C);
  911.         
  912.             if (FindPort("SetMan"))
  913.             {
  914.                 Disable();
  915.                 SetFunction (LIB1,VEC1,(ULONG(*)())(OldVector1));
  916.                 SetFunction (LIB2,VEC2,(ULONG(*)())(OldVector2));
  917.                 CacheClearU();
  918.                 Enable();
  919.             }
  920.             else Wait(0);    /* DO NOT SIGNAL THIS !! */
  921.  
  922.             UnloadDrawer();
  923.         }
  924.  
  925.         FreeClass(W95GadgetClass);
  926.     }
  927.         FreeClass(W95ImageClass);
  928.     }
  929.         CloseFont(&ta);
  930.     }
  931.  
  932.     FreeArgs(rda);
  933.  
  934.     return 0;
  935. }
  936.