DEFINITION GemApp; (* Stephan Junker   31.10.93 *)


(* GemApp implements the objects to run a GEM application. Some of the
 * names and the concept are similar to Turbo Pascal.
 *
 * Usage:
 * Define an extension of GemApp.ApplDesc. You may override the procedures,
 * but don't forget to call the inherited ones. Then call Init, Run and Exit
 * in the modules body.
 *
 * Notes: The type Events can also be extended in order to provide
 *        additional events.
 *
 *        One can broadcast messages or simulate events by using
 *        free bits of Events.events and calling GemApp.HandleEvent.
 *)


CONST
  KEY* = 0; BUTTON* = 1; MOUSE1* = 2; MOUSE2* = 3; MESSAGE* = 4; TIME* = 5;
    (* the types of events which can be awaited *)


TYPE
  Application*= POINTER TO ApplDesc;
  ApplDesc*   = RECORD (* for extension *)
                  which-  : SET; (* the events to wait for *)
                  clicks- : INTEGER;
                  mask-   : SET; (* the buttons to recognize *)
                  state-  : SET; (* bit = 1 : event if clicked
                                    bit = 0 : event if released *)
                  m1flags-,m1x-,m1y-,m1w-,m1h- : INTEGER;
                  m2flags-,m2x-,m2y-,m2w-,m2h- : INTEGER;
                  time-   : LONGINT;
                  events* : SET; (* events recognized *)
                  msgBuf* : Evnt.msgbuf;
                  mx*,my* : INTEGER;
                  mbut*   : SET; (* the button that made the event *)
                  shift*  : SET; (* CAPSLOCK excluded, RSHIFT -> LSHIFT *)
                  oshift* : SET; (* contains the original shift bits returned by Evnt.Multi *)
                  scan*   : INTEGER;
                  ascii*  : CHAR;
                  nClicks*: INTEGER;


                  PROCEDURE(app : Application) SetButtonEvent*(mask,state : SET; clicks : INTEGER);
                    (* sets waiting for a mouse button event *)


                  PROCEDURE(app : Application) SetMouse1Event*(flags,x,y,w,h : INTEGER);
                    (* sets waiting for a mouse event *)


                  PROCEDURE(app : Application) SetMouse2Event*(flags,x,y,w,h : INTEGER);
                    (* sets waiting for a mouse event *)


                  PROCEDURE(app : Application) SetTimerEvent*(time : LONGINT);
                    (* sets waiting for a timer event *)


                  PROCEDURE(app : Application) Init*;
                    (* initializes an application. Call when starting program
                       run *)


                  PROCEDURE(app : Application) Run*;
                    (* the event loop of every program *)


                  PROCEDURE(app : Application) Exit*;
                    (* terminates an application. Call before leaving a
                       program *)

                END(*RECORD*);



VAR
  exit* : BOOLEAN; (* if exit is true, Run terminates *)


PROCEDURE StoreEventHandler*(handler : EventProc);
  (* stores a procedure which is called for every event. If this procedure
     reacts on an event, it must clear the according event bit. *)


PROCEDURE HandleEvent*(VAR event : Events);
  (* the main message handler for all applications. It will call all
     stored event handlers and then delete the events if not already
     done. The only event directly handled by HandleEvent AFTER having
     called the stored handlers is the pressing of control q. This will
     lead to program termination (exit set true) *)


END GemApp.