subroutine gtv_points(n,x,y,error)
  use gbl_message
  use gtv_interfaces, except_this=>gtv_points
  use gtv_tree
  use gtv_buffers
  use gtv_graphic
  use gtv_plot
  !---------------------------------------------------------------------
  ! @ public
  !  Store a list of dotted points in the GTV tree. For larger points,
  ! polylines (one per point) must be used.
  ! ---
  !   Threads status: thread safe
  !---------------------------------------------------------------------
  integer(kind=4), intent(in)    :: n      ! Number of points
  real(kind=4),    intent(in)    :: x(n)   !
  real(kind=4),    intent(in)    :: y(n)   !
  logical,         intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='GTV_POINT'
  integer(kind=4) :: ier
  !
  if (.not.awake .or. error_condition) return
  if (n.le.0)  return  ! No data
  !
  if (.not.associated(co_segment)) then
    call gtv_message(seve%e,rname,'Programming error: no segment opened')
    error = .true.
    return
  endif
  !
  ! First flush POLYL%X and POLYL%Y buffers if they are not empty
  call gtx_frxry(error)
  if (error) return
  !
  ! Do we need to save the current PENLUT in the metacode before starting
  ! to write the points?
  if (lut_static) then
    if (.not.associated(co_segment%head%lut)) then
      ! We have to save the current global PENLUT in the metacode
      call gt_penlut_segdata(error)  ! This sets co_segment%head%lut
      if (error)  return
    endif
  endif
  !
  ! Update minmax
  co_segment%head%gen%minmax(1) = min(minval(x),co_segment%head%gen%minmax(1))  ! xmin
  co_segment%head%gen%minmax(2) = max(maxval(x),co_segment%head%gen%minmax(2))  ! xmax
  co_segment%head%gen%minmax(3) = min(minval(y),co_segment%head%gen%minmax(3))  ! ymin
  co_segment%head%gen%minmax(4) = max(maxval(y),co_segment%head%gen%minmax(4))  ! ymax
  !
  call gtv_open_segments_for_writing_from_main()
  !
  if (.not.associated(co_segment_data)) then
    allocate(co_segment%data,stat=ier)
    if (ier.ne.0) then
      call gtv_message(seve%e,rname,'Internal error: allocation failure (1)')
      error = .true.
      goto 10
    endif
    co_segment_data => co_segment%data
  else
    allocate(co_segment_data%nextdata,stat=ier)
    if (ier.ne.0) then
      call gtv_message(seve%e,rname,'Internal error: allocation failure (2)')
      error = .true.
      goto 10
    endif
    co_segment_data => co_segment_data%nextdata
  endif
  co_segment_data%nextdata => null()
  !
  ! Store the data
  allocate(co_segment_data%poly%x(n),co_segment_data%poly%y(n),stat=ier)
  if (ier.ne.0) then
    call gtv_message(seve%e,rname,'Internal error: allocation failure (3)')
    error = .true.
    goto 10
  endif
  co_segment_data%kind = seg_points
  co_segment_data%poly%n = n
  co_segment_data%poly%x = x
  co_segment_data%poly%y = y
  co_segment_data%poly%penlut => co_segment%head%lut  ! Which can be null()
  !
10 continue
  !
  call gtv_close_segments_for_writing_from_main()
  !
end subroutine gtv_points
!
subroutine gti_points(out,poly)
  use gtv_types
  use gtv_tree
  use gtv_buffers
  use gtv_graphic
  use gtv_interfaces, except_this=>gti_points
  use gtv_protocol
  !---------------------------------------------------------------------
  ! @ private
  !  Draw a list of dot points
  !---------------------------------------------------------------------
  type(gt_display),  intent(inout) :: out   ! Input gt_display
  type(gt_polyline), intent(in)    :: poly  !
  ! Local
  integer(kind=4) :: i
  !
  if (.not.awake .or. error_condition) return
  ! call gtx_pen(out,ipenx_i)
  !
  ! No device selected
  if (out%dev%protocol.eq.p_null)  return
  !
  if (associated(poly%penlut)) then
    ! LUT STATIC:
    ! Load the appropriate pen into the device
    call gtx_pen(out,out%icolou,poly%penlut)
  endif
  !
  select case (out%dev%protocol)
  case(p_x)
    do i = 1,poly%n
      call gtx_plot(out,poly%x(i),poly%y(i),3)
    enddo
    !
  case(p_postscript)
    call ps_points(poly%n,poly%x,poly%y)
    !
  case(p_svg)
    call svg_points(out,poly%n,poly%x,poly%y)
    !
  case(p_png)
    call png_points(out,poly%n,poly%x,poly%y)
    !
  end select
  !
end subroutine gti_points
