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

import "inspectable.idl";
import "asyncinfo.idl";
import "eventtoken.idl";
import "windowscontracts.idl";
import "windows.foundation.idl";

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