subroutine load_greg (line)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>load_greg
  use greg_kernel
  use greg_pen
  use greg_xyz
  !---------------------------------------------------------------------
  ! @ public
  ! LOAD_GREG('INTERACTIVE GREGi')
  ! LOAD_GREG('LIBRARY GREGi')
  !---------------------------------------------------------------------
  character(len=*) :: line          !
  ! Local
  integer, parameter :: mcom1=76, mcom2=79, mcom3=7+4
  character(len=12) :: ccom1(mcom1),ccom2(mcom2),ccom3(mcom3)
  character(len=12) :: name
  character(len=128) :: chain
  integer :: istatus,i,lv
  character(len=1), parameter :: backslash=char(92)
  logical :: error
  character(len=72) :: vers
  ! Data
  data vers/'9.2-00  19-Jun-2012   S.Guilloteau, J.Pety, S.Bardeau'/
  !
  ! Language initialisation
  data ccom1/                                                                &
    ' AXIS',      '/TICK','/LABEL','/LOCATION','/LOG','/NOLOG','/ABSOLUTE',  &
                  '/UNIT','/BRIEF','/NOBRIEF',                               &
    ' BOX',       '/ABSOLUTE','/UNIT','/LABEL','/FILL','/BRIEF','/NOBRIEF',  &
    ' COLUMN',    '/FILE','/LINES','/TABLE','/COMMENT','/CLOSE',             &
    ' CONNECT',   '/BLANKING','/FILL',                                       &
    ' CORNERS',                                                              &
    ' CURVE',     '/ACCURACY','/VARIABLE','/PERIODIC','/BLANKING',           &
    '*DRAW',      '/USER','/BOX','/CHARACTER','/CLIP',                       &
    ' ERRORBAR',                                                             &
    ' HISTOGRAM', '/BLANKING','/FILL','/BASE','/HATCH','/Y',                 &
    ' LABEL',     '/X','/Y','/CENTERING','/APPEND',                          &
    ' LIMITS',    '/XLOG','/YLOG','/RGDATA','/BLANKING','/REVERSE',          &
                  '/VARIABLES','/MARGIN',                                    &
    '*LOOK',                                                                 &
    ' PENCIL',    '/COLOUR','/DASHED','/WEIGHT','/DEFAULT',                  &
    ' POINTS',    '/BLANKING','/SIZE','/MARKER',                             &
    ' RULE',      '/MAJOR','/MINOR',                                         &
    ' SET',       '/DEFAULT',                                                &
    ' SHOW',                                                                 &
    ' TICKSPACE',                                                            &
    ' VALUES',    '/BLANKING' /
  data ccom2 /                                                                 &
    ' ARROW',                                                                  &
    ' CONVERT',     '/TYPE','/UNIT','/SYSTEM','/VARIABLE',                     &
    ' ELLIPSE',     '/BOX','/USER','/ARC','/FILL','/HATCH','/SAVE',            &
    '$EXTREMA',     '/BLANKING','/PLOT','/COMPUTE','/LOCAL',                   &
    ' GRID',        '/ALTERNATE','/LABEL',                                     &
    ' LEVELS',                                                                 &
    ' MASK',        '/BLANKING',                                               &
    ' MEAN',        '/CLIP',                                                   &
    ' PLOT',        '/BLANKING','/SCALING','/POSITION','/BOUNDARIES',          &
                    '/VISIBLE',                                                &
    ' PROJECTION',  '/TYPE',                                                   &
    ' PERSPECTIVE', '/FACTOR','/LOWER','/LINES','/STEP','/AXES','/CENTER',     &
                    '/VERTICAL',                                               &
    ' POLYGON',     '/PLOT','/VARIABLE','/FILL','/RESET','/HATCH',             &
    ' RANDOM_MAP',  '/BLANKING','/NEIGHBOURS','/TRIANGLES','/EXTRAPOLATE',     &
                    '/VARIABLE','/SKIP',                                       &
    ' RESAMPLE',    '/X','/Y','/BLANKING',                                     &
    ' RGDATA',      '/SUBSET','/VARIABLE','/FORMAT','/INCREMENT','/BLANKING',  &
    ' RGMAP',       '/ABSOLUTE','/PERCENT','/KEEP','/BLANKING','/GREY',        &
                    '/PENS','/ONLY',                                           &
    ' STRIP',                                                                  &
    ' WRITE',       '/TABLE',                                                  &
    ' WEDGE',       '/SCALING','/LEVELS'/
  data ccom3 /                                       &
    ' IMAGE', '/PLANE','/SUBSET','/WRITE','/CLOSE',  &
    ' KILL',                                         &
    ' SPECTRUM','/CORNER','/MEAN','/PLANES', '/SUM'  /
  !
  ! Initialize module variables
  call greg_mod_init
  !
  error = gterrtst()
  !
  ! Set up language
  i = index(line,' ')
  if (i.eq.0) then
    i = lenc(line)
    name = ' '
  else
    name = line(i+1:)
    i = i-1
  endif
  lv = lenc(vers)
  if (line(1:i).eq.'LIBRARY') then
    if (jtmp.eq.0) library = .true.
    if (name.eq.' ' .or. name.eq.'GREG1') then
      call sic_begin('GREG1',' ',mcom1,ccom1,vers(1:lv),run_greg1,gterrtst)
    endif
    if (name.eq.' ' .or. name.eq.'GREG2') then
      call sic_begin('GREG2',' ',mcom2,ccom2,vers(1:lv),run_greg2,gterrtst)
    elseif (name.eq.'GREG3') then
      call sic_begin('GREG3',' ',mcom3,ccom3,vers(1:lv),run_greg3,gterrtst)
    endif
  else
    library = .false.
    if (name.eq.' ' .or. name.eq.'GREG1') then
      call sic_begin('GREG1','GAG_HELP_GREG1',mcom1,ccom1,vers(1:lv),  &
      run_greg1,gterrtst)
    endif
    if (name.eq.' ' .or. name.eq.'GREG2') then
      call sic_begin('GREG2','GAG_HELP_GREG2',mcom2,ccom2,vers(1:lv),  &
      run_greg2,gterrtst)
    elseif (name.eq.'GREG3') then
      call sic_begin('GREG3','GAG_HELP_GREG3',mcom3,ccom3,vers(1:lv),  &
      run_greg3,gterrtst)
    endif
  endif
  !
  ! If already set return
  if (jtmp.ne.0) return
  !
  ! Initialize X Y Z buffers
  maxxy = 0
  nxy = 0
  !
  ! Allocate logical units
  istatus = sic_getlun(jtmp)
  if (mod(istatus,2).eq.0) call sysexi(istatus)
  !
  ! Initialize GTVIRT
  if (lung.eq.0) istatus = sic_getlun(lung)
  if (lunh.eq.0) istatus = sic_getlun(lunh)
  call gtinit(lxs_d,lys_d,lung,lunh,'<GREG',greg_user,error)
  if (error)  return
  call gterflag(.true.)  ! Set GTVIRT to error recovery mode
  !
  ! Resolve default pen:
  ! - colours (translate human names to GTV internal IDs)
  ! - weights (translate Greg numbers to cm)
  do i=0,maxpen
    call gtv_pencol_name2id('GREG',defcolname(i),defcolid(i),error)
    if (error)  return
    call gtv_penwei_num2val('GREG',defweinum(i),defweival(i),error)
    if (error)  return
  enddo
  !
  ! And initialise GREG
  call greg_variables
  call gr_exec1('SET /DEFAULT')
  call gr_exec1('PENCIL /DEFAULT')
  call gr_exec1('TICKSPACE 0 0 0 0')
  chain = 'GREG1'//backslash//'SET /DEFAULT'
  call sic_insert(chain)
  chain = 'GREG1'//backslash//'PENCIL /DEFAULT'
  call sic_insert(chain)
  chain = 'GREG1'//backslash//'TICKSPACE 0 0 0 0'
  call sic_insert(chain)
  !
  ! Initialize graphic library
#if defined(GAG_USE_STATICLINK)
  call init_graph_api
#endif
  !
end subroutine load_greg
!
subroutine exit_greg(error)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>exit_greg
  use greg_kernel
  !---------------------------------------------------------------------
  ! @ private
  ! Clean the GREG-related components on exit
  !---------------------------------------------------------------------
  logical, intent(inout) :: error  ! Logical error flag
  !
  call sic_frelun(jtmp)
  call sic_frelun(lung)
  call sic_frelun(lunh)
  !
  call greg3_close
  !
end subroutine exit_greg
!
subroutine greg_user(flagin,array)
  use greg_interfaces, except_this=>greg_user
  use greg_kernel
  use greg_pen
  !---------------------------------------------------------------------
  ! @ private-mandatory (because symbol is used elsewhere)
  !   Give or retrieve coordinate conversion formula to/from GTVIRT.
  ! The buffer is of size 26, same as the type 'greg_values' in the
  ! GTVIRT.
  !---------------------------------------------------------------------
  integer(kind=4), intent(in) :: flagin     !
  integer(kind=4)             :: array(26)  !
  !
  if (flagin.lt.0) then
    ! Change Directory
    call r8tor8(array( 1),gux1,     8)
    call l4tol4(array(17),axis_xlog,1)
    call l4tol4(array(18),axis_ylog,1)
    call r4tor4(array(19),gx1,      4)
    call r4tor4(array(23),lx1,      4)
    gxp = -1e10
    gyp = -1e10
    penupd = .true.
    call setrem  ! Trial ... does not restore the PANGLE correctly
  elseif  (flagin.eq.0) then
    ! Clear Plot
    gxp = -1e10
    gyp = -1e10
    penupd = .true.
  else
    ! Transmit values
    call r8tor8(gux1,     array( 1),8)
    call l4tol4(axis_xlog,array(17),1)
    call l4tol4(axis_ylog,array(18),1)
    call r4tor4(gx1,      array(19),4)
  ! call r4tor4(lx1,      array(23),4)
  endif
  !
end subroutine greg_user
