Gr		The commonly used graphics protocol of the MyMouse software
ver 1.25	package, the Graphics Vision library, and MetaGraph.
		Copyright (c) 1993 by Matthias Kppe.



Gr is a Turbo Pascal unit that manages the VGA memory, provides information
about the graphics mode and handles commonly used graphic data structures.
Further, it is the central unit of the pointer/quality conception for
graphical modularization and the notification chain conception.

Versions 1.22+ support DPMI; and they provide the 7.0 procedures NewCache,
DispoceCache, and GetShiftState for 6.0.

Versions 1.25+ support video memory mapping, such that there is no limit
of video memory supported. Using the VESA unit, VESA devices are supported.


P r o c e d u r e s


procedure SetGrMode(Mode: Word);

  SetGrMode sets the parameters of a graphics mode. If graphics is active
  when calling SetGrMode, the procedure will close graphics, set the new
  parameters, and initialize graphics again. In the other case, graphics
  will not be initialized. This should be done by an InitGraphics call.

  The Mode parameter is one of the following grXXXX constants. They identify
  - independently from the computer system - the graphics modes.

  Name		Also Named	Description
    
  grVgaLoStd			* 640 x 200, 2 pages, normal arrangement
  grVgaLoPak	gr640x200x16	  640 x 200, 2 pages, packed arrangement
  grVgaMedStd			* 640 x 350, 2 pages, normal arrangement
  grVgaMedOne	gr640x350x16	* 640 x 350, 1 page
  grVgaMedPak			  640 x 350, 2 pages, packed arrangement
  grVgaHiStd	gr640x480x16	* 640 x 480, 1 page
  grSvgaStd	gr800x600x16	+ 800 x 600, 1 page
  grVga256Std	gr320x200x256	  320 x 200, 1 page, 256 colors
  grVgaWdMedStd			  720 x 350, 2 pages, normal arrangement
  grVgaWdMedOne	gr720x350x16	  720 x 350, 1 page
  grVgaWdMedPak			  720 x 350, 2 pages, packed arrangement
  grVgaWdHiStd	gr720x480x16	  720 x 480, 1 page
  gr640x480x256			+ 640 x 480, 256 colors
  gr800x600x256			+ 800 x 600, 256 colors
  gr1024x768x16			+1024 x 768, 16 colors
  gr1024x768x256		+1024 x 768, 256 colors


  NOTE: Only the modes marked with an asterix (*) are standard modes, i.e.
	they are supported by the BGI. Modes marked with a plus (+) require
	the VESA unit and a VESA driver.

  There are several so-called modifications of a graphics mode. The page
  arrangement differs from modification to modification. Normal arrangement
  is necessary for applications using BGI. Packed arrangement is useful
  for applications using the VGA rest memory with the VgaMem unit. One-page
  modes are useful if you need a very large rest memory.

  In chapter Methods 1, you will find more information about graphics mode
  initialization.

function InitGraphics: Boolean;

  InitGraphics initializes the graphics mode specified with a SetGrMode
  call and notifies other modules by the GrNotify chain.
  The function returns true if graphics has been initialized successfully.

procedure CloseGraphics;

  CloseGraphics notifies other modules by the GrNotify chain and close
  the graphics mode, returning to text mode.

procedure SetActivePage(Page: Word);

  This procedure sets the screen page that shall be modified. The parameter
  is assigned to the ActivePage variable. The ActiveSeg variable is set
  to the appropriate real mode memory segment selector.
  Further, SetActivepage calls ActivePageProc for notifying e.g. the BGI.

procedure SetVisualPage(Page: Word);

  This procedure sets the screen page that shall appear on screen. Always
  use this procedure, never Graph.SetVisualPage.


DrawOrigin/ClipRect support


Following routines should be called instead of direct assignments to the
respective data structures.

procedure SetDrawOrigin(x, y: Integer);

  This procedure sets the drawing origin to the given co-ordinates and
  informs other modules by a ClipNotifyProc(gcnUpdOrigin) call.

procedure SetDrawOriginP(var P: TPoint);

  This procedure sets the drawing origin to the given point and informs other
  modules by a ClipNotifyProc(gcnUpdOrigin) call.

procedure SetClipRect(x1, y1, x2, y2: Integer);

  This procedure sets the clipping rectangle to the given co-ordinates and
  informs other modules by a ClipNotifyProc(gcnUpdAll) call.
  NOTE: Turbo Vision notation is used, i.e. x2, y2 are just outside the
	drawing region.

procedure SetClipRectR(var R: TRect);

  This procedure sets the clipping rectangle to the given rectangle and
  informs other modules by a ClipNotifyProc(gcnUpdAll) call.


Screen Page Management, Memory Mapping, and Address Translation


function PageSeg(Page: Word): Word;

  This function returns the pseudo-segment of a screen page.

function PageLinear(Page: Word): LongInt;

  This function returns the linear video memory address of a screen page.

function PageAddr(Page: Word): pointer;

  This function maps the video memory such that the window includes the
  beginning of the given screen page, and returns the memory address.

function SegLinear(Seg: Word): LongInt;

  This function translates a pseudo-segment into a linear video address,
  handling Granularity and MapFlags.

function SegAddr(Seg: Word): pointer;

  This function maps the video memory such that the byte addressed by the
  given pseudo-segment is included in the memory window, and returns a
  memory address.

function LinearToAddress(Linear: LongInt): pointer;

  This function maps the video mode such that the memory window contains
  the byte at the specified linear video address, and returns the memory
  address.

procedure MapToNextWindow;

  This procedure maps the video memory to the next memory window.

procedure MapToPrevWindow;

  This procedure maps the video memory to the previous memory window.


Video Memory Allocation


function ReserveSegs(Size: Integer): LongInt;

  This function reserves adaptor memory. The required size is to be given in
  granularity units (mostly paragraphs [16 bytes]). The pseudo-segment
  which addresses the memory position is returned in the lower word.
  If Size is set to -1, the largest available memory block is reserved.
  The actually reserved block size (in granularity units) is returned in
  the higher word.

function GetFreeSegs: LongInt;

  This function returns the video memory allocation information. Store
  this value before allocating memory if you need to cancel allocated
  memory later by use of SetFreeSegsBack.

procedure SetFreeSegsBack(Segs: LongInt);

  This procedure uses previously stored (see GetFreeSegs) allocation
  information to restore this state, and to cancel allocated video memory.


BIOS Interface


These interface routines need not be called directly.

procedure SetBiosMode(Mode: Byte);

  This procedure initializes a screen mode by a VGA BIOS function call. The
  Mode values are partly device-dependent. Choose...

  $0E	for 640 x 200 x 16
  $10	for 640 x 350 x 16
  $12	for 640 x 480 x 16
  $13	for 320 x 200 x 256

procedure SaveTextMode;

  This procedure saves the current text mode. It can be restored via
  RestoreTextMode. SetBiosMode calls SaveTextMode.

procedure RestoreTextMode;

  This procedure switches back to the text mode active before the first
  SetBiosMode call.

procedure Extend;

  This procedure modifies an initialized graphics mode of 640 coloumns
  width such that it provides 720 coloumns. For initializing the grVgaWdHiStd
  mode, call SetBiosMode($12) and Extend.
  The video memory additionally needed has not necessarily been initialized
  by the BIOS. The result will be pixels set in this region.

procedure InitBiosGraph;		* InitGraphProc, quality 10

  This procedure determines the appropriate standard VGA BIOS mode from
  the Gr mode and calls SetBiosMode. If necessary, it also calls Extend.
  NOTE:  SuperVGA modes are device-dependent and cannot be initialized by
	 InitBiosGraph. If you wish such a graphics mode by InitGraphProc,
	 and don't have a VESA driver, write a procedure of higher "quality".
	 (See pointer/quality conception)

procedure CloseBiosGraph;		* CloseGraphProc, quality 10

  This procedure calls RestoreTextMode, so that graphics is de-initialized.

Gr Temporary Memory


procedure GetTempMem(var Handle: Integer; Size: Word);

  This procedure allocates commonly used Temporary Memory of a certain
  Size. Call GetTempMem with Handle set 0, and a unique handle is returned.
  Using this handle, the memory requirements for a certain purpose can
  be adjusted later. The maximum of all requested sizes stays allocated.

  A pointer to the allocated memory size is available in the TempMem
  variable.

Background Color/Mode


procedure SetBkColor(Color: Word);

  This procedure sets the background color, which is used in an opaque
  graphic output.

procedure SetBkMode(Mode: Integer);

  This procedure sets the background mode to Transparent or Opaque.
  This may cause a notification proc call.


V a r i a b l e s


* Parameters of the graphics mode (set by SetGrMode)

  GrMode	Word	Gr mode (grXXXX, parameter of SetGrMode)
  SavedTextMode	Byte	BIOS number of the previous text mode

  SizeX		Word	Horizontal pixel count (e.g. 640)
  SizeY		Word	Vertical piexl count (e.g. 480)

  Page0Seg	Word	Pseudo-segment address of page 0
  Free0Seg	Word	Pseudo-segment address of free block 0
  Page1Seg	Word	Pseudo-segment address of page 1
  Free1Seg	Word	Pseudo-segment address of free block 1
  EndSeg	Word	Pseudo-segment address of graphics memory end

  GrFlags	Word	A combination of the following flags:

			Flag	Description
			  
			gf16	Indicates a 16-color mode.
			gf256	Indicates a 256-color mode.
			gfMap	Indicates that the mode requires mapping.

  ScreenF	Word	Aspect factor * 10000
  RealBytesPerLine	Number of bytes in one pixel row
		Word
  Granularity	Byte	Pseudo-segment granularity (left-shift count)
  MapFlags	Byte	1 indicates compatibility mapping mode
			(pseudo-segments start at $A000, and not at 0)

* Current graphics parameters

  ActivePage	Word	Number of active screen page (0 or 1)
  ActiveSeg	Word	Active screen page pseudo-segment address
  BytesPerLine	Word	Number of bytes in one pixel row
  GrActive	Boolean	true, if graphics has been initialized

* Video Memory Mapping support

  WindowSize	Word	Size of a memory window in bytes, zero if 64K
  OffsetMask	Word    WindowSize minus 1
  GransPerWindow Word	Number of mapping-granularity units per memory window
  MapGranRight	Byte	logarithmus dualis of the mapping-granularity unit
			(shift count)
  MapGranLeft	Byte	16 minus MapGranRight
  WindowNum	Word	Position of the current memory window in
			mapping-granularity units
  WindowAddr	pointer	Pointer to the screen memory

  NOTE: Mapping-granularity units do not necessarily match the
	pseudo-segment Granularity.

* Shared additional parameters

  DrawOrigin	TPoint	Drawing origin of higher graphical routines
  ClipRect	TRect	Clipping rectangle for graphical routines
  BkMode	Integer	Background mode (Opaque or Transparent)
  BkColor	Word	Background color

* Gr Temporary Memory

  TempUsed	Word	Number of used Temporary Memory handles
  TempHandles	array	Requested sizes, indexed by the handle
		of Word
  TempMem	pointer	Address of the Temporary Memory
  TempMemSize	Word	Currently allocated Temporary Memory size

* MetaGraph support

  MetaState	Word	Drawing and/or recording of graphics
  MetaClipRect	TRect	Global clipping rectangle during meta output
  MetaOrigin	TRect	Global draw origin during meta output

* Pointer/quality conception

  UserXX	pointer	Freely available pointers, intended for commonly
			used graphical routines.
  QualityXX	Byte	Quality-indicating bytes of the respective pointers.

* Segment selectors for version 6.0

  Seg0040	Word	Contains the value $0040.
  SegA000	Word	Contains the value $A000.
  SegB000	Word	Contains the value $B000.
  SegB800	Word	Contains the value $B800.

* Storage of VGA registers

  UserRegArea	array	Data area for register storage
		of Byte


M e t h o d s


1 Graphics Mode Initialization


  After setting a graphics mode by Gr.SetGrMode, you have several
  possibilities to initialize the adaptor.

  You should rather use the high-level InitGraphics routine than the
  following methods.

  (a) Graph.InitGraph	Call this procedure if you want to use the Graph unit
			for graphical output. Pay attention to using the
			appropriate drive/mode values.
  (b) BGI.InitBgiGraph	This procedure calls Graph.InitGraph and automatically
			uses the right value, which is determined from the
			set Gr mode.
  (c) Gr.SetBiosMode	Call this procedure if you want to initialize a
			graphics mode that is supported by your VGA BIOS.
			The required parameter is dependent from your
			adaptor card (non-standard modes).
  (d) Gr.InitBiosGraph	This procedure calls Gr.SetBiosMode and automatically
			uses the appropriate parameter if a standard mode
			is set.
  (e) Direct access	Use system-dependent direct access to your adaptor
			card to initialize graphics modes which are not
			supported by the adaptor's BIOS.
  (f) UserParams(0);	Use these instructions for initialization the
      InitGraphProc;	graphics appropriately to the requirements of the
			installed software modules.
			(See pointer/quality conception.)

2 Switching Back to Text Mode


  You should use the high-level CloseGraphics routine instead of one of
  the following methods.

  (a) Graph.CloseGraph
  (b) BGI.CloseBgiGraph
  (c) Gr.RestoreTextMode
  (d) Gr.CloseBiosGraph
  (e) Again direct access
  (f) UserParams(0); CloseGraphProc;

3 Chaining up Graphic Modules to the Notification


The GR unit supports a graphic notification chain, in which other units
can link procedures, which will be called on certain events.

For more information on notification chains, read the section
"Notification Chain Conception", and the GrNotifyProc documentation.


P o i n t e r / Q u a l i t y   C o n c e p t i o n


The Gr unit provides a certain number of freely available pointers, which
are to store addresses of far-coded routines, so that program modules can
make use of certain services without knowing the module that provides these
services.

Most of these pointers are still unused, so that Gr does not know the
calling scheme of the respective routines. Gr's initialization part puts
a dummy routine, which takes the routine's parameters from the stack, in
all UserXX pointers. Therefore, the number of parameter words must be given
in the AX register when calling. If you want to call a user routine from
Pascal, use the macro UserParams(Count: Word).

Gr provides a mechanism with which it is possible for multiple module to
provide routines for the same purpose, from which only the "best" is
installed, independently from the order in the uses-unit list.

Each pointer UserXX has got a quality-indicating byte QualityXX. If the
initialization parts of the modules want to install their routines, they are
to check whether they have got a higher quality than these previously
installed.

Some of the pointers are already reserved. In Gr, alias identifiers
(var ... absolute UserXX) are defined, often as procedural variables, so that
you can easily access them from pascal programming level.

UserXX	Alias           Service					Supporter(s)
      
User00	ExtSave         MetaGraph - Recording [external]	MetaGr
User01	LineProc        Exported Line Drawing Routine		MetaGr, BGI
User02	ClipNotifyProc	Clipping Notification			BGI
User03	InitGraphProc	Initialize Graphics by GrMode		BGI, Gr
User04	CloseGraphProc	De-initialize Graphics			BGI, Gr
User05	ActivePageProc	Set active page by ActivePage		BGI
User06  ChParamsProc	Change Graphics Parameters		MetaGr, BGI
User07	GrNotifyProc	Graphics Notification Chain		MyMouse, VgaMem
User08	procedure	Video Memory Mapping procedure		Gr, Vesa
User09	SetDispStartProc  Set the Display start                 Gr, Vesa

The "Supporter" column shows the units which install this service in the
descending order of the qualities.

Example


  Let's assume you are using a graphical user interface, which uses the
  MetaGraph unit for maximal performance instead of the Graph unit, for
  your applications. Of course, Graph is not initialized then.
  Now you insert an element which requires the Graph unit into the GUI.
  You will just have to insert the BGI unit in a USES list (this unit links
  the Graph unit routines with the Gr unit conventions).
  BGI's Init- and CloseGraphProc have a higher quality than Gr's ones, so
  that - without any code modifications - the graphics is now initialized
  by a BGI call rather than a VGA BIOS call, and you can use your BGI
  element.

Detailed Pointer Services Documentation


User00	ExtSave         MetaGraph - Recording [external]	MetaGr

  This routine is used for recording graphics parameters for the metafile
  conception. It must be called within assembler routines and has got a
  very special calling scheme.
  This routine is described in detail in the MetaGraph documentation.

User01	LineProc        Exported Line Drawing Routine		MetaGr, BGI

  This routine is used for drawing a line. It is used by MyFonts for
  drawing scalable fonts.
  The BGI unit provides such a line routines. We recommend the use of the
  MetaGraph unit.

User02	ClipNotifyProc	Clipping Notification			BGI

  This routine is used for informing other modules, that the clipping
  rectangle or the drawing origin has changed, and for changing the
  clipping mode of such modules.
  ClipNotifyProc has got one parameter. Use the following gcnXXXX constants
  for that.

  Parameter	  Description
    
  (commands)
  gcnUpdAll	  Adapts the module's clipping to the new parameters.
  gcnUpdOrigin	  Adapts the module's clipping to the new drawing origin.

  (change the clipping mode)
  gcnStopUpd	  Stops the automatical adaption.
  gcnContUpd	  Continues the automatical adaption.
  gcnHaltUpd	  Halts the automatical adaption.
  gcnStartUpd	  Begins the automatical adaption.
  gcnUpdOnReq	  Sets a special mode, in which the commands directly
		  adapt the module's clipping.

  The BGI unit uses the clipping notification, so that it doesn't need to
  adapt Graph's clipping mechanism to the parameters at every graphical
  operation, which takes too much time.

  ClipNotifyProc is called by the routines SetDrawOrigin, SetDrawOriginP,
  SetClipRect, and SetClipRectR.

User03	InitGraphProc	Initialize Graphics by GrMode		BGI, Gr

  This routine is used for graphics initialization, after the Gr mode has
  been set. It returns true if it was successful.

User04	CloseGraphProc	De-initialize Graphics			BGI, Gr

  This routine is used to de-initialize graphics mode and to return to
  text mode.

User05	ActivePageProc	Set active page by ActivePage		BGI

  This routine is used to set the active screen page of another module to
  the value of the ActivePage variable.

User06  ChParamsProc	Change Graphics Parameters		MetaGr, BGI

  This routine is used to change graphics parameters module-independently.
  The first parameter specifies the parameter and the actionto be performed,
  and the second one specifies a buffer. The function returns the buffer size
  required.

  Value		Parameter/Action				Type
      
  gcpColor	Current color					Word
  gcpLineStyle	Current line style (dependent from module)	???
  gcpSolidThLn  Sets a solid line of a certain thickness	Word

  gcpGetSize    Determines the buffer size.
  gcpGetParams  Puts the parameter in the buffer.
  gcpSetParams	Reads the parameter from the buffer.

User07	GrNotifyProc	Graphics Notification Chain		MyMouse, VgaMem

  This routine is an instance of the notification chain conception
  (see there).

  The following messages may occur:

  Notice	    Sender	      Event
      
  gnpInitGraphics   Gr.InitGraphics   after having successfully initialized
				      graphics
  gnpCloseGraphics  Gr.CloseGraphics  before graphics is closed
  gnpBkMode	    Gr.SetBkMode      after BkMode change

  Graphics modules can react to these messages in order to change their
  behaviour.

User08	procedure	Video Memory Mapping procedure		Gr, Vesa

  This is a low-level procedure, which is called in order to map a
  certain video memory region into the "visible" memory window.
  The procedure has a very special call scheme.

  In:	BH = 00
	DX = Address in mapping-granularity units
  Out:	AL = 4Fh if function supported
	AH = 00h if successful
	All other registers can be destroyed.

  Normally, you will not need to call this procedure directly, or
  provide one on your own.

User09	SetDispStartProc  Set the Display start                 Gr, Vesa

  This routine sets the display start to the given linear address.
  It is defined by Gr to support VGA devices, and redefined by Vesa
  to support VESA-compatible SuperVGA devices.


N o t i f i c a t i o n   C h a i n   C o n c e p t i o n


The notification chain conception is used for notify modules of graphic
actions.

A notification chain is a chain of notification functions of type
TNotifyProc. You will implement such a function if a module has to react
to a certain notice. With Gr.InstallNotifyProc, you can install a function
to a chain; with Gr.UninstallProc, you can remove it from the chain. The
function is inserted into the chain according to its quality.

The default behaviour of a notification function is provided by
Gr.DefaultNotify. A notification function must handle the notices it needs
to and then call DefaultNotify.

Parameter	Description
  
Notice		The notice specified in the function call.
Info		Additional information specified in the funtion call.
ThisProc	The notification function.
NextProc	A global variable of TNotifyProc type, which belongs to
		the notification function.
Quality		The quality of the notification function.


D e t a i l s


1  Difference between BytesPerLine and RealBytesPerLine


   Certain programs allocate VGA rest memory and draw any graphics into
   that screen buffer. Therefore, they change the ActiveSeg and BytesPerLine
   variables. So, graphical routines will use BytesPerLine and not
   RealBytesPerLine.
   A mouse cursor may not be drawn into that buffer but still appear on
   the real screen. A mouse driver will use RealBytesPerLine and not
   BytesPerLine.

2  Exotic graphics modes


   If your graphics adapter supports some exotic graphic modes that are not
   provided by SetGrMode, you can set the Gr parameters manually.

   Defining a mapping function, you can make GR support as much video memory
   as you need. Use granularities greater than 16 bytes in order to allow
   access to wider address spaces.

3  Supporting a non-VESA SuperVGA adaptor


   If your adaptor card supports a SVGA mode and you wish to initialize
   graphics by an InitGraphics call, use a unit like the following:

     unit MySvga;

     interface
     implementation

     uses Gr;

     const
       qInitSvgaGraph = 20;		{ <-- quality, greater than 10 }

     procedure InitSvgaGraph; far;
     begin
       If GrMode = grSvgaStd
	 then SetBiosMode($52)		{ <-- BIOS mode number }
	 else InitBiosGraph
     end;

     begin
       if qInitSvgaGraph > qInitGraphProc then Begin
	 qInitGraphProc := qInitSvgaGraph;
	  InitGraphProc :=  InitSvgaGraph
       End
     end.


   NOTE: Using the VESA unit on a VESA-compatible device, you need not
	 define a method on your own to switch to the mode. Moreover,
	 this unit provides access to any other mode, as 1024x768, or
	 the 256-color modes.

