(*------------------------------------------

  :Program.     NewLook4Menus
  :Author.      Albert Weinert [awn]
  :Address.     Krähenweg 21, D-5000 Köln 30
  :Version.     V1.1
  :Date.        03-May-1993
  :Copyright.   AlberWeinert 1993
  :Language.    Oberon-2
  :Translator.  Amiga Oberon 3.00d
  :Contents.    Erzwingt unter AmigaOS 3.0 die NewLookMenus.
  :Imports.     Basiert auf dem SourceCode "NTSC4NTSC.mod" von Kai Bolay
  :Remarks.     <Was Du willst, evtl. Usage>
  :Bugs.        <Bekannte Fehler>
  :Usage.       <Angaben zur Anwendung>
  :History.     V1.0   [awn] 12-Apr-1993 : Erstellt
  :History.     V1.0a  [awn] 22-Apr-1993 : SuperDuper Check drin, und mehr
  :History.            Überprüfungen auf die eingestellten Optionen drin.
  :History.     V1.0b  [awn] 03-Mai-1993 : Wenn RECOLORMENU gesetzt ist, dann
  :History.            automatisch auch NEWLOOKMENU gesetzt.
  :History.     V1.1   [awn] 03-May-1993 : WITHBORDER Option, hiermit wird
  :History.            auf Verlangen, das propBorderless Flag aus normalen Prop-
  :History.            Gagdets entfernt.
  :History.            Außerdem wurden die Optionen in der Template mit Abkürzungen
  :History.            versehen. SuperDuper Check entfernt, es war ein Fehler in
  :History.            NewOpenWindow

--------------------------------------------*)
(* $IF SmallData *)
MODULE  NewLook4Menus; (* Mit SmallData gehts nicht! Mit diesem Konstrukt ist *)
                       (* der Quellcode noch vom OEd aus parsebar und gibt    *)
                       (* trotzdem beim kompilieren eine Fehlermeldung raus.  *)
BEGIN
  Nicht.mit.SmallData.kompilieren;
END NewLook4Menus.
(* $ELSE *)
MODULE NewLook4Menus;
(* $END *)

(* $TypeChk- $OvflChk- $RangeChk- $StackChk- $NilChk-
   $ReturnChk- $OddChk- $CaseChk- $ClearVars- *)

IMPORT
  e: Exec, I: Intuition, g: Graphics, u: Utility, d: Dos, y: SYSTEM, gt: GadTools,
  ver:NewLook4MenusVersion;

CONST
  OpenScreenOfs      = -198;
  OpenScreenTagsOfs  = -612;
  OpenWindowOfs      = -204;
  OpenWindowTagsOfs  = -606;
  LayoutMenuItemsOfs = -60;
  LayoutMenusOfs     = -66;
  SetMenuStripOfs    = -264;
  RefreshGListOfs    = -432;
  AddGListOfs        = -438;
  AddGadgetOfs       = -42;
  ModifyPropOfs      = -156;
  NewModifyPropOfs   = -468;

  Template = "NM=NEWLOOKMENU/S,RM=RECOLORMENU/S,PN=PROPNEWLOOK/S,3D=PROP3D/S,WB=WITHBORDER/S";
  ExtHelp = "\n"
            "NEWLOOKMENU erzwingt NewLooks Menus für GadTools-Menus\n"
            "RECOLORMENU versucht NewLooks Menus für normale Menus zu erzeugen\n"
            "PROPNEWLOOK erzwingt den PropNewLook für Proportinal Gadgets\n"
            "PROP3D      versucht 3D PropGadgets in den Fensterrahmen zu erzeugen\n"
            "WITHBORDER  wenn PROPNEWLOOK gesetzt ist dann kann man dieses ausehen\n"
            "            noch varieren. Wirkt sich nicht auf Rahmen Propgadgets aus\n\n";

  NEWLOOKMENU = 0;
  RECOLORMENU = 1;
  PROPNEWLOOK = 2;
  PROP3D      = 3;
  WITHBORDER  = 4;
  NumOpts     = 5;

  mnFrontPen = gt.tagBase+50; (* v39 *)
  mnNewLookMenus = gt.tagBase+67; (* v39 *)
  waNewLookMenus = I.waDummy+030H; (* v39 *)

  barDetailPen = 9;
  barBlockPen = 10;
  barTrimPen = 11;
  numDRIPens = 12;

TYPE
  TagArray = ARRAY OF u.TagItem;

  TagArrayPtr = UNTRACED POINTER TO ARRAY MAX (INTEGER) OF u.TagItem;

  ExtNewScreenPtr = UNTRACED POINTER TO I.ExtNewScreen;

  OpenScreenProc      = PROCEDURE (newScreen{8} : ExtNewScreenPtr): I.ScreenPtr;

  OpenScreenTagsProc  = PROCEDURE (newScreen{8} : I.NewScreenPtr;
                                   paraTagList{9} : TagArray): I.ScreenPtr;

  OpenWindowProc      = PROCEDURE (newWindow{8} : I.ExtNewWindowPtr): I.WindowPtr;

  OpenWindowTagsProc  = PROCEDURE (newWindow{8}   : I.NewWindowPtr;
                                   paraTagList{9} : TagArray): I.WindowPtr;

  LayoutMenuItemsProc = PROCEDURE (firstitem{8}    : I.MenuItemPtr;
                                   vi{9}           : gt.VisualInfo;
                                   paraTagList{10} : TagArray): BOOLEAN;

  LayoutMenusProc     = PROCEDURE (firstmenu{8}    : I.MenuPtr;
                                   vi{9}           : gt.VisualInfo;
                                   paraTagList{10} : TagArray): BOOLEAN;

  SetMenuStripProc    = PROCEDURE (window{8} : I.WindowPtr;
                                   menu{9}   : I.MenuPtr):BOOLEAN;

  AddGListProc        = PROCEDURE (window{8}     : I.WindowPtr;
                                   gadget{9}     : I.GadgetPtr;
                                   position{0}   : LONGINT;
                                   numGad{1}     : LONGINT;
                                   requester{10} : I.RequesterPtr):INTEGER;

  AddGadgetProc       = PROCEDURE (window{8}   : I.WindowPtr;
                                   gadget{9}   : I.GadgetPtr;
                                   position{0} : LONGINT):INTEGER;
      
  RefreshGListProc    = PROCEDURE (gadget{8}     : I.GadgetPtr;
                                   window{9}     : I.WindowPtr;
                                   requester{10} : I.RequesterPtr;
                                   numGad{0}     : LONGINT):INTEGER;

  ModifyPropProc      = PROCEDURE (gadget{8}     : I.GadgetPtr;
                                   window{9}     : I.WindowPtr;
                                   requester{10} : I.RequesterPtr;
                                   flags{0}      : SET;
                                   horizPot{1}   : LONGINT;
                                   vertPot{2}    : LONGINT;
                                   horizBody{3}  : LONGINT;
                                   vertBody{4}   : LONGINT);

  NewModifyPropProc   = PROCEDURE (gadget{8}     : I.GadgetPtr;
                                   window{9}     : I.WindowPtr;
                                   requester{10} : I.RequesterPtr;
                                   flags{0}      : SET;
                                   horizPot{1}   : LONGINT;
                                   vertPot{2}    : LONGINT;
                                   horizBody{3}  : LONGINT;
                                   vertBody{4}   : LONGINT;
                                   numGad{5}     : LONGINT);

  PenPtr = UNTRACED POINTER TO ARRAY numDRIPens OF INTEGER;

VAR
  OldOpenScreen      : OpenScreenProc;
  OldOpenScreenTags  : OpenScreenTagsProc;
  OldOpenWindow      : OpenWindowProc;
  OldOpenWindowTags  : OpenWindowTagsProc;
  OldLayoutMenuItems : LayoutMenuItemsProc;
  OldLayoutMenus     : LayoutMenusProc;
  OldSetMenuStrip    : SetMenuStripProc;
  OldAddGList        : AddGListProc;
  OldAddGadget       : AddGadgetProc;
  OldRefreshGList    : RefreshGListProc;
  OldModifyProp      : ModifyPropProc;
  OldNewModifyProp   : NewModifyPropProc;

  Opt: ARRAY NumOpts OF e.APTR;

  RD: d.RDArgsPtr;

(* $Debug- *)

  PROCEDURE NewOpenScreenTags (newScreen{8}   : I.NewScreenPtr;
                                paraTagList{9} : TagArrayPtr) : I.ScreenPtr;

    VAR Base  : I.IntuitionBasePtr;
        myTag : u.Tags3;
        i     : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);

      i:=0;
      IF Opt[RECOLORMENU] # 0 THEN
        myTag[i]:=u.TagItem(I.saDetailPen,1);
        INC(i);
        myTag[i]:=u.TagItem(I.saBlockPen,2);
        INC(i);
      END;
      IF paraTagList = NIL THEN
        myTag[i].tag:=u.done;
        myTag[i].data:=NIL;
      ELSE;
        myTag[i].tag := u.more;
        myTag[i].data := paraTagList;
      END;
      y.SETREG (14, Base);
      RETURN OldOpenScreenTags(newScreen, myTag);
    END NewOpenScreenTags;

  PROCEDURE NewOpenScreen (newScreen{8}: ExtNewScreenPtr) : I.ScreenPtr;

    VAR Base    : I.IntuitionBasePtr;
        nScrPtr : I.NewScreenPtr;
        scrPtr  : I.ScreenPtr;
    
    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      IF (I.nsExtended IN newScreen.ns.type) THEN
        nScrPtr := e.AllocVec (y.SIZE (I.NewScreen), LONGSET {});
        IF nScrPtr = NIL THEN
          y.SETREG (14, Base);
          RETURN OldOpenScreen (newScreen);
        END;
        e.CopyMem (newScreen^, nScrPtr^, y.SIZE (I.NewScreen));
        EXCL (nScrPtr.type, I.nsExtended);
        y.SETREG (14, Base);
        scrPtr := NewOpenScreenTags (nScrPtr, y.VAL(TagArrayPtr,newScreen.extension));
        e.FreeVec (nScrPtr);
        y.SETREG (14, Base);
        RETURN scrPtr;
      ELSE
        y.SETREG (14, Base);
        RETURN NewOpenScreenTags (newScreen, NIL);
      END;
    END NewOpenScreen;
  


  PROCEDURE SetPropFlags(gadget : I.GadgetPtr; flags : SET):SET;

    (* $SaveRegs+ *)
    BEGIN
      IF (y.VAL(INTEGER,y.VAL(SET,gadget.gadgetType) * y.VAL(SET,I.gTypeMask))) = I.propGadget THEN

        IF Opt[PROPNEWLOOK] # 0 THEN;
          INCL(flags,I.propNewLook);
          IF Opt[WITHBORDER] # 0 THEN
            EXCL(flags,I.propBorderless);
          END;
        END;

        IF Opt[PROP3D] # 0 THEN
          IF (y.VAL(INTEGER,gadget.activation * SET{I.rightBorder,
                                                    I.leftBorder,
                                                    I.topBorder,
                                                    I.bottomBorder})) # 0 THEN

             INCL(flags,I.propNewLook);
             INCL(flags,I.propBorderless);
          END;
        END;

      END;
      RETURN flags;
    END SetPropFlags;
  
  PROCEDURE Set3DLook(gadget : I.GadgetPtr; nums : LONGINT);
  
    VAR propinfo : I.PropInfoPtr;
        type     : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      IF ((Opt[PROPNEWLOOK] # 0) OR (Opt[PROP3D] # 0)) THEN
        WHILE (gadget # NIL) AND (nums # 0) DO
          propinfo:=gadget.specialInfo;
          IF propinfo # NIL THEN
            propinfo.flags:=SetPropFlags(gadget,propinfo.flags)
          END;
          gadget:=gadget.nextGadget;
          DEC(nums);
        END;
      END;
    END Set3DLook;
  
  
  PROCEDURE NewModifyProp (gadget{8}     : I.GadgetPtr;
                           window{9}     : I.WindowPtr;
                           requester{10} : I.RequesterPtr;
                           flags{0}      : SET;
                           horizPot{1}   : LONGINT;
                           vertPot{2}    : LONGINT;
                           horizBody{3}  : LONGINT;
                           vertBody{4}   : LONGINT);

    VAR Base    : I.IntuitionBasePtr;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      flags:=SetPropFlags(gadget,flags);
      y.SETREG (14, Base);
      OldModifyProp(gadget,window,requester,flags,horizPot,vertPot,horizBody,vertBody);
    END NewModifyProp;
  
  PROCEDURE NewNewModifyProp (gadget{8}     : I.GadgetPtr;
                              window{9}     : I.WindowPtr;
                              requester{10} : I.RequesterPtr;
                              flags{0}      : SET;
                              horizPot{1}   : LONGINT;
                              vertPot{2}    : LONGINT;
                              horizBody{3}  : LONGINT;
                              vertBody{4}   : LONGINT;
                              numGad{5}     : LONGINT);
  
  VAR Base    : I.IntuitionBasePtr;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      flags:=SetPropFlags(gadget,flags);
      y.SETREG (14, Base);
      OldNewModifyProp(gadget,window,requester,flags,horizPot,vertPot,horizBody,vertBody,numGad);
    END NewNewModifyProp;
  
  PROCEDURE  NewAddGList (window{8}     : I.WindowPtr;
                          gadget{9}     : I.GadgetPtr;
                          position{0}   : LONGINT;
                          numGad{1}     : LONGINT;
                          requester{10} : I.RequesterPtr) : INTEGER;

    VAR Base : I.IntuitionBasePtr;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      Set3DLook(gadget,numGad);
      y.SETREG (14, Base);
      RETURN OldAddGList(window,gadget,position,numGad,requester);
    END NewAddGList;
  
  PROCEDURE  NewRefreshGList (gadget{8}     : I.GadgetPtr;
                              window{9 }     : I.WindowPtr;
                              requester{10} : I.RequesterPtr;
                              numGad{0}     : LONGINT) : INTEGER;

    VAR Base : I.IntuitionBasePtr;
  
    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      Set3DLook(gadget,numGad);
      y.SETREG (14, Base);
      RETURN OldRefreshGList(gadget,window,requester,numGad);
    END NewRefreshGList;
  
  PROCEDURE  NewAddGadget (window{8}   : I.WindowPtr;
                           gadget{9}   : I.GadgetPtr;
                           position{0} : LONGINT):INTEGER;

    VAR Base : I.IntuitionBasePtr;
  
    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      Set3DLook(gadget,1);
      y.SETREG (14, Base);
      RETURN OldAddGadget(window,gadget,position);
    END NewAddGadget;


  PROCEDURE NewOpenWindowTags (newWindow{8}   : I.NewWindowPtr;
                                paraTagList{9} : TagArrayPtr): I.WindowPtr;
    VAR Base  : I.IntuitionBasePtr;
        myTag : u.Tags4;
        menu  : I.MenuPtr;
        glist : I.GadgetPtr;
        i     : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      i:=0;
      IF Opt[NEWLOOKMENU] # 0 THEN
        myTag[i]:=u.TagItem(waNewLookMenus,I.LTRUE);
        INC(i);
        IF Opt[RECOLORMENU] # 0 THEN
          myTag[i]:=u.TagItem(I.waDetailPen,0);
          INC(i);
          myTag[i]:=u.TagItem(I.waBlockPen,1);
          INC(i);
        END;
      END;
  
      IF paraTagList # NIL THEN
        myTag[i].tag:=u.more;
        myTag[i].data:=paraTagList;
      ELSE
        myTag[i].tag:=u.done;
        myTag[i].data:=NIL;
      END;
  
      glist:=NIL;
      IF newWindow # NIL THEN
        glist:=newWindow.firstGadget;
      END;
      glist:=y.VAL(I.GadgetPtr,u.GetTagData(I.waGadgets,y.VAL(LONGINT,glist),myTag));
      Set3DLook(glist,-1);
      y.SETREG (14, Base);
      RETURN OldOpenWindowTags(newWindow,myTag);
    END NewOpenWindowTags;
  
  (* $CopyArrays- *)
  PROCEDURE CompStr(org,comp : ARRAY OF CHAR; num : INTEGER) : BOOLEAN;

    VAR i : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      WHILE (org[i] = comp[i]) AND (num # 0) DO
        INC(i);
        DEC(num);
      END;
      IF (num = 0) THEN RETURN TRUE END;
      RETURN FALSE;
    END CompStr;
  (* $CopyArrays+ *)

  PROCEDURE NewOpenWindow (newWindow{8} : I.ExtNewWindowPtr) : I.WindowPtr;

    VAR Base    : I.IntuitionBasePtr;
        nWinPtr : I.NewWindowPtr;
        winPtr  : I.WindowPtr;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      IF newWindow # NIL THEN
        IF (I.nwExtended IN newWindow.nw.flags) THEN
          nWinPtr := e.AllocVec (y.SIZE (I.NewWindow), LONGSET {});
          IF nWinPtr = NIL THEN
            y.SETREG (14, Base);
            RETURN OldOpenWindow (newWindow);
          END;
          e.CopyMem (newWindow^, nWinPtr^, y.SIZE (I.NewWindow));
          EXCL (nWinPtr.flags, I.nwExtended);
          y.SETREG (14, Base);
          winPtr:=NewOpenWindowTags (nWinPtr, y.VAL (TagArrayPtr, newWindow.extension));
          e.FreeVec (nWinPtr);
          y.SETREG (14, Base);
          RETURN winPtr;
        ELSE
          y.SETREG (14, Base);
          RETURN NewOpenWindowTags (newWindow, NIL);
        END;
      END;

      y.SETREG (14, Base);
      RETURN NIL;
    END NewOpenWindow;
  
  PROCEDURE NewSetMenuStrip (window{8} : I.WindowPtr; menu{9} : I.MenuPtr) : BOOLEAN;
  
    PROCEDURE SetColor(item : I.MenuItemPtr; front, back : SHORTINT);

      VAR itext : I.IntuiTextPtr;

      BEGIN
        IF I.itemText IN item.flags THEN
          itext:=item.itemFill;
          itext.frontPen:=front;
          itext.backPen:=back;
        END;
      END SetColor;
  
    PROCEDURE ReColor(menu : I.MenuPtr; front, back : SHORTINT);

      VAR item, subitem : I.MenuItemPtr;

      BEGIN
        WHILE menu # NIL DO
          item:=menu.firstItem;
          WHILE item # NIL DO
            subitem:=item.subItem;
            WHILE subitem # NIL DO
              SetColor(subitem,front,back);
              subitem:=subitem.nextItem;
            END;
            SetColor(item,front,back);
            item:=item.nextItem;
          END;
          menu:=menu.nextMenu;
        END;
      END ReColor;
  
    VAR Base        : I.IntuitionBasePtr;
        dinfo       : I.DrawInfoPtr;
        Pens        : PenPtr;
        front, back : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      IF window # NIL THEN
        IF Opt[RECOLORMENU] # NIL THEN
          IF menu # NIL THEN
            dinfo:=I.GetScreenDrawInfo(window.wScreen);
            IF dinfo # NIL THEN
              Pens:=y.VAL(PenPtr,dinfo.pens);
              front:=I.shinePen;
              back:=I.shadowPen;
              IF dinfo.numPens >= I.numDRIPens THEN
                IF dinfo.numPens <= numDRIPens THEN
                  front:=barDetailPen;
                  back:=barBlockPen;
                END;
              END;
              (* $RangeChk- *)
              ReColor(menu,SHORT(Pens[front]),SHORT(Pens[back]));
              (* $RangeChk= *)
            ELSE
              ReColor(menu,1,2);
            END;
          END;
        END;
      END;
      y.SETREG (14, Base);
      RETURN OldSetMenuStrip (window,menu);
    END NewSetMenuStrip;
  
  PROCEDURE NewLayoutMenuItems (firstitem{8}    : I.MenuItemPtr;
                                vi{9}           : gt.VisualInfo;
                                paraTagList{10} : TagArrayPtr): BOOLEAN;

    VAR Base  : e.LibraryPtr;
        myTag : u.Tags2;
        i     : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      IF Opt[NEWLOOKMENU] # 0 THEN
        myTag[i]:=u.TagItem(mnNewLookMenus,I.LTRUE);
        INC(i);
      END;
    
      IF paraTagList # NIL THEN
        myTag[i].tag:=u.more;
        myTag[i].data:=paraTagList;
      ELSE
        myTag[i].tag:=u.done;
        myTag[i].tag:=NIL;
      END;
    
      y.SETREG (14, Base);
      RETURN OldLayoutMenuItems(firstitem,vi,myTag);
    END NewLayoutMenuItems;
  
  PROCEDURE NewLayoutMenus (firstmenu{8}    : I.MenuPtr;
                            vi{9}           : gt.VisualInfo;
                            paraTagList{10} : TagArrayPtr): BOOLEAN;

    VAR Base  : e.LibraryPtr;
        myTag : u.Tags2;
        i     : INTEGER;

    (* $SaveRegs+ *)
    BEGIN
      Base := y.REG (14);
      i:=0;
      IF Opt[NEWLOOKMENU] # 0 THEN
        myTag[i]:=u.TagItem(mnNewLookMenus,I.LTRUE);
        INC(i);
      END;
    
      IF paraTagList # NIL THEN
        myTag[i].tag:=u.more;
        myTag[i].data:=paraTagList;
      ELSE
        myTag[i].tag:=u.done;
        myTag[i].tag:=NIL;
      END;
      y.SETREG (14, Base);
      RETURN OldLayoutMenus(firstmenu,vi,myTag);
    END NewLayoutMenus;
  

(* $Debug= *)

BEGIN
  IF I.int.libNode.version < 37 THEN
    IF d.Output () # NIL THEN
      y.SETREG (0, d.Write (d.Output (), "Sorry, I need Release 2.04 or higher!\n", 23));
    END;
    HALT (20);
  END;

  RD := d.AllocDosObject (d.rdArgs, NIL);
  IF RD # NIL THEN RD.extHelp := y.ADR (ExtHelp) END;
  IF (RD = NIL) OR (d.ReadArgs (Template, Opt, RD) = NIL) THEN
    d.PrintF ("%s\nUsage: %s\n%s", y.ADR (ver.ver[6]), y.ADR (Template), y.ADR (ExtHelp));
    HALT (20);
  END; (* IF *)

  IF Opt[RECOLORMENU] # 0 THEN Opt[NEWLOOKMENU] := I.LTRUE END;
  IF Opt[WITHBORDER]  # 0 THEN Opt[PROPNEWLOOK] := I.LTRUE END;
  (* Patch *)

  e.Forbid;
  OldOpenScreen      := y.VAL (OpenScreenProc,
                               e.SetFunction (I.int, OpenScreenOfs,
                                              y.VAL (e.PROC, NewOpenScreen)));

  OldOpenScreenTags  := y.VAL (OpenScreenTagsProc,
                               e.SetFunction (I.int, OpenScreenTagsOfs,
                                              y.VAL (e.PROC, NewOpenScreenTags)));

  OldOpenWindow      := y.VAL (OpenWindowProc,
                               e.SetFunction (I.int, OpenWindowOfs,
                                              y.VAL (e.PROC, NewOpenWindow)));

  OldOpenWindowTags  := y.VAL (OpenWindowTagsProc,
                               e.SetFunction (I.int, OpenWindowTagsOfs,
                                              y.VAL (e.PROC, NewOpenWindowTags)));

  OldLayoutMenuItems := y.VAL (LayoutMenuItemsProc,
                               e.SetFunction (gt.base, LayoutMenuItemsOfs,
                                              y.VAL (e.PROC, NewLayoutMenuItems)));

  OldLayoutMenus     := y.VAL (LayoutMenusProc,
                               e.SetFunction (gt.base, LayoutMenusOfs,
                                              y.VAL (e.PROC, NewLayoutMenus)));

  OldSetMenuStrip    := y.VAL (SetMenuStripProc,
                               e.SetFunction (I.int, SetMenuStripOfs,
                                              y.VAL (e.PROC, NewSetMenuStrip)));

  OldAddGList        := y.VAL (AddGListProc,
                               e.SetFunction (I.int, AddGListOfs,
                                              y.VAL (e.PROC, NewAddGList)));

  OldAddGadget       := y.VAL (AddGadgetProc,
                               e.SetFunction (I.int, AddGadgetOfs,
                                              y.VAL (e.PROC, NewAddGadget)));

  OldRefreshGList    := y.VAL (RefreshGListProc,
                               e.SetFunction (I.int, RefreshGListOfs,
                                              y.VAL (e.PROC, NewRefreshGList)));

  OldModifyProp      := y.VAL (ModifyPropProc,
                               e.SetFunction (I.int, ModifyPropOfs,
                                              y.VAL (e.PROC, NewModifyProp)));

  OldNewModifyProp   := y.VAL (NewModifyPropProc,
                               e.SetFunction (I.int, NewModifyPropOfs,
                                              y.VAL (e.PROC, NewNewModifyProp)));

  e.Permit;

  (* Wait for Break *)

  y.SETREG (0, e.Wait (LONGSET {d.ctrlC})); (* ... *)

  (* Unpatch *)
  e.Forbid;
  OldOpenScreen      := y.VAL (OpenScreenProc,
                               e.SetFunction (I.int, OpenScreenOfs,
                                              y.VAL (e.PROC, OldOpenScreen)));

  OldOpenScreenTags  := y.VAL (OpenScreenTagsProc,
                               e.SetFunction (I.int, OpenScreenTagsOfs,
                                              y.VAL (e.PROC, OldOpenScreenTags)));

  OldOpenWindow      := y.VAL (OpenWindowProc,
                               e.SetFunction (I.int, OpenWindowOfs,
                                              y.VAL (e.PROC, OldOpenWindow)));

  OldOpenWindowTags  := y.VAL (OpenWindowTagsProc,
                               e.SetFunction (I.int, OpenWindowTagsOfs,
                                              y.VAL (e.PROC, OldOpenWindowTags)));

  OldLayoutMenuItems := y.VAL (LayoutMenuItemsProc,
                               e.SetFunction (gt.base, LayoutMenuItemsOfs,
                                              y.VAL (e.PROC, OldLayoutMenuItems)));

  OldLayoutMenus     := y.VAL (LayoutMenusProc,
                               e.SetFunction (gt.base, LayoutMenusOfs,
                                              y.VAL (e.PROC, OldLayoutMenus)));

  OldSetMenuStrip    := y.VAL (SetMenuStripProc,
                               e.SetFunction (I.int, SetMenuStripOfs,
                                              y.VAL (e.PROC, OldSetMenuStrip)));

  OldAddGList        := y.VAL (AddGListProc,
                               e.SetFunction (I.int, AddGListOfs,
                                              y.VAL (e.PROC, OldAddGList)));

  OldAddGadget       := y.VAL (AddGadgetProc,
                               e.SetFunction (I.int, AddGadgetOfs,
                                              y.VAL (e.PROC, OldAddGadget)));

  OldRefreshGList    := y.VAL (RefreshGListProc,
                               e.SetFunction (I.int, RefreshGListOfs,
                                              y.VAL (e.PROC, OldRefreshGList)));

  OldModifyProp      := y.VAL (ModifyPropProc,
                               e.SetFunction (I.int, ModifyPropOfs,
                                              y.VAL (e.PROC, OldModifyProp)));

  OldNewModifyProp   := y.VAL (NewModifyPropProc,
                               e.SetFunction (I.int, NewModifyPropOfs,
                                              y.VAL (e.PROC, OldNewModifyProp)));

  e.Permit;
  IF (y.VAL (y.ADDRESS, OldOpenScreen)     # y.VAL (y.ADDRESS, NewOpenScreen)     ) OR
     (y.VAL (y.ADDRESS, OldOpenScreenTags) # y.VAL (y.ADDRESS, NewOpenScreenTags) ) OR
     (y.VAL (y.ADDRESS, OldOpenWindow)     # y.VAL (y.ADDRESS, NewOpenWindow)     ) OR
     (y.VAL (y.ADDRESS, OldOpenWindowTags) # y.VAL (y.ADDRESS, NewOpenWindowTags) ) OR
     (y.VAL (y.ADDRESS, OldLayoutMenus)    # y.VAL (y.ADDRESS, NewLayoutMenus)    ) OR
     (y.VAL (y.ADDRESS, OldLayoutMenuItems)# y.VAL (y.ADDRESS, NewLayoutMenuItems)) OR
     (y.VAL (y.ADDRESS, OldAddGList)       # y.VAL (y.ADDRESS, NewAddGList)       ) OR
     (y.VAL (y.ADDRESS, OldRefreshGList)   # y.VAL (y.ADDRESS, NewRefreshGList)   ) OR
     (y.VAL (y.ADDRESS, OldAddGadget)      # y.VAL (y.ADDRESS, NewAddGadget)      ) OR
     (y.VAL (y.ADDRESS, OldModifyProp)     # y.VAL (y.ADDRESS, NewModifyProp)     ) OR
     (y.VAL (y.ADDRESS, OldNewModifyProp)  # y.VAL (y.ADDRESS, NewNewModifyProp)  ) OR
     (y.VAL (y.ADDRESS, OldSetMenuStrip)   # y.VAL (y.ADDRESS, NewSetMenuStrip)   ) THEN

     IF I.DisplayAlert (I.recoveryAlert,
                        "\x00\x10\x10Someone else patched too. Safety cannot be guarateed, please reboot!\o\n\x00\x10\x1A     -> Reboot <-                           -> Hope and pray <-     \o\o",
                        40) THEN
      e.ColdReboot;
    END;
  END;
CLOSE
  IF RD # NIL THEN
    d.FreeArgs (RD);
    d.FreeDosObject (d.rdArgs, RD); RD := NIL;
  END;
END NewLook4Menus.
