// 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;

    // True if this mode is interlaced.
    boolean isInterlaced;
  };

  // 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();
  };
};
