<!-- -*-  mode: nxml -*- -->
<!--
    c.xml: "C Language" chapter

Copyright (C) 1994  Geoffrey Furnish and Maurice LeBrun
Copyright (C) 1999-2017 Alan W. Irwin
Copyright (C) 1999, 2000, 2001, 2002, 2003  Rafael Laboissiere
Copyright (C) 2003  Joao Cardoso

Redistribution and use in source (XML DocBook) and "compiled" forms
(HTML, PDF, PostScript, DVI, TeXinfo and so forth) with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code (XML DocBook) must retain the
above copyright notice, this list of conditions and the following
disclaimer as the first lines of this file unmodified.

2. Redistributions in compiled form (transformed to other DTDs,
converted to HTML, PDF, PostScript, and other formats) must
reproduce the above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or other
materials provided with the distribution.

Important: THIS DOCUMENTATION IS PROVIDED BY THE PLPLOT PROJECT "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE PLPLOT PROJECT BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->

<chapter id="c">
  <title>C Language</title>
  <para>The C computer language is fundamental to PLplot because our
  core plotting library and our definitive set of standard examples are
  written in that language, and the remainder of the computer languages
  that we support are implemented as bindings for our core C library.
  The C standard we use is <ulink
  url="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n897.pdf">C99</ulink>,
  and our experience is that all C compilers accessible to our users
  support that standard sufficiently to have no trouble building
  PLplot.</para>
  <para><anchor id="plplot-types"/></para>
  <itemizedlist><title>Argument Types for our C API</title>
  <listitem><itemizedlist><title>Argument types for input scalars</title>
    <listitem><para><anchor id="PLFLT-type"/>Floating-point type (where the C macro PL_DOUBLE is #defined if the
    CMake variable PL_DOUBLE is set to ON [which occurs by default])<programlisting>
#if defined ( PL_DOUBLE )
typedef double PLFLT;
#else
typedef float PLFLT;
#endif
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLINT-type"/>Integer type<programlisting>
typedef int32_t PLINT;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLBOOL-type"/>Boolean type<programlisting>
typedef PLINT PLBOOL;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLUNICODE-type"/>32-bit type that contains either UCS4-encoded unicode or FCI (font characterization integer) data<programlisting>
typedef uint32_t PLUNICODE;
    </programlisting></para></listitem>
  </itemizedlist></listitem>
  <listitem><itemizedlist><title>Argument types for input/output scalars</title>
    <listitem><para><anchor id="PLFLT_NC_SCALAR-type"/>Input/output PLFLT scalar<programlisting>
typedef PLFLT * PLFLT_NC_SCALAR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLINT_NC_SCALAR-type"/>Input/output PLINT scalar<programlisting>
typedef PLINT * PLINT_NC_SCALAR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLBOOL_NC_SCALAR-type"/>Input/output PLBOOL scalar<programlisting>
typedef PLBOOL * PLBOOL_NC_SCALAR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLUNICODE_NC_SCALAR-type"/>Input/output PLUNICODE scalar<programlisting>
typedef PLUNICODE * PLUNICODE_NC_SCALAR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLCHAR_NC_SCALAR-type"/>Input/output char scalar<programlisting>
typedef char * PLCHAR_NC_SCALAR;
    </programlisting></para></listitem>
  </itemizedlist></listitem>
  <listitem><itemizedlist><title>Argument types for input vectors</title>
    <listitem><para><anchor id="PLFLT_VECTOR-type"/>Input PLFLT vector<programlisting>
typedef const PLFLT * PLFLT_VECTOR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLINT_VECTOR-type"/>Input PLINT vector<programlisting>
typedef const PLINT * PLINT_VECTOR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLBOOL_VECTOR-type"/>Input PLBOOL vector<programlisting>
typedef const PLBOOL * PLBOOL_VECTOR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLCHAR_VECTOR-type"/>Input character string<programlisting>
typedef const char * PLCHAR_VECTOR;
    </programlisting>This string is NULL-terminated in C.</para></listitem>
  </itemizedlist></listitem>
  <listitem><itemizedlist><title>Argument types for input/output vectors</title>
    <listitem><para><anchor id="PLFLT_NC_VECTOR-type"/>Input/output PLFLT vector<programlisting>
typedef PLFLT * PLFLT_NC_VECTOR;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLCHAR_NC_VECTOR-type"/>Input/output character string<programlisting>
typedef char * PLCHAR_NC_VECTOR;
    </programlisting>This string is NULL-terminated in C.</para></listitem>
  </itemizedlist></listitem>
  <listitem><para><itemizedlist><title>Argument types for input 2D matrices</title>
    <listitem><para><anchor id="PLFLT_MATRIX-type"/>Input PLFLT 2D matrix<programlisting>
typedef const PLFLT * const * PLFLT_MATRIX;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLCHAR_MATRIX-type"/>Input vector of character strings<programlisting>
typedef const char * const * PLCHAR_MATRIX;
    </programlisting>These strings are NULL-terminated in C.</para></listitem>
  </itemizedlist>
    Note that for the C language case the above
    definitions allow input matrices to be organized either in the
    traditional <ulink
    url="https://en.wikipedia.org/wiki/Row-major_order">row-major</ulink>
    order or as an <ulink
    url="https://en.wikipedia.org/wiki/Iliffe_vector">Iliffe column
    vector</ulink> of pointers to row vectors.
  </para></listitem>
  <listitem><para><itemizedlist><title>Argument types for input/output 2D matrices</title>
  <listitem><para><anchor id="PLFLT_NC_MATRIX-type"/>Input/output PLFLT 2D matrix<programlisting>
typedef PLFLT ** PLFLT_NC_MATRIX;
  </programlisting></para></listitem>
  <listitem><para><anchor id="PLCHAR_NC_MATRIX-type"/>Input/output vector of character strings<programlisting>
typedef char ** PLCHAR_NC_MATRIX;
  </programlisting>These strings are NULL-terminated in C.</para></listitem>
  </itemizedlist>
  Note that for the C language case the above
  definitions allow input/output matrices to be organized either in the
  traditional <ulink
  url="https://en.wikipedia.org/wiki/Row-major_order">row-major</ulink>
  order or as an <ulink
  url="https://en.wikipedia.org/wiki/Iliffe_vector">Iliffe column
  vector</ulink> of pointers to row vectors.</para>
  </listitem>
  <listitem><itemizedlist><title>Argument type for a generic pointer</title>
    <listitem><para><anchor id="PLPointer-type"/>Input/output generic pointer<programlisting>
typedef void * PLPointer;
    </programlisting></para></listitem>
  </itemizedlist></listitem>
  <listitem><itemizedlist><title>Argument types for callback functions</title>
    <listitem><para><anchor id="PLMAPFORM_callback-type"/>Map transformation callback type<programlisting>
typedef void ( *PLMAPFORM_callback )( PLINT n, PLFLT_NC_VECTOR x, PLFLT_NC_VECTOR y );
    </programlisting>where the callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>n</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>Number of elements in the <literal>x</literal> and <literal>y</literal> vectors.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>x</parameter>
          (<literal>PLFLT_NC_VECTOR</literal>, input/output)
        </term>
        <listitem>
          <para>
            Vector of <literal>x</literal> coordinates of points to be transformed.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>y</parameter>
          (<literal>PLFLT_NC_VECTOR</literal>, input/output)
        </term>
        <listitem>
          <para>
            Vector of <literal>y</literal> coordinates of points to be transformed.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
    <listitem><para><anchor id="PLTRANSFORM_callback-type"/>Coordinate transformation callback type<programlisting>
typedef void ( *PLTRANSFORM_callback )( PLFLT x, PLFLT y, PLFLT_NC_SCALAR tx, PLFLT_NC_SCALAR ty, PLPointer data);
    </programlisting>where the callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>x</parameter>
          (<literal>PLFLT</literal>, input)
        </term>
        <listitem>
          <para>
            <literal>x</literal>-position to be transformed.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>y</parameter>
          (<literal>PLFLT</literal>, input)
        </term>
        <listitem>
          <para>
            <literal>y</literal>-position to be transformed.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
         <term>
          <parameter>tx</parameter>
          (<literal>PLFLT_NC_SCALAR</literal>, output)
        </term>
        <listitem>
          <para>
            Transformed <literal>x</literal>-position.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>ty</parameter>
          (<literal>PLFLT_NC_SCALAR</literal>, output)
        </term>
        <listitem>
          <para>
            Transformed <literal>y</literal>-position.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>data</parameter>
          (<literal>PLPointer</literal>, input)
        </term>
        <listitem>
          <para>
            Generic pointer to additional input data that may be required by the callback routine in
            order to implement the transformation.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
    <listitem><para><anchor id="PLLABEL_FUNC_callback-type"/>Custom label callback type<programlisting>
typedef void ( *PLLABEL_FUNC_callback )( PLINT axis, PLFLT value, PLCHAR_NC_VECTOR label, PLINT length, PLPointer data);
    </programlisting>where the callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>axis</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>
	    An integer whose value is <literal>PL_X_AXIS = 1</literal> if an
	    <literal>x</literal>-axis label is being generated and
	    <literal>PL_Y_AXIS = 2</literal> if a <literal>y</literal>-axis label
	    is being generated.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>value</parameter>
          (<literal>PLFLT</literal>, input)
        </term>
        <listitem>
          <para>
	    Floating-point numerical value to be used to help generate the label.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>label</parameter>
          (<literal>PLCHAR_NC_VECTOR</literal>, output)
        </term>
        <listitem>
          <para>
	    A pointer to a memory area suitable for containing the output
	    NULL-terminated character string of maximum length (including
	    the NULL-terminating byte) of <literal>length</literal>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>length</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>
	    The maximum possible length (including NULL-terminating byte) of the
	    output NULL-terminated character string.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>data</parameter>
          (<literal>PLPointer</literal>, input)
        </term>
        <listitem>
          <para>
            Generic pointer to additional input data that may be required by the callback routine in
	    order to generate a label.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
    <listitem><para><anchor id="PLF2EVAL_callback-type"/>Two-dimensional function array lookup callback type<programlisting>
typedef PLFLT ( *PLF2EVAL_callback )( PLINT ix, PLINT iy, PLPointer data);
    </programlisting>where the callback function returns the looked-up value, and the
callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>ix</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>The <literal>x</literal> index of the function array lookup.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>iy</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>The <literal>y</literal> index of the function array lookup.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>data</parameter>
          (<literal>PLPointer</literal>, input)
        </term>
        <listitem>
	  <para>Generic pointer to the two-dimensional function input data that
	  are required by the callback routine.  Since this is a generic
	  pointer, these two-dimensional data can be arranged in any way that is
	  desired by the user.</para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
    <listitem><para><anchor id="PLFILL_callback-type"/>Fill callback type<programlisting>
typedef void ( *PLFILL_callback )( PLINT n, PLFLT_VECTOR x, PLFLT_VECTOR y );
    </programlisting>where the callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>n</parameter>
          (<literal>PLINT</literal>, input)
        </term>
        <listitem>
          <para>Number of vertices in polygon to be filled.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>x</parameter>
          (<literal>PLFLT_VECTOR</literal>, input)
        </term>
        <listitem>
          <para>Vector of <literal>x</literal>-coordinates of vertices.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>y</parameter>
          (<literal>PLFLT_VECTOR</literal>, input)
        </term>
        <listitem>
          <para>Vector of <literal>y</literal>-coordinates of vertices.</para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
    <listitem><para><anchor id="PLDEFINED_callback-type"/>Defined callback type<programlisting>
typedef PLINT ( *PLDEFINED_callback )( PLFLT x, PLFLT y );
</programlisting>where the callback function returns a 1 or 0 depending on whether the
<literal>x</literal> and <literal>y</literal> arguments are within specified defined
area, and the callback arguments are the following:</para>
    <variablelist>
      <varlistentry>
        <term>
          <parameter>x</parameter>
          (<literal>PLFLT</literal>, input)
        </term>
        <listitem>
          <para><literal>x</literal>-coordinate to be tested for whether it is in the defined region.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <parameter>y</parameter>
          (<literal>PLFLT</literal>, input)
        </term>
        <listitem>
          <para><literal>y</literal>-coordinate to be tested for whether it is in the defined region.</para>
        </listitem>
      </varlistentry>
    </variablelist>
    </listitem>
  </itemizedlist></listitem>
  <listitem><itemizedlist><title>Arguments of miscellaneous types</title>
    <listitem><para><anchor id="PLGraphicsIn-type"/>A struct containing output mouse/keyboard event data<programlisting>
typedef struct
{
    int          type;              // of event (CURRENTLY UNUSED)
    unsigned int state;             // key or button mask
    unsigned int keysym;            // key selected
    unsigned int button;            // mouse button selected
    PLINT        subwindow;         // subwindow (alias subpage, alias subplot) number
    char         string[PL_MAXKEY]; // translated string
    int          pX, pY;            // absolute device coordinates of pointer
    PLFLT        dX, dY;            // relative device coordinates of pointer
    PLFLT        wX, wY;            // world coordinates of pointer
} PLGraphicsIn;
    </programlisting></para></listitem>
    <listitem><para><anchor id="PLF2OPS-type"/>Input/output pointer to a struct that holds pointers to functions that are used to
    get, set, modify, and test individual 2-D data points referenced by
    a PLPointer or PLPointer<programlisting>
typedef struct
{
    PLFLT ( *get )( PLPointer p, PLINT ix, PLINT iy );
    PLFLT ( *set )( PLPointer p, PLINT ix, PLINT iy, PLFLT z );
    PLFLT ( *add )( PLPointer p, PLINT ix, PLINT iy, PLFLT z );
    PLFLT ( *sub )( PLPointer p, PLINT ix, PLINT iy, PLFLT z );
    PLFLT ( *mul )( PLPointer p, PLINT ix, PLINT iy, PLFLT z );
    PLFLT ( *div )( PLPointer p, PLINT ix, PLINT iy, PLFLT z );
    PLINT ( *is_nan )( PLPointer p, PLINT ix, PLINT iy );
    void ( *minmax )( PLPointer p, PLINT nx, PLINT ny, PLFLT_NC_SCALAR zmin, PLFLT_NC_SCALAR zmax );
    //
    // f2eval is backwards compatible signature for "f2eval" functions that
    // existed before plf2ops "operator function families" were used.
    //
    PLFLT ( *f2eval )( PLINT ix, PLINT iy, PLPointer p );
} plf2ops_t;

typedef plf2ops_t * PLF2OPS;
    </programlisting>
    </para></listitem>
    <listitem><para><anchor id="PLFLT_FE_POINTER-type"/>Input/output pointer to first element of contiguous PLFLT array<programlisting>
typedef PLFLT * PLFLT_FE_POINTER;
    </programlisting>
    Note the array must correspond to a contiguous block of memory but may be organized
    with arbitrary dimensions that conform to that block of memory.
    </para></listitem>
  </itemizedlist></listitem>
  </itemizedlist>

  <para>For more information on calling PLplot from C, please consult
  the example C programs in <filename>examples/c</filename> that are
  distributed with PLplot.  For more information on building your own
  PLplot-related C routines, please consult either the traditional
  (Makefile + pkg-config) or CMake-based build systems that are created
  as part of the install step for our C (and other language)
  examples.</para>
</chapter>
