/*
 * Copyright (C) 2024 Zhiyi Zhang for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef __WIDL__
#pragma winrt ns_prefix
#endif

#ifndef DO_NO_IMPORTS
import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";
#endif

namespace Windows.Devices.Input {
    typedef enum PointerDeviceType PointerDeviceType;
    typedef struct PointerDeviceUsage PointerDeviceUsage;

    interface IPointerDevice;
    interface IPointerDevice2;
    interface IPointerDeviceStatics;

    runtimeclass PointerDevice;

    declare {
        interface Windows.Foundation.Collections.IVectorView<Windows.Devices.Input.PointerDevice *>;
        interface Windows.Foundation.Collections.IVectorView<Windows.Devices.Input.PointerDeviceUsage>;
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0)
    ]
    enum PointerDeviceType
    {
        Touch = 0,
        Pen   = 1,
        Mouse = 2
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0)
    ]
    struct PointerDeviceUsage
    {
        UINT32 UsagePage;
        UINT32 Usage;
        INT32 MinLogical;
        INT32 MaxLogical;
        INT32 MinPhysical;
        INT32 MaxPhysical;
        UINT32 Unit;
        FLOAT PhysicalMultiplier;
    };

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Input.PointerDevice),
        uuid(93c9bafc-ebcb-467e-82c6-276feae36b5a)
    ]
    interface IPointerDevice : IInspectable
    {
        [propget] HRESULT PointerDeviceType([out, retval] Windows.Devices.Input.PointerDeviceType *value);
        [propget] HRESULT IsIntegrated([out, retval] boolean *value);
        [propget] HRESULT MaxContacts([out, retval] UINT32 *value);
        [propget] HRESULT PhysicalDeviceRect([out, retval] Windows.Foundation.Rect *value);
        [propget] HRESULT ScreenRect([out, retval] Windows.Foundation.Rect *value);
        [propget] HRESULT SupportedUsages([out, retval] Windows.Foundation.Collections.IVectorView<Windows.Devices.Input.PointerDeviceUsage> **value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Input.PointerDevice),
        uuid(f8a6d2a0-c484-489f-ae3e-30d2ee1ffd3e)
    ]
    interface IPointerDevice2 : IInspectable
    {
        [propget] HRESULT MaxPointersWithZDistance([out, retval] UINT32 *value);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        exclusiveto(Windows.Devices.Input.PointerDevice),
        uuid(d8b89aa1-d1c6-416e-bd8d-5790914dc563)
    ]
    interface IPointerDeviceStatics : IInspectable
    {
        HRESULT GetPointerDevice([in] UINT32 pointer_id, [out, retval] Windows.Devices.Input.PointerDevice **pointer_device);
        HRESULT GetPointerDevices([out, retval] Windows.Foundation.Collections.IVectorView<Windows.Devices.Input.PointerDevice *> **pointer_devices);
    }

    [
        contract(Windows.Foundation.UniversalApiContract, 1.0),
        marshaling_behavior(none),
        static(Windows.Devices.Input.IPointerDeviceStatics, Windows.Foundation.UniversalApiContract, 1.0)
    ]
    runtimeclass PointerDevice
    {
        [default] interface Windows.Devices.Input.IPointerDevice;
        [contract(Windows.Foundation.UniversalApiContract, 1.0)] interface Windows.Devices.Input.IPointerDevice2;
    }
}
