!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_tree
  use gildas_def
  !--------------------------------------------------------------------
  ! GTV tree support.
  ! For portability, SAVE Fortran variables (or their common) which are
  ! target of SIC variables.
  !--------------------------------------------------------------------
  !
  ! GTV tree key-symbols
  character(len=1), parameter :: dir_sep  = '<'      ! Directory separator
  character(len=1), parameter :: dir_root = dir_sep  ! Root directory
  character(len=1), parameter :: dir_top  = '^'      ! Shortcut for top-level dir
  character(len=2), parameter :: dir_up   = '..'     ! Upper directory
  !
  integer(kind=4), parameter :: segname_length=32
  integer(kind=4), parameter :: gtvpath_length=128
  !
  ! Segment identifiers
  integer(kind=4), parameter :: seg_points = -1    ! Points (dots)
  integer(kind=4), parameter :: seg_poly   = -2    ! Polyline
  integer(kind=4), parameter :: seg_image  = -3    ! Image
  integer(kind=4), parameter :: seg_hfpoly = -4    ! Horizontal filled polygon
  integer(kind=4), parameter :: seg_vfpoly = -5    ! Vertical filled polygon
  integer(kind=4), parameter :: seg_pencol = -6    ! Pen colors
  integer(kind=4), parameter :: seg_lutcol = -7    ! Lut colors
  !
  integer(kind=4), parameter :: nrdim=8192/2
  !
end module gtv_tree
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_segatt
  !--------------------------------------------------------------------
  ! Segment attributes
  !--------------------------------------------------------------------
  ! Visibility
  integer(kind=4), parameter :: att_vis=0
  integer(kind=4), parameter :: att_dash=1      ! Internal id for dash style
  integer(kind=4), parameter :: att_weight=2    ! Internal id for weight
  integer(kind=4), parameter :: att_colour=3    ! Internal id for colour
  integer(kind=4), parameter :: att_depth=4     ! Internal id for depth
  !
  integer(kind=4), parameter :: min_dash=1
  integer(kind=4), parameter :: max_dash=8
  integer(kind=4), parameter :: min_weight=1
  integer(kind=4), parameter :: max_weight=5
  !
  integer(kind=4), parameter :: min_depth=1
  integer(kind=4), parameter :: max_depth=40
  !
  ! The following array provides the possible widths in cm. These data
  ! are redundant because of the technic used for the other protocols
  ! (X and PS), but isn't it better to show it directly?
  real(4), parameter :: graisse(max_weight) =  &
             (/ 0.015, 0.030, 0.045, 0.075, 0.120 /)
  real(4), parameter :: onoff(4,2:max_dash) = reshape((/  &
             .250, .200, .250, .200,     &  ! 2
             .025, .100, .025, .100,     &  ! 3
             .250, .200, .075, .200,     &  ! 4
             .500, .400, .500, .400,     &  ! 5
             .500, .200, .075, .200,     &  ! 6
             .500, .200, .250, .200,     &  ! 7
             .100, .150, .100, .150  /), &  ! 8
             (/4,max_dash-1/) )
  real(4), parameter :: onofflen(2:max_dash) = &
             (/ .900, .250, .725, 1.800, .975, 1.150, .500 /)
  !
end module gtv_segatt
!
module gtv_colors
  use gtv_segatt
  !
  ! <0:           user colors (LUT /PEN)
  ! >0:           standard colors
  ! >X11_ncolors: special color codes
  !
  integer(kind=4), parameter :: X11_ncolors=142            ! Number of fixed colors
  integer(kind=4), parameter :: pen_ncolors=X11_ncolors+3  ! GTV provides 3 more special "colors"
  !
  integer(kind=4), parameter :: pen_color_black=7
  integer(kind=4), parameter :: pen_color_white=139
  integer(kind=4), parameter :: pen_color_background=X11_ncolors+1
  integer(kind=4), parameter :: pen_color_foreground=X11_ncolors+2
  integer(kind=4), parameter :: pen_color_negative=X11_ncolors+3
  !
  integer(kind=4), parameter :: colname_length=19
  character(len=colname_length), parameter :: pen_colors(pen_ncolors) =  (/  &
    'ALICE_BLUE         ','ANTIQUE_WHITE      ','AQUAMARINE         ',  &
    'AZURE              ','BEIGE              ','BISQUE             ',  &
    'BLACK              ','BLANCHED_ALMOND    ','BLUE               ',  &
    'BLUE_VIOLET        ','BROWN              ','BURLYWOOD          ',  &
    'CADET_BLUE         ','CHARTREUSE         ','CHOCOLATE          ',  &
    'CORAL              ','CORNFLOWER         ','CORNSILK           ',  &
    'CRIMSON            ','CYAN               ','DARK_BLUE          ',  &
    'DARK_CYAN          ','DARK_GOLDENROD     ','DARK_GREEN         ',  &
    'DARK_GREY          ','DARK_KHAKI         ','DARK_MAGENTA       ',  &
    'DARK_OLIVE_GREEN   ','DARK_ORANGE        ','DARK_ORCHID        ',  &
    'DARK_RED           ','DARK_SALMON        ','DARK_SEA_GREEN     ',  &
    'DARK_SLATE_BLUE    ','DARK_SLATE_GREY    ','DARK_TURQUOISE     ',  &
    'DARK_VIOLET        ','DEEP_PINK          ','DEEP_SKY_BLUE      ',  &
    'DIM_GREY           ','DODGER_BLUE        ','FIREBRICK          ',  &
    'FLORAL_WHITE       ','FOREST_GREEN       ','GAINSBORO          ',  &
    'GHOST_WHITE        ','GOLD               ','GOLDENROD          ',  &
    'GREEN              ','GREEN_YELLOW       ','GREY               ',  &
    'HONEYDEW           ','HOT_PINK           ','INDIAN_RED         ',  &
    'INDIGO             ','IVORY              ','KHAKI              ',  &
    'LAVENDER           ','LAVENDER_BLUSH     ','LAWN_GREEN         ',  &
    'LEMON_CHIFFON      ','LIGHT_BLUE         ','LIGHT_CORAL        ',  &
    'LIGHT_CYAN         ','LIGHT_GOLDENROD    ','LIGHT_GREEN        ',  &
    'LIGHT_GREY         ','LIGHT_PINK         ','LIGHT_SALMON       ',  &
    'LIGHT_SEA_GREEN    ','LIGHT_SKY_BLUE     ','LIGHT_SLATE_GREY   ',  &
    'LIGHT_STEEL_BLUE   ','LIGHT_YELLOW       ','LIME_GREEN         ',  &
    'LINEN              ','MAGENTA            ','MAROON             ',  &
    'MEDIUM_AQUAMARINE  ','MEDIUM_BLUE        ','MEDIUM_ORCHID      ',  &
    'MEDIUM_PURPLE      ','MEDIUM_SEA_GREEN   ','MEDIUM_SLATE_BLUE  ',  &
    'MEDIUM_SPRING_GREEN','MEDIUM_TURQUOISE   ','MEDIUM_VIOLET_RED  ',  &
    'MIDNIGHT_BLUE      ','MINT_CREAM         ','MISTY_ROSE         ',  &
    'MOCCASIN           ','NAVAJO_WHITE       ','NAVY_BLUE          ',  &
    'OLD_LACE           ','OLIVE              ','OLIVE_DRAB         ',  &
    'ORANGE             ','ORANGE_RED         ','ORCHID             ',  &
    'PALE_GOLDENROD     ','PALE_GREEN         ','PALE_TURQUOISE     ',  &
    'PALE_VIOLET_RED    ','PAPAYA_WHIP        ','PEACH_PUFF         ',  &
    'PERU               ','PINK               ','PLUM               ',  &
    'POWDER_BLUE        ','PURPLE             ','REBECCA_PURPLE     ',  &
    'RED                ','ROSY_BROWN         ','ROYAL_BLUE         ',  &
    'SADDLE_BROWN       ','SALMON             ','SANDY_BROWN        ',  &
    'SEA_GREEN          ','SEASHELL           ','SIENNA             ',  &
    'SILVER             ','SKY_BLUE           ','SLATE_BLUE         ',  &
    'SLATE_GREY         ','SNOW               ','SPRING_GREEN       ',  &
    'STEEL_BLUE         ','TAN                ','TEAL               ',  &
    'THISTLE            ','TOMATO             ','TURQUOISE          ',  &
    'VIOLET             ','WEB_GREEN          ','WEB_GREY           ',  &
    'WEB_MAROON         ','WEB_PURPLE         ','WHEAT              ',  &
    'WHITE              ','WHITE_SMOKE        ','YELLOW             ',  &
    'YELLOW_GREEN       ',                                              &
    ! Special colors
    'BACKGROUND         ','FOREGROUND         ','NEGATIVE           '  /)
  !
  integer(kind=4), parameter :: X11_rgb(3,X11_ncolors) = reshape( (/  &
    240,  248,  255,  &  ! ALICE_BLUE
    250,  235,  215,  &  ! ANTIQUE_WHITE
    127,  255,  212,  &  ! AQUAMARINE
    240,  255,  255,  &  ! AZURE
    245,  245,  220,  &  ! BEIGE
    255,  228,  196,  &  ! BISQUE
      0,    0,    0,  &  ! BLACK
    255,  235,  205,  &  ! BLANCHED_ALMOND
      0,    0,  255,  &  ! BLUE
    138,   43,  226,  &  ! BLUE_VIOLET
    165,   42,   42,  &  ! BROWN
    222,  184,  135,  &  ! BURLYWOOD
     95,  158,  160,  &  ! CADET_BLUE
    127,  255,    0,  &  ! CHARTREUSE
    210,  105,   30,  &  ! CHOCOLATE
    255,  127,   80,  &  ! CORAL
    100,  149,  237,  &  ! CORNFLOWER
    255,  248,  220,  &  ! CORNSILK
    220,   20,   60,  &  ! CRIMSON
      0,  255,  255,  &  ! CYAN
      0,    0,  139,  &  ! DARK_BLUE
      0,  139,  139,  &  ! DARK_CYAN
    184,  134,   11,  &  ! DARK_GOLDENROD
      0,  100,    0,  &  ! DARK_GREEN
    169,  169,  169,  &  ! DARK_GREY
    189,  183,  107,  &  ! DARK_KHAKI
    139,    0,  139,  &  ! DARK_MAGENTA
     85,  107,   47,  &  ! DARK_OLIVE_GREEN
    255,  140,    0,  &  ! DARK_ORANGE
    153,   50,  204,  &  ! DARK_ORCHID
    139,    0,    0,  &  ! DARK_RED
    233,  150,  122,  &  ! DARK_SALMON
    143,  188,  143,  &  ! DARK_SEA_GREEN
     72,   61,  139,  &  ! DARK_SLATE_BLUE
     47,   79,   79,  &  ! DARK_SLATE_GREY
      0,  206,  209,  &  ! DARK_TURQUOISE
    148,    0,  211,  &  ! DARK_VIOLET
    255,   20,  147,  &  ! DEEP_PINK
      0,  191,  255,  &  ! DEEP_SKY_BLUE
    105,  105,  105,  &  ! DIM_GREY
     30,  144,  255,  &  ! DODGER_BLUE
    178,   34,   34,  &  ! FIREBRICK
    255,  250,  240,  &  ! FLORAL_WHITE
     34,  139,   34,  &  ! FOREST_GREEN
    220,  220,  220,  &  ! GAINSBORO
    248,  248,  255,  &  ! GHOST_WHITE
    255,  215,    0,  &  ! GOLD
    218,  165,   32,  &  ! GOLDENROD
      0,  255,    0,  &  ! GREEN
    173,  255,   47,  &  ! GREEN_YELLOW
    190,  190,  190,  &  ! GREY
    240,  255,  240,  &  ! HONEYDEW
    255,  105,  180,  &  ! HOT_PINK
    205,   92,   92,  &  ! INDIAN_RED
     75,    0,  130,  &  ! INDIGO
    255,  255,  240,  &  ! IVORY
    240,  230,  140,  &  ! KHAKI
    230,  230,  250,  &  ! LAVENDER
    255,  240,  245,  &  ! LAVENDER_BLUSH
    124,  252,    0,  &  ! LAWN_GREEN
    255,  250,  205,  &  ! LEMON_CHIFFON
    173,  216,  230,  &  ! LIGHT_BLUE
    240,  128,  128,  &  ! LIGHT_CORAL
    224,  255,  255,  &  ! LIGHT_CYAN
    250,  250,  210,  &  ! LIGHT_GOLDENROD
    144,  238,  144,  &  ! LIGHT_GREEN
    211,  211,  211,  &  ! LIGHT_GREY
    255,  182,  193,  &  ! LIGHT_PINK
    255,  160,  122,  &  ! LIGHT_SALMON
     32,  178,  170,  &  ! LIGHT_SEA_GREEN
    135,  206,  250,  &  ! LIGHT_SKY_BLUE
    119,  136,  153,  &  ! LIGHT_SLATE_GREY
    176,  196,  222,  &  ! LIGHT_STEEL_BLUE
    255,  255,  224,  &  ! LIGHT_YELLOW
     50,  205,   50,  &  ! LIME_GREEN
    250,  240,  230,  &  ! LINEN
    255,    0,  255,  &  ! MAGENTA
    176,   48,   96,  &  ! MAROON
    102,  205,  170,  &  ! MEDIUM_AQUAMARINE
      0,    0,  205,  &  ! MEDIUM_BLUE
    186,   85,  211,  &  ! MEDIUM_ORCHID
    147,  112,  219,  &  ! MEDIUM_PURPLE
     60,  179,  113,  &  ! MEDIUM_SEA_GREEN
    123,  104,  238,  &  ! MEDIUM_SLATE_BLUE
      0,  250,  154,  &  ! MEDIUM_SPRING_GREEN
     72,  209,  204,  &  ! MEDIUM_TURQUOISE
    199,   21,  133,  &  ! MEDIUM_VIOLET_RED
     25,   25,  112,  &  ! MIDNIGHT_BLUE
    245,  255,  250,  &  ! MINT_CREAM
    255,  228,  225,  &  ! MISTY_ROSE
    255,  228,  181,  &  ! MOCCASIN
    255,  222,  173,  &  ! NAVAJO_WHITE
      0,    0,  128,  &  ! NAVY_BLUE
    253,  245,  230,  &  ! OLD_LACE
    128,  128,    0,  &  ! OLIVE
    107,  142,   35,  &  ! OLIVE_DRAB
    255,  165,    0,  &  ! ORANGE
    255,   69,    0,  &  ! ORANGE_RED
    218,  112,  214,  &  ! ORCHID
    238,  232,  170,  &  ! PALE_GOLDENROD
    152,  251,  152,  &  ! PALE_GREEN
    175,  238,  238,  &  ! PALE_TURQUOISE
    219,  112,  147,  &  ! PALE_VIOLET_RED
    255,  239,  213,  &  ! PAPAYA_WHIP
    255,  218,  185,  &  ! PEACH_PUFF
    205,  133,   63,  &  ! PERU
    255,  192,  203,  &  ! PINK
    221,  160,  221,  &  ! PLUM
    176,  224,  230,  &  ! POWDER_BLUE
    160,   32,  240,  &  ! PURPLE
    102,   51,  153,  &  ! REBECCA_PURPLE
    255,    0,    0,  &  ! RED
    188,  143,  143,  &  ! ROSY_BROWN
     65,  105,  225,  &  ! ROYAL_BLUE
    139,   69,   19,  &  ! SADDLE_BROWN
    250,  128,  114,  &  ! SALMON
    244,  164,   96,  &  ! SANDY_BROWN
     46,  139,   87,  &  ! SEA_GREEN
    255,  245,  238,  &  ! SEASHELL
    160,   82,   45,  &  ! SIENNA
    192,  192,  192,  &  ! SILVER
    135,  206,  235,  &  ! SKY_BLUE
    106,   90,  205,  &  ! SLATE_BLUE
    112,  128,  144,  &  ! SLATE_GREY
    255,  250,  250,  &  ! SNOW
      0,  255,  127,  &  ! SPRING_GREEN
     70,  130,  180,  &  ! STEEL_BLUE
    210,  180,  140,  &  ! TAN
      0,  128,  128,  &  ! TEAL
    216,  191,  216,  &  ! THISTLE
    255,   99,   71,  &  ! TOMATO
     64,  224,  208,  &  ! TURQUOISE
    238,  130,  238,  &  ! VIOLET
      0,  128,    0,  &  ! WEB_GREEN
    128,  128,  128,  &  ! WEB_GREY
    127,    0,    0,  &  ! WEB_MAROON
    127,    0,  127,  &  ! WEB_PURPLE
    245,  222,  179,  &  ! WHEAT
    255,  255,  255,  &  ! WHITE
    245,  245,  245,  &  ! WHITE_SMOKE
    255,  255,    0,  &  ! YELLOW
    154,  205,   50   &  ! YELLOW_GREEN
    /), (/ 3,X11_ncolors /) )
  !
end module gtv_colors
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_bitmap_parameters
  !--------------------------------------------------------------------
  ! Bitmap images parameters
  !--------------------------------------------------------------------
  !
  ! Size of integers the bitmaps are computed in. If you are willing to
  ! change this, you also have to change things from the C side (see
  ! x_affiche_image and subsequent routines)
  integer(kind=4), parameter :: bitmap_depth=2  ! Depth of bitmaps
  integer(kind=2*bitmap_depth) :: bitmap_dynamic_max  ! Maximum number of levels
  !
  integer(kind=4), parameter :: scale_lin=1  ! Linear
  integer(kind=4), parameter :: scale_log=2  ! Logarithmic
  integer(kind=4), parameter :: scale_equ=3  ! Equalised
  integer(kind=4), parameter :: scale_lup=4  ! Lupton (for RGB images only)
  !
end module gtv_bitmap_parameters
!
module gtv_types
  use gildas_def
  use gtv_bitmap_parameters
  use gtv_segatt
  use gtv_tree
  !---------------------------------------------------------------------
  !   Derived types and associated parameters. No variables or instances
  ! here.
  !---------------------------------------------------------------------
  !
  type :: gt_segment_general
    character(len=segname_length) :: name
    real(kind=4)                  :: minmax(4)
    logical                       :: visible
  end type gt_segment_general
  !
  type :: gt_segment_attr
    integer(kind=4) :: dash    ! [code]
    real(kind=4)    :: weight  ! [cm]   Pen weight
    integer(kind=4) :: colour  ! [code] GTV internal colour code
    integer(kind=4) :: depth   ! [1-3]
  end type gt_segment_attr
  !
  type :: greg_values
    ! Used GREG saved values (might certainly be reduced). The sequence
    ! is required since the whole block of values is attached to the
    ! directory, and set from/put to the corresponding Greg global
    ! variables. One instance has a length of 26 words now: it must be
    ! the same for the buffer size in the routine 'greg_user' in GreG.
    !
    ! LX1, LX2, LY1, LY2 are a property of top-directories (e.g. <GREG
    ! is landscape and <FOO is portrait, and changing from one to another
    ! ensures Greg always knows the correct plot page).
    sequence
    real(kind=8) :: gux1, gux2  !  1- 4 user_xmin, user_xmax
    real(kind=8) :: guy1, guy2  !  5- 8 user_ymin, user_ymax
    real(kind=8) :: gux, guy    !  9-12 Conversion factor
    real(kind=8) :: lux, luy    ! 13-16 Logarithmique conversion offset
    logical      :: xlog, ylog  ! 17-18 X and Y axes log status
    real(kind=4) :: gx1, gx2    ! 19-20 X coordinates of the box
    real(kind=4) :: gy1, gy2    ! 21-22 Y coordinates of the box
    real(kind=4) :: lx1, lx2    ! 23-24 Plot X physical limits
    real(kind=4) :: ly1, ly2    ! 25-26 Plot Y physical limits
  end type greg_values
  !
  type :: polyline_buffer  ! Should use type 'gt_polyline'
    integer(kind=4) :: n
    real(kind=4) :: x(nrdim)  ! X, World units
    real(kind=4) :: y(nrdim)  ! Y, World units
  end type polyline_buffer
  !
  type :: gt_polyline
    integer(kind=4)       :: n                 ! Number of points
    real(kind=4), pointer :: x(:) => null()    ! X coordinates
    real(kind=4), pointer :: y(:) => null()    ! Y coordinates
    type(gt_lut), pointer :: penlut => null()  ! PENLUT to be used
  end type gt_polyline
  !
  ! Colormap description
  type :: gt_lut
    integer(kind=4) :: size=0              ! Size. Last value is blanking.
    integer(kind=address_length) :: xlut=0 ! Pointer the equivalent LUT for X window
    ! Data
    real(kind=4), allocatable :: r(:)    ! Red
    real(kind=4), allocatable :: g(:)    ! Green
    real(kind=4), allocatable :: b(:)    ! Blue
    real(kind=4), allocatable :: hue(:)  ! Hue
    real(kind=4), allocatable :: sat(:)  ! Saturation
    real(kind=4), allocatable :: val(:)  ! Value
  end type gt_lut
  !
  ! Image type for original (not resampled) GTV images: data
  type :: gt_image_data
    ! Data
    integer(kind=index_length) :: taille(2)                     ! Image size
    real(kind=4), pointer      :: values(:,:)                   ! True values
    integer(kind=2*bitmap_depth), allocatable :: eqvalues(:,:)  ! Equalized values
    ! Display
    real(kind=4)    :: blank(3)    ! Blanking
    real(kind=4)    :: cuts(2)     ! Low and high cuts of image
    real(kind=4)    :: extrema(2)  ! Actual extrema of image
  end type gt_image_data
  !
  ! Image type for original (not resampled) GTV images: descriptor + data
  type :: gt_image
    logical :: isrgb  ! Indexed image or RGB?
    ! Descriptor
    real(kind=4)    :: conv(6)              ! Conversion formula for image
    real(kind=4)    :: limits(4)            ! User limits of the image
    real(kind=4)    :: position(4)          ! Centimetric position of the image
    integer(kind=4) :: scaling              ! Scaling mode
    ! Specific to indexed images
    type(gt_lut), pointer :: lut => null()  ! LUT to be used (if indexed image)
    ! Specific to RGB images
    real(kind=4)    :: scaling_lup_b        ! Beta parameter for Lupton scaling mode
    ! Data
    type(gt_image_data) :: r  ! True values (indexed image or R value)
    type(gt_image_data) :: g  ! True G values (if RGB image). Allocatable?
    type(gt_image_data) :: b  ! True B values (if RGB image). Allocatable?
    ! Linked list
    type(gt_image), pointer :: next => null()  ! Next image in the linked list
  end type gt_image
  !
  type :: gt_segment_head
    ! Generic attributes
    type(gt_segment_general) :: gen
    type(gt_segment_attr)    :: attr         ! Pen attributes
    type(gt_lut), pointer    :: lut=>null()  ! Pointer to the LUT to be used by this segment
    !
  end type gt_segment_head
  !
  ! Segment data
  type :: gt_segment_data
    ! Kind
    integer(kind=4) :: kind  ! Kind of data stored here
    ! Data
    type(gt_polyline)       :: poly             ! Polylines or polygons
    type(gt_lut)            :: lut              ! Image LUT or pen LUT
    type(gt_image), pointer :: image => null()  ! Images
    ! Linked list:
    !   a GTV segment can be a collection of different data
    type(gt_segment_data), pointer :: nextdata => null()  ! Pointer to next block of data
  end type gt_segment_data
  !
  ! Polyline type for polyline and polygon segments: header+data
  type :: gt_segment
    ! Header
    type(gt_segment_head) :: head
    ! Data
    type(gt_segment_data), pointer :: data
    ! Tree
    type(gt_directory), pointer :: father  ! Parent directory
    ! Chain
    type(gt_segment), pointer :: nextseg  ! Next leaf in the directory
  end type gt_segment
  !
  ! X specific attributes for directories
  type :: gt_directory_x
    integer(kind=4)              :: curwin      ! Current window
    integer(kind=4)              :: nbwin       ! Number of windows attached
    integer(kind=address_length) :: genv        ! Pointer on the active window
    integer(kind=address_length) :: genv_array  ! Pointer on the table of addresses
  end type gt_directory_x
  !
  type :: gt_directory
    ! Generic attributes
    type(gt_segment_general) :: gen
    ! Directory-specific attributes
    real(kind=4)         :: phys_size(2)  ! Physical paper size
    type(greg_values)    :: val_greg      ! GREG values
    type(gt_directory_x) :: x             ! X specific attributes
    ! Tree
    type(gt_directory), pointer :: ancestor   ! Parent just under the root
    type(gt_directory), pointer :: father     ! Parent directory
    type(gt_directory), pointer :: brother    ! Next brother
    type(gt_directory), pointer :: son_first  ! First son
    type(gt_directory), pointer :: son_last   ! Last son
    ! Segments
    type(gt_segment), pointer :: leaf_first  ! First leaf in the directory
    type(gt_segment), pointer :: leaf_last   ! Last leaf in the directory
    integer(kind=4)           :: segn        ! Number of segments (maximum reached,
                                             ! NOT the actual number). It is used to
                                             ! build a unique name for each segment.
  end type gt_directory
  !
  ! Image type for GTV images resampled (virtual memory or disk)
  type :: gt_bitmap
    integer(kind=bitmap_depth), pointer :: irvalues(:,:)  ! Scaled R values
    integer(kind=bitmap_depth), pointer :: igvalues(:,:)  ! Scaled G values
    integer(kind=bitmap_depth), pointer :: ibvalues(:,:)  ! Scaled B values
    integer(kind=4) :: size(2)      ! Size on the display
    integer(kind=4) :: position(2)  ! Position offset on the display
    real(kind=4)    :: trans(4)     ! Image to display conversion
    !
    type(gt_image), pointer  :: image => null()  ! Backward pointer to the original image
    type(gt_bitmap), pointer :: next => null()   ! Next bitmap, if used in a chained list (see x_output)
  end type gt_bitmap
  !
  ! Variables describing a position or a size in screen units
  type :: x_coordinates
    real(kind=4)     :: x
    character(len=1) :: unitx
    real(kind=4)     :: y
    character(len=1) :: unity
  end type x_coordinates
  !
  ! X output specific variables
  type :: x_output
    ! General subsection
    integer(kind=address_length) :: graph_env=0      ! Window address
    integer(kind=4)              :: number           ! Window number seen by the user
    logical                      :: is_zoom=.false.  ! Is a zoom window?
    character(len=32)            :: name             ! Window name
    type(x_coordinates)          :: geometry         ! Initial window geometry
    type(x_coordinates)          :: position         ! Initial window position
    ! Associated bitmaps subsection
    integer(kind=4)          :: update_status
    type(gt_bitmap), pointer :: bitmap_first => null() ! Chained list of the resampled
    type(gt_bitmap), pointer :: bitmap_last => null()  ! images for the instance
  end type x_output
  !
  ! PS output specific variables
  type :: ps_output
    logical :: encapsulated  ! PS or EPS?
    logical :: fast          ! Fast i.e. use hardware generated lines?
    logical :: exact         ! PS/EPS /EXACT (i.e. use GTV coordinates as is)
  end type ps_output
  !
  ! PNG output specific variables
  type :: png_output
    ! Properties
    logical :: transparency  ! Transparent background (different from the 'black' logical)
    logical :: cropped       ! Should the white margins be kept or not?
    logical :: noblank       ! Should blanked pixels be replaced by background color?
    ! Channels
    integer(kind=4) :: nchan                ! Number of channels (R/G/B/A)
    integer(kind=1), allocatable :: R(:,:)  !
    integer(kind=1), allocatable :: G(:,:)  !
    integer(kind=1), allocatable :: B(:,:)  !
    integer(kind=1), allocatable :: A(:,:)  !
    ! Pen in use in the filler
    integer(kind=1) :: rpen      ! Red intensity of the current pen
    integer(kind=1) :: gpen      ! Green intensity of the current pen
    integer(kind=1) :: bpen      ! Blue intensity of the current pen
    logical         :: negative  ! Negate colors?
    integer(kind=4) :: width     ! Pen width (pixels)
    real(kind=4)    :: xpos      ! Pen current X location
    real(kind=4)    :: ypos      ! Pen current Y location
  end type png_output
  !
  ! SVG output specific variables
  type :: svg_output
    ! Properties
    logical :: cropped       ! Should the white margins be kept or not?
  end type svg_output
  !
  ! Device definition and defaults from gtvdef.
  type :: gt_device
    ! Miscellaneous informations
    integer(kind=4)   :: protocol=0    ! Protocol identifier
    integer(kind=4)   :: ident=0       ! Device identifier
    character(len=64) :: defout        ! Default /OUTPUT terminal device
    integer(kind=4)   :: background    ! 0 Black, 1 White
    ! Initialisation sequences
    integer(kind=4)    :: linit1       !
    character(len=255) :: init1        ! Initialisation sequence in GTOPEN
    character(len=1)   :: pad1         ! Padding which ensures 4-bytes alignment
    integer(kind=4)    :: linit2       !
    character(len=255) :: init2        !
    character(len=1)   :: pad2         !
    ! Device default size in "pixels"
    integer(kind=4) :: px1,px2         ! First and last pixels in X
    integer(kind=4) :: py1,py2         ! First and last pixels in Y
    real(kind=4)    :: rxy             !
    real(kind=4)    :: poff            ! Pixel offset (from int to real axis):
                                       !  0.0 -> pixel #1 runs from 0.0 to 1.0
                                       !  0.5 -> pixel #1 runs from 0.5 to 1.5
    ! Colormap capabilities of the device
    integer(kind=4) :: map_size        ! Size of usable color map
    integer(kind=4) :: map_offset      ! Offset of usable color map
    logical         :: map_color       ! Use colors?
    logical         :: map_static      !
    ! Hardware capabilities
    logical         :: hardw_line_weig ! Hardware can generate weight?
    logical         :: hardw_line_dash ! Hardware can generate dashed?
    logical         :: hardw_cursor    ! Hardware cursor available?
  end type gt_device
  !
  ! Device description
  type :: gt_display
    !
    ! Subsections
    type(gt_device), pointer :: dev  ! Device section (MUST BE FIRST!)
    type(x_output)           :: x    ! X protocol section
    type(ps_output)          :: ps   ! PostScript protocol section
    type(png_output)         :: png  ! PNG protocol section
    type(svg_output)         :: svg  ! SVG protocol section
    !
    ! Miscellanous attributes
    logical :: used=.false.        ! Is the instance currently in use?
    logical :: autorotate=.false.  ! Should rotate the drawing to adapt at most the display?
    logical :: autoscale=.true.    ! Should scale the drawing to adapt at most the display?
    !
    logical         :: tofile  ! Write in a file or terminal?
    integer(kind=4) :: iunit   ! Logical Unit for Output, for devices which require one
    logical         :: opened  ! Is the Output currently opened on Iunit?
    character(len=filename_length) :: file  ! File connected to Iunit, for devices which require one
    !
    integer(kind=4) :: px1,px2     ! Actual instance size in pixels
    integer(kind=4) :: py1,py2     !
    real(kind=4)    :: gx1,gx2     ! Clipping Window in world coordinates.
    real(kind=4)    :: gy1,gy2     !
    !
    integer(kind=4) :: background  ! Actual background color
    logical         :: color       ! A color or grey output?
    !
    real(kind=4) :: totdist        !
    !
    ! Attributes of the pen in current use in this display
    integer(kind=4) :: idashe=1           ! [code] Dashed attribute
    real(kind=4)    :: iweigh=graisse(1)  ! [cm]   Weight attribute
    integer(kind=4) :: icolou=1           ! [code] Colour attribute
  end type gt_display
  !
end module gtv_types
!
module gtv_bitmap
  use gtv_types
  use gtv_bitmap_parameters
  !--------------------------------------------------------------------
  ! Bitmap images
  ! For portability, SAVE Fortran variables which are target of SIC
  ! variables.
  !--------------------------------------------------------------------
  !
  integer, save :: nb_image=0  ! Number of images currently in use
  type(gt_image), pointer :: image_first => null()  ! First image in the linked list
  type(gt_image), pointer :: image_last => null()   ! Last image in the linked list
  !
  ! Support for equalization SIC variables
  integer(kind=4),                        save :: eqnlev    ! CURIMA%EQUAL%NLEV: number of levels
  real(kind=4),              allocatable, save :: eqlev(:)  ! CURIMA%EQUAL%LEV: levels
  integer(kind=size_length), allocatable, save :: eqbin(:)  ! CURIMA%EQUAL%HIST: bin number
  !
end module gtv_bitmap
!
module gtv_graphic
  use gildas_def
  use gtv_tree
  !--------------------------------------------------------------------
  ! Conversion factors, internal values, and interactive buffer support
  ! For portability, SAVE Fortran variables (or their common) which are
  ! target of SIC variables.
  !--------------------------------------------------------------------
  !
  ! Conversion factors
  procedure(), pointer :: gt_greg_user => null()
  logical :: flag_greg  ! Is 'gt_greg_user' set?
  !
  ! Physical paper size (PLOT_PAGE): default values used when creating
  ! a new tree, when user does not provide custom values.
  real(4) :: phys_sizex_def   ! Default size of world plot area in X
  real(4) :: phys_sizey_def   ! Default size of world plot area in Y
  !
  logical       :: erflag=.false.           ! Error recovery?
  logical       :: error_condition=.false.  ! Set on error
  logical, save :: user_hardw_line=.true.   ! User prefers hardware generated?
  logical       :: awake=.false.            ! GTLIB awake?
  !
  character(len=segname_length+1) :: top_dir  ! "Login" directory name
  !
  ! GTVIRT Specials
  logical, save :: nofail=.false.                ! GTV%NOFAIL: no precaution for hardcopy
  logical, save :: stdout=.false.                ! GTV%STDOUT
  logical, save :: fitpage=.false.               ! GTV%FITPAGE
  logical, save :: dexist=.false.                ! GTV%EXIST
  character(len=gtvpath_length), save :: pwd     ! GTV%PWD
  character(len=10), save :: gtv_device          ! GTV%DEVICE
  logical,           save :: strict2011=.false.  ! GTV%STRICT2011: .false.
                   ! means that obsolete commands and behaviours will only
                   ! raise a warning, .true. that they will raise an error.
  !
end module gtv_graphic
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_protocol
  use gtv_types
  !--------------------------------------------------------------------
  ! For portability, SAVE Fortran variables (or their common) which are
  ! target of SIC variables.
  !--------------------------------------------------------------------
  !
  !--------------------------------------------------------------------
  !    Protocols should be defined as contiguous integer values
  !    in the range [1...NPROT]. Protocols are always checked as
  !    integers excepted in the external terminal definition file
  !    in which they are defined as character strings.
  !--------------------------------------------------------------------
  integer, parameter :: nprot=13         ! Number of protocols (p_null excluded)
  integer, parameter :: p_null      = 0  ! No device
  integer, parameter :: p_tektro    = 1  ! Obsolete. Tektro 4010 compatible
  integer, parameter :: p_regis     = 2  ! Obsolete. Regis (VT125)
  integer, parameter :: p_hpgl      = 3  ! Obsolete. HP-GL (Hewlett-Packard devices)
  integer, parameter :: p_args      = 4  ! Obsolete. ARGS-Sigma colour image display
  integer, parameter :: p_gt600     = 5  ! Obsolete. GT600 graphics card for VT100 terminals
  integer, parameter :: p_vicom     = 6  ! Obsolete. Vicom colour image display
  integer, parameter :: p_hp2648    = 7  ! Obsolete. HP-2648
  integer, parameter :: p_mvax_gpx  = 8  ! Obsolete. m-Vax GPX graphics workstation
  integer, parameter :: p_x         = 9  ! Terminal X
  integer, parameter :: p_postscript=10  ! PostScript
  integer, parameter :: p_pict      =11  ! Unused. PICT for MacIntosh
  integer, parameter :: p_svg       =12  ! Scalable Vector Graphics
  integer, parameter :: p_png       =13  ! Portable Network Graphics
  !
  character(len=12), parameter :: protocol_list(0:nprot) =  (/ &
    'NONE        ',  &  !  0
    'TEKTRO      ',  &  !  1
    'REGIS       ',  &  !  2
    'HPGL        ',  &  !  3
    'ARGS        ',  &  !  4
    'GT600       ',  &  !  5
    'VICOM       ',  &  !  6
    'HP2648      ',  &  !  7
    'MVAX_GPX    ',  &  !  8
    'X           ',  &  !  9
    'POSTSCRIPT  ',  &  ! 10
    'PICT        ',  &  ! 11
    'SVG         ',  &  ! 12
    'PNG         '  /)  ! 13
  !
  ! List of currently supported devices (command GTV\DEVICE)
  integer(kind=4), parameter :: ndevices=9
  character(len=10), parameter :: device_list(0:ndevices) =  &
              (/ 'NONE      ',  &
                 'IMAGE     ',  &
                 'XPORTRAIT ',  &
                 'XLANDSCAPE',  &
                 'PS        ',  &
                 'EPS       ',  &
                 'PDF       ',  &
                 'EPDF      ',  &
                 'SVG       ',  &
                 'PNG       ' /)
  !
  ! Devices instances. "Devices" are opened with the command GTV\DEVICE,
  ! e.g DEVICE IMAGE or DEVICE PNG
  type(gt_device), target, save :: cw_device  ! Current working Device
  !
  ! Output instances which have a permanent life. "Outputs" are instances of
  ! a "device", e.g. 2 white X windows. Hardcopies create a temporary output
  ! with no permanent life, they do not consume a slot here.
  integer, parameter :: moutputs=20      ! Arbitrary limited
  type(gt_display), target, save :: all_outputs(moutputs)  ! All opened outputs
  type(gt_display), target, save :: null_output  ! Dummy output when no active output
  type(gt_display), pointer :: cw_output  ! Current Working Output
  !
  ! Parameter(s) and variable(s) specific to X protocol (ZZZ move
  ! somewhere else?)
  integer, parameter :: mwindows=5  ! Maximum number of windows viewing a directory
  !
end module gtv_protocol
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_buffers
  use gtv_tree
  use gtv_types
  !
  ! Segments
  type(gt_segment), pointer      :: co_segment => null()       ! Currently opened segment
  type(gt_segment_data), pointer :: co_segment_data => null()  ! Currently opened data segment
  !
  ! Directories
  type(gt_directory), pointer :: root => null()  ! The root directory "<"
  type(gt_directory), pointer :: cw_directory => null()  ! User's current working directory
  !
  integer(kind=4) :: cdepth             ! Max Depth Level in use
  logical         :: vdepth(max_depth)  ! Which levels are in use?
  !
  ! Current attributes for new segments
  type(gt_segment_attr) :: cattr
  !
  type(polyline_buffer) :: polyl  ! Buffer RELOC/DRAW (for storing internal metacode)
  !
end module gtv_buffers
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module gtv_plot
  use gtv_types
  !--------------------------------------------------------------------
  ! Variables and parameters for plot support (color map, line styles)
  ! For portability, SAVE Fortran variables (or their common) which are
  ! target of SIC variables.
  !--------------------------------------------------------------------
  !
  integer, parameter :: hsv_mode=1
  integer, parameter :: rgb_mode=2
  !
  integer, parameter :: pen_size=16       ! Pens from 8 to 23
  !
  integer, save :: lut_size          ! Support variable for LUT%SIZE
  integer, save :: lut_mode=hsv_mode ! Support variable for LUT%MODE
  logical, save :: lut_static        ! Support variable for LUT%STATIC
  !
  ! Colormaps. One is global for use in case of LUT DYNAMIC. Save because it
  ! contains variables which are target of SIC variables. The other is a
  ! pointer which can be used in case of LUT STATIC.
  type(gt_lut), target, save :: gbl_colormap
  !
  ! Current Working Pens (for pens 8 to 23)
  type(gt_lut), target, save :: gbl_pen  ! Save because it contains variables which are target of SIC variables
  !
end module gtv_plot
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
