// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>system.display</code> API to query display metadata.
namespace system.display {

  dictionary Bounds {
    // The x-coordinate of the upper-left corner.
    long left;

    // The y-coordinate of the upper-left corner.
    long top;

    // The width of the display in pixels.
    long width;

    // The height of the display in pixels.
    long height;
  };

  dictionary Insets {
    // The x-axis distance from the left bound.
    long left;

    // The y-axis distance from the top bound.
    long top;

    // The x-axis distance from the right bound.
    long right;

    // The y-axis distance from the bottom bound.
    long bottom;
  };

  dictionary Point {
    // The x-coordinate of the point.
    long x;

    // The y-coordinate of the point.
    long y;
  };

  dictionary TouchCalibrationPair {
    // The coordinates of the display point.
    Point displayPoint;

    // The coordinates of the touch point corresponding to the display point.
    Point touchPoint;
  };

  dictionary TouchCalibrationPairQuad {
    // First pair of touch and display point required for touch calibration.
    TouchCalibrationPair pair1;

    // Second pair of touch and display point required for touch calibration.
    TouchCalibrationPair pair2;

    // Third pair of touch and display point required for touch calibration.
    TouchCalibrationPair pair3;

    // Fourth pair of touch and display point required for touch calibration.
    TouchCalibrationPair pair4;
  };

  dictionary DisplayMode {
    // The display mode width in device independent (user visible) pixels.
    long width;

    // The display mode height in device independent (user visible) pixels.
    long height;

    // The display mode width in native pixels.
    long widthInNativePixels;

    // The display mode height in native pixels.
    long heightInNativePixels;

    // The display mode UI scale factor.
    [deprecated="Use $(ref: displayZoomFactor)"] double? uiScale;

    // The display mode device scale factor.
    double deviceScaleFactor;

    // The display mode refresh rate in hertz.
    double refreshRate;

    // True if the mode is the display's native mode.
    boolean isNative;

    // True if the display mode is currently selected.
    boolean isSelected;
  };

  // Layout position, i.e. edge of parent that the display is attached to.
  enum LayoutPosition { top, right, bottom, left };

  dictionary DisplayLayout {
    // The unique identifier of the display.
    DOMString id;

    // The unique identifier of the parent display. Empty if this is the root.
    DOMString parentId;

    // The layout position of this display relative to the parent. This will
    // be ignored for the root.
    LayoutPosition position;

    // The offset of the display along the connected edge. 0 indicates that
    // the topmost or leftmost corners are aligned.
    long offset;
  };

  // EDID extracted parameters. Field description refers to "VESA ENHANCED
  // EXTENDED DISPLAY IDENTIFICATION DATA STANDARD (Defines EDID Structure
  // Version 1, Revision 4)" Release A, Revision 2 September 25, 2006.
  // https://www.vesa.org/vesa-standards
  dictionary Edid {
    // 3 character manufacturer code. See Sec. 3.4.1 page 21. Required in v1.4.
    DOMString manufacturerId;

    // 2 byte manufacturer-assigned code, Sec. 3.4.2 page 21. Required in v1.4.
    DOMString productId;

    // Year of manufacturer, Sec. 3.4.4 page 22. Required in v1.4.
    long yearOfManufacture;
  };

  dictionary DisplayUnitInfo {
    // The unique identifier of the display.
    DOMString id;

    // The user-friendly name (e.g. "HP LCD monitor").
    DOMString name;

    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    Edid? edid;

    // Chrome OS only. Identifier of the display that is being mirrored if
    // mirroring is enabled, otherwise empty. This will be set for all displays
    // (including the display being mirrored).
    DOMString mirroringSourceId;

    // Chrome OS only. Identifiers of the displays to which the source display
    // is being mirrored. Empty if no displays are being mirrored. This will be
    // set to the same value for all displays. This must not include
    // |mirroringSourceId|.
    DOMString[] mirroringDestinationIds;

    // True if this is the primary display.
    boolean isPrimary;

    // True if this is an internal display.
    boolean isInternal;

    // True if this display is enabled.
    boolean isEnabled;

    // True for all displays when in unified desktop mode. See documentation
    // for $(ref:enableUnifiedDesktop).
    boolean isUnified;

    // True when the display is in tablet mode. This may be set for touch
    // devices where hasAccelerometerSupport is true, e.g. when an app opens in
    // tablet mode. The default value is false.
    // Provided for ChromeOS Settings UI only. TODO(stevenjb): Remove when
    // Settings switches to a mojo API.
    [nodoc] boolean? isTabletMode;

    // The number of pixels per inch along the x-axis.
    double dpiX;

    // The number of pixels per inch along the y-axis.
    double dpiY;

    // The display's clockwise rotation in degrees relative to the vertical
    // position.
    // Currently exposed only on ChromeOS. Will be set to 0 on other platforms.
    long rotation;

    // The display's logical bounds.
    Bounds bounds;

    // The display's insets within its screen's bounds.
    // Currently exposed only on ChromeOS. Will be set to empty insets on
    // other platforms.
    Insets overscan;

    // The usable work area of the display within the display bounds. The work
    // area excludes areas of the display reserved for OS, for example taskbar
    // and launcher.
    Bounds workArea;

    // The list of available display modes. The current mode will have
    // isSelected=true. Only available on Chrome OS. Will be set to an empty
    // array on other platforms.
    DisplayMode[] modes;

    // True if this display has a touch input device associated with it.
    boolean hasTouchSupport;

    // True if this display has an accelerometer associated with it.
    // Provided for ChromeOS Settings UI only. TODO(stevenjb): Remove when
    // Settings switches to a mojo API. NOTE: The name of this may change.
    [nodoc] boolean hasAccelerometerSupport;

    // A list of zoom factor values that can be set for the display.
    double[] availableDisplayZoomFactors;

    // The ratio between the display's current and default zoom.
    // For example, value 1 is equivalent to 100% zoom, and value 1.5 is
    // equivalent to 150% zoom.
    double displayZoomFactor;
  };

  dictionary DisplayProperties {
    // Chrome OS only. If set to true, changes the display mode to unified
    // desktop (see $(ref:enableUnifiedDesktop) for details). If set to false,
    // unified desktop mode will be disabled. This is only valid for the
    // primary display. If provided, mirroringSourceId must not be provided and
    // other properties will be ignored. This is has no effect if not provided.
    boolean? isUnified;

    // Chrome OS only. If set and not empty, enables mirroring for this display
    // only. Otherwise disables mirroring for all displays. This value should
    // indicate the id of the source display to mirror, which must not be the
    // same as the id passed to setDisplayProperties. If set, no other property
    // may be set.
    [deprecated="Use $(ref:setMirrorMode)."] DOMString? mirroringSourceId;

    // If set to true, makes the display primary. No-op if set to false.
    // Note: If set, the display is considered primary for all other properties
    // (i.e. $(ref:isUnified) may be set and bounds origin may not).
    boolean? isPrimary;

    // If set, sets the display's overscan insets to the provided values. Note
    // that overscan values may not be negative or larger than a half of the
    // screen's size. Overscan cannot be changed on the internal monitor.
    Insets? overscan;

    // If set, updates the display's rotation.
    // Legal values are [0, 90, 180, 270]. The rotation is set clockwise,
    // relative to the display's vertical position.
    long? rotation;

    // If set, updates the display's logical bounds origin along the x-axis.
    // Applied together with $(ref:boundsOriginY). Defaults to the current value
    // if not set and $(ref:boundsOriginY) is set. Note that when updating the
    // display origin, some constraints will be applied, so the final bounds
    // origin may be different than the one set. The final bounds can be
    // retrieved using $(ref:getInfo). The bounds origin cannot be changed on
    // the primary display.
    long? boundsOriginX;

    // If set, updates the display's logical bounds origin along the y-axis.
    // See documentation for $(ref:boundsOriginX) parameter.
    long? boundsOriginY;

    // If set, updates the display mode to the mode matching this value.
    // If other parameters are invalid, this will not be applied. If the
    // display mode is invalid, it will not be applied and an error will be
    // set, but other properties will still be applied.
    DisplayMode? displayMode;

    // If set, updates the zoom associated with the display. This zoom performs
    // re-layout and repaint thus resulting in a better quality zoom than just
    // performing a pixel by pixel stretch enlargement.
    double? displayZoomFactor;
  };

  dictionary GetInfoFlags {
    // If set to true, only a single $(ref:DisplayUnitInfo) will be returned
    // by $(ref:getInfo) when in unified desktop mode (see
    // $(ref:enableUnifiedDesktop)). Defaults to false.
    boolean? singleUnified;
  };

  // Mirror mode, i.e. different ways of how a display is mirrored to other
  // displays.
  enum MirrorMode {
    // Use the default mode (extended or unified desktop).
    off,

    // The default source display will be mirrored to all other displays.
    normal,

    // The specified source display will be mirrored to the provided
    // destination displays. All other connected displays will be extended.
    mixed
  };

  dictionary MirrorModeInfo {
    // The mirror mode that should be set.
    MirrorMode mode;

    // The id of the mirroring source display. This is only valid for 'mixed'.
    DOMString? mirroringSourceId;

    // The ids of the mirroring destination displays. This is only valid for
    // 'mixed'.
    DOMString[]? mirroringDestinationIds;
  };

  callback DisplayInfoCallback = void (DisplayUnitInfo[] displayInfo);
  callback DisplayLayoutCallback = void (DisplayLayout[] layouts);
  callback SetDisplayUnitInfoCallback = void();
  callback SetDisplayLayoutCallback = void();
  callback NativeTouchCalibrationCallback = void(boolean success);
  callback SetMirrorModeCallback = void();

  interface Functions {
    // Requests the information for all attached display devices.
    // |flags|: Options affecting how the information is returned.
    // |callback|: The callback to invoke with the results.
    static void getInfo(optional GetInfoFlags flags,
                        DisplayInfoCallback callback);

    // Requests the layout info for all displays.
    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    // |callback|: The callback to invoke with the results.
    static void getDisplayLayout(DisplayLayoutCallback callback);

    // Updates the properties for the display specified by |id|, according to
    // the information provided in |info|. On failure, $(ref:runtime.lastError)
    // will be set.
    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    // |id|: The display's unique identifier.
    // |info|: The information about display properties that should be changed.
    //     A property will be changed only if a new value for it is specified in
    //     |info|.
    // |callback|: Empty function called when the function finishes. To find out
    //     whether the function succeeded, $(ref:runtime.lastError) should be
    //     queried.
    static void setDisplayProperties(
        DOMString id,
        DisplayProperties info,
        optional SetDisplayUnitInfoCallback callback);

    // Set the layout for all displays. Any display not included will use the
    // default layout. If a layout would overlap or be otherwise invalid it
    // will be adjusted to a valid layout. After layout is resolved, an
    // onDisplayChanged event will be triggered.
    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    // |layouts|: The layout information, required for all displays except
    //     the primary display.
    // |callback|: Empty function called when the function finishes. To find out
    //     whether the function succeeded, $(ref:runtime.lastError) should be
    //     queried.
    static void setDisplayLayout(DisplayLayout[] layouts,
                                 optional SetDisplayLayoutCallback callback);

    // Enables/disables the unified desktop feature. If enabled while mirroring
    // is active, the desktop mode will not change until mirroring is turned
    // off. Otherwise, the desktop mode will switch to unified immediately.
    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    // |enabled|: True if unified desktop should be enabled.
    static void enableUnifiedDesktop(boolean enabled);

    // Starts overscan calibration for a display. This will show an overlay
    // on the screen indicating the current overscan insets. If overscan
    // calibration for display |id| is in progress this will reset calibration.
    // |id|: The display's unique identifier.
    static void overscanCalibrationStart(DOMString id);

    // Adjusts the current overscan insets for a display. Typically this should
    // either move the display along an axis (e.g. left+right have the same
    // value) or scale it along an axis (e.g. top+bottom have opposite values).
    // Each Adjust call is cumulative with previous calls since Start.
    // |id|: The display's unique identifier.
    // |delta|: The amount to change the overscan insets.
    static void overscanCalibrationAdjust(DOMString id, Insets delta);

    // Resets the overscan insets for a display to the last saved value (i.e
    // before Start was called).
    // |id|: The display's unique identifier.
    static void overscanCalibrationReset(DOMString id);

    // Complete overscan adjustments for a display  by saving the current values
    // and hiding the overlay.
    // |id|: The display's unique identifier.
    static void overscanCalibrationComplete(DOMString id);

    // Displays the native touch calibration UX for the display with |id| as
    // display id. This will show an overlay on the screen with required
    // instructions on how to proceed. The callback will be invoked in case of
    // successful calibration only. If the calibration fails, this will throw an
    // error.
    // |id|: The display's unique identifier.
    // |callback|: Optional callback to inform the caller that the touch
    //      calibration has ended. The argument of the callback informs if the
    //      calibration was a success or not.
    static void showNativeTouchCalibration(
        DOMString id, optional NativeTouchCalibrationCallback callback);

    // Starts custom touch calibration for a display. This should be called when
    // using a custom UX for collecting calibration data. If another touch
    // calibration is already in progress this will throw an error.
    // |id|: The display's unique identifier.
    static void startCustomTouchCalibration(DOMString id);

    // Sets the touch calibration pairs for a display. These |pairs| would be
    // used to calibrate the touch screen for display with |id| called in
    // startCustomTouchCalibration(). Always call |startCustomTouchCalibration|
    // before calling this method. If another touch calibration is already in
    // progress this will throw an error.
    // |pairs|: The pairs of point used to calibrate the display.
    // |bounds|: Bounds of the display when the touch calibration was performed.
    //     |bounds.left| and |bounds.top| values are ignored.
    static void completeCustomTouchCalibration(TouchCalibrationPairQuad pairs,
                                               Bounds bounds);

    // Resets the touch calibration for the display and brings it back to its
    // default state by clearing any touch calibration data associated with the
    // display.
    // |id|: The display's unique identifier.
    static void clearTouchCalibration(DOMString id);

    // Sets the display mode to the specified mirror mode. Each call resets the
    // state from previous calls. Calling setDisplayProperties() will fail for
    // the mirroring destination displays.
    // NOTE: This is only available to Chrome OS Kiosk apps and Web UI.
    // |info|: The information of the mirror mode that should be applied to the
    //     display mode.
    // |callback|: Empty function called when the function finishes. To find out
    //     whether the function succeeded, $(ref:runtime.lastError) should be
    //     queried.
    static void setMirrorMode(MirrorModeInfo info,
                              optional SetMirrorModeCallback callback);
  };

  interface Events {
    // Fired when anything changes to the display configuration.
    static void onDisplayChanged();
  };
};
