(***********************************************************************

   :Program.    Plotinit.mod
   :Author.     Stefan Köhle
   :Address.    Erhardtstr. 10
                W-7033 Herrenberg
   :Phone.      07032/5146
   :shortcut.
   :Version.    1.0
   :Date.       31.12.92
   :Copyright.  nix
   :Language.   Modula-II.
   :Translator. M2Amiga 4.107d
   :Imports.    Formelauswertung,
                FormelausFText   by Stefan Salewski    (AMOK 11)
                Req.Library      by Jürgen Zimmermann  (AMOK 55)
                ReqSupport       by Jürgen Zimmermann  (AMOK 55)
                ReqTools.Library by Nico Francois      (AMOK 69)
                ReqTools.def     by Kai Bolay          (AMOK 69)
                ReqToolsSupport  by Frank Lömker       (AMOK 69)
                IFFLib           by Christian A. Weber (AMOK 18)
                IFFLib.def       by Fridtjof Siebert   (AMOK 18)
                MyMathLib        by myself
   :UpDate.     -
   :Contents.
   :Remark.

**********************************************************************)

IMPLEMENTATION MODULE PlotInit;


FROM   Formelauswertung IMPORT AssignFFP,DefFormel ;
FROM   FormelausFText   IMPORT GetFehlertext ;
FROM   ReqSupport       IMPORT FileRequest ;
IMPORT rt: ReqTools ;
FROM   ReqToolsSupport  IMPORT vEZRequest,EZRequest ;
IMPORT IFFLib ;

FROM MyMathLib   IMPORT FFPToInt ;

FROM SYSTEM IMPORT BYTE,ADR,ADDRESS,FFP,LONGSET,BITSET,TAG ;
IMPORT GraphicsL,  GraphicsD ;
IMPORT IntuitionL, IntuitionD ;
IMPORT ExecL,      ExecD ;
IMPORT String ;
IMPORT DosL ;

FROM IntuitionD  IMPORT WindowPtr,checked ;
FROM InOut       IMPORT WriteCard,WriteInt,SetOutput,WriteBytes,SetInput,
                        WriteString,ReadString,ReadBytes,CloseOutput,CloseInput;
FROM DosL        IMPORT Lock,UnLock,CurrentDir ;
FROM DosD        IMPORT FileLockPtr,FileLock,sharedLock ;
FROM UtilityD    IMPORT tagEnd ;
FROM GraphicsD   IMPORT BitMapPtr,ViewModeSet,ViewModes ;


CONST
     Depth = 1 ;
     Colors = 2 ;
     RasWidth = 320 ;
     RasHeight = 200 ;
     BitMapWidth = 1720 ;
     BitMapHeight = 1351 ;

TYPE
     Array      = ARRAY[0..3] OF BYTE ;
     FFPPtr     = POINTER TO FFP ;
     IntegerPtr = POINTER TO INTEGER ;

     FeldText= ARRAY [0..59] OF CHAR;
     Datum= RECORD
             text:FeldText;
             sichtbareZeichen:[1..250];
             buffer:Buffer;
            END;

     Variablen = RECORD
                    tr           : GraphicsD.TmpRas ;
                    ai           : GraphicsD.AreaInfo ;
                    AreaBuffer   : ARRAY [0..16] OF CARDINAL ;
                    ScreenHeight,
                    ScreenWidth  : INTEGER ;
                    gfxBase      : GraphicsD.GfxBasePtr ;
                    topaz80attr  : GraphicsD.TextAttr;
                    Bytewert     : CARDINAL ;
                    Bitwert      : SHORTCARD;
                    BytePtr      : POINTER TO BITSET ;
                    Index        : CARDINAL ;
                    windowTitel  : Buffer ;
                    eingaben     : ARRAY [0..3] OF Datum ;
                    Funktion     : Buffer ;
                    FlPtr,OldLock: FileLockPtr ;
                 END (* RECORD *) ;


VAR
     V          :  POINTER TO Variablen ;
     Pb         :  PlotBasePtr ;
     error      :  (noerror,cancel,Fehler) ;
     i          :  CARDINAL ;
     j          :  INTEGER ;
     l          :  FFP ;
     trp        :  ADDRESS ;
     PlaneSpeicher: ADDRESS ;
     OK         : BOOLEAN ;
     MyBitMapPtr:  GraphicsD.BitMapPtr ;



PROCEDURE Request(Text: ARRAY OF CHAR; GadgetText: ARRAY OF CHAR;
                  Win: WindowPtr) ;

 VAR
    tagbuf    : ARRAY [0..3] OF LONGINT;
    adr       : ADDRESS ;

 BEGIN
    IF Win # NIL THEN
       adr := TAG(tagbuf,rt.Window,Win,tagEnd ) ;
       vEZRequest(ADR(Text),ADR(GadgetText),NIL,NIL,adr) ;
    ELSE
       vEZRequest(ADR(Text),ADR(GadgetText),NIL,NIL,NIL) ;
    END ;
 END Request ;



PROCEDURE YesNoRequest(Text: ARRAY OF CHAR; GadgetText: ARRAY OF CHAR;
                       Win: WindowPtr): BOOLEAN ;

 VAR
    tagbuf    : ARRAY [0..3] OF LONGINT;
    adr       : ADDRESS ;

 BEGIN
    IF Win # NIL THEN
       adr := TAG(tagbuf,rt.Window,Win,tagEnd ) ;
    ELSE
       adr := NIL ;
    END ;

    IF EZRequest(ADR(Text),ADR(GadgetText),NIL,NIL,adr) = 0 THEN
       RETURN TRUE ;
    ELSE
       RETURN FALSE ;
    END ;


 END YesNoRequest ;



PROCEDURE StringRequest(VAR Pb: PlotBasePtr): BOOLEAN ;

 VAR reqInfo: rt.ReqInfoPtr ;
     tagbuf : ARRAY[0..3] OF LONGINT ;
     adr    : ADDRESS ;

 BEGIN

  reqInfo := rt.AllocRequestA (rt.TypeReqInfo, NIL);
  reqInfo^.width := 600 ;

  adr := TAG(tagbuf,rt.Window,Pb^.Window,tagEnd) ;

  IF NOT rt.GetString(ADR(Pb^.Funktion),250,ADR(V^.windowTitel),reqInfo,adr) THEN
     rt.FreeRequest(reqInfo) ;
     RETURN FALSE ;
  ELSE
     rt.FreeRequest(reqInfo) ;
     RETURN TRUE ;
  END ;

 END StringRequest ;



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

     Hier werden alle Speicher alloziert, die Bitmap initialisiert
     und der Screen und das Fenster aufgemacht

  --------------------------------------------------------------------------*)

PROCEDURE SetUp(VAR Pb: PlotBasePtr): CARDINAL ;

 VAR
     MyWindow   : IntuitionD.NewWindow ;
     MyScreen   : IntuitionD.NewScreen ;


 BEGIN
                                     (**** Speicher allozieren ****)

   V := ExecL.AllocMem(SIZE(Variablen),
                       ExecD.MemReqSet{ExecD.public,ExecD.memClear}) ;
   IF V = NIL THEN
      CleanUp(Pb) ;
      RETURN 7 ;
   END ;


   IF Pb^.GrosserSpeicher THEN       (**** fuer Plane ****)
      PlaneSpeicher := GraphicsL.AllocRaster(BitMapWidth,BitMapHeight) ;
      IF PlaneSpeicher = NIL THEN
         CleanUp(Pb) ;
         RETURN 3 ;
      END (* IF *) ;
                                     (**** fuer BitMapPointer ****)
      MyBitMapPtr   := ExecL.AllocMem(SIZE(GraphicsD.BitMap),
                                      ExecD.MemReqSet{ExecD.public}) ;

      IF MyBitMapPtr = NIL  THEN
         CleanUp(Pb) ;
         RETURN 2 ;
      END ;

   END ;


   trp := GraphicsL.AllocRaster(RasWidth,RasHeight) ;(**** fuer TempRas ****)
   IF trp = NIL THEN
      CleanUp(Pb) ;
      RETURN 4 ;
   END (* IF *) ;


   WITH V^.topaz80attr DO
     name  := ADR("topaz.font");
     ySize := 8;
     style := GraphicsD.normalFont;
     flags := GraphicsD.FontFlagSet{GraphicsD.romFont}
   END;


   V^.gfxBase := ADR(GraphicsL) ;

   IF V^.gfxBase = NIL THEN
      Pb^.ScreenHeight := 512 ; Pb^.ScreenWidth := 640 ;
   ELSE
      Pb^.ScreenHeight := 2*V^.gfxBase^.normalDisplayRows ;
      Pb^.ScreenWidth := V^.gfxBase^.normalDisplayColumns ;
   END (* IF *) ;


   WITH MyWindow DO

      leftEdge    := 0   ;   detailPen := 0   ;   width  := Pb^.ScreenWidth  ;
      topEdge     := 0   ;   blockPen  := 1   ;   height := Pb^.ScreenHeight ;
      firstGadget := NIL ;   checkMark := NIL ;   title  := NIL ;
      minWidth    := 0   ;   maxWidth  := 0   ;   screen := NIL ;
      minHeight   := 0   ;   maxHeight := 0   ;   bitMap := NIL ;

      idcmpFlags  := IntuitionD.IDCMPFlagSet {IntuitionD.menuPick,
                                              IntuitionD.rawKey   } ;
      type        := IntuitionD.ScreenFlagSet{IntuitionD.publicScreen} ;

      IF Pb^.GrosserSpeicher THEN
         flags    := IntuitionD.WindowFlagSet{IntuitionD.superBitMap  ,
                                              IntuitionD.backDrop     ,
                                              IntuitionD.gimmeZeroZero,
                                              IntuitionD.activate     };
      ELSE
         flags    := IntuitionD.WindowFlagSet{IntuitionD.backDrop     ,
                                              IntuitionD.gimmeZeroZero,
                                              IntuitionD.activate     };
      END (* IF *) ;

   END (* WITH *) ;


   WITH MyScreen DO
      leftEdge := 0 ;  detailPen := 0   ;  width  := Pb^.ScreenWidth  ;
      topEdge  := 0 ;  blockPen  := 1   ;  height := Pb^.ScreenHeight ;
      depth    := 1 ;  gadgets   := NIL ;  defaultTitle := NIL ;

      font     := ADR(V^.topaz80attr)   ;  customBitMap := NIL ;
      type     := IntuitionD.ScreenFlagSet{IntuitionD.publicScreen,
                                         IntuitionD.screenBehind} ;
      viewModes:= ViewModeSet{hires,lace};
   END (* WITH *) ;


   IF Pb^.GrosserSpeicher THEN
      GraphicsL.InitBitMap(MyBitMapPtr^,1,BitMapWidth,BitMapHeight) ;
      MyBitMapPtr^.planes[0] := PlaneSpeicher ;
      MyWindow.bitMap := MyBitMapPtr ;
   END (* IF *) ;


   GraphicsL.InitTmpRas(V^.tr,trp,((RasWidth+15) DIV 16)*RasHeight);
   GraphicsL.InitArea(V^.ai,ADR(V^.AreaBuffer),SIZE(V^.AreaBuffer) DIV 5) ;


                 (********** Screen aufmachen **********)

   Pb^.Screen:=IntuitionL.OpenScreen(MyScreen) ;
   IF Pb^.Screen = NIL THEN
      CleanUp(Pb) ;
      RETURN 5 ;
   END (* IF *) ;



                   (********** Window aufmachen **********)

   MyWindow.screen := Pb^.Screen ;

   Pb^.Window:=IntuitionL.OpenWindow(MyWindow) ;
   IF Pb^.Window = NIL THEN
      CleanUp(Pb) ;
      RETURN 6 ;
   END (* IF *) ;


   Pb^.Rp := Pb^.Window^.rPort ;
   Pb^.Layer := Pb^.Rp^.layer ;
   Pb^.Rp^.areaInfo := ADR(V^.ai) ;
   Pb^.Rp^.tmpRas := ADR(V^.tr) ;

   GraphicsL.SetRGB4(ADR(Pb^.Screen^.viewPort),0,10,10,10) ;
   GraphicsL.SetRGB4(ADR(Pb^.Screen^.viewPort),1,0,0,0) ;


   RETURN 0 ;

END SetUp;



PROCEDURE CleanUp(VAR Pb: PlotBasePtr); (*************************************)

 BEGIN

   IF Pb # NIL THEN
      IF Pb^.Screen # NIL THEN
         IF Pb^.Window # NIL THEN
            IF Pb^.Window^.menuStrip # NIL THEN
               IntuitionL.ClearMenuStrip(Pb^.Window) ;
               Pb^.Window^.menuStrip := NIL ;
            END (* IF *) ;
            IntuitionL.CloseWindow(Pb^.Window) ;
            Pb^.Window := NIL ;
         END (* IF *) ;
         IntuitionL.CloseScreen(Pb^.Screen) ;
         Pb^.Screen := NIL ;
      END (* IF *) ;
   END (* IF Pb=NIL *) ;


   IF MyBitMapPtr # NIL THEN
      IF MyBitMapPtr^.planes[0] # NIL THEN
         GraphicsL.FreeRaster(MyBitMapPtr^.planes[0],BitMapWidth,BitMapHeight) ;
         MyBitMapPtr^.planes[0] := NIL ;
      END ;

      ExecL.FreeMem(MyBitMapPtr,SIZE(GraphicsD.BitMap)) ;
      MyBitMapPtr := NIL ;
   END (* IF *) ;


   IF trp # NIL THEN
      GraphicsL.FreeRaster(trp,RasWidth,RasHeight) ;
      trp := NIL ;
   END (* IF *) ;

   IF V  # NIL THEN
      ExecL.FreeMem(V,SIZE(Variablen)) ;
      V := NIL ;
   END ;


END CleanUp ;



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

    Hier wird nach Aufruf des Filerequesters die Funktion, alle
    Zoom- und sonstigen Faktoren und Einstellungen gespeichert.

  -----------------------------------------------------------------*)

PROCEDURE Speichern(VAR Pb: PlotBasePtr): BOOLEAN ;  (***********************)

 VAR SpeicherString : ARRAY[0..10] OF CHAR ;
     BytesPtr       : POINTER TO Array ;
     Bytes          : Array ;

 BEGIN

  Pb^.letzterName := Pb^.FunktionName ;

  IF FileRequest(Pb^.Window,FALSE,FALSE,'Funktion speichern',
                                      Pb^.DirFunktionen,Pb^.FunktionName)  THEN

     V^.FlPtr:=Lock(ADR(Pb^.DirFunktionen),sharedLock);

     IF V^.FlPtr = NIL THEN
        vEZRequest(ADR("Sorry, kriege keinen Lock auf dieses Verzeichnis"),
                   ADR("Na dann nicht"),NIL,NIL,NIL) ;
        UnLock(V^.FlPtr);
     ELSE
        V^.OldLock := CurrentDir(V^.FlPtr) ;
     END ;

     SetOutput(Pb^.FunktionName) ;

     SpeicherString := 'PlF ' ;
     WriteString(SpeicherString) ;

     IF Pb^.Raster THEN
        SpeicherString[0] := 'R' ;
     ELSE
        SpeicherString[0] := '0' ;
     END ;

     IF Pb^.Achsen THEN
        SpeicherString[1] := 'A' ;
     ELSE
        SpeicherString[1] := '0' ;
     END ;

     IF Pb^.Kasten THEN
        SpeicherString[2] := 'K' ;
     ELSE
        SpeicherString[2] := '0' ;
     END ;

     IF Pb^.Beschriftung THEN
        SpeicherString[3] := 'B' ;
     ELSE
        SpeicherString[3] := '0' ;
     END ;

     IF Pb^.Flaeche THEN
        SpeicherString[4] := 'F' ;
     ELSE
        SpeicherString[4] := '0' ;
     END ;

     IF Pb^.FSchreiben THEN
        SpeicherString[5] := 'S' ;
     ELSE
        SpeicherString[5] := '0' ;
     END ;

     SpeicherString[6] := ' ' ;

     WriteString(SpeicherString) ;

     BytesPtr := ADR(Pb^.B.XLinks) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.B.DeltaX) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.B.YHinten) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.B.DeltaY) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.B.ZOben) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.B.DeltaZ) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     BytesPtr := ADR(Pb^.Schritt) ;
     Bytes   := BytesPtr^ ;
     WriteBytes(Bytes) ;

     WriteString(Pb^.Funktion) ;

     CloseOutput ;
     RETURN TRUE ;
  ELSE
     Pb^.FunktionName := Pb^.letzterName ;
     RETURN FALSE ;
  END;

END Speichern ;



PROCEDURE Laden(VAR Pb: PlotBasePtr; Req: BOOLEAN): BOOLEAN  ;  (**************)

 VAR SpeicherString : ARRAY[0..15] OF CHAR ;
     Bytes          : Array ;
     ffpPtr         : FFPPtr ;
     IntPtr         : IntegerPtr ;
     ffp1,ffp2,ffp3,
     ffp4,ffp5,ffp6 : FFP ;
     Int1           : INTEGER ;
     Fl2Ptr         : FileLockPtr ;


 BEGIN


  IF Req THEN                          (*********** Requester ***************)

     Pb^.letzterName := Pb^.FunktionName ;
     IF NOT FileRequest(Pb^.Window,TRUE,FALSE,'Funktion laden',
                               Pb^.DirFunktionen,Pb^.FunktionName)  THEN
        RETURN FALSE ;           (********** Cancel im FileRequester **********)
     END ;
  END ;

  V^.FlPtr:=Lock(ADR(Pb^.DirFunktionen),sharedLock);
  V^.OldLock := CurrentDir(V^.FlPtr) ;

  Fl2Ptr := Lock(ADR(Pb^.FunktionName),sharedLock) ;
                                             (* Gucken obs das File gibt *)

  IF Fl2Ptr = NIL THEN
     UnLock(Fl2Ptr) ;
     IF Laden(Pb,TRUE) THEN
        RETURN TRUE
     ELSE
        Pb^.FunktionName := Pb^.letzterName ;
        RETURN FALSE
     END (* IF *) ;
  END ;
  UnLock(Fl2Ptr) ;

  SetInput(Pb^.FunktionName) ;
  ReadString(SpeicherString) ;

  IF String.ComparePart(SpeicherString,0,3,'PlF',TRUE) # 0 THEN
     CloseInput ;
     UnLock(V^.FlPtr) ;
     Pb^.FunktionName := Pb^.letzterName ;
     Request("Ist keine Plot-Funktion","Sowas",Pb^.Window) ;
     RETURN FALSE ;
  END ;

  ReadString(SpeicherString) ;
  Pb^.LetzteFunktion := Pb^.Funktion ;

  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp1 := ffpPtr^ ;
  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp2 := ffpPtr^ ;
  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp3 := ffpPtr^ ;
  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp4 := ffpPtr^ ;
  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp5 := ffpPtr^ ;
  ReadBytes(Bytes) ;  ffpPtr := ADR(Bytes) ;  ffp6 := ffpPtr^ ;
  ReadBytes(Bytes) ;  IntPtr := ADR(Bytes) ;  Int1 := IntPtr^ ;

  ReadString(Pb^.Funktion) ;
  CloseInput ;

  IF NOT FunktionTesten(Pb) THEN
     IF FunktionHolen(Pb,FALSE,FALSE) THEN
        RETURN TRUE ;
     ELSE
        Pb^.Funktion := Pb^.LetzteFunktion ;
        Pb^.FunktionName := Pb^.letzterName ;
        RETURN FALSE ;
     END ;
  END  ;

  IF SpeicherString[0] = 'R' THEN
     Pb^.Raster := TRUE ;
  ELSE
     Pb^.Raster := FALSE ;
  END ;
  IF SpeicherString[1] = 'A' THEN
     Pb^.Achsen := TRUE ;
  ELSE
     Pb^.Achsen := FALSE ;
  END ;
  IF SpeicherString[2] = 'K' THEN
     Pb^.Kasten := TRUE ;
  ELSE
     Pb^.Kasten := FALSE ;
  END ;

  IF SpeicherString[3] = 'B' THEN
     Pb^.Beschriftung := TRUE ;
  ELSE
     Pb^.Beschriftung := FALSE ;
  END ;

  IF SpeicherString[4] = 'F' THEN
     Pb^.Flaeche := TRUE ;
  ELSE
     Pb^.Flaeche := FALSE ;
  END ;

  IF SpeicherString[5] = 'S' THEN
     Pb^.FSchreiben := TRUE ;
  ELSE
     Pb^.FSchreiben := FALSE ;
  END ;

  Pb^.B.XLinks := ffp1 ;
  Pb^.B.DeltaX := ffp2 ;
  Pb^.B.YHinten:= ffp3 ;
  Pb^.B.DeltaY := ffp4 ;
  Pb^.B.ZOben  := ffp5 ;
  Pb^.B.DeltaZ := ffp6 ;
  Pb^.Schritt  := Int1 ;
  UnLock(V^.FlPtr) ;
  RETURN TRUE ;              (********** Alles OK **********)


END Laden ;



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

    Hier werden die Haken an den Menus gesetzt oder gelöscht

  -------------------------------------------------------------*)

PROCEDURE UpdateMenus(VAR Pb: PlotBasePtr; welches: CARDINAL) ;

 VAR ItemPtr: IntuitionD.MenuItemPtr ;

 BEGIN

   ItemPtr := IntuitionL.ItemAddress(Pb^.Window^.menuStrip,1) ;

   CASE welches OF 2:

      IF Pb^.GrosseBitmap THEN
         EXCL (ItemPtr^.nextItem^.flags,IntuitionD.itemEnabled) ;(* gering   *)
      ELSE
         INCL (ItemPtr^.nextItem^.flags,IntuitionD.itemEnabled) ;(* gering   *)
      END ;

      IF Pb^.Schritt = 6 THEN                   (* laecherlich *)
         INCL (ItemPtr^.flags,checked) ;           (* laecherlich *)
         EXCL (ItemPtr^.nextItem^.flags,checked) ; (* gering      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.flags, (* mittel      *)
                                          checked) ;
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem^.flags,
                                          checked) ;    (* hoch        *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem
                     ^.nextItem^.flags,checked) ;  (* noch hoeher *)

      END ;

      IF Pb^.Schritt = 4 THEN                   (* gering *)
         EXCL (ItemPtr^.flags,checked) ;                      (* laecherlich *)
         INCL (ItemPtr^.nextItem^.flags,checked) ;            (* gering      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.flags,checked) ;  (* mittel      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem^.
                                          flags,checked) ;    (* hoch        *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem
                              ^.nextItem^.flags,checked) ;    (* noch hoeher *)
      END ;

      IF Pb^.Schritt = 3 THEN                   (* mittel *)
         EXCL (ItemPtr^.flags,checked) ;                      (* laecherlich *)
         EXCL (ItemPtr^.nextItem^.flags,checked) ;            (* gering      *)
         INCL (ItemPtr^.nextItem^.nextItem^.flags,checked) ;  (* mittel      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem^.
                                          flags,checked) ;    (* hoch        *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem
                              ^.nextItem^.flags,checked) ;    (* noch hoeher *)
      END ;

      IF Pb^.Schritt = 2 THEN                   (* hoch *)
         EXCL (ItemPtr^.flags,checked) ;                        (* laecherlich *)
         EXCL (ItemPtr^.nextItem^.flags,checked) ;              (* gering      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.flags,checked) ;    (* mittel      *)
         INCL (ItemPtr^.nextItem^.nextItem^.nextItem^.
                                            flags,checked) ;    (* hoch        *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem
                                ^.nextItem^.flags,checked) ;    (* noch hoeher *)
      END ;

      IF Pb^.Schritt = 1 THEN                   (* noch hoeher *)
         EXCL (ItemPtr^.flags,checked) ;                        (* laecherlich *)
         EXCL (ItemPtr^.nextItem^.flags,checked) ;              (* gering      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.flags,checked) ;    (* mittel      *)
         EXCL (ItemPtr^.nextItem^.nextItem^.nextItem^.
                                            flags,checked) ;    (* hoch        *)
         INCL (ItemPtr^.nextItem^.nextItem^.nextItem
                                ^.nextItem^.flags,checked) ;    (* noch hoeher *)
      END |
   3:
      ItemPtr := IntuitionL.ItemAddress(Pb^.Window^.menuStrip,2) ;

      IF Pb^.Raster THEN
         INCL (ItemPtr^.flags,checked) ;
      ELSE
         EXCL (ItemPtr^.flags,checked) ;
      END ;

      IF Pb^.Kasten THEN
         INCL(ItemPtr^.nextItem^.flags,checked) ;
      ELSE
         EXCL(ItemPtr^.nextItem^.flags,checked) ;
      END ;

      IF Pb^.Achsen THEN
         INCL(ItemPtr^.nextItem^.nextItem^.flags,checked) ;
      ELSE
         EXCL(ItemPtr^.nextItem^.nextItem^.flags,checked) ;
      END ;

      IF Pb^.Beschriftung THEN
         INCL(ItemPtr^.nextItem^.nextItem^.nextItem^.flags,checked) ;
      ELSE
         EXCL(ItemPtr^.nextItem^.nextItem^.nextItem^.flags,checked) ;
      END ;

      IF Pb^.Flaeche THEN
         INCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.flags,checked) ;
      ELSE
         EXCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.flags,checked) ;
      END ;

      IF Pb^.FSchreiben THEN
         INCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.
                                                     nextItem^.flags,checked) ;
      ELSE
         EXCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.
                                                     nextItem^.flags,checked) ;
      END ;

      IF Pb^.GrosseBitmap THEN
         EXCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.nextItem^.
                                                     nextItem^.flags,checked) ;
         INCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.nextItem^.
                                           nextItem^.nextItem^.flags,checked) ;
      ELSE
         INCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.nextItem^.
                                                     nextItem^.flags,checked) ;
         EXCL(ItemPtr^.nextItem^.nextItem^.nextItem^.nextItem^.nextItem^.
                                           nextItem^.nextItem^.flags,checked) ;
      END ;

   ELSE
   END ; (* CASE  *)
END UpdateMenus ;



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

   Hier wird der Stringrequester aufgerufen und der eingegebene String
   auf Tauglichkeit untersucht. Wenn der String keine verwertbare Funktion
   ist, dann kommt der Stringrequester nochmal mit der Fehlermeldung
   als Fenstertitel.

   Es sei denn, Disk = TRUE, dann wurde
   eine Funktion geladen und die wird dann nur getestet.

  ----------------------------------------------------------------------*)

PROCEDURE FunktionHolen(VAR Pb: PlotBasePtr ; Disk: BOOLEAN; NeueFunktion:
                        BOOLEAN): BOOLEAN ;


 BEGIN

   IF NeueFunktion THEN
      Pb^.LetzteFunktion := Pb^.Funktion ;
      Pb^.Funktion := "" ;
   END ;


   REPEAT

        IF Pb^.FehlerNummer = 0 THEN
           V^.windowTitel:='Bitte Funktion eingeben: f(x,y) = ';
        ELSE
           GetFehlertext(Pb^.FehlerNummer,V^.windowTitel) ;
        END ;

        IF Disk THEN   (* Falls laden per Requester testen obs ne Funktion ist*)
           error := noerror ;
        ELSE
           IF StringRequest(Pb) THEN
              error := noerror ;
           ELSE                                         (* cancel gedrueckt *)
              error := cancel ;
           END (* IF *) ;
        END  ;

        IF error = noerror THEN
           IF NOT FunktionTesten(Pb) THEN
              IF Pb^.FehlerNummer = 31 THEN (* Formel ist leer *)
                 error := cancel ;
              ELSE
                 error := Fehler ;
              END ;
           END (* IF *) ;

        END (* IF *) ;
        Disk := FALSE ;

   UNTIL error # Fehler ;

   IF error = cancel THEN
      Pb^.FunktionName := Pb^.letzterName ;
      RETURN FALSE ;
   ELSE
      RETURN TRUE ;
   END (* IF *) ;

END FunktionHolen ;


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

   Die Procedur, die den String testet

  -------------------------------------------------------------------*)

PROCEDURE FunktionTesten(VAR Pb: PlotBasePtr): BOOLEAN ;

 VAR onlyLong : BOOLEAN ;

 BEGIN

    V^.eingaben[0].buffer :=Pb^.Funktion ;

    OK := AssignFFP("x",0.0) ;
    OK := AssignFFP("y",0.0) ;
    Pb^.FehlerNummer := DefFormel(2,V^.eingaben[0].buffer,TRUE,FALSE);

    IF Pb^.FehlerNummer#0 THEN
       RETURN FALSE ;
    ELSE
       RETURN TRUE ;
    END (* IF *) ;

END FunktionTesten ;



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

   Hier werden die beim Aufruf aus dem CLI eventuell übergebenen Argumente
   ausgewertet und geguckt obs ein Directory 'Bilder' und/oder 'Funktionen'
   gibt, wohin dann beim Laden oder Speichern automatisch verzweigt wird.

   Das Argument (es wird nur das Erste genommen) wird zuerst als Name einer
   gespeicherten Funktion interpretiert. Nur wenn es in Funktionen kein
   solches File gibt, wird das Argument als Funktion interpretiert.
   Falls die Funktion Fehler enthält, kommt der Stringrequester und weist
   darauf hin.

  -----------------------------------------------------------------------*)


PROCEDURE ArgTesten(VAR Pb: PlotBasePtr; Arg: BOOLEAN): BOOLEAN ;

 VAR   Lenge : INTEGER ;


 BEGIN

             (********** Gucken obs Dir Bilder gibt **********)

   String.Copy(Pb^.OldDir,Pb^.DirBilder) ;          (* aktuelles Dir retten *)
   Lenge := String.Length(Pb^.DirBilder) ;

   IF String.Occurs(Pb^.DirBilder,Lenge-1,':',TRUE) # -1 THEN  (* dann haengt ein : dran *)
      String.Insert(Pb^.DirBilder,-1,'Bilder') ;           (* im RootDir *)
   ELSE
      String.Insert(Pb^.DirBilder,-1,'/Bilder') ;          (* sonst *)
   END ;


   V^.FlPtr:=Lock(ADR(Pb^.DirBilder),sharedLock);

   IF V^.FlPtr = NIL THEN                      (* gibt kein Dir Bilder *)
      String.Copy(Pb^.DirBilder,Pb^.OldDir) ;  (* nehme aktuelles *)
   END ;

   UnLock(V^.FlPtr);


              (********** Gucken obs Dir Funktionen gibt**********)

   String.Copy(Pb^.DirFunktionen,Pb^.OldDir) ;           (* aktuelles Dir holen *)
   Lenge := String.Length(Pb^.DirFunktionen) ;

   IF String.Occurs(Pb^.DirFunktionen,Lenge-1,':',TRUE) # -1 THEN  (* dann haengt ein : dran *)
      String.Insert(Pb^.DirFunktionen,-1,'Funktionen') ;     (* im RootDir *)
   ELSE
      String.Insert(Pb^.DirFunktionen,-1,'/Funktionen') ;  (* sonst *)
   END ;


   V^.FlPtr:=Lock(ADR(Pb^.DirFunktionen),sharedLock);

   IF V^.FlPtr = NIL THEN                    (* gibt kein Dir Funktionen *)
      String.Copy(Pb^.DirFunktionen,Pb^.OldDir) ;(* Dir = aktuelles *)
   END ;

   UnLock(V^.FlPtr);


   IF Arg THEN                            (* Argument vorhanden ? *)

      Pb^.FunktionName := Pb^.Funktion ;  (* Argument sei der Name  *)

      V^.FlPtr:=Lock(ADR(Pb^.DirFunktionen),sharedLock);
      V^.OldLock := CurrentDir(V^.FlPtr) ;
      V^.FlPtr := Lock(ADR(Pb^.Funktion),sharedLock) ;

      IF V^.FlPtr # NIL THEN
         UnLock(V^.FlPtr) ;               (* File existiert *)
         IF Laden(Pb,FALSE) THEN
            RETURN TRUE ;
         ELSE
            RETURN FALSE ;
         END ;
      ELSE
         UnLock(V^.FlPtr) ;               (* File gibts nicht, dann war das *)
         Pb^.FunktionName := '' ;         (* Argument die Funktion *)
         Pb^.letzterName  := '' ;
      END (* IF *);

      IF FunktionTesten(Pb) THEN          (* Funktion ist da *)
         Pb^.BildName := Pb^.FunktionName ;
         RETURN TRUE ;
      END ;

      IF FunktionHolen(Pb,FALSE,FALSE) THEN      (* Funktion hat Fehler *)
         RETURN TRUE ;
      END ;
   END ;


   RETURN FALSE ;                  (* cancel beim Stringrequester *)
                                   (* oder kein Argument  *)
END ArgTesten ;



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

   Hier werden, je nachdem, ob große oder kleine Bitmap gewählt ist,
   der Nullpunkt des Koordinatenkreuzes und die x- und y-Offsets des
   Kastens berechnet.

  ------------------------------------------------------------------------*)

PROCEDURE UpdatePb(Pb: PlotBasePtr) ;

 BEGIN

    IF Pb^.GrosseBitmap THEN
      Pb^.KastenX0 := 450 ;
      Pb^.KastenY0 := 138 ;

      Pb^.A.XNull := -(FFPToInt(Pb^.B.XLinks*96.0/Pb^.B.DeltaX));
      IF Pb^.A.XNull < 0 THEN Pb^.A.XNull := 0 ; END ;
      IF Pb^.A.XNull > 384 THEN Pb^.A.XNull := 384 ; END ;

      Pb^.A.YNull := -FFPToInt(Pb^.B.YHinten*48.0/Pb^.B.DeltaY) ;
      IF Pb^.A.YNull < 0   THEN Pb^.A.YNull := 0   ; END ;
      IF Pb^.A.YNull > 144 THEN Pb^.A.YNull := 144 ; END ;

      Pb^.A.ZNull := FFPToInt(Pb^.B.ZOben/Pb^.B.DeltaZ *60.0) ;
      IF Pb^.A.ZNull < 0  THEN Pb^.A.ZNull := 0  ; END ;
      IF Pb^.A.ZNull > 240 THEN Pb^.A.ZNull := 240 ; END ;

    ELSE
      Pb^.KastenX0 := 160 ;
      Pb^.KastenY0 := 46 ;

      Pb^.A.XNull := -(FFPToInt(Pb^.B.XLinks*96.0/Pb^.B.DeltaX));
      IF Pb^.A.XNull < 0 THEN Pb^.A.XNull := 0 ; END ;
      IF Pb^.A.XNull > 384 THEN Pb^.A.XNull := 384 ; END ;

      Pb^.A.YNull := -FFPToInt(Pb^.B.YHinten*48.0/Pb^.B.DeltaY) ;
      IF Pb^.A.YNull < 0   THEN Pb^.A.YNull := 0   ; END ;
      IF Pb^.A.YNull > 144 THEN Pb^.A.YNull := 144 ; END ;

      Pb^.A.ZNull := FFPToInt(Pb^.B.ZOben/Pb^.B.DeltaZ *60.0) ;
      IF Pb^.A.ZNull < 0  THEN Pb^.A.ZNull := 0  ; END ;
      IF Pb^.A.ZNull > 240 THEN Pb^.A.ZNull := 240 ; END ;
   END ;

END UpdatePb ;




PROCEDURE ScreenHoch(MyScreenPtr:IntuitionD.ScreenPtr) ;
  VAR i,h,t : INTEGER ;


  BEGIN
     h := MyScreenPtr^.height ;
     t := MyScreenPtr^.topEdge ;
     IntuitionL.MoveScreen(MyScreenPtr,0,h-t-3) ;  (* erst mal ganz runter *)
     IntuitionL.ScreenToFront(MyScreenPtr) ;

     IntuitionL.MoveScreen(MyScreenPtr,0,-2) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-4) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-5) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-6) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-7) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-8) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-9) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-10) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-11) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-12) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-13) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-15) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-17) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-19) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-21) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-23) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-25) ;

     FOR i := 1 TO MyScreenPtr^.topEdge/35  DO
        IntuitionL.MoveScreen(MyScreenPtr,0,-35) ;
     END (* FOR *) ;

     IntuitionL.MoveScreen(MyScreenPtr,0,-MyScreenPtr^.topEdge);
     IntuitionL.MoveScreen(MyScreenPtr,0,16) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,16) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,16) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,16) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,14) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,12) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,10) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,8) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,3) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,4) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,2) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,2) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,1) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,0) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-2) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,-4) ;
     FOR i := 1 TO 16 DO
        IntuitionL.MoveScreen(MyScreenPtr,0,-7) ;
     END ;


END ScreenHoch ;



PROCEDURE ScreenWeg(MyScreenPtr: IntuitionD.ScreenPtr) ;
  VAR i : INTEGER ;

  BEGIN
     IntuitionL.MoveScreen(MyScreenPtr,0,2) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,4) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,5) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,6) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,7) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,8) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,9) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,10) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,11) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,12) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,13) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,15) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,17) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,19) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,21) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,23) ;
     IntuitionL.MoveScreen(MyScreenPtr,0,25) ;

     FOR i := 1 TO MyScreenPtr^.topEdge/35 DO
        IntuitionL.MoveScreen(MyScreenPtr,0,35) ;
     END (* FOR *) ;

     IntuitionL.ScreenToBack(MyScreenPtr) ;
END ScreenWeg ;


PROCEDURE MenuNummer(code:CARDINAL):CARDINAL;
  BEGIN
    RETURN code MOD 32
  END MenuNummer;


PROCEDURE ItemNummer(code:CARDINAL):CARDINAL;
  BEGIN
    RETURN (code DIV 32) MOD 64
  END ItemNummer;


PROCEDURE SubItemNummer(code:CARDINAL):CARDINAL ;
  BEGIN
    RETURN ((code DIV 32) DIV 64) MOD 32
  END SubItemNummer ;


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

   Das Problem hier ist, den Tastenrepeater auszuschalten. Es wird nur
   eine Taste weitergemeldet, wenn diese losgelassen wird.
   Es werden nur die Funkrionstasten, die Zahlentasten direkt drunter, der
   Zahlenblock, die ESC, CTRL-C, die Helptaste, die beiden SHIFT und die
   beiden ALT-Tasten abgefragt.
   Beim Drücken einer ALT,SHIFT oder CTRL Taste wird AltR,AltL,ShiftL,ShiftR
   oder Ctrl auf TRUE gesetzt. Bei anderen Tasten wird Ein = TRUE.
   Wenn jetzt der Tastenrepeater anfängt diese Taste sinnlos zu wiederholen,
   passiert überhaupt nichts. Erst wenn die Taste losgelassen wird, wird
   Ein, bzw ShiftL,ShiftR... auf FALSE gesetzt und die Taste wird gemeldet.

   Das geht, weil die RawKey-Codes vom Drücken einer Taste und vom Loslassen
   unterschiedlich sind.

  --------------------------------------------------------------------------*)


PROCEDURE WelcheTaste(code:CARDINAL):CARDINAL ;


VAR
    Ein,ShiftL,ShiftR,AltL,AltR,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10: BOOLEAN ;
    Ctrl   : BOOLEAN ;


   BEGIN
       IF NOT Ein THEN
          CASE code OF
             76     : Ein := TRUE ;
                      IF (ShiftL OR ShiftR) THEN RETURN 261; (* rauf *)
                      ELSIF (AltL OR AltR)  THEN RETURN 262;
                      ELSE                       RETURN 260 ;
                      END (* IF *) ; |

             77     : Ein := TRUE ;
                      IF (ShiftL OR ShiftR) THEN RETURN 266; (* runter *)
                      ELSIF (AltL OR AltR)  THEN RETURN 267;
                      ELSE                       RETURN 265 ;
                      END (* IF *) ; |

             78     : Ein := TRUE ;
                      IF (ShiftL OR ShiftR) THEN RETURN 276 ; (* rechts *)
                      ELSIF (AltL OR AltR)  THEN RETURN 277 ;
                      ELSE                       RETURN 275 ;
                      END (* IF *) ; |

             79     : Ein := TRUE ;
                      IF (ShiftL OR ShiftR) THEN RETURN 271 ; (* links *)
                      ELSIF (AltL OR AltR)  THEN RETURN 272 ;
                      ELSE                       RETURN 270;
                      END (* IF *) ; |

             51     : Ein := TRUE ;                          (* CTRL C  *)
                      IF Ctrl THEN RETURN 278 ;  END (* IF *); |

             69     : Ein := TRUE ;
                      RETURN 280 ;                           (* ESC *) |

             95     : Ein := TRUE ; RETURN 281; (* Help *) |

             80     : Ein := TRUE ; RETURN 291; (* F1 *) |

             81     : Ein := TRUE ; RETURN 292; (* F2 *) |

             82     : Ein := TRUE ; RETURN 293; (* F3 *) |

             83     : Ein := TRUE ; RETURN 294; (* F4 *) |

             84     : Ein := TRUE ; RETURN 295; (* F5 *) |

             85     : Ein := TRUE ; RETURN 296; (* F6 *) |

             86     : Ein := TRUE ; RETURN 297; (* F7 *) |

             87     : Ein := TRUE ; RETURN 298; (* F8 *) |

             88     : Ein := TRUE ; RETURN 299; (* F9 *) |

             89     : Ein := TRUE ; RETURN 300; (* F10 *) |

             1      : Ein := TRUE ; RETURN 301; (* 1 *) |

             2      : Ein := TRUE ; RETURN 302; (* 2 *) |

             3      : Ein := TRUE ; RETURN 303; (* 3 *) |

             4      : Ein := TRUE ; RETURN 304; (* 4 *) |

             5      : Ein := TRUE ; RETURN 305; (* 5 *) |

             6      : Ein := TRUE ; RETURN 306; (* 6 *) |

             7      : Ein := TRUE ; RETURN 307; (* 7 *) |

             8      : Ein := TRUE ; RETURN 308; (* 8 *) |

             9      : Ein := TRUE ; RETURN 309; (* 9 *) |

             10     : Ein := TRUE ; RETURN 310; (* 0 *) |

             29     : Ein := TRUE ;             (* 1 *)    (* Zehnerblock *)
                      IF (ShiftL OR ShiftR) THEN RETURN 321 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 331 ;
                      ELSE                       RETURN 311;
                      END (* IF *) ; |

             30     : Ein := TRUE ;             (* 2 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 322 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 332 ;
                      ELSE                       RETURN 312;
                      END (* IF *) ; |

             31     : Ein := TRUE ;             (* 3 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 323 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 333 ;
                      ELSE                       RETURN 313;
                      END (* IF *) ; |

             45     : Ein := TRUE ;             (* 4 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 324 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 334 ;
                      ELSE                       RETURN 314;
                      END (* IF *) ; |

             46     : Ein := TRUE ;             (* 5 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 325 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 335 ;
                      ELSE                       RETURN 315;
                      END (* IF *) ; |

             47     : Ein := TRUE ;             (* 6 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 326 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 336 ;
                      ELSE                       RETURN 316;
                      END (* IF *) ; |

             61     : Ein := TRUE ;             (* 7 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 327 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 337 ;
                      ELSE                       RETURN 317;
                      END (* IF *) ; |

             62     : Ein := TRUE ;             (* 8 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 328 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 338 ;
                      ELSE                       RETURN 318;
                      END (* IF *) ; |

             63     : Ein := TRUE ;             (* 9 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 329 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 339 ;
                      ELSE                       RETURN 319;
                      END (* IF *) ; |

             15     : Ein := TRUE ;             (* 0 *)
                      IF (ShiftL OR ShiftR) THEN RETURN 330 ;
                      ELSIF (AltL OR AltR)  THEN RETURN 340 ;
                      ELSE                       RETURN 320;
                      END (* IF *) ; |

          ELSE
          END (* CASE *) ;
       END (* IF *) ;

       CASE code OF 129..223 : Ein    := FALSE; |
                         224 : ShiftL := FALSE; |
                         225 : ShiftR := FALSE; |
                         227 : Ctrl   := FALSE; |
                         228 : AltL   := FALSE; |
                         229 : AltR   := FALSE; |
                         96  : ShiftL := TRUE; |
                         97  : ShiftR := TRUE; |
                         99  : Ctrl   := TRUE; |
                         100 : AltL   := TRUE; |
                         101 : AltR   := TRUE;
       ELSE ;
       END (* CASE *) ;
       RETURN 0 ;

END WelcheTaste ;



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

  Hier wird nach Aufruf des Filerequesters das Bild als IFF-Datei gespeichert.
  Falls am Dateinamen schon ein .IFF dranhängt ists ok, andernfalls kommt
  ein .IFF hin.

  ----------------------------------------------------------------------*)

PROCEDURE BildSpeichern(Pb: PlotBasePtr) ;

 VAR
     TempStr : ARRAY[0..4] OF CHAR ;
     colTab  : ADDRESS;
     bmp     : ADDRESS ;
     f       : IFFLib.SaveIFFFlagSet;

 BEGIN

    IF FileRequest(Pb^.Window,FALSE,TRUE,'Bild speichern',
                              Pb^.DirBilder,Pb^.BildName)  THEN


       V^.FlPtr:=Lock(ADR(Pb^.DirBilder),sharedLock);

       IF V^.FlPtr # NIL THEN

          GraphicsL.SetRGB4(ADR(Pb^.Screen^.viewPort),0,15,15,15) ;
          V^.OldLock := CurrentDir(V^.FlPtr) ;

          f := IFFLib.SaveIFFFlagSet{IFFLib.cmpByteRun1};
          colTab := Pb^.Screen^.viewPort.colorMap^.colorTable ;

          TempStr := '.IFF' ;

          IF String.ComparePart(Pb^.BildName,(String.Length(Pb^.BildName)-4),
                                4,TempStr,FALSE) # 0 THEN
                                                      (* .IFF fehlt noch *)
             String.Concat(Pb^.BildName,TempStr) ;    (* .IFF dranmachen *)

          END  (* IF *) ;



          IF Pb^.GrosseBitmap THEN
             bmp := MyBitMapPtr ;
             OK := IFFLib.SaveClip(ADR(Pb^.BildName),bmp,colTab,f,0,0,215,1350) ;
          ELSE
             bmp := ADR(Pb^.Screen^.bitMap) ;
             OK := IFFLib.SaveClip(ADR(Pb^.BildName),bmp,colTab,f,1,10,79,480) ;
          END ;

          UnLock(V^.FlPtr);

          GraphicsL.SetRGB4(ADR(Pb^.Screen^.viewPort),0,10,10,10) ;
       END ; (* IF FlPtr *)


    END (* IF FileRequest *) ;

 END BildSpeichern ;



PROCEDURE BildLaden(Pb: PlotBasePtr): INTEGER ;

 TYPE Str = ARRAY[0..50] OF CHAR ;

 VAR ifffile : ADDRESS ;
     name    : Str ;
     NamePtr : POINTER TO Str ;
     BitmapPtr: GraphicsD.BitMapPtr ;

 BEGIN

    NamePtr := ADR(name) ;
    IF FileRequest(Pb^.Window,FALSE,TRUE,'Bild laden',
                              Pb^.DirBilder,name)  THEN

       V^.FlPtr:=Lock(ADR(Pb^.DirBilder),sharedLock);

       IF V^.FlPtr # NIL THEN

          V^.OldLock := CurrentDir(V^.FlPtr) ;
          ifffile := IFFLib.OpenIFF(NamePtr) ;
          IF ifffile = 0 THEN
             UnLock(V^.FlPtr);
             RETURN IFFLib.IffError() ;
          END ;


          IF Pb^.GrosserSpeicher THEN

             IF NOT IFFLib.DecodePic(ifffile,MyBitMapPtr) THEN
                UnLock(V^.FlPtr);
                IFFLib.CloseIFF(ifffile) ;
                ExecL.FreeMem(BitmapPtr,SIZE(GraphicsD.BitMap)) ;
                BitmapPtr := NIL ;
                RETURN IFFLib.IffError() ;
             END ;

          ELSE
             BitmapPtr := ExecL.AllocMem(SIZE(GraphicsD.BitMap),
                                         ExecD.MemReqSet{ExecD.public}) ;

             IF BitmapPtr = NIL THEN
                UnLock(V^.FlPtr);
                IFFLib.CloseIFF(ifffile) ;
                RETURN 1 ;
             END ;

             BitmapPtr^ := Pb^.Screen^.bitMap ;

             IF NOT IFFLib.DecodePic(ifffile,BitmapPtr) THEN
                UnLock(V^.FlPtr);
                IFFLib.CloseIFF(ifffile) ;
                ExecL.FreeMem(BitmapPtr,SIZE(GraphicsD.BitMap)) ;
                BitmapPtr := NIL ;
                RETURN IFFLib.IffError() ;
             END ;

             ExecL.FreeMem(BitmapPtr,SIZE(GraphicsD.BitMap)) ;
             BitmapPtr := NIL ;

          END (* IF Pb^.GrosserSpeicher *) ;


          UnLock(V^.FlPtr);
          IFFLib.CloseIFF(ifffile) ;
          RETURN 0 ;

       END (* IF FlPtr *) ;
    END (* IF FileRequest *) ;

END BildLaden ;


END PlotInit.







