# This file has been autogenerated by the pywayland scanner

# Copyright 2014 © Stephen "Lyude" Chandler Paul
# Copyright 2015-2016 © Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice (including the
# next paragraph) shall be included in all copies or substantial
# portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from __future__ import annotations

import enum

from pywayland.protocol_core import (
    Argument,
    ArgumentType,
    Global,
    Interface,
    Proxy,
    Resource,
)
from ..wayland import WlSurface
from .zwp_tablet_v1 import ZwpTabletV1


class ZwpTabletToolV1(Interface):
    """A physical tablet tool

    An object that represents a physical tool that has been, or is currently in
    use with a tablet in this seat. Each wp_tablet_tool object stays valid
    until the client destroys it; the compositor reuses the wp_tablet_tool
    object to indicate that the object's respective physical tool has come into
    proximity of a tablet again.

    A wp_tablet_tool object's relation to a physical tool depends on the
    tablet's ability to report serial numbers. If the tablet supports this
    capability, then the object represents a specific physical tool and can be
    identified even when used on multiple tablets.

    A tablet tool has a number of static characteristics, e.g. tool type,
    hardware_serial and capabilities. These capabilities are sent in an event
    sequence after the wp_tablet_seat.tool_added event before any actual events
    from this tool. This initial event sequence is terminated by a
    wp_tablet_tool.done event.

    Tablet tool events are grouped by wp_tablet_tool.frame events. Any events
    received before a wp_tablet_tool.frame event should be considered part of
    the same hardware state change.
    """

    name = "zwp_tablet_tool_v1"
    version = 1

    class type(enum.IntEnum):
        pen = 0x140
        eraser = 0x141
        brush = 0x142
        pencil = 0x143
        airbrush = 0x144
        finger = 0x145
        mouse = 0x146
        lens = 0x147

    class capability(enum.IntEnum):
        tilt = 1
        pressure = 2
        distance = 3
        rotation = 4
        slider = 5
        wheel = 6

    class button_state(enum.IntEnum):
        released = 0
        pressed = 1

    class error(enum.IntEnum):
        role = 0


class ZwpTabletToolV1Proxy(Proxy[ZwpTabletToolV1]):
    interface = ZwpTabletToolV1

    @ZwpTabletToolV1.request(
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Object, interface=WlSurface, nullable=True),
        Argument(ArgumentType.Int),
        Argument(ArgumentType.Int),
    )
    def set_cursor(self, serial: int, surface: WlSurface | None, hotspot_x: int, hotspot_y: int) -> None:
        """Set the tablet tool's surface

        Sets the surface of the cursor used for this tool on the given tablet.
        This request only takes effect if the tool is in proximity of one of
        the requesting client's surfaces or the surface parameter is the
        current pointer surface. If there was a previous surface set with this
        request it is replaced. If surface is NULL, the cursor image is hidden.

        The parameters hotspot_x and hotspot_y define the position of the
        pointer surface relative to the pointer location. Its top-left corner
        is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the
        coordinates of the pointer location, in surface-local coordinates.

        On surface.attach requests to the pointer surface, hotspot_x and
        hotspot_y are decremented by the x and y parameters passed to the
        request. Attach must be confirmed by :func:`WlSurface.commit()
        <pywayland.protocol.wayland.WlSurface.commit>` as usual.

        The hotspot can also be updated by passing the currently set pointer
        surface to this request with new values for hotspot_x and hotspot_y.

        The current and pending input regions of the
        :class:`~pywayland.protocol.wayland.WlSurface` are cleared, and
        :func:`WlSurface.set_input_region()
        <pywayland.protocol.wayland.WlSurface.set_input_region>` is ignored
        until the :class:`~pywayland.protocol.wayland.WlSurface` is no longer
        used as the cursor. When the use as a cursor ends, the current and
        pending input regions become undefined, and the
        :class:`~pywayland.protocol.wayland.WlSurface` is unmapped.

        This request gives the surface the role of a cursor. The role assigned
        by this request is the same as assigned by
        :func:`WlPointer.set_cursor()
        <pywayland.protocol.wayland.WlPointer.set_cursor>` meaning the same
        surface can be used both as a
        :class:`~pywayland.protocol.wayland.WlPointer` cursor and a wp_tablet
        cursor. If the surface already has another role, it raises a protocol
        error. The surface may be used on multiple tablets and across multiple
        seats.

        :param serial:
            serial of the enter event
        :type serial:
            `ArgumentType.Uint`
        :param surface:
        :type surface:
            :class:`~pywayland.protocol.wayland.WlSurface` or `None`
        :param hotspot_x:
            surface-local x coordinate
        :type hotspot_x:
            `ArgumentType.Int`
        :param hotspot_y:
            surface-local y coordinate
        :type hotspot_y:
            `ArgumentType.Int`
        """
        self._marshal(0, serial, surface, hotspot_x, hotspot_y)

    @ZwpTabletToolV1.request()
    def destroy(self) -> None:
        """Destroy the tool object

        This destroys the client's resource for this tool object.
        """
        self._marshal(1)
        self._destroy()


class ZwpTabletToolV1Resource(Resource):
    interface = ZwpTabletToolV1

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def type(self, tool_type: int) -> None:
        """Tool type

        The tool type is the high-level type of the tool and usually decides
        the interaction expected from this tool.

        This event is sent in the initial burst of events before the
        wp_tablet_tool.done event.

        :param tool_type:
            the physical tool type
        :type tool_type:
            `ArgumentType.Uint`
        """
        self._post_event(0, tool_type)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Uint),
    )
    def hardware_serial(self, hardware_serial_hi: int, hardware_serial_lo: int) -> None:
        """Unique hardware serial number of the tool

        If the physical tool can be identified by a unique 64-bit serial
        number, this event notifies the client of this serial number.

        If multiple tablets are available in the same seat and the tool is
        uniquely identifiable by the serial number, that tool may move between
        tablets.

        Otherwise, if the tool has no serial number and this event is missing,
        the tool is tied to the tablet it first comes into proximity with. Even
        if the physical tool is used on multiple tablets, separate
        wp_tablet_tool objects will be created, one per tablet.

        This event is sent in the initial burst of events before the
        wp_tablet_tool.done event.

        :param hardware_serial_hi:
            the unique serial number of the tool, most significant bits
        :type hardware_serial_hi:
            `ArgumentType.Uint`
        :param hardware_serial_lo:
            the unique serial number of the tool, least significant bits
        :type hardware_serial_lo:
            `ArgumentType.Uint`
        """
        self._post_event(1, hardware_serial_hi, hardware_serial_lo)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Uint),
    )
    def hardware_id_wacom(self, hardware_id_hi: int, hardware_id_lo: int) -> None:
        """Hardware id notification in wacom's format

        This event notifies the client of a hardware id available on this tool.

        The hardware id is a device-specific 64-bit id that provides extra
        information about the tool in use, beyond the wl_tool.type enumeration.
        The format of the id is specific to tablets made by Wacom Inc. For
        example, the hardware id of a Wacom Grip Pen (a stylus) is 0x802.

        This event is sent in the initial burst of events before the
        wp_tablet_tool.done event.

        :param hardware_id_hi:
            the hardware id, most significant bits
        :type hardware_id_hi:
            `ArgumentType.Uint`
        :param hardware_id_lo:
            the hardware id, least significant bits
        :type hardware_id_lo:
            `ArgumentType.Uint`
        """
        self._post_event(2, hardware_id_hi, hardware_id_lo)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def capability(self, capability: int) -> None:
        """Tool capability notification

        This event notifies the client of any capabilities of this tool, beyond
        the main set of x/y axes and tip up/down detection.

        One event is sent for each extra capability available on this tool.

        This event is sent in the initial burst of events before the
        wp_tablet_tool.done event.

        :param capability:
            the capability
        :type capability:
            `ArgumentType.Uint`
        """
        self._post_event(3, capability)

    @ZwpTabletToolV1.event()
    def done(self) -> None:
        """Tool description events sequence complete

        This event signals the end of the initial burst of descriptive events.
        A client may consider the static description of the tool to be complete
        and finalize initialization of the tool.
        """
        self._post_event(4)

    @ZwpTabletToolV1.event()
    def removed(self) -> None:
        """Tool removed

        This event is sent when the tool is removed from the system and will
        send no further events. Should the physical tool come back into
        proximity later, a new wp_tablet_tool object will be created.

        It is compositor-dependent when a tool is removed. A compositor may
        remove a tool on proximity out, tablet removal or any other reason. A
        compositor may also keep a tool alive until shutdown.

        If the tool is currently in proximity, a proximity_out event will be
        sent before the removed event. See wp_tablet_tool.proximity_out for the
        handling of any buttons logically down.

        When this event is received, the client must wp_tablet_tool.destroy the
        object.
        """
        self._post_event(5)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Object, interface=ZwpTabletV1),
        Argument(ArgumentType.Object, interface=WlSurface),
    )
    def proximity_in(self, serial: int, tablet: ZwpTabletV1, surface: WlSurface) -> None:
        """Proximity in event

        Notification that this tool is focused on a certain surface.

        This event can be received when the tool has moved from one surface to
        another, or when the tool has come back into proximity above the
        surface.

        If any button is logically down when the tool comes into proximity, the
        respective button event is sent after the proximity_in event but within
        the same frame as the proximity_in event.

        :param serial:
        :type serial:
            `ArgumentType.Uint`
        :param tablet:
            The tablet the tool is in proximity of
        :type tablet:
            :class:`~pywayland.protocol.tablet_unstable_v1.ZwpTabletV1`
        :param surface:
            The current surface the tablet tool is over
        :type surface:
            :class:`~pywayland.protocol.wayland.WlSurface`
        """
        self._post_event(6, serial, tablet, surface)

    @ZwpTabletToolV1.event()
    def proximity_out(self) -> None:
        """Proximity out event

        Notification that this tool has either left proximity, or is no longer
        focused on a certain surface.

        When the tablet tool leaves proximity of the tablet, button release
        events are sent for each button that was held down at the time of
        leaving proximity. These events are sent before the proximity_out event
        but within the same wp_tablet.frame.

        If the tool stays within proximity of the tablet, but the focus changes
        from one surface to another, a button release event may not be sent
        until the button is actually released or the tool leaves the proximity
        of the tablet.
        """
        self._post_event(7)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def down(self, serial: int) -> None:
        """Tablet tool is making contact

        Sent whenever the tablet tool comes in contact with the surface of the
        tablet.

        If the tool is already in contact with the tablet when entering the
        input region, the client owning said region will receive a
        wp_tablet.proximity_in event, followed by a wp_tablet.down event and a
        wp_tablet.frame event.

        Note that this event describes logical contact, not physical contact.
        On some devices, a compositor may not consider a tool in logical
        contact until a minimum physical pressure threshold is exceeded.

        :param serial:
        :type serial:
            `ArgumentType.Uint`
        """
        self._post_event(8, serial)

    @ZwpTabletToolV1.event()
    def up(self) -> None:
        """Tablet tool is no longer making contact

        Sent whenever the tablet tool stops making contact with the surface of
        the tablet, or when the tablet tool moves out of the input region and
        the compositor grab (if any) is dismissed.

        If the tablet tool moves out of the input region while in contact with
        the surface of the tablet and the compositor does not have an ongoing
        grab on the surface, the client owning said region will receive a
        wp_tablet.up event, followed by a wp_tablet.proximity_out event and a
        wp_tablet.frame event. If the compositor has an ongoing grab on this
        device, this event sequence is sent whenever the grab is dismissed in
        the future.

        Note that this event describes logical contact, not physical contact.
        On some devices, a compositor may not consider a tool out of logical
        contact until physical pressure falls below a specific threshold.
        """
        self._post_event(9)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Fixed),
        Argument(ArgumentType.Fixed),
    )
    def motion(self, x: float, y: float) -> None:
        """Motion event

        Sent whenever a tablet tool moves.

        :param x:
            surface-local x coordinate
        :type x:
            `ArgumentType.Fixed`
        :param y:
            surface-local y coordinate
        :type y:
            `ArgumentType.Fixed`
        """
        self._post_event(10, x, y)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def pressure(self, pressure: int) -> None:
        """Pressure change event

        Sent whenever the pressure axis on a tool changes. The value of this
        event is normalized to a value between 0 and 65535.

        Note that pressure may be nonzero even when a tool is not in logical
        contact. See the down and up events for more details.

        :param pressure:
            The current pressure value
        :type pressure:
            `ArgumentType.Uint`
        """
        self._post_event(11, pressure)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def distance(self, distance: int) -> None:
        """Distance change event

        Sent whenever the distance axis on a tool changes. The value of this
        event is normalized to a value between 0 and 65535.

        Note that distance may be nonzero even when a tool is not in logical
        contact. See the down and up events for more details.

        :param distance:
            The current distance value
        :type distance:
            `ArgumentType.Uint`
        """
        self._post_event(12, distance)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Int),
        Argument(ArgumentType.Int),
    )
    def tilt(self, tilt_x: int, tilt_y: int) -> None:
        """Tilt change event

        Sent whenever one or both of the tilt axes on a tool change. Each tilt
        value is in 0.01 of a degree, relative to the z-axis of the tablet. The
        angle is positive when the top of a tool tilts along the positive x or
        y axis.

        :param tilt_x:
            The current value of the X tilt axis
        :type tilt_x:
            `ArgumentType.Int`
        :param tilt_y:
            The current value of the Y tilt axis
        :type tilt_y:
            `ArgumentType.Int`
        """
        self._post_event(13, tilt_x, tilt_y)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Int),
    )
    def rotation(self, degrees: int) -> None:
        """Z-rotation change event

        Sent whenever the z-rotation axis on the tool changes. The rotation
        value is in 0.01 of a degree clockwise from the tool's logical neutral
        position.

        :param degrees:
            The current rotation of the Z axis
        :type degrees:
            `ArgumentType.Int`
        """
        self._post_event(14, degrees)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Int),
    )
    def slider(self, position: int) -> None:
        """Slider position change event

        Sent whenever the slider position on the tool changes. The value is
        normalized between -65535 and 65535, with 0 as the logical neutral
        position of the slider.

        The slider is available on e.g. the Wacom Airbrush tool.

        :param position:
            The current position of slider
        :type position:
            `ArgumentType.Int`
        """
        self._post_event(15, position)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Int),
        Argument(ArgumentType.Int),
    )
    def wheel(self, degrees: int, clicks: int) -> None:
        """Wheel delta event

        Sent whenever the wheel on the tool emits an event. This event contains
        two values for the same axis change. The degrees value is in 0.01 of a
        degree in the same orientation as the
        :func:`WlPointer.vertical_scroll()
        <pywayland.protocol.wayland.WlPointer.vertical_scroll>` axis. The
        clicks value is in discrete logical clicks of the mouse wheel. This
        value may be zero if the movement of the wheel was less than one
        logical click.

        Clients should choose either value and avoid mixing degrees and clicks.
        The compositor may accumulate values smaller than a logical click and
        emulate click events when a certain threshold is met. Thus,
        wl_tablet_tool.wheel events with non-zero clicks values may have
        different degrees values.

        :param degrees:
            The wheel delta in 0.01 of a degree
        :type degrees:
            `ArgumentType.Int`
        :param clicks:
            The wheel delta in discrete clicks
        :type clicks:
            `ArgumentType.Int`
        """
        self._post_event(16, degrees, clicks)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Uint),
        Argument(ArgumentType.Uint),
    )
    def button(self, serial: int, button: int, state: int) -> None:
        """Button event

        Sent whenever a button on the tool is pressed or released.

        If a button is held down when the tool moves in or out of proximity,
        button events are generated by the compositor. See
        wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for
        details.

        :param serial:
        :type serial:
            `ArgumentType.Uint`
        :param button:
            The button whose state has changed
        :type button:
            `ArgumentType.Uint`
        :param state:
            Whether the button was pressed or released
        :type state:
            `ArgumentType.Uint`
        """
        self._post_event(17, serial, button, state)

    @ZwpTabletToolV1.event(
        Argument(ArgumentType.Uint),
    )
    def frame(self, time: int) -> None:
        """Frame event

        Marks the end of a series of axis and/or button updates from the
        tablet. The Wayland protocol requires axis updates to be sent
        sequentially, however all events within a frame should be considered
        one hardware event.

        :param time:
            The time of the event with millisecond granularity
        :type time:
            `ArgumentType.Uint`
        """
        self._post_event(18, time)


class ZwpTabletToolV1Global(Global):
    interface = ZwpTabletToolV1


ZwpTabletToolV1._gen_c()
ZwpTabletToolV1.proxy_class = ZwpTabletToolV1Proxy
ZwpTabletToolV1.resource_class = ZwpTabletToolV1Resource
ZwpTabletToolV1.global_class = ZwpTabletToolV1Global
