{*********************************************************************
 *
 * $Id: yocto_display.pas 75637 2026-08-20 16:54:40Z mvuilleu $
 *
 * Implements yFindDisplay(), the high-level API for Display functions
 *
 * - - - - - - - - - License information: - - - - - - - - -
 *
 *  Copyright (C) 2011 and beyond by Yoctopuce Sarl, Switzerland.
 *
 *  Yoctopuce Sarl (hereafter Licensor) grants to you a perpetual
 *  non-exclusive license to use, modify, copy and integrate this
 *  file into your software for the sole purpose of interfacing
 *  with Yoctopuce products.
 *
 *  You may reproduce and distribute copies of this file in
 *  source or object form, as long as the sole purpose of this
 *  code is to interface with Yoctopuce products. You must retain
 *  this notice in the distributed source file.
 *
 *  You should refer to Yoctopuce General Terms and Conditions
 *  for additional information regarding your rights and
 *  obligations.
 *
 *  THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
 *  WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
 *  WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS
 *  FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO
 *  EVENT SHALL LICENSOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
 *  INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
 *  COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR
 *  SERVICES, ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT
 *  LIMITED TO ANY DEFENSE THEREOF), ANY CLAIMS FOR INDEMNITY OR
 *  CONTRIBUTION, OR OTHER SIMILAR COSTS, WHETHER ASSERTED ON THE
 *  BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF
 *  WARRANTY, OR OTHERWISE.
 *
 *********************************************************************}


unit yocto_display;
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}

interface

uses
   sysutils, classes,{$IFNDEF UNIX}windows,
{$ENDIF}
 yocto_api, yjson;

//--- (generated code: YDisplay definitions)
type  TYFASTREFRESH = (Y_FASTREFRESH_WHENEVER_POSSIBLE,Y_FASTREFRESH_WHENEVER_SUPPORTED,Y_FASTREFRESH_NEVER,Y_FASTREFRESH_INVALID);
type  TYREGENERATE = (Y_REGENERATE_ON_REQUEST_ONLY,Y_REGENERATE_EVERY_DAY,Y_REGENERATE_EVERY_12H,Y_REGENERATE_EVERY_6H,Y_REGENERATE_EVERY_3H,Y_REGENERATE_EVERY_2H,Y_REGENERATE_EVERY_HOUR,Y_REGENERATE_EVERY_30MIN,Y_REGENERATE_EVERY_15MIN,Y_REGENERATE_EVERY_480,Y_REGENERATE_EVERY_432,Y_REGENERATE_EVERY_360,Y_REGENERATE_EVERY_288,Y_REGENERATE_EVERY_240,Y_REGENERATE_EVERY_192,Y_REGENERATE_EVERY_144,Y_REGENERATE_EVERY_96,Y_REGENERATE_EVERY_48,Y_REGENERATE_EVERY_36,Y_REGENERATE_EVERY_24,Y_REGENERATE_EVERY_12,Y_REGENERATE_EVERY_10,Y_REGENERATE_EVERY_8,Y_REGENERATE_EVERY_6,Y_REGENERATE_EVERY_4,Y_REGENERATE_ALWAYS,Y_REGENERATE_INVALID);
type  TYDISPLAYSTATE = (Y_DISPLAYSTATE_FAILURE,Y_DISPLAYSTATE_OFF,Y_DISPLAYSTATE_POWERING,Y_DISPLAYSTATE_IDLE,Y_DISPLAYSTATE_REFRESHING,Y_DISPLAYSTATE_INVALID);

const Y_ENABLED_FALSE = 0;
const Y_ENABLED_TRUE = 1;
const Y_ENABLED_INVALID = -1;
const Y_STARTUPSEQ_INVALID            = YAPI_INVALID_STRING;
const Y_BRIGHTNESS_INVALID            = YAPI_INVALID_UINT;
const Y_AUTOINVERTDELAY_INVALID       = YAPI_INVALID_UINT;
const Y_ORIENTATION_LEFT = 0;
const Y_ORIENTATION_UP = 1;
const Y_ORIENTATION_RIGHT = 2;
const Y_ORIENTATION_DOWN = 3;
const Y_ORIENTATION_INVALID = -1;
const Y_DISPLAYPANEL_INVALID          = YAPI_INVALID_STRING;
const Y_DISPLAYWIDTH_INVALID          = YAPI_INVALID_UINT;
const Y_DISPLAYHEIGHT_INVALID         = YAPI_INVALID_UINT;
const Y_DISPLAYTYPE_MONO = 0;
const Y_DISPLAYTYPE_EPAPER_BW = 1;
const Y_DISPLAYTYPE_EPAPER_BWR = 2;
const Y_DISPLAYTYPE_EPAPER_BWRY = 3;
const Y_DISPLAYTYPE_INVALID = -1;
const Y_LAYERWIDTH_INVALID            = YAPI_INVALID_UINT;
const Y_LAYERHEIGHT_INVALID           = YAPI_INVALID_UINT;
const Y_LAYERCOUNT_INVALID            = YAPI_INVALID_UINT;
const Y_COMMAND_INVALID               = YAPI_INVALID_STRING;

//--- (end of generated code: YDisplay definitions)

//--- (generated code: YDisplayLayer definitions)
type  TYALIGN = (Y_ALIGN_TOP_LEFT,Y_ALIGN_CENTER_LEFT,Y_ALIGN_BASELINE_LEFT,Y_ALIGN_BOTTOM_LEFT,Y_ALIGN_TOP_CENTER,Y_ALIGN_CENTER,Y_ALIGN_BASELINE_CENTER,Y_ALIGN_BOTTOM_CENTER,Y_ALIGN_TOP_DECIMAL,Y_ALIGN_CENTER_DECIMAL,Y_ALIGN_BASELINE_DECIMAL,Y_ALIGN_BOTTOM_DECIMAL,Y_ALIGN_TOP_RIGHT,Y_ALIGN_CENTER_RIGHT,Y_ALIGN_BASELINE_RIGHT,Y_ALIGN_BOTTOM_RIGHT);

const Y_NO_INK                        = -1;
const Y_BG_INK                        = -2;
const Y_FG_INK                        = -3;
//--- (end of generated code: YDisplayLayer definitions)

type
 TYDisplayLayer = class;
 TYDisplay = class;
 TYDisplayLayerArray = array of TYDisplayLayer;


  //--- (generated code: YDisplay class start)
  TYDisplayValueCallback = procedure(func: TYDisplay; value:string);
  TYDisplayTimedReportCallback = procedure(func: TYDisplay; value:TYMeasure);

  ////
  /// <summary>
  ///   TYDisplay Class: display control interface, available for instance in the Yocto-Display, the
  ///   Yocto-MaxiDisplay, the Yocto-MaxiDisplay-G or the Yocto-MiniDisplay
  /// <para>
  ///   The <c>YDisplay</c> class allows to drive Yoctopuce displays.
  ///   Yoctopuce display interface has been designed to easily
  ///   show information and images. The device provides built-in
  ///   multi-layer rendering. Layers can be drawn offline, individually,
  ///   and freely moved on the display. It can also replay recorded
  ///   sequences (animations).
  /// </para>
  /// <para>
  ///   In order to draw on the screen, you should use the
  ///   <c>display.get_displayLayer</c> method to retrieve the layer(s) on
  ///   which you want to draw, and then use methods defined in
  ///   <c>YDisplayLayer</c> to draw on the layers.
  /// </para>
  /// </summary>
  ///-
  TYDisplay=class(TYFunction)
  //--- (end of generated code: YDisplay class start)
  protected
  //--- (generated code: YDisplay declaration)
    // Attributes (function value cache)
    _enabled                  : Integer;
    _startupSeq               : string;
    _brightness               : LongInt;
    _autoInvertDelay          : LongInt;
    _orientation              : Integer;
    _displayPanel             : string;
    _displayWidth             : LongInt;
    _displayHeight            : LongInt;
    _displayType              : Integer;
    _layerWidth               : LongInt;
    _layerHeight              : LongInt;
    _layerCount               : LongInt;
    _command                  : string;
    _valueCallbackDisplay     : TYDisplayValueCallback;
    _allDisplayLayers         : TYDisplayLayerArray;
    _frozenUntil              : u64;
    _recording                : boolean;
    _sequence                 : string;
    // Function-specific method for reading JSON output and caching result
    function _parseAttr(member:PJSONRECORD):integer; override;
    //--- (end of generated code: YDisplay declaration)

public
   destructor Destroy(); override;

   //--- (generated code: YDisplay accessors declaration)
    constructor Create(func:string);

    ////
    /// <summary>
    ///   Returns true if the screen is powered, false otherwise.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   either <c>YDisplay.ENABLED_FALSE</c> or <c>YDisplay.ENABLED_TRUE</c>, according to true if the
    ///   screen is powered, false otherwise
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.ENABLED_INVALID</c>.
    /// </para>
    ///-
    function get_enabled():Integer;

    ////
    /// <summary>
    ///   Changes the power state of the display.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   either <c>YDisplay.ENABLED_FALSE</c> or <c>YDisplay.ENABLED_TRUE</c>, according to the power state
    ///   of the display
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_enabled(newval:Integer):integer;

    ////
    /// <summary>
    ///   Returns the name of the sequence to play when the displayed is powered on.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a string corresponding to the name of the sequence to play when the displayed is powered on
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.STARTUPSEQ_INVALID</c>.
    /// </para>
    ///-
    function get_startupSeq():string;

    ////
    /// <summary>
    ///   Changes the name of the sequence to play when the display is powered on.
    /// <para>
    ///   Remember to call the <c>saveToFlash()</c> method of the module if the
    ///   modification must be kept.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   a string corresponding to the name of the sequence to play when the display is powered on
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_startupSeq(newval:string):integer;

    ////
    /// <summary>
    ///   Returns the luminosity of the  module informative LEDs (from 0 to 100).
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the luminosity of the  module informative LEDs (from 0 to 100)
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.BRIGHTNESS_INVALID</c>.
    /// </para>
    ///-
    function get_brightness():LongInt;

    ////
    /// <summary>
    ///   Changes the brightness of the display.
    /// <para>
    ///   The parameter is a value between 0 and
    ///   100. Remember to call the <c>saveToFlash()</c> method of the module if the
    ///   modification must be kept.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   an integer corresponding to the brightness of the display
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_brightness(newval:LongInt):integer;

    ////
    /// <summary>
    ///   Returns the interval between automatic display inversions, or 0 if automatic
    ///   inversion is disabled.
    /// <para>
    ///   Using the automatic inversion mechanism reduces the
    ///   burn-in that occurs on OLED screens over long periods when the same content
    ///   remains displayed on the screen.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the interval between automatic display inversions, or 0 if automatic
    ///   inversion is disabled
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.AUTOINVERTDELAY_INVALID</c>.
    /// </para>
    ///-
    function get_autoInvertDelay():LongInt;

    ////
    /// <summary>
    ///   Changes the interval between automatic display inversions.
    /// <para>
    ///   The parameter is the number of seconds, or 0 to disable automatic inversion.
    ///   Using the automatic inversion mechanism reduces the burn-in that occurs on OLED
    ///   screens over long periods when the same content remains displayed on the screen.
    ///   Remember to call the <c>saveToFlash()</c> method of the module if the
    ///   modification must be kept.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   an integer corresponding to the interval between automatic display inversions
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_autoInvertDelay(newval:LongInt):integer;

    ////
    /// <summary>
    ///   Returns the currently selected display orientation.
    /// <para>
    ///   The orientation is defined as the side of the screen where the
    ///   USB connector (for OLED displays) or the ribbon cable (for ePaper panels) is located when the
    ///   display is up straight.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a value among <c>YDisplay.ORIENTATION_LEFT</c>, <c>YDisplay.ORIENTATION_UP</c>,
    ///   <c>YDisplay.ORIENTATION_RIGHT</c> and <c>YDisplay.ORIENTATION_DOWN</c> corresponding to the
    ///   currently selected display orientation
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.ORIENTATION_INVALID</c>.
    /// </para>
    ///-
    function get_orientation():Integer;

    ////
    /// <summary>
    ///   Changes the display orientation.
    /// <para>
    ///   he orientation is defined as the side of the screen where the
    ///   USB connector (for OLED displays) or the ribbon cable (for ePaper panels) is located when the
    ///   display is up straight. Remember to call the <c>saveToFlash()</c>
    ///   method of the module if the modification must be kept.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   a value among <c>YDisplay.ORIENTATION_LEFT</c>, <c>YDisplay.ORIENTATION_UP</c>,
    ///   <c>YDisplay.ORIENTATION_RIGHT</c> and <c>YDisplay.ORIENTATION_DOWN</c> corresponding to the display orientation
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_orientation(newval:Integer):integer;

    ////
    /// <summary>
    ///   Returns the exact model of the display panel.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a string corresponding to the exact model of the display panel
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.DISPLAYPANEL_INVALID</c>.
    /// </para>
    ///-
    function get_displayPanel():string;

    ////
    /// <summary>
    ///   Changes the model of display to match the connected display panel.
    /// <para>
    ///   This function has no effect if the module does not support the selected
    ///   display panel. Remember to call the <c>saveToFlash()</c>
    ///   method of the module if the modification must be kept.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="newval">
    ///   a string corresponding to the model of display to match the connected display panel
    /// </param>
    /// <para>
    /// </para>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_displayPanel(newval:string):integer;

    ////
    /// <summary>
    ///   Returns the display width, in pixels.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the display width, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.DISPLAYWIDTH_INVALID</c>.
    /// </para>
    ///-
    function get_displayWidth():LongInt;

    ////
    /// <summary>
    ///   Returns the display height, in pixels.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the display height, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.DISPLAYHEIGHT_INVALID</c>.
    /// </para>
    ///-
    function get_displayHeight():LongInt;

    ////
    /// <summary>
    ///   Returns the display type: monochrome OLED, black and white ePaper, color ePaper, and so on.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a value among <c>YDisplay.DISPLAYTYPE_MONO</c>, <c>YDisplay.DISPLAYTYPE_EPAPER_BW</c>,
    ///   <c>YDisplay.DISPLAYTYPE_EPAPER_BWR</c> and <c>YDisplay.DISPLAYTYPE_EPAPER_BWRY</c> corresponding to
    ///   the display type: monochrome OLED, black and white ePaper, color ePaper, and so on
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.DISPLAYTYPE_INVALID</c>.
    /// </para>
    ///-
    function get_displayType():Integer;

    ////
    /// <summary>
    ///   Returns the width of the layers to draw on, in pixels.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the width of the layers to draw on, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.LAYERWIDTH_INVALID</c>.
    /// </para>
    ///-
    function get_layerWidth():LongInt;

    ////
    /// <summary>
    ///   Returns the height of the layers to draw on, in pixels.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the height of the layers to draw on, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.LAYERHEIGHT_INVALID</c>.
    /// </para>
    ///-
    function get_layerHeight():LongInt;

    ////
    /// <summary>
    ///   Returns the number of available layers to draw on.
    /// <para>
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the number of available layers to draw on
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.LAYERCOUNT_INVALID</c>.
    /// </para>
    ///-
    function get_layerCount():LongInt;

    function get_command():string;

    function set_command(newval:string):integer;

    ////
    /// <summary>
    ///   Retrieves $AFUNCTION$ for a given identifier.
    /// <para>
    ///   The identifier can be specified using several formats:
    /// </para>
    /// <para>
    /// </para>
    /// <para>
    ///   - FunctionLogicalName
    /// </para>
    /// <para>
    ///   - ModuleSerialNumber.FunctionIdentifier
    /// </para>
    /// <para>
    ///   - ModuleSerialNumber.FunctionLogicalName
    /// </para>
    /// <para>
    ///   - ModuleLogicalName.FunctionIdentifier
    /// </para>
    /// <para>
    ///   - ModuleLogicalName.FunctionLogicalName
    /// </para>
    /// <para>
    /// </para>
    /// <para>
    ///   This function does not require that $THEFUNCTION$ is online at the time
    ///   it is invoked. The returned object is nevertheless valid.
    ///   Use the method <c>YDisplay.isOnline()</c> to test if $THEFUNCTION$ is
    ///   indeed online at a given time. In case of ambiguity when looking for
    ///   $AFUNCTION$ by logical name, no error is notified: the first instance
    ///   found is returned. The search is performed first by hardware name,
    ///   then by logical name.
    /// </para>
    /// <para>
    ///   If a call to this object's is_online() method returns FALSE although
    ///   you are certain that the matching device is plugged, make sure that you did
    ///   call registerHub() at application initialization time.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="func">
    ///   a string that uniquely characterizes $THEFUNCTION$, for instance
    ///   <c>$FULLHARDWAREID$</c>.
    /// </param>
    /// <returns>
    ///   a <c>YDisplay</c> object allowing you to drive $THEFUNCTION$.
    /// </returns>
    ///-
    class function FindDisplay(func: string):TYDisplay;

    ////
    /// <summary>
    ///   Registers the callback function that is invoked on every change of advertised value.
    /// <para>
    ///   The callback is then invoked only during the execution of <c>ySleep</c> or <c>yHandleEvents</c>.
    ///   This provides control over the time when the callback is triggered. For good responsiveness,
    ///   remember to call one of these two functions periodically. The callback is called once juste after beeing
    ///   registered, passing the current advertised value  of the function, provided that it is not an empty string.
    ///   To unregister a callback, pass a NIL pointer as argument.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="callback">
    ///   the callback function to call, or a NIL pointer. The callback function should take two
    ///   arguments: the function object of which the value has changed, and the character string describing
    ///   the new advertised value.
    /// @noreturn
    /// </param>
    ///-
    function registerValueCallback(callback: TYDisplayValueCallback):LongInt; overload;

    function _invokeValueCallback(value: string):LongInt; override;

    function sendCommand(cmd: string):LongInt; overload; virtual;

    function flushLayers():LongInt; overload; virtual;

    function resetHiddenLayerFlags():LongInt; overload; virtual;

    function isFrozen():boolean; overload; virtual;

    ////
    /// <summary>
    ///   Returns the fast refresh usage policy in use (ePaper displays only).
    /// <para>
    ///   This setting is combined with the regenerate policy to determine when the screen
    ///   should be updated using a fast update versus or regenerated using a slower,
    ///   flickering full refresh.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a value among the <c>YDisplay.FASTREFRESH</c> enumeration
    ///   (<c>YDisplay.FASTREFRESH_WHENEVER_POSSIBLE</c>,
    ///   <c>YDisplay.FASTREFRESH_WHENEVER_SUPPORTED</c>,
    ///   <c>YDisplay.FASTREFRESH_NEVER</c>).
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.FASTREFRESH_INVALID</c>.
    /// </para>
    ///-
    function get_fastRefreshPolicy():TYFASTREFRESH; overload; virtual;

    ////
    /// <summary>
    ///   Returns the display regeneration minimal frequency (ePaper displays only).
    /// <para>
    ///   This setting is combined with the fast refresh usage policy to determine
    ///   when the screen should be updated using a fast update versus or regenerated
    ///   using a slower, flickering full refresh. To change the display regeneration minimal
    ///   frequency, use methode <c>set_fastRefreshPolicy()</c>.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   a value among the <c>YDisplay.REGENERATE</c> enumeration
    ///   (<c>YDisplay.REGENERATE_ON_REQUEST_ONLY</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_DAY</c>, <c>YDisplay.REGENERATE_EVERY_12H</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_6H</c>, <c>YDisplay.REGENERATE_EVERY_3H</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_2H</c>, <c>YDisplay.REGENERATE_EVERY_HOUR</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_30MIN</c>, <c>YDisplay.REGENERATE_EVERY_15MIN</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_480</c>, <c>YDisplay.REGENERATE_EVERY_432</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_360</c>, <c>YDisplay.REGENERATE_EVERY_288</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_240</c>, <c>YDisplay.REGENERATE_EVERY_192</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_144</c>, <c>YDisplay.REGENERATE_EVERY_96</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_48</c>, <c>YDisplay.REGENERATE_EVERY_36</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_24</c>, <c>YDisplay.REGENERATE_EVERY_12</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_10</c>, <c>YDisplay.REGENERATE_EVERY_8</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_6</c>, <c>YDisplay.REGENERATE_EVERY_4</c>,
    ///   <c>YDisplay.REGENERATE_ALWAYS</c>).
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>YDisplay.REGENERATE_INVALID</c>.
    /// </para>
    ///-
    function get_regeneratePolicy():TYREGENERATE; overload; virtual;

    ////
    /// <summary>
    ///   Changes the fast refresh usage policy and display regeneration minimal frequency
    ///   (ePaper displays only).
    /// <para>
    ///   These settings jointly determine when the screen should be
    ///   updated using a fast update versus or regenerated using a slower, flickering full
    ///   refresh.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="fastRefresh">
    ///   a value among the <c>YDisplay.FASTREFRESH</c> enumeration
    ///   (<c>YDisplay.FASTREFRESH_WHENEVER_POSSIBLE</c>,
    ///   <c>YDisplay.FASTREFRESH_WHENEVER_SUPPORTED</c>,
    ///   <c>YDisplay.FASTREFRESH_NEVER</c>),
    ///   corresponding to the policy for using fast refresh.
    /// </param>
    /// <param name="regenerate">
    ///   a value among the enumeration <c>YRefFrame.REGENERATE</c>
    ///   (<c>YDisplay.REGENERATE_ON_REQUEST_ONLY</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_DAY</c>, <c>YDisplay.REGENERATE_EVERY_12H</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_6H</c>, <c>YDisplay.REGENERATE_EVERY_3H</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_2H</c>, <c>YDisplay.REGENERATE_EVERY_HOUR</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_30MIN</c>, <c>YDisplay.REGENERATE_EVERY_15MIN</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_480</c>, <c>YDisplay.REGENERATE_EVERY_432</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_360</c>, <c>YDisplay.REGENERATE_EVERY_288</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_240</c>, <c>YDisplay.REGENERATE_EVERY_192</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_144</c>, <c>YDisplay.REGENERATE_EVERY_96</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_48</c>, <c>YDisplay.REGENERATE_EVERY_36</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_24</c>, <c>YDisplay.REGENERATE_EVERY_12</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_10</c>, <c>YDisplay.REGENERATE_EVERY_8</c>,
    ///   <c>YDisplay.REGENERATE_EVERY_6</c>, <c>YDisplay.REGENERATE_EVERY_4</c>,
    ///   <c>YDisplay.REGENERATE_ALWAYS</c>),
    ///   corresponding to the display minimal regeneration frequency.
    /// </param>
    /// <para>
    ///   Remember to call the <c>saveToFlash()</c>
    ///   method of the module if the modification must be kept.
    /// </para>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function set_fastRefreshPolicy(fastRefresh: TYFASTREFRESH; regenerate: TYREGENERATE):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Clears the display screen and resets all display layers to their default state.
    /// <para>
    ///   Using this function in a sequence will kill the sequence play-back. Do not use that
    ///   function to reset the display at sequence start-up.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function resetAll():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Forces an ePaper screen to perform a regenerative update using the slow
    ///   update method.
    /// <para>
    ///   Periodic use of the slow method (total panel update with
    ///   multiple inversions) prevents ghosting effects and improves contrast.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function regenerateDisplay():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Returns the current state of an ePaper display, specifically to
    ///   determine whether an update is in progress or whether a
    ///   configuration issue has been detected.
    /// <para>
    ///   If a display configuration
    ///   error has been detected, the error message can be retrieved.
    /// </para>
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="errmsg">
    ///   a string passed by reference to receive the error message.
    /// </param>
    /// <returns>
    ///   a value among the enumeration <c>YDisplay.DISPLAYSTATE</c>
    ///   (<c>YDisplay.DISPLAYSTATE_FAILURE</c>, <c>YDisplay.DISPLAYSTATE_OFF</c>,
    ///   <c>YDisplay.DISPLAYSTATE_POWERING</c>, <c>YDisplay.DISPLAYSTATE_IDLE</c>,
    ///   <c>YDisplay.DISPLAYSTATE_REFRESHING</c>)
    ///   corresponding to the current display state.
    /// </returns>
    ///-
    function get_ePaperState(var errmsg: string):TYDISPLAYSTATE; overload; virtual;

    ////
    /// <summary>
    ///   Disables screen refresh for a short period of time.
    /// <para>
    ///   The combination of
    ///   <c>postponeRefresh</c> and <c>triggerRefresh</c> can be used as an
    ///   alternative to double-buffering to avoid flickering during display updates.
    /// </para>
    /// </summary>
    /// <param name="duration">
    ///   duration of deactivation in milliseconds (max. 30 seconds)
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function postponeRefresh(duration: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Triggers an immediate screen refresh.
    /// <para>
    ///   The combination of
    ///   <c>postponeRefresh</c> and <c>triggerRefresh</c> can be used as an
    ///   alternative to double-buffering to avoid flickering during display updates.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function triggerRefresh():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Smoothly changes the brightness of the screen to produce a fade-in or fade-out
    ///   effect.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="brightness">
    ///   the new screen brightness
    /// </param>
    /// <param name="duration">
    ///   duration of the brightness transition, in milliseconds.
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function fade(brightness: LongInt; duration: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Starts to record all display commands into a sequence, for later replay.
    /// <para>
    ///   The name used to store the sequence is specified when calling
    ///   <c>saveSequence()</c>, once the recording is complete.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function newSequence():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Stops recording display commands and saves the sequence into the specified
    ///   file on the display internal memory.
    /// <para>
    ///   The sequence can be later replayed
    ///   using <c>playSequence()</c>.
    /// </para>
    /// </summary>
    /// <param name="sequenceName">
    ///   the name of the newly created sequence
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function saveSequence(sequenceName: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Replays a display sequence previously recorded using
    ///   <c>newSequence()</c> and <c>saveSequence()</c>.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="sequenceName">
    ///   the name of the newly created sequence
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function playSequence(sequenceName: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Waits for a specified delay (in milliseconds) before playing next
    ///   commands in current sequence.
    /// <para>
    ///   This method can be used while
    ///   recording a display sequence, to insert a timed wait in the sequence
    ///   (without any immediate effect). It can also be used dynamically while
    ///   playing a pre-recorded sequence, to suspend or resume the execution of
    ///   the sequence. To cancel a delay, call the same method with a zero delay.
    /// </para>
    /// </summary>
    /// <param name="delay_ms">
    ///   the duration to wait, in milliseconds
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function pauseSequence(delay_ms: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Stops immediately any ongoing sequence replay.
    /// <para>
    ///   The display is left as is.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function stopSequence():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Uploads an arbitrary file (for instance a GIF file) to the display, to the
    ///   specified full path name.
    /// <para>
    ///   If a file already exists with the same path name,
    ///   its content is overwritten.
    /// </para>
    /// </summary>
    /// <param name="pathname">
    ///   path and name of the new file to create
    /// </param>
    /// <param name="content">
    ///   binary buffer with the content to set
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function upload(pathname: string; content: TByteArray):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Copies the whole content of a layer to another layer.
    /// <para>
    ///   The color and transparency
    ///   of all the pixels from the destination layer are set to match the source pixels.
    ///   This method only affects the displayed content, but does not change any
    ///   property of the layer object.
    ///   Note that layer 0 has no transparency support (it is always completely opaque).
    /// </para>
    /// </summary>
    /// <param name="srcLayerId">
    ///   the identifier of the source layer (a number in range 0..layerCount-1)
    /// </param>
    /// <param name="dstLayerId">
    ///   the identifier of the destination layer (a number in range 0..layerCount-1)
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function copyLayerContent(srcLayerId: LongInt; dstLayerId: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Swaps the whole content of two layers.
    /// <para>
    ///   The color and transparency of all the pixels from
    ///   the two layers are swapped. This method only affects the displayed content, but does
    ///   not change any property of the layer objects. In particular, the visibility of each
    ///   layer stays unchanged. When used between one hidden layer and a visible layer,
    ///   this method makes it possible to easily implement double-buffering.
    ///   Note that layer 0 has no transparency support (it is always completely opaque).
    /// </para>
    /// </summary>
    /// <param name="layerIdA">
    ///   the first layer (a number in range 0..layerCount-1)
    /// </param>
    /// <param name="layerIdB">
    ///   the second layer (a number in range 0..layerCount-1)
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function swapLayerContent(layerIdA: LongInt; layerIdB: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Returns a YDisplayLayer object that can be used to draw on the specified
    ///   layer.
    /// <para>
    ///   The content is displayed only when the layer is active on the
    ///   screen (and not masked by other overlapping layers).
    /// </para>
    /// </summary>
    /// <param name="layerId">
    ///   the identifier of the layer (a number in range 0..layerCount-1)
    /// </param>
    /// <returns>
    ///   an <c>YDisplayLayer</c> object
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns <c>NIL</c>.
    /// </para>
    ///-
    function get_displayLayer(layerId: LongInt):TYDisplayLayer; overload; virtual;

    ////
    /// <summary>
    ///   Returns a color image with the current content of the display.
    /// <para>
    ///   The image is returned as a binary object, where each byte represents a pixel,
    ///   from left to right and from top to bottom. The palette used to map byte
    ///   values to RGB colors is filled into the list provided as argument.
    ///   In all cases, the first palette entry (value 0) corresponds to the
    ///   screen default background color.
    ///   The image dimensions are given by the display width and height.
    /// </para>
    /// </summary>
    /// <param name="palette">
    ///   a list to be filled with the image palette
    /// </param>
    /// <returns>
    ///   a binary object if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns an empty binary object.
    /// </para>
    ///-
    function readDisplay(palette: TLongIntArray):TByteArray; overload; virtual;

    function gifEncode(pixmap: TByteArray; palette: TLongIntArray; w: LongInt; shortHdr: boolean):TByteArray; overload; virtual;


    ////
    /// <summary>
    ///   Continues the enumeration of displays started using <c>yFirstDisplay()</c>.
    /// <para>
    ///   Caution: You can't make any assumption about the returned displays order.
    ///   If you want to find a specific a display, use <c>Display.findDisplay()</c>
    ///   and a hardwareID or a logical name.
    /// </para>
    /// </summary>
    /// <returns>
    ///   a pointer to a <c>YDisplay</c> object, corresponding to
    ///   a display currently online, or a <c>NIL</c> pointer
    ///   if there are no more displays to enumerate.
    /// </returns>
    ///-
    function nextDisplay():TYDisplay;
    ////
    /// <summary>
    ///   c
    /// <para>
    ///   omment from .yc definition
    /// </para>
    /// </summary>
    ///-
    class function FirstDisplay():TYDisplay;
  //--- (end of generated code: YDisplay accessors declaration)


end;

 // from YDisplayLayer


//--- (generated code: YDisplayLayer class start)
  ////
  /// <summary>
  ///   TYDisplayLayer Class: Interface for drawing into display layers, obtained by calling <c>display.get_displayLayer</c>.
  /// <para>
  /// </para>
  /// <para>
  ///   Each <c>DisplayLayer</c> represents an image layer containing objects
  ///   to display (bitmaps, text, etc.). The content is displayed only when
  ///   the layer is active on the screen (and not masked by other
  ///   overlapping layers).
  /// </para>
  /// </summary>
  ///-
  TYDisplayLayer=class(TObject)
  //--- (end of generated code: YDisplayLayer class start)


  //--- (generated code: YDisplayLayer declaration)
    // Attributes (function value cache)
    _cmdbuff                  : string;
    _hidden                   : boolean;
    _polyPrevX                : LongInt;
    _polyPrevY                : LongInt;
    //--- (end of generated code: YDisplayLayer declaration)
private
   _display : TYdisplay;
   _id:integer;

public
   constructor Create(parent: TYdisplay; id :integer);

   //--- (generated code: YDisplayLayer accessors declaration)

    function must_be_flushed():boolean; overload; virtual;

    function resetHiddenFlag():LongInt; overload; virtual;

    function flush_now():LongInt; overload; virtual;

    function command_push(cmd: string):LongInt; overload; virtual;

    function command_flush(cmd: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Reverts the layer to its initial state (fully transparent, default settings).
    /// <para>
    ///   Reinitializes the drawing pointer to the upper left position,
    ///   and selects the most visible pen color. If you only want to erase the layer
    ///   content, use the method <c>clear()</c> instead.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function reset():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Erases the whole content of the layer (makes it fully transparent).
    /// <para>
    ///   This method does not change any other attribute of the layer.
    ///   To reinitialize the layer attributes to defaults settings, use the method
    ///   <c>reset()</c> instead.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function clear():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects the color to be used for all subsequent drawing functions,
    ///   for filling as well as for line and text drawing.
    /// <para>
    ///   To select a different fill and outline color, use
    ///   <c>selectFillColor</c> and <c>selectLineColor</c>.
    ///   The pen color is provided as an RGB value.
    ///   For grayscale or monochrome displays, the value is
    ///   automatically converted to the proper range.
    /// </para>
    /// </summary>
    /// <param name="color">
    ///   the desired pen color, as a 24-bit RGB value
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectColorPen(color: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects the pen gray level for all subsequent drawing functions,
    ///   for filling as well as for line and text drawing.
    /// <para>
    ///   To select a different fill and outline color, use
    ///   <c>selectFillColor</c> and <c>selectLineColor</c>.
    ///   The gray level is provided as a number between
    ///   0 (black) and 255 (white, or whichever the lightest color is).
    ///   For monochrome displays (without gray levels), any value
    ///   lower than 128 is rendered as black, and any value equal
    ///   or above to 128 is non-black.
    /// </para>
    /// </summary>
    /// <param name="graylevel">
    ///   the desired gray level, from 0 to 255
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectGrayPen(graylevel: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects an eraser instead of a pen for all subsequent drawing functions,
    ///   except for bitmap copy functions.
    /// <para>
    ///   Any point drawn using the eraser
    ///   becomes transparent (as when the layer is empty), showing the other
    ///   layers beneath it.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectEraser():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects the color to be used for filling rectangular bars,
    ///   discs and polygons.
    /// <para>
    ///   The color is provided as an RGB value.
    ///   For grayscale or monochrome displays, the value is
    ///   automatically converted to the proper range.
    ///   You can also use the constants <c>FG_INK</c> to use the
    ///   default drawing colour, <c>BG_INK</c> to use the default
    ///   background colour, and <c>NO_INK</c> to disable filling.
    /// </para>
    /// </summary>
    /// <param name="color">
    ///   the desired drawing color, as a 24-bit RGB value,
    ///   or one of the constants <c>NO_INK</c>, <c>FG_INK</c>
    ///   or <c>BG_INK</c>
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectFillColor(color: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects the color to be used for drawing the outline of rectangular
    ///   bars, discs and polygons, as well as for drawing lines and text.
    /// <para>
    ///   The color is provided as an RGB value.
    ///   For grayscale or monochrome displays, the value is
    ///   automatically converted to the proper range.
    ///   You can also use the constants <c>FG_INK</c> to use the
    ///   default drawing colour, <c>BG_INK</c> to use the default
    ///   background colour, and <c>NO_INK</c> to disable outline drawing.
    /// </para>
    /// </summary>
    /// <param name="color">
    ///   the desired drawing color, as a 24-bit RGB value,
    ///   or one of the constants <c>NO_INK</c>, <c>FG_INK</c>
    ///   or <c>BG_INK</c>
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectLineColor(color: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects the line width for drawing the outline of rectangular
    ///   bars, discs and polygons, as well as for drawing lines.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="width">
    ///   the desired line width, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectLineWidth(width: LongInt):LongInt; overload; virtual;

    function setAntialiasingMode(mode: boolean):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a single pixel at the specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawPixel(x: LongInt; y: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws an empty rectangle at a specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x1">
    ///   the distance from left of layer to the left border of the rectangle, in pixels
    /// </param>
    /// <param name="y1">
    ///   the distance from top of layer to the top border of the rectangle, in pixels
    /// </param>
    /// <param name="x2">
    ///   the distance from left of layer to the right border of the rectangle, in pixels
    /// </param>
    /// <param name="y2">
    ///   the distance from top of layer to the bottom border of the rectangle, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawRect(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a filled rectangular bar at a specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x1">
    ///   the distance from left of layer to the left border of the rectangle, in pixels
    /// </param>
    /// <param name="y1">
    ///   the distance from top of layer to the top border of the rectangle, in pixels
    /// </param>
    /// <param name="x2">
    ///   the distance from left of layer to the right border of the rectangle, in pixels
    /// </param>
    /// <param name="y2">
    ///   the distance from top of layer to the bottom border of the rectangle, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawBar(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws an empty circle at a specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the center of the circle, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the center of the circle, in pixels
    /// </param>
    /// <param name="r">
    ///   the radius of the circle, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawCircle(x: LongInt; y: LongInt; r: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a filled disc at a given position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the center of the disc, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the center of the disc, in pixels
    /// </param>
    /// <param name="r">
    ///   the radius of the disc, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawDisc(x: LongInt; y: LongInt; r: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Selects a font to use for the next text drawing functions, by providing the name of the
    ///   font file.
    /// <para>
    ///   You can use a built-in font as well as a font file that you have previously
    ///   uploaded to the device built-in memory. If you experience problems selecting a font
    ///   file, check the device logs for any error message such as missing font file or bad font
    ///   file format.
    /// </para>
    /// </summary>
    /// <param name="fontname">
    ///   the font file name, embedded fonts are 8x8.yfm, Small.yfm, Medium.yfm, Large.yfm (not available on
    ///   Yocto-MiniDisplay).
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function selectFont(fontname: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a text string at the specified position.
    /// <para>
    ///   The point of the text that is aligned
    ///   to the specified pixel position is called the anchor point, and can be chosen among
    ///   several options. Text is rendered from left to right, without implicit wrapping.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the text anchor point, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the text anchor point, in pixels
    /// </param>
    /// <param name="anchor">
    ///   the text anchor point, chosen among the <c>YDisplayLayer.ALIGN</c> enumeration:
    ///   <c>YDisplayLayer.ALIGN_TOP_LEFT</c>,         <c>YDisplayLayer.ALIGN_CENTER_LEFT</c>,
    ///   <c>YDisplayLayer.ALIGN_BASELINE_LEFT</c>,    <c>YDisplayLayer.ALIGN_BOTTOM_LEFT</c>,
    ///   <c>YDisplayLayer.ALIGN_TOP_CENTER</c>,       <c>YDisplayLayer.ALIGN_CENTER</c>,
    ///   <c>YDisplayLayer.ALIGN_BASELINE_CENTER</c>,  <c>YDisplayLayer.ALIGN_BOTTOM_CENTER</c>,
    ///   <c>YDisplayLayer.ALIGN_TOP_DECIMAL</c>,      <c>YDisplayLayer.ALIGN_CENTER_DECIMAL</c>,
    ///   <c>YDisplayLayer.ALIGN_BASELINE_DECIMAL</c>, <c>YDisplayLayer.ALIGN_BOTTOM_DECIMAL</c>,
    ///   <c>YDisplayLayer.ALIGN_TOP_RIGHT</c>,        <c>YDisplayLayer.ALIGN_CENTER_RIGHT</c>,
    ///   <c>YDisplayLayer.ALIGN_BASELINE_RIGHT</c>,   <c>YDisplayLayer.ALIGN_BOTTOM_RIGHT</c>.
    /// </param>
    /// <param name="text">
    ///   the text string to draw
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawText(x: LongInt; y: LongInt; anchor: TYALIGN; text: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws an image previously uploaded to the device filesystem, at the specified position.
    /// <para>
    ///   At present time, GIF images are the only supported image format. If you experience
    ///   problems using an image file, check the device logs for any error message such as
    ///   missing image file or bad image file format.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the left of the image, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the top of the image, in pixels
    /// </param>
    /// <param name="imagename">
    ///   the GIF file name
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawImage(x: LongInt; y: LongInt; imagename: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a GIF image provided as a binary buffer at the specified position.
    /// <para>
    ///   If the image drawing must be included in an animation sequence, save it
    ///   in the device filesystem first and use <c>drawImage</c> instead.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the left of the image, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the top of the image, in pixels
    /// </param>
    /// <param name="gifimage">
    ///   a binary object with the content of a GIF file
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawGIF(x: LongInt; y: LongInt; gifimage: TByteArray):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a bitmap at the specified position.
    /// <para>
    ///   The bitmap is provided as a binary object,
    ///   where each pixel maps to a bit, from left to right and from top to bottom.
    ///   The most significant bit of each byte maps to the leftmost pixel, and the least
    ///   significant bit maps to the rightmost pixel. Bits set to 1 are drawn using the
    ///   layer selected pen color. Bits set to 0 are drawn using the specified background
    ///   color, unless <c>NO_INK</c> (-1) is specified, in which case they are not
    ///   drawn at all (as if transparent).
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the left of the bitmap, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the top of the bitmap, in pixels
    /// </param>
    /// <param name="w">
    ///   the width of the bitmap, in pixels
    /// </param>
    /// <param name="bitmap">
    ///   a binary object
    /// </param>
    /// <param name="bgcol">
    ///   the RGB background color to use for zero bits, as a 24-bit RGB value,
    ///   or one of the constants <c>NO_INK</c>, <c>FG_INK</c> or <c>BG_INK</c>
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawBitmap(x: LongInt; y: LongInt; w: LongInt; bitmap: TByteArray; bgcol: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a color pixmap at the specified position.
    /// <para>
    ///   The pixmap is provided as a binary
    ///   object, where each byte maps to one pixel. The 24 bit RGB value corresponding to each
    ///   byte value is defined in the palette provided as extra argument.
    ///   The palette maximal size is 8, and it is recommended to use the smallest possible
    ///   palette size to optimize the size of data to be sent to the display.
    ///   The height of the pixmap is implicitely given by the pixmap buffer size.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the left of the pixmap, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the top of the pixmap, in pixels
    /// </param>
    /// <param name="w">
    ///   the width of the pixmap, in pixels
    /// </param>
    /// <param name="pixmap">
    ///   a binary buffer where each byte maps to one pixel
    /// </param>
    /// <param name="palette">
    ///   an array of 24-bit RGB values, defining the color for each byte value in pixmap
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function drawPixmap(x: LongInt; y: LongInt; w: LongInt; pixmap: TByteArray; palette: TLongIntArray):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Moves the drawing pointer of this layer to the specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function moveTo(x: LongInt; y: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Draws a line from current drawing pointer position to the specified position.
    /// <para>
    ///   The specified destination pixel is included in the line. The pointer position
    ///   is then moved to the end point of the line.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the end point of the line, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the end point of the line, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function lineTo(x: LongInt; y: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Starts drawing a polygon with the first corner at the specified position.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function polygonStart(x: LongInt; y: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Adds a point to the currently open polygon, previously opened using
    ///   <c>polygonStart</c>.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of layer to the new point, in pixels
    /// </param>
    /// <param name="y">
    ///   the distance from top of layer to the new point, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function polygonAdd(x: LongInt; y: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Closes the currently open polygon, fill its content the fill color currently
    ///   selected for the layer, and draw its outline using the selected line color.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function polygonEnd():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Outputs a message in the console area, and advances the console pointer accordingly.
    /// <para>
    ///   The console pointer position is automatically moved to the beginning
    ///   of the next line when a newline character is met, or when the right margin
    ///   is hit. When the new text to display extends below the lower margin, the
    ///   console area is automatically scrolled up.
    /// </para>
    /// </summary>
    /// <param name="text">
    ///   the message to display
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function consoleOut(text: string):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Sets up display margins for the <c>consoleOut</c> function.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="x1">
    ///   the distance from left of layer to the left margin, in pixels
    /// </param>
    /// <param name="y1">
    ///   the distance from top of layer to the top margin, in pixels
    /// </param>
    /// <param name="x2">
    ///   the distance from left of layer to the right margin, in pixels
    /// </param>
    /// <param name="y2">
    ///   the distance from top of layer to the bottom margin, in pixels
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function setConsoleMargins(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Sets up the background color used by the <c>clearConsole</c> function and by
    ///   the console scrolling feature.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="bgcol">
    ///   the background gray level to use when scrolling (0 = black,
    ///   255 = white), or -1 for transparent
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function setConsoleBackground(bgcol: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Sets up the wrapping behavior used by the <c>consoleOut</c> function.
    /// <para>
    /// </para>
    /// </summary>
    /// <param name="wordwrap">
    ///   <c>true</c> to wrap only between words,
    ///   <c>false</c> to wrap on the last column anyway.
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function setConsoleWordWrap(wordwrap: boolean):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Blanks the console area within console margins, and resets the console pointer
    ///   to the upper left corner of the console.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function clearConsole():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Sets the position of the layer relative to the display upper left corner.
    /// <para>
    ///   When smooth scrolling is used, the display offset of the layer is
    ///   automatically updated during the next milliseconds to animate the move of the layer.
    /// </para>
    /// </summary>
    /// <param name="x">
    ///   the distance from left of display to the upper left corner of the layer
    /// </param>
    /// <param name="y">
    ///   the distance from top of display to the upper left corner of the layer
    /// </param>
    /// <param name="scrollTime">
    ///   number of milliseconds to use for smooth scrolling, or
    ///   0 if the scrolling should be immediate.
    /// </param>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function setLayerPosition(x: LongInt; y: LongInt; scrollTime: LongInt):LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Hides the layer.
    /// <para>
    ///   The state of the layer is preserved but the layer is not displayed
    ///   on the screen until the next call to <c>unhide()</c>. Hiding the layer can positively
    ///   affect the drawing speed, since it postpones the rendering until all operations are
    ///   completed (double-buffering).
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function hide():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Shows the layer.
    /// <para>
    ///   Shows the layer again after a hide command.
    /// </para>
    /// </summary>
    /// <returns>
    ///   <c>YAPI.SUCCESS</c> if the call succeeds.
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns a negative error code.
    /// </para>
    ///-
    function unhide():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Gets parent YDisplay.
    /// <para>
    ///   Returns the parent YDisplay object of the current YDisplayLayer.
    /// </para>
    /// </summary>
    /// <returns>
    ///   an <c>YDisplay</c> object
    /// </returns>
    ///-
    function get_display():TYDisplay; overload; virtual;

    ////
    /// <summary>
    ///   Returns the display width, in pixels.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the display width, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns Y_DISPLAYWIDTH_INVALID.
    /// </para>
    ///-
    function get_displayWidth():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Returns the display height, in pixels.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the display height, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns Y_DISPLAYHEIGHT_INVALID.
    /// </para>
    ///-
    function get_displayHeight():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Returns the width of the layers to draw on, in pixels.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the width of the layers to draw on, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns Y_LAYERWIDTH_INVALID.
    /// </para>
    ///-
    function get_layerWidth():LongInt; overload; virtual;

    ////
    /// <summary>
    ///   Returns the height of the layers to draw on, in pixels.
    /// <para>
    /// </para>
    /// </summary>
    /// <returns>
    ///   an integer corresponding to the height of the layers to draw on, in pixels
    /// </returns>
    /// <para>
    ///   On failure, throws an exception or returns Y_LAYERHEIGHT_INVALID.
    /// </para>
    ///-
    function get_layerHeight():LongInt; overload; virtual;


  //--- (end of generated code: YDisplayLayer accessors declaration)
end;

//--- (generated code: YDisplay functions declaration)
  ////
  /// <summary>
  ///   Retrieves a display for a given identifier.
  /// <para>
  ///   The identifier can be specified using several formats:
  /// </para>
  /// <para>
  /// </para>
  /// <para>
  ///   - FunctionLogicalName
  /// </para>
  /// <para>
  ///   - ModuleSerialNumber.FunctionIdentifier
  /// </para>
  /// <para>
  ///   - ModuleSerialNumber.FunctionLogicalName
  /// </para>
  /// <para>
  ///   - ModuleLogicalName.FunctionIdentifier
  /// </para>
  /// <para>
  ///   - ModuleLogicalName.FunctionLogicalName
  /// </para>
  /// <para>
  /// </para>
  /// <para>
  ///   This function does not require that the display is online at the time
  ///   it is invoked. The returned object is nevertheless valid.
  ///   Use the method <c>YDisplay.isOnline()</c> to test if the display is
  ///   indeed online at a given time. In case of ambiguity when looking for
  ///   a display by logical name, no error is notified: the first instance
  ///   found is returned. The search is performed first by hardware name,
  ///   then by logical name.
  /// </para>
  /// <para>
  ///   If a call to this object's is_online() method returns FALSE although
  ///   you are certain that the matching device is plugged, make sure that you did
  ///   call registerHub() at application initialization time.
  /// </para>
  /// <para>
  /// </para>
  /// </summary>
  /// <param name="func">
  ///   a string that uniquely characterizes the display, for instance
  ///   <c>YD128X32.display</c>.
  /// </param>
  /// <returns>
  ///   a <c>YDisplay</c> object allowing you to drive the display.
  /// </returns>
  ///-
  function yFindDisplay(func:string):TYDisplay;
  ////
  /// <summary>
  ///   Starts the enumeration of displays currently accessible.
  /// <para>
  ///   Use the method <c>YDisplay.nextDisplay()</c> to iterate on
  ///   next displays.
  /// </para>
  /// </summary>
  /// <returns>
  ///   a pointer to a <c>YDisplay</c> object, corresponding to
  ///   the first display currently online, or a <c>NIL</c> pointer
  ///   if there are none.
  /// </returns>
  ///-
  function yFirstDisplay():TYDisplay;

//--- (end of generated code: YDisplay functions declaration)

implementation

destructor TYDisplay.destroy();
 var
  i:integer;
 begin
  if _allDisplayLayers<>nil then
   begin
    for i:=0 to  length(_allDisplayLayers)-1 do
      begin
        _allDisplayLayers[i].free();
        _allDisplayLayers[i]:=nil;
      end;
    setlength(_allDisplayLayers,0);

  end;
  inherited destroy();
 end;


 constructor TYDisplay.Create(func:string);
    begin
      inherited Create(func);
      _className := 'Display';
	  //--- (generated code: YDisplay accessors initialization)
      _enabled := Y_ENABLED_INVALID;
      _startupSeq := Y_STARTUPSEQ_INVALID;
      _brightness := Y_BRIGHTNESS_INVALID;
      _autoInvertDelay := Y_AUTOINVERTDELAY_INVALID;
      _orientation := Y_ORIENTATION_INVALID;
      _displayPanel := Y_DISPLAYPANEL_INVALID;
      _displayWidth := Y_DISPLAYWIDTH_INVALID;
      _displayHeight := Y_DISPLAYHEIGHT_INVALID;
      _displayType := Y_DISPLAYTYPE_INVALID;
      _layerWidth := Y_LAYERWIDTH_INVALID;
      _layerHeight := Y_LAYERHEIGHT_INVALID;
      _layerCount := Y_LAYERCOUNT_INVALID;
      _command := Y_COMMAND_INVALID;
      _valueCallbackDisplay := nil;
      _frozenUntil := 0;
      //--- (end of generated code: YDisplay accessors initialization)
    end;


//--- (generated code: YDisplay implementation)
{$HINTS OFF}
  function TYDisplay._parseAttr(member:PJSONRECORD):integer;
    var
      sub : PJSONRECORD;
      i,l        : integer;
    begin
      if (member^.name = 'enabled') then
        begin
          _enabled := member^.ivalue;
         result := 1;
         exit;
         end;
      if (member^.name = 'startupSeq') then
        begin
          _startupSeq := string(member^.svalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'brightness') then
        begin
          _brightness := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'autoInvertDelay') then
        begin
          _autoInvertDelay := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'orientation') then
        begin
          _orientation := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'displayPanel') then
        begin
          _displayPanel := string(member^.svalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'displayWidth') then
        begin
          _displayWidth := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'displayHeight') then
        begin
          _displayHeight := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'displayType') then
        begin
          _displayType := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'layerWidth') then
        begin
          _layerWidth := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'layerHeight') then
        begin
          _layerHeight := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'layerCount') then
        begin
          _layerCount := integer(member^.ivalue);
         result := 1;
         exit;
         end;
      if (member^.name = 'command') then
        begin
          _command := string(member^.svalue);
         result := 1;
         exit;
         end;
      result := inherited _parseAttr(member);
    end;
{$HINTS ON}

  function TYDisplay.get_enabled():Integer;
    var
      res : Integer;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_ENABLED_INVALID;
              exit;
            end;
        end;
      res := self._enabled;
      result := res;
      exit;
    end;


  function TYDisplay.set_enabled(newval:Integer):integer;
    var
      rest_val: string;
    begin
      if(newval>0) then rest_val := '1' else rest_val := '0';
      result := _setAttr('enabled',rest_val);
    end;

  function TYDisplay.get_startupSeq():string;
    var
      res : string;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_STARTUPSEQ_INVALID;
              exit;
            end;
        end;
      res := self._startupSeq;
      result := res;
      exit;
    end;


  function TYDisplay.set_startupSeq(newval:string):integer;
    var
      rest_val: string;
    begin
      rest_val := newval;
      result := _setAttr('startupSeq',rest_val);
    end;

  function TYDisplay.get_brightness():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_BRIGHTNESS_INVALID;
              exit;
            end;
        end;
      res := self._brightness;
      result := res;
      exit;
    end;


  function TYDisplay.set_brightness(newval:LongInt):integer;
    var
      rest_val: string;
    begin
      rest_val := inttostr(newval);
      result := _setAttr('brightness',rest_val);
    end;

  function TYDisplay.get_autoInvertDelay():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_AUTOINVERTDELAY_INVALID;
              exit;
            end;
        end;
      res := self._autoInvertDelay;
      result := res;
      exit;
    end;


  function TYDisplay.set_autoInvertDelay(newval:LongInt):integer;
    var
      rest_val: string;
    begin
      rest_val := inttostr(newval);
      result := _setAttr('autoInvertDelay',rest_val);
    end;

  function TYDisplay.get_orientation():Integer;
    var
      res : Integer;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_ORIENTATION_INVALID;
              exit;
            end;
        end;
      res := self._orientation;
      result := res;
      exit;
    end;


  function TYDisplay.set_orientation(newval:Integer):integer;
    var
      rest_val: string;
    begin
      rest_val := inttostr(newval);
      result := _setAttr('orientation',rest_val);
      _clearLazyCache();
    end;

  function TYDisplay.get_displayPanel():string;
    var
      res : string;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_DISPLAYPANEL_INVALID;
              exit;
            end;
        end;
      res := self._displayPanel;
      result := res;
      exit;
    end;


  function TYDisplay.set_displayPanel(newval:string):integer;
    var
      rest_val: string;
    begin
      rest_val := newval;
      result := _setAttr('displayPanel',rest_val);
      _clearLazyCache();
    end;

  function TYDisplay.get_displayWidth():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_DISPLAYWIDTH_INVALID;
              exit;
            end;
        end;
      res := self._displayWidth;
      result := res;
      exit;
    end;


  function TYDisplay.get_displayHeight():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_DISPLAYHEIGHT_INVALID;
              exit;
            end;
        end;
      res := self._displayHeight;
      result := res;
      exit;
    end;


  function TYDisplay.get_displayType():Integer;
    var
      res : Integer;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_DISPLAYTYPE_INVALID;
              exit;
            end;
        end;
      res := self._displayType;
      result := res;
      exit;
    end;


  function TYDisplay.get_layerWidth():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_LAYERWIDTH_INVALID;
              exit;
            end;
        end;
      res := self._layerWidth;
      result := res;
      exit;
    end;


  function TYDisplay.get_layerHeight():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_LAYERHEIGHT_INVALID;
              exit;
            end;
        end;
      res := self._layerHeight;
      result := res;
      exit;
    end;


  function TYDisplay.get_layerCount():LongInt;
    var
      res : LongInt;
    begin
      if self._cacheExpiration = 0 then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_LAYERCOUNT_INVALID;
              exit;
            end;
        end;
      res := self._layerCount;
      result := res;
      exit;
    end;


  function TYDisplay.get_command():string;
    var
      res : string;
    begin
      if self._cacheExpiration <= yGetTickCount then
        begin
          if self.load(_yapicontext.GetCacheValidity()) <> YAPI_SUCCESS then
            begin
              result := Y_COMMAND_INVALID;
              exit;
            end;
        end;
      res := self._command;
      result := res;
      exit;
    end;


  function TYDisplay.set_command(newval:string):integer;
    var
      rest_val: string;
    begin
      rest_val := newval;
      result := _setAttr('command',rest_val);
    end;

  class function TYDisplay.FindDisplay(func: string):TYDisplay;
    var
      obj : TYDisplay;
    begin
      obj := TYDisplay(TYFunction._FindFromCache('Display', func));
      if (obj = nil) then
        begin
          obj :=  TYDisplay.create(func);
          TYFunction._AddToCache('Display', func, obj);
        end;
      result := obj;
      exit;
    end;


  function TYDisplay.registerValueCallback(callback: TYDisplayValueCallback):LongInt;
    var
      val : string;
    begin
      if (addr(callback) <> nil) then
        begin
          TYFunction._UpdateValueCallbackList(self, true);
        end
      else
        begin
          TYFunction._UpdateValueCallbackList(self, false);
        end;
      self._valueCallbackDisplay := callback;
      // Immediately invoke value callback with current value
      if (addr(callback) <> nil) and self.isOnline then
        begin
          val := self._advertisedValue;
          if not((val = '')) then
            begin
              self._invokeValueCallback(val);
            end;
        end;
      result := 0;
      exit;
    end;


  function TYDisplay._invokeValueCallback(value: string):LongInt;
    begin
      if (addr(self._valueCallbackDisplay) <> nil) then
        begin
          self._valueCallbackDisplay(self, value);
        end
      else
        begin
          inherited _invokeValueCallback(value);
        end;
      result := 0;
      exit;
    end;


  function TYDisplay.sendCommand(cmd: string):LongInt;
    begin
      if not(self._recording) then
        begin
          result := self.set_command(cmd);
          exit;
        end;
      self._sequence := ''+self._sequence+''+cmd+''#10'';
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplay.flushLayers():LongInt;
    var
      ii_0 : LongInt;
    begin
      for ii_0:=0 to length(self._allDisplayLayers)-1 do
        begin
          if self._allDisplayLayers[ii_0].must_be_flushed() then
            begin
              self._allDisplayLayers[ii_0].flush_now();
            end;
        end;
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplay.resetHiddenLayerFlags():LongInt;
    var
      ii_0 : LongInt;
    begin
      for ii_0:=0 to length(self._allDisplayLayers)-1 do
        begin
          self._allDisplayLayers[ii_0].resetHiddenFlag();
        end;
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplay.isFrozen():boolean;
    begin
      if self._frozenUntil = 0 then
        begin
          result := false;
          exit;
        end;
      if self._frozenUntil <= yGetTickCount then
        begin
          self._frozenUntil := 0;
          result := false;
          exit;
        end;
      result := true;
      exit;
    end;


  function TYDisplay.get_fastRefreshPolicy():TYFASTREFRESH;
    var
      combined : LongInt;
      fmod : LongInt;
    begin
      combined := self.get_brightness;
      if combined < 0 then
        begin
          result := Y_FASTREFRESH_INVALID;
          exit;
        end;
      fmod := (combined div 25);
      if fmod >= 2 then
        begin
          fmod := fmod - 2;
        end;
      result := TYFASTREFRESH(fmod);
      exit;
    end;


  function TYDisplay.get_regeneratePolicy():TYREGENERATE;
    var
      combined : LongInt;
      fval : LongInt;
    begin
      combined:= self.get_brightness;
      if combined < 0 then
        begin
          result := Y_REGENERATE_INVALID;
          exit;
        end;
      if combined >= 100 then
        begin
          fval := 25;
        end
      else
        begin
          fval := (combined mod 25);
        end;
      result := TYREGENERATE(fval);
      exit;
    end;


  function TYDisplay.set_fastRefreshPolicy(fastRefresh: TYFASTREFRESH; regenerate: TYREGENERATE):LongInt;
    var
      combined : LongInt;
      fmod : LongInt;
      fval : LongInt;
    begin
      fmod := ord(fastRefresh);
      fval := ord(regenerate);
      if (fval = 25) or(fmod = 2) then
        begin
          combined := 100;
        end
      else
        begin
          combined := 50 + fmod * 25 + fval;
        end;
      result := self.set_brightness(combined);
      exit;
    end;


  function TYDisplay.resetAll():LongInt;
    begin
      self.flushLayers;
      self.resetHiddenLayerFlags;
      result := self.sendCommand('Z');
      exit;
    end;


  function TYDisplay.regenerateDisplay():LongInt;
    begin
      result := self.sendCommand('z');
      exit;
    end;


  function TYDisplay.get_ePaperState(var errmsg: string):TYDISPLAYSTATE;
    var
      json : TByteArray;
      dispError : string;
      dispState : LongInt;
    begin
      if self.get_displayType = Y_DISPLAYTYPE_MONO then
        begin
          errmsg := 'Not an ePaper display';
          result := TYDISPLAYSTATE(0);
          exit;
        end;
      json := self._download('disp.json');
      if length(json) = 0 then
        begin
          errmsg := self.get_errorMessage;
          result := TYDISPLAYSTATE(0);
          exit;
        end
      else
        begin
          dispError := self._json_get_string(self._get_json_path(json, 'err'));
          errmsg := dispError;
          if Length(dispError) > 0 then
            begin
              result := TYDISPLAYSTATE(0);
              exit;
            end;
          dispState := _atoi(self._json_get_key(json, 'state'));
          if dispState > 10 then
            begin
              result := TYDISPLAYSTATE(4);
              exit;
            end;
          if dispState = 10 then
            begin
              result := TYDISPLAYSTATE(3);
              exit;
            end;
          if dispState > 0 then
            begin
              result := TYDISPLAYSTATE(2);
              exit;
            end;
        end;
      result := TYDISPLAYSTATE(1);
      exit;
    end;


  function TYDisplay.postponeRefresh(duration: LongInt):LongInt;
    begin
      self._frozenUntil := yGetTickCount + duration;
      result := self.sendCommand('H'+inttostr(duration));
      exit;
    end;


  function TYDisplay.triggerRefresh():LongInt;
    begin
      self._frozenUntil := 0;
      self.flushLayers;
      result := self.sendCommand('H0');
      exit;
    end;


  function TYDisplay.fade(brightness: LongInt; duration: LongInt):LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('+'+inttostr(brightness)+','+inttostr(duration));
      exit;
    end;


  function TYDisplay.newSequence():LongInt;
    begin
      self.flushLayers;
      self._sequence := '';
      self._recording := true;
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplay.saveSequence(sequenceName: string):LongInt;
    begin
      self.flushLayers;
      self._recording := false;
      self._upload(sequenceName, _StrToByte(self._sequence));
      //We need to use YPRINTF("") for Objective-C
      self._sequence := '';
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplay.playSequence(sequenceName: string):LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('S'+sequenceName);
      exit;
    end;


  function TYDisplay.pauseSequence(delay_ms: LongInt):LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('W'+inttostr(delay_ms));
      exit;
    end;


  function TYDisplay.stopSequence():LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('S');
      exit;
    end;


  function TYDisplay.upload(pathname: string; content: TByteArray):LongInt;
    begin
      self.flushLayers;
      result := self._upload(pathname, content);
      exit;
    end;


  function TYDisplay.copyLayerContent(srcLayerId: LongInt; dstLayerId: LongInt):LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('o'+inttostr(srcLayerId)+','+inttostr(dstLayerId));
      exit;
    end;


  function TYDisplay.swapLayerContent(layerIdA: LongInt; layerIdB: LongInt):LongInt;
    begin
      self.flushLayers;
      result := self.sendCommand('E'+inttostr(layerIdA)+','+inttostr(layerIdB));
      exit;
    end;


  function TYDisplay.get_displayLayer(layerId: LongInt):TYDisplayLayer;
    var
      layercount : LongInt;
      idx : LongInt;
      _allDisplayLayers_pos : LongInt;
    begin
      layercount := self.get_layerCount;
      if not((layerId >= 0) and(layerId < layercount)) then
        begin
          self._throw(YAPI_INVALID_ARGUMENT,'invalid DisplayLayer index');
          result:=nil;
          exit;
        end;
      if length(self._allDisplayLayers) = 0 then
        begin
          _allDisplayLayers_pos := length(self._allDisplayLayers);
          SetLength(self._allDisplayLayers, _allDisplayLayers_pos+layercount);
          idx := 0;
          while idx < layercount do
            begin
              self._allDisplayLayers[_allDisplayLayers_pos] := TYDisplayLayer.create(self, idx);
              inc(_allDisplayLayers_pos);
              idx := idx + 1;
            end;
          SetLength(self._allDisplayLayers, _allDisplayLayers_pos);
        end;
      result := self._allDisplayLayers[layerId];
      exit;
    end;


  function TYDisplay.readDisplay(palette: TLongIntArray):TByteArray;
    var
      zipmap : TByteArray;
      zipsize : LongInt;
      zipwidth : LongInt;
      zipheight : LongInt;
      ziprotate : LongInt;
      zipcolors : LongInt;
      zipcol : LongInt;
      zipbits : LongInt;
      zipmask : LongInt;
      srcpos : LongInt;
      endrun : LongInt;
      srcpat : LongInt;
      srcbit : LongInt;
      srcval : LongInt;
      srcx : LongInt;
      srcy : LongInt;
      srci : LongInt;
      pixmap : TByteArray;
      pixcount : LongInt;
      pixval : LongInt;
      pixpos : LongInt;
      rotmap : TByteArray;
      palette_pos : LongInt;
    begin
      setlength(pixmap,0);
      // Check if the display firmware has autoInvertDelay and pixels.bin support

      if self.get_autoInvertDelay < 0 then
        begin
          // Old firmware, use uncompressed GIF output to rebuild pixmap
          zipmap := self._download('display.gif');
          zipsize := length(zipmap);
          if zipsize = 0 then
            begin
              result := pixmap;
              exit;
            end;
          if not(zipsize >= 32) then
            begin
              self._throw(YAPI_IO_ERROR,'not a GIF image');
              result:=pixmap;
              exit;
            end;
          if not((zipmap[0] = 71) and(zipmap[2] = 70)) then
            begin
              self._throw(YAPI_INVALID_ARGUMENT,'not a GIF image');
              result:=pixmap;
              exit;
            end;
          zipwidth := zipmap[6] + 256 * zipmap[7];
          zipheight := zipmap[8] + 256 * zipmap[9];
          palette_pos := 0;
          SetLength(palette, 2);
          zipcol := zipmap[13] * 65536 + zipmap[14] * 256 + zipmap[15];
          palette[palette_pos] := zipcol;
          inc(palette_pos);
          zipcol := zipmap[16] * 65536 + zipmap[17] * 256 + zipmap[18];
          palette[palette_pos] := zipcol;
          inc(palette_pos);
          SetLength(palette, palette_pos);
          pixcount := zipwidth * zipheight;
          setlength(pixmap,pixcount);
          pixpos := 0;
          srcpos := 30;
          zipsize := zipsize - 2;
          while srcpos < zipsize do
            begin
              // load next run size
              endrun := srcpos + 1 + zipmap[srcpos];
              srcpos := srcpos + 1;
              while srcpos < endrun do
                begin
                  srcval := zipmap[srcpos];
                  srcpos := srcpos + 1;
                  srcbit := 8;
                  while srcbit <> 0 do
                    begin
                      if srcbit < 3 then
                        begin
                          srcval := srcval + ((zipmap[srcpos]) shl (srcbit));
                          srcpos := srcpos + 1;
                        end;
                      pixval := ((srcval) and 7);
                      srcval := ((srcval) shr 3);
                      if not((pixval > 1) and(pixval <> 4)) then
                        begin
                          self._throw(YAPI_INVALID_ARGUMENT,'unexpected encoding');
                          result:=pixmap;
                          exit;
                        end;
                      pixmap[pixpos] := pixval;
                      pixpos := pixpos + 1;
                      srcbit := srcbit - 3;
                    end;
                end;
            end;
          result := pixmap;
          exit;
        end;
      // New firmware, use compressed pixels.bin
      zipmap := self._download('pixels.bin');
      zipsize := length(zipmap);
      if zipsize = 0 then
        begin
          result := pixmap;
          exit;
        end;
      if not(zipsize >= 16) then
        begin
          self._throw(YAPI_IO_ERROR,'not a pixmap');
          result:=pixmap;
          exit;
        end;
      if not((zipmap[0] = 80) and(zipmap[2] = 88)) then
        begin
          self._throw(YAPI_INVALID_ARGUMENT,'not a pixmap');
          result:=pixmap;
          exit;
        end;
      zipwidth := zipmap[4] + 256 * zipmap[5];
      zipheight := zipmap[6] + 256 * zipmap[7];
      ziprotate := zipmap[8];
      zipcolors := zipmap[9];
      palette_pos := 0;
      SetLength(palette, zipcolors);;
      srcpos := 10;
      srci := 0;
      while srci < zipcolors do
        begin
          zipcol := zipmap[srcpos] * 65536 + zipmap[srcpos+1] * 256 + zipmap[srcpos+2];
          palette[palette_pos] := zipcol;
          inc(palette_pos);
          srcpos := srcpos + 3;
          srci := srci + 1;
        end;
      zipbits := 1;
      while ((1) shl (zipbits)) < zipcolors do
        begin
          zipbits := zipbits + 1;
        end;
      zipmask := ((1) shl (zipbits)) - 1;
      SetLength(palette, palette_pos);;
      pixcount := zipwidth * zipheight;
      setlength(pixmap,pixcount);
      srcx := 0;
      srcy := 0;
      srcval := 0;
      while srcpos < zipsize do
        begin
          // load next compression pattern byte
          srcpat := zipmap[srcpos];
          srcpos := srcpos + 1;
          srcbit := 7;
          while srcbit >= 0 do
            begin
              // get next bitmap byte
              if ((srcpat) and 128) <> 0 then
                begin
                  srcval := zipmap[srcpos];
                  srcpos := srcpos + 1;
                  if zipbits > 1 then
                    begin
                      srcval := ((srcval) shl 8) + zipmap[srcpos];
                      srcpos := srcpos + 1;
                    end;
                end;
              srcpat := ((srcpat) shl 1);
              pixpos := srcy * zipwidth + srcx;
              // produce 8 pixels
              srci := 7 * zipbits;
              while srci >= 0 do
                begin
                  pixval := ((((srcval) shr (srci))) and (zipmask));
                  pixmap[pixpos] := pixval;
                  pixpos := pixpos + 1;
                  srci := srci - zipbits;
                end;
              srcy := srcy + 1;
              if srcy >= zipheight then
                begin
                  srcy := 0;
                  srcx := srcx + 8;
                  // drop last bytes if image is not a multiple of 8
                  if srcx >= zipwidth then
                    begin
                      srcbit := 0;
                    end;
                end;
              srcbit := srcbit - 1;
            end;
        end;
      // rotate pixmap to match display orientation
      if ziprotate = 0 then
        begin
          result := pixmap;
          exit;
        end;
      if ((ziprotate) and 2) <> 0 then
        begin
          // rotate buffer 180 degrees by swapping pixels
          srcpos := 0;
          pixpos := pixcount - 1;
          while srcpos < pixpos do
            begin
              pixval := pixmap[srcpos];
              pixmap[srcpos] := pixmap[pixpos];
              pixmap[pixpos] := pixval;
              srcpos := srcpos + 1;
              pixpos := pixpos - 1;
            end;
        end;
      if ((ziprotate) and 1) = 0 then
        begin
          result := pixmap;
          exit;
        end;
      // rotate 90 ccw: first pixel is bottom left
      setlength(rotmap,pixcount);
      srcx := 0;
      srcy := zipwidth - 1;
      srcpos := 0;
      while srcpos < pixcount do
        begin
          pixval := pixmap[srcpos];
          pixpos := srcy * zipheight + srcx;
          rotmap[pixpos] := pixval;
          srcy := srcy - 1;
          if srcy < 0 then
            begin
              srcx := srcx + 1;
              srcy := zipwidth - 1;
            end;
          srcpos := srcpos + 1;
        end;
      result := rotmap;
      exit;
    end;


  function TYDisplay.gifEncode(pixmap: TByteArray; palette: TLongIntArray; w: LongInt; shortHdr: boolean):TByteArray;
    var
      minCodeSize : LongInt;
      LZW_CLRCODE : LongInt;
      LZW_ENDCODE : LongInt;
      LZW_1STCODE : LongInt;
      codeSize : LongInt;
      maxCode : LongInt;
      codes : TLongIntArray;
      nCodes : LongInt;
      pixmapSize : LongInt;
      dataStream : TByteArray;
      blockStart : LongInt;
      blockEnd : LongInt;
      prevCode : LongInt;
      pixPos : LongInt;
      wrBits : LongInt;
      wrBitCnt : LongInt;
      outPos : LongInt;
      nextVal : LongInt;
      i : LongInt;
      hdrSize : LongInt;
      res : TByteArray;
      h : LongInt;
      codes_pos : LongInt;
    begin
      if length(palette) > 8 then
        begin
          self._throw(YAPI_INVALID_ARGUMENT, 'Palette should have no more than 8 colors');
          setlength(res,0);
          result := res;
          exit;
        end;
      if length(palette) <= 4 then
        begin
          minCodeSize := 2;
        end
      else
        begin
          minCodeSize := 3;
        end;
      LZW_CLRCODE := ((1) shl (minCodeSize));
      LZW_ENDCODE := LZW_CLRCODE + 1;
      LZW_1STCODE := LZW_ENDCODE + 1;
      codeSize := minCodeSize + 1;
      maxCode := ((1) shl (codeSize)) - 1 - LZW_1STCODE;
      codes_pos := 0;
      SetLength(codes, 4090);;
      nCodes := 0;
      pixmapSize := length(pixmap);
      setlength(dataStream,((2 * pixmapSize) div 3) + 8);
      outPos := 0;
      wrBits := LZW_CLRCODE;
      wrBitCnt := 3;
      // prefetch first byte
      prevCode := pixmap[0];
      pixPos := 1;
      while pixPos < pixmapSize + 3 do
        begin
          blockStart := outPos;
          outPos := blockStart + 1;
          blockEnd := blockStart + 256;
          // flush any carry-over output byte from previous data sub-block
          while wrBitCnt >= 8 do
            begin
              dataStream[outPos] := ((wrBits) and ($0ff));
              outPos := outPos + 1;
              wrBits := ((wrBits) shr 8);
              wrBitCnt := wrBitCnt - 8;
            end;
          while (outPos < blockEnd) and(pixPos < pixmapSize) do
            begin
              // search for an existing code matching the running input segment
              // printf("[%d] ", rdBits >> 12);
              nextVal := ((prevCode) or (((pixmap[pixPos]) shl 12)));
              pixPos := pixPos + 1;
              if prevCode < LZW_1STCODE then
                begin
                  i := 0;
                end
              else
                begin
                  i := prevCode - LZW_ENDCODE;
                end;
              while (i < nCodes) and(codes[i] <> nextVal) do
                begin
                  i := i + 1;
                end;
              if i >= nCodes then
                begin
                  // not found, emit prevCode and create new code
                  wrBits := ((wrBits) or (((prevCode) shl (wrBitCnt))));
                  wrBitCnt := wrBitCnt + codeSize;
                  if nCodes <= maxCode then
                    begin
                      //fprintf(stderr, "#%d: #%d + %d\n", nextCode, nextVal & 63, nextVal >> 6);
                      codes[codes_pos] := nextVal;
                      inc(codes_pos);
                      nCodes := nCodes + 1;
                    end
                  else
                    begin
                      codeSize := codeSize + 1;
                      if codeSize <= 12 then
                        begin
                          //fprintf(stderr, "#%d: #%d + %d\n", nextCode, nextVal & 63, nextVal >> 6);
                          codes[codes_pos] := nextVal;
                          inc(codes_pos);
                          nCodes := nCodes + 1;
                        end
                      else
                        begin
                          wrBits := ((wrBits) or (((LZW_CLRCODE) shl (wrBitCnt))));
                          wrBitCnt := wrBitCnt + codeSize;
                          codes_pos := 0;
                          SetLength(codes, 4090);
                          nCodes := 0;
                          codeSize := minCodeSize + 1;
                        end;
                      maxCode := ((1) shl (codeSize)) - 1 - LZW_1STCODE;
                    end;
                  // flush one (or two) codes to output stream
                  while (wrBitCnt >= 8) and(outPos < blockEnd) do
                    begin
                      dataStream[outPos] := ((wrBits) and ($0ff));
                      outPos := outPos + 1;
                      wrBits := ((wrBits) shr 8);
                      wrBitCnt := wrBitCnt - 8;
                    end;
                  prevCode := ((nextVal) shr 12);
                end
              else
                begin
                  prevCode := i + LZW_1STCODE;
                end;
            end;
          if pixPos >= pixmapSize then
            begin
              if (outPos < blockEnd) and(pixPos = pixmapSize) then
                begin
                  // append code for last run
                  wrBits := ((wrBits) or (((prevCode) shl (wrBitCnt))));
                  wrBitCnt := wrBitCnt + codeSize;
                  while (wrBitCnt >= 8) and(outPos < blockEnd) do
                    begin
                      dataStream[outPos] := ((wrBits) and ($0ff));
                      outPos := outPos + 1;
                      wrBits := ((wrBits) shr 8);
                      wrBitCnt := wrBitCnt - 8;
                    end;
                  pixPos := pixPos + 1;
                end;
              if (outPos < blockEnd) and(pixPos = pixmapSize + 1) then
                begin
                  // append end code
                  wrBits := ((wrBits) or (((LZW_ENDCODE) shl (wrBitCnt))));
                  wrBitCnt := wrBitCnt + codeSize;
                  while (wrBitCnt >= 8) and(outPos < blockEnd) do
                    begin
                      dataStream[outPos] := ((wrBits) and ($0ff));
                      outPos := outPos + 1;
                      wrBits := ((wrBits) shr 8);
                      wrBitCnt := wrBitCnt - 8;
                    end;
                  pixPos := pixPos + 1;
                end;
              if (outPos < blockEnd) and(pixPos = pixmapSize + 2) then
                begin
                  // flush last 0-7 bits
                  if wrBitCnt > 0 then
                    begin
                      dataStream[outPos] := ((wrBits) and ($0ff));
                      outPos := outPos + 1;
                      wrBitCnt := 0;
                    end;
                  pixPos := pixPos + 1;
                end;
            end;
          dataStream[blockStart] := outPos - (blockStart + 1);
        end;
      blockEnd := outPos;
      // Now write final buffer
      hdrSize := 24 + LZW_CLRCODE * 3;
      setlength(res,hdrSize + outPos + 2);
      // GIF89a header
      res[$000] := $047;
      res[$001] := $049;
      res[$002] := $046;
      res[$003] := $038;
      res[$004] := $039;
      res[$005] := $061;
      // Logical screen descriptor
      h := (length(pixmap) div w);
      res[$006] := ((w) and ($0ff));
      res[$007] := ((w) shr 8);
      res[$008] := ((h) and ($0ff));
      res[$009] := ((h) shr 8);
      res[$00a] := $0f0 + minCodeSize - 1;
      res[$00b] := 0;
      res[$00c] := 0;
      // Palette
      outPos := $00d;
      i := 0;
      while i < LZW_CLRCODE do
        begin
          if i < length(palette) then
            begin
              wrBits := palette[i];
              res[outPos] := ((((wrBits) shr 16)) and ($0ff));
              res[outPos + 1] := ((((wrBits) shr 8)) and ($0ff));
              res[outPos + 2] := ((wrBits) and ($0ff));
            end;
          outPos := outPos + 3;
          i := i + 1;
        end;
      // Image descriptor
      res[outPos] := $02c;
      res[outPos + 5] := ((w) and ($0ff));
      res[outPos + 6] := ((w) shr 8);
      res[outPos + 7] := ((h) and ($0ff));
      res[outPos + 8] := ((h) shr 8);
      outPos := outPos + 10;
      // Prepare to append Image data
      res[outPos] := minCodeSize;
      i := 0;
      while i < blockEnd do
        begin
          outPos := outPos + 1;
          res[outPos] := dataStream[i];
          i := i + 1;
        end;
      // Append zero-block and trailer
      outPos := outPos + 1;
      res[outPos] := 0;
      outPos := outPos + 1;
      res[outPos] := $03b;
      result := res;
      exit;
    end;


  function TYDisplay.nextDisplay(): TYDisplay;
    var
      hwid: string;
    begin
      if YISERR(_nextFunction(hwid)) then
        begin
          nextDisplay := nil;
          exit;
        end;
      if hwid = '' then
        begin
          nextDisplay := nil;
          exit;
        end;
      nextDisplay := TYDisplay.FindDisplay(hwid);
    end;

  class function TYDisplay.FirstDisplay(): TYDisplay;
    var
      v_fundescr      : YFUN_DESCR;
      dev             : YDEV_DESCR;
      neededsize, err : integer;
      serial, funcId, funcName, funcVal, errmsg : string;
    begin
      err := yapiGetFunctionsByClass('Display', 0, PyHandleArray(@v_fundescr), sizeof(YFUN_DESCR), neededsize, errmsg);
      if (YISERR(err) or (neededsize = 0)) then
        begin
          result := nil;
          exit;
        end;
      if (YISERR(yapiGetFunctionInfo(v_fundescr, dev, serial, funcId, funcName, funcVal, errmsg))) then
        begin
          result := nil;
          exit;
        end;
     result := TYDisplay.FindDisplay(serial+'.'+funcId);
    end;

//--- (end of generated code: YDisplay implementation)


//--- (generated code: YDisplay functions)

  function yFindDisplay(func:string): TYDisplay;
    begin
      result := TYDisplay.FindDisplay(func);
    end;

  function yFirstDisplay(): TYDisplay;
    begin
      result := TYDisplay.FirstDisplay();
    end;

  procedure _DisplayCleanup();
    begin
    end;

//--- (end of generated code: YDisplay functions)

 constructor TYDisplayLayer.Create(parent: TYdisplay; id :integer);
 begin
    inherited create();
    self._display := parent;
    self._id := id;
    self._cmdbuff:='';
 end;

//--- (generated code: YDisplayLayer implementation)

  function TYDisplayLayer.must_be_flushed():boolean;
    begin
      result := Length(self._cmdbuff) > 0;
      exit;
    end;


  function TYDisplayLayer.resetHiddenFlag():LongInt;
    begin
      self._hidden := false;
      result := YAPI_SUCCESS;
      exit;
    end;


  function TYDisplayLayer.flush_now():LongInt;
    var
      res : LongInt;
    begin
      res := YAPI_SUCCESS;
      if Length(self._cmdbuff) > 0 then
        begin
          res := self._display.sendCommand(self._cmdbuff);
          self._cmdbuff := '';
        end;
      result := res;
      exit;
    end;


  function TYDisplayLayer.command_push(cmd: string):LongInt;
    var
      res : LongInt;
    begin
      res := YAPI_SUCCESS;
      if Length(self._cmdbuff) + Length(cmd) >= 64 then
        begin
          // force flush before, to prevent overflow
          self.flush_now;
        end;
      if Length(self._cmdbuff) = 0 then
        begin
          // always prepend layer ID first
          self._cmdbuff := IntToStr(self._id);
        end;
      self._cmdbuff := self._cmdbuff + cmd;
      result := res;
      exit;
    end;


  function TYDisplayLayer.command_flush(cmd: string):LongInt;
    var
      res : LongInt;
    begin
      res := self.command_push(cmd);
      if self._hidden then
        begin
          result := res;
          exit;
        end;
      if self._display.isFrozen then
        begin
          result := res;
          exit;
        end;
      result := self.flush_now;
      exit;
    end;


  function TYDisplayLayer.reset():LongInt;
    begin
      self._hidden := false;
      result := self.command_flush('X');
      exit;
    end;


  function TYDisplayLayer.clear():LongInt;
    begin
      result := self.command_flush('x');
      exit;
    end;


  function TYDisplayLayer.selectColorPen(color: LongInt):LongInt;
    begin
      result := self.command_push('c'+AnsiLowerCase(inttohex(color,06)));
      exit;
    end;


  function TYDisplayLayer.selectGrayPen(graylevel: LongInt):LongInt;
    begin
      result := self.command_push('g'+inttostr(graylevel));
      exit;
    end;


  function TYDisplayLayer.selectEraser():LongInt;
    begin
      result := self.command_push('e');
      exit;
    end;


  function TYDisplayLayer.selectFillColor(color: LongInt):LongInt;
    var
      r : LongInt;
      g : LongInt;
      b : LongInt;
    begin
      if color=-1 then
        begin
          result := self.command_push('f_');
          exit;
        end;
      if color=-2 then
        begin
          result := self.command_push('f-');
          exit;
        end;
      if color=-3 then
        begin
          result := self.command_push('f.');
          exit;
        end;
      r := ((((color) shr 20)) and 15);
      g := ((((color) shr 12)) and 15);
      b := ((((color) shr 4)) and 15);
      result := self.command_push('f'+AnsiLowerCase(inttohex(r,1))+''+AnsiLowerCase(inttohex(g,1))+''+AnsiLowerCase(inttohex(b,1)));
      exit;
    end;


  function TYDisplayLayer.selectLineColor(color: LongInt):LongInt;
    var
      r : LongInt;
      g : LongInt;
      b : LongInt;
    begin
      if color=-1 then
        begin
          result := self.command_push('l_');
          exit;
        end;
      if color=-2 then
        begin
          result := self.command_push('l-');
          exit;
        end;
      if color=-3 then
        begin
          result := self.command_push('l*');
          exit;
        end;
      r := ((((color) shr 20)) and 15);
      g := ((((color) shr 12)) and 15);
      b := ((((color) shr 4)) and 15);
      result := self.command_push('l'+AnsiLowerCase(inttohex(r,1))+''+AnsiLowerCase(inttohex(g,1))+''+AnsiLowerCase(inttohex(b,1)));
      exit;
    end;


  function TYDisplayLayer.selectLineWidth(width: LongInt):LongInt;
    begin
      result := self.command_push('t'+inttostr(width));
      exit;
    end;


  function TYDisplayLayer.setAntialiasingMode(mode: boolean):LongInt;
    begin
      result := self.command_push('a'+_yapiBoolToStr(mode));
      exit;
    end;


  function TYDisplayLayer.drawPixel(x: LongInt; y: LongInt):LongInt;
    begin
      result := self.command_flush('P'+inttostr(x)+','+inttostr(y));
      exit;
    end;


  function TYDisplayLayer.drawRect(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt;
    begin
      result := self.command_flush('R'+inttostr(x1)+','+inttostr(y1)+','+inttostr(x2)+','+inttostr(y2));
      exit;
    end;


  function TYDisplayLayer.drawBar(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt;
    begin
      result := self.command_flush('B'+inttostr(x1)+','+inttostr(y1)+','+inttostr(x2)+','+inttostr(y2));
      exit;
    end;


  function TYDisplayLayer.drawCircle(x: LongInt; y: LongInt; r: LongInt):LongInt;
    begin
      result := self.command_flush('C'+inttostr(x)+','+inttostr(y)+','+inttostr(r));
      exit;
    end;


  function TYDisplayLayer.drawDisc(x: LongInt; y: LongInt; r: LongInt):LongInt;
    begin
      result := self.command_flush('D'+inttostr(x)+','+inttostr(y)+','+inttostr(r));
      exit;
    end;


  function TYDisplayLayer.selectFont(fontname: string):LongInt;
    begin
      result := self.command_push('&'+fontname+''+chr(27));
      exit;
    end;


  function TYDisplayLayer.drawText(x: LongInt; y: LongInt; anchor: TYALIGN; text: string):LongInt;
    var
      textlen : LongInt;
      destname : string;
    begin
      textlen := Length(text);
      if textlen > 60 then
        begin
          if textlen > 1000 then
            begin
              self._display._throw(YAPI_INVALID_ARGUMENT, 'text too large (max 1000 characters)');
              result := YAPI_INVALID_ARGUMENT;
              exit;
            end;
          self._display.flushLayers;
          destname := 'layer'+inttostr(self._id)+':T'+inttostr(x)+','+inttostr(y)+','+inttostr(ord(anchor))+',';
          result := self._display.upload(destname, _StrToByte(text));
          exit;
        end;
      result := self.command_flush('T'+inttostr(x)+','+inttostr(y)+','+inttostr(ord(anchor))+','+text+''+chr(27));
      exit;
    end;


  function TYDisplayLayer.drawImage(x: LongInt; y: LongInt; imagename: string):LongInt;
    begin
      result := self.command_flush('*'+inttostr(x)+','+inttostr(y)+','+imagename+''+chr(27));
      exit;
    end;


  function TYDisplayLayer.drawGIF(x: LongInt; y: LongInt; gifimage: TByteArray):LongInt;
    var
      destname : string;
    begin
      self._display.flushLayers;
      destname := 'layer'+inttostr(self._id)+':G,-1@'+inttostr(x)+','+inttostr(y);
      result := self._display.upload(destname, gifimage);
      exit;
    end;


  function TYDisplayLayer.drawBitmap(x: LongInt; y: LongInt; w: LongInt; bitmap: TByteArray; bgcol: LongInt):LongInt;
    var
      destname : string;
      r : LongInt;
      g : LongInt;
      b : LongInt;
      rgbcol : string;
    begin
      if (w < 0) or(w > 512) then
        begin
          self._display._throw(YAPI_INVALID_ARGUMENT, 'bitmap width must be in range 1..512');
          result := YAPI_INVALID_ARGUMENT;
          exit;
        end;
      self._display.flushLayers;
      if bgcol <= 255 then
        begin
          if bgcol >= -1 then
            begin
              // backward-compatible behaviour (gray level)
              rgbcol := ''+inttostr(bgcol);
            end
          else
            begin
              // background color or foreground color
              if bgcol <= -3 then
                begin
                  rgbcol := '#.';
                end
              else
                begin
                  rgbcol := '#-';
                end;
            end;
        end
      else
        begin
          // RGB color
          r := ((((bgcol) shr 20)) and 15);
          g := ((((bgcol) shr 12)) and 15);
          b := ((((bgcol) shr 4)) and 15);
          rgbcol := '#'+AnsiLowerCase(inttohex(r,1))+''+AnsiLowerCase(inttohex(g,1))+''+AnsiLowerCase(inttohex(b,1));
        end;
      destname := 'layer'+inttostr(self._id)+':'+inttostr(w)+','+rgbcol+'@'+inttostr(x)+','+inttostr(y);
      result := self._display.upload(destname, bitmap);
      exit;
    end;


  function TYDisplayLayer.drawPixmap(x: LongInt; y: LongInt; w: LongInt; pixmap: TByteArray; palette: TLongIntArray):LongInt;
    var
      gifimage : TByteArray;
    begin
      gifimage := self._display.gifEncode(pixmap, palette, w, false);
      result := self.drawGIF(x, y, gifimage);
      exit;
    end;


  function TYDisplayLayer.moveTo(x: LongInt; y: LongInt):LongInt;
    begin
      result := self.command_push('@'+inttostr(x)+','+inttostr(y));
      exit;
    end;


  function TYDisplayLayer.lineTo(x: LongInt; y: LongInt):LongInt;
    begin
      result := self.command_flush('-'+inttostr(x)+','+inttostr(y));
      exit;
    end;


  function TYDisplayLayer.polygonStart(x: LongInt; y: LongInt):LongInt;
    begin
      self._polyPrevX := x;
      self._polyPrevY := y;
      result := self.command_push('['+inttostr(x)+','+inttostr(y));
      exit;
    end;


  function TYDisplayLayer.polygonAdd(x: LongInt; y: LongInt):LongInt;
    var
      dx : LongInt;
      dy : LongInt;
    begin
      dx := x - self._polyPrevX;
      dy := y - self._polyPrevY;
      self._polyPrevX := x;
      self._polyPrevY := y;
      result := self.command_flush(';'+inttostr(dx)+','+inttostr(dy));
      exit;
    end;


  function TYDisplayLayer.polygonEnd():LongInt;
    begin
      result := self.command_flush(']');
      exit;
    end;


  function TYDisplayLayer.consoleOut(text: string):LongInt;
    var
      textlen : LongInt;
      destname : string;
    begin
      textlen := Length(text);
      if textlen > 60 then
        begin
          if textlen > 1000 then
            begin
              self._display._throw(YAPI_INVALID_ARGUMENT, 'text too large (max 1000 characters)');
              result := YAPI_INVALID_ARGUMENT;
              exit;
            end;
          self._display.flushLayers;
          destname := 'layer'+inttostr(self._id)+':!';
          result := self._display.upload(destname, _StrToByte(text));
          exit;
        end;
      result := self.command_flush('!'+text+''+chr(27));
      exit;
    end;


  function TYDisplayLayer.setConsoleMargins(x1: LongInt; y1: LongInt; x2: LongInt; y2: LongInt):LongInt;
    begin
      result := self.command_push('m'+inttostr(x1)+','+inttostr(y1)+','+inttostr(x2)+','+inttostr(y2));
      exit;
    end;


  function TYDisplayLayer.setConsoleBackground(bgcol: LongInt):LongInt;
    begin
      result := self.command_push('b'+inttostr(bgcol));
      exit;
    end;


  function TYDisplayLayer.setConsoleWordWrap(wordwrap: boolean):LongInt;
    begin
      result := self.command_push('w'+_yapiBoolToStr(wordwrap));
      exit;
    end;


  function TYDisplayLayer.clearConsole():LongInt;
    begin
      result := self.command_flush('^');
      exit;
    end;


  function TYDisplayLayer.setLayerPosition(x: LongInt; y: LongInt; scrollTime: LongInt):LongInt;
    begin
      result := self.command_flush('#'+inttostr(x)+','+inttostr(y)+','+inttostr(scrollTime));
      exit;
    end;


  function TYDisplayLayer.hide():LongInt;
    begin
      self.command_push('h');
      self._hidden := true;
      result := self.flush_now;
      exit;
    end;


  function TYDisplayLayer.unhide():LongInt;
    begin
      self._hidden := false;
      result := self.command_flush('s');
      exit;
    end;


  function TYDisplayLayer.get_display():TYDisplay;
    begin
      result := self._display;
      exit;
    end;


  function TYDisplayLayer.get_displayWidth():LongInt;
    begin
      result := self._display.get_displayWidth;
      exit;
    end;


  function TYDisplayLayer.get_displayHeight():LongInt;
    begin
      result := self._display.get_displayHeight;
      exit;
    end;


  function TYDisplayLayer.get_layerWidth():LongInt;
    begin
      result := self._display.get_layerWidth;
      exit;
    end;


  function TYDisplayLayer.get_layerHeight():LongInt;
    begin
      result := self._display.get_layerHeight;
      exit;
    end;


//--- (end of generated code: YDisplayLayer implementation)

 //--- (generated code: YDisplayLayer functions)

  procedure _DisplayLayerCleanup();
    begin
    end;

//--- (end of generated code: YDisplayLayer functions)



initialization
   //--- (generated code: YDisplay initialization)
  //--- (end of generated code: YDisplay initialization)

finalization
   //--- (generated code: YDisplay cleanup)
  _DisplayCleanup();
  //--- (end of generated code: YDisplay cleanup)
end.
