Add wayland support to devdraw.
This commit is contained in:
parent
a2567fcac9
commit
5f20010eb6
10 changed files with 4770 additions and 3 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[ -f $PLAN9/config ] && . $PLAN9/config
|
[ -f $PLAN9/config ] && . $PLAN9/config
|
||||||
|
|
||||||
if [ "x$X11" = "x" ]; then
|
if [ "x$X11" = "x" ]; then
|
||||||
if [ -d /usr/X11R6 ]; then
|
if [ -d /usr/X11R6 ]; then
|
||||||
X11=/usr/X11R6
|
X11=/usr/X11R6
|
||||||
elif [ -d /usr/local/X11R6 ]; then
|
elif [ -d /usr/local/X11R6 ]; then
|
||||||
|
|
@ -29,6 +29,8 @@ if [ "x$WSYSTYPE" = "x" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
WSYSTYPE=mac
|
WSYSTYPE=mac
|
||||||
|
elif [ "x$XDG_SESSION_TYPE" = "xwayland" ]; then
|
||||||
|
WSYSTYPE=wayland
|
||||||
elif [ -d "$X11" ]; then
|
elif [ -d "$X11" ]; then
|
||||||
WSYSTYPE=x11
|
WSYSTYPE=x11
|
||||||
else
|
else
|
||||||
|
|
@ -43,7 +45,7 @@ if [ "x$WSYSTYPE" = "xx11" -a "x$X11H" = "x" ]; then
|
||||||
X11H=""
|
X11H=""
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo 'WSYSTYPE='$WSYSTYPE
|
echo 'WSYSTYPE='$WSYSTYPE
|
||||||
echo 'X11='$X11
|
echo 'X11='$X11
|
||||||
echo 'X11H='$X11H
|
echo 'X11H='$X11H
|
||||||
|
|
@ -58,6 +60,12 @@ elif [ $WSYSTYPE = mac ]; then
|
||||||
echo 'WSYSOFILES=$WSYSOFILES mac-draw.o mac-screen.o'
|
echo 'WSYSOFILES=$WSYSOFILES mac-draw.o mac-screen.o'
|
||||||
echo 'WSYSHFILES='
|
echo 'WSYSHFILES='
|
||||||
echo 'MACARGV=macargv.o'
|
echo 'MACARGV=macargv.o'
|
||||||
|
elif [ $WSYSTYPE = wayland ]; then
|
||||||
|
echo 'LDFLAGS=$LDFLAGS -lwayland-client -lxkbcommon'
|
||||||
|
XO=`ls wayland*.c 2>/dev/null | sed 's/\.c/\.o/'`
|
||||||
|
echo 'WSYSOFILES=$WSYSOFILES '$XO
|
||||||
|
XH=`ls wayland*.h 2>/dev/null`
|
||||||
|
echo 'WSYSHFILES='$XH
|
||||||
elif [ $WSYSTYPE = nowsys ]; then
|
elif [ $WSYSTYPE = nowsys ]; then
|
||||||
echo 'WSYSOFILES=nowsys.o'
|
echo 'WSYSOFILES=nowsys.o'
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
99
src/cmd/devdraw/wayland-pointer-constraints.c
Normal file
99
src/cmd/devdraw/wayland-pointer-constraints.c
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* Generated by wayland-scanner 1.23.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_pointer_interface;
|
||||||
|
extern const struct wl_interface wl_region_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface zwp_confined_pointer_v1_interface;
|
||||||
|
extern const struct wl_interface zwp_locked_pointer_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *pointer_constraints_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zwp_locked_pointer_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
NULL,
|
||||||
|
&zwp_confined_pointer_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_pointer_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_region_interface,
|
||||||
|
&wl_region_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_pointer_constraints_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 2 },
|
||||||
|
{ "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 7 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface zwp_pointer_constraints_v1_interface = {
|
||||||
|
"zwp_pointer_constraints_v1", 1,
|
||||||
|
3, zwp_pointer_constraints_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_locked_pointer_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_region", "?o", pointer_constraints_unstable_v1_types + 12 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_locked_pointer_v1_events[] = {
|
||||||
|
{ "locked", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "unlocked", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface zwp_locked_pointer_v1_interface = {
|
||||||
|
"zwp_locked_pointer_v1", 1,
|
||||||
|
3, zwp_locked_pointer_v1_requests,
|
||||||
|
2, zwp_locked_pointer_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_confined_pointer_v1_requests[] = {
|
||||||
|
{ "destroy", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "set_region", "?o", pointer_constraints_unstable_v1_types + 13 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwp_confined_pointer_v1_events[] = {
|
||||||
|
{ "confined", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
{ "unconfined", "", pointer_constraints_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface zwp_confined_pointer_v1_interface = {
|
||||||
|
"zwp_confined_pointer_v1", 1,
|
||||||
|
2, zwp_confined_pointer_v1_requests,
|
||||||
|
2, zwp_confined_pointer_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
667
src/cmd/devdraw/wayland-pointer-constraints.h
Normal file
667
src/cmd/devdraw/wayland-pointer-constraints.h
Normal file
|
|
@ -0,0 +1,667 @@
|
||||||
|
/* Generated by wayland-scanner 1.23.0 */
|
||||||
|
|
||||||
|
#ifndef POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define POINTER_CONSTRAINTS_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_pointer_constraints_unstable_v1 The pointer_constraints_unstable_v1 protocol
|
||||||
|
* protocol for constraining pointer motions
|
||||||
|
*
|
||||||
|
* @section page_desc_pointer_constraints_unstable_v1 Description
|
||||||
|
*
|
||||||
|
* This protocol specifies a set of interfaces used for adding constraints to
|
||||||
|
* the motion of a pointer. Possible constraints include confining pointer
|
||||||
|
* motions to a given region, or locking it to its current position.
|
||||||
|
*
|
||||||
|
* In order to constrain the pointer, a client must first bind the global
|
||||||
|
* interface "wp_pointer_constraints" which, if a compositor supports pointer
|
||||||
|
* constraints, is exposed by the registry. Using the bound global object, the
|
||||||
|
* client uses the request that corresponds to the type of constraint it wants
|
||||||
|
* to make. See wp_pointer_constraints for more details.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and backward
|
||||||
|
* incompatible changes may be made. Backward compatible changes may be added
|
||||||
|
* together with the corresponding interface version bump. Backward
|
||||||
|
* incompatible changes are done by bumping the version number in the protocol
|
||||||
|
* and interface names and resetting the interface version. Once the protocol
|
||||||
|
* is to be declared stable, the 'z' prefix and the version number in the
|
||||||
|
* protocol and interface names are removed and the interface version number is
|
||||||
|
* reset.
|
||||||
|
*
|
||||||
|
* @section page_ifaces_pointer_constraints_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zwp_pointer_constraints_v1 - constrain the movement of a pointer
|
||||||
|
* - @subpage page_iface_zwp_locked_pointer_v1 - receive relative pointer motion events
|
||||||
|
* - @subpage page_iface_zwp_confined_pointer_v1 - confined pointer object
|
||||||
|
* @section page_copyright_pointer_constraints_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2014 Jonas Ådahl
|
||||||
|
* Copyright © 2015 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.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_pointer;
|
||||||
|
struct wl_region;
|
||||||
|
struct wl_surface;
|
||||||
|
struct zwp_confined_pointer_v1;
|
||||||
|
struct zwp_locked_pointer_v1;
|
||||||
|
struct zwp_pointer_constraints_v1;
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_INTERFACE
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_pointer_constraints_v1 zwp_pointer_constraints_v1
|
||||||
|
* @section page_iface_zwp_pointer_constraints_v1_desc Description
|
||||||
|
*
|
||||||
|
* The global interface exposing pointer constraining functionality. It
|
||||||
|
* exposes two requests: lock_pointer for locking the pointer to its
|
||||||
|
* position, and confine_pointer for locking the pointer to a region.
|
||||||
|
*
|
||||||
|
* The lock_pointer and confine_pointer requests create the objects
|
||||||
|
* wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||||
|
* use these objects to interact with the lock.
|
||||||
|
*
|
||||||
|
* For any surface, only one lock or confinement may be active across all
|
||||||
|
* wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||||
|
* when another lock or confinement is active or requested on the same surface
|
||||||
|
* and with any of the wl_pointer objects of the same seat, an
|
||||||
|
* 'already_constrained' error will be raised.
|
||||||
|
* @section page_iface_zwp_pointer_constraints_v1_api API
|
||||||
|
* See @ref iface_zwp_pointer_constraints_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_pointer_constraints_v1 The zwp_pointer_constraints_v1 interface
|
||||||
|
*
|
||||||
|
* The global interface exposing pointer constraining functionality. It
|
||||||
|
* exposes two requests: lock_pointer for locking the pointer to its
|
||||||
|
* position, and confine_pointer for locking the pointer to a region.
|
||||||
|
*
|
||||||
|
* The lock_pointer and confine_pointer requests create the objects
|
||||||
|
* wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||||
|
* use these objects to interact with the lock.
|
||||||
|
*
|
||||||
|
* For any surface, only one lock or confinement may be active across all
|
||||||
|
* wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||||
|
* when another lock or confinement is active or requested on the same surface
|
||||||
|
* and with any of the wl_pointer objects of the same seat, an
|
||||||
|
* 'already_constrained' error will be raised.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_pointer_constraints_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_LOCKED_POINTER_V1_INTERFACE
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_locked_pointer_v1 zwp_locked_pointer_v1
|
||||||
|
* @section page_iface_zwp_locked_pointer_v1_desc Description
|
||||||
|
*
|
||||||
|
* The wp_locked_pointer interface represents a locked pointer state.
|
||||||
|
*
|
||||||
|
* While the lock of this object is active, the wl_pointer objects of the
|
||||||
|
* associated seat will not emit any wl_pointer.motion events.
|
||||||
|
*
|
||||||
|
* This object will send the event 'locked' when the lock is activated.
|
||||||
|
* Whenever the lock is activated, it is guaranteed that the locked surface
|
||||||
|
* will already have received pointer focus and that the pointer will be
|
||||||
|
* within the region passed to the request creating this object.
|
||||||
|
*
|
||||||
|
* To unlock the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_locked_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unlock the pointer the unlocked event is
|
||||||
|
* sent. See wp_locked_pointer.unlock for details.
|
||||||
|
*
|
||||||
|
* When unlocking, the compositor may warp the cursor position to the set
|
||||||
|
* cursor position hint. If it does, it will not result in any relative
|
||||||
|
* motion events emitted via wp_relative_pointer.
|
||||||
|
*
|
||||||
|
* If the surface the lock was requested on is destroyed and the lock is not
|
||||||
|
* yet activated, the wp_locked_pointer object is now defunct and must be
|
||||||
|
* destroyed.
|
||||||
|
* @section page_iface_zwp_locked_pointer_v1_api API
|
||||||
|
* See @ref iface_zwp_locked_pointer_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_locked_pointer_v1 The zwp_locked_pointer_v1 interface
|
||||||
|
*
|
||||||
|
* The wp_locked_pointer interface represents a locked pointer state.
|
||||||
|
*
|
||||||
|
* While the lock of this object is active, the wl_pointer objects of the
|
||||||
|
* associated seat will not emit any wl_pointer.motion events.
|
||||||
|
*
|
||||||
|
* This object will send the event 'locked' when the lock is activated.
|
||||||
|
* Whenever the lock is activated, it is guaranteed that the locked surface
|
||||||
|
* will already have received pointer focus and that the pointer will be
|
||||||
|
* within the region passed to the request creating this object.
|
||||||
|
*
|
||||||
|
* To unlock the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_locked_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unlock the pointer the unlocked event is
|
||||||
|
* sent. See wp_locked_pointer.unlock for details.
|
||||||
|
*
|
||||||
|
* When unlocking, the compositor may warp the cursor position to the set
|
||||||
|
* cursor position hint. If it does, it will not result in any relative
|
||||||
|
* motion events emitted via wp_relative_pointer.
|
||||||
|
*
|
||||||
|
* If the surface the lock was requested on is destroyed and the lock is not
|
||||||
|
* yet activated, the wp_locked_pointer object is now defunct and must be
|
||||||
|
* destroyed.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_locked_pointer_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZWP_CONFINED_POINTER_V1_INTERFACE
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwp_confined_pointer_v1 zwp_confined_pointer_v1
|
||||||
|
* @section page_iface_zwp_confined_pointer_v1_desc Description
|
||||||
|
*
|
||||||
|
* The wp_confined_pointer interface represents a confined pointer state.
|
||||||
|
*
|
||||||
|
* This object will send the event 'confined' when the confinement is
|
||||||
|
* activated. Whenever the confinement is activated, it is guaranteed that
|
||||||
|
* the surface the pointer is confined to will already have received pointer
|
||||||
|
* focus and that the pointer will be within the region passed to the request
|
||||||
|
* creating this object. It is up to the compositor to decide whether this
|
||||||
|
* requires some user interaction and if the pointer will warp to within the
|
||||||
|
* passed region if outside.
|
||||||
|
*
|
||||||
|
* To unconfine the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_confined_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unconfine the pointer the unconfined event is
|
||||||
|
* sent. The wp_confined_pointer object is at this point defunct and should
|
||||||
|
* be destroyed.
|
||||||
|
* @section page_iface_zwp_confined_pointer_v1_api API
|
||||||
|
* See @ref iface_zwp_confined_pointer_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwp_confined_pointer_v1 The zwp_confined_pointer_v1 interface
|
||||||
|
*
|
||||||
|
* The wp_confined_pointer interface represents a confined pointer state.
|
||||||
|
*
|
||||||
|
* This object will send the event 'confined' when the confinement is
|
||||||
|
* activated. Whenever the confinement is activated, it is guaranteed that
|
||||||
|
* the surface the pointer is confined to will already have received pointer
|
||||||
|
* focus and that the pointer will be within the region passed to the request
|
||||||
|
* creating this object. It is up to the compositor to decide whether this
|
||||||
|
* requires some user interaction and if the pointer will warp to within the
|
||||||
|
* passed region if outside.
|
||||||
|
*
|
||||||
|
* To unconfine the pointer, send the destroy request. This will also destroy
|
||||||
|
* the wp_confined_pointer object.
|
||||||
|
*
|
||||||
|
* If the compositor decides to unconfine the pointer the unconfined event is
|
||||||
|
* sent. The wp_confined_pointer object is at this point defunct and should
|
||||||
|
* be destroyed.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwp_confined_pointer_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
* wp_pointer_constraints error values
|
||||||
|
*
|
||||||
|
* These errors can be emitted in response to wp_pointer_constraints
|
||||||
|
* requests.
|
||||||
|
*/
|
||||||
|
enum zwp_pointer_constraints_v1_error {
|
||||||
|
/**
|
||||||
|
* pointer constraint already requested on that surface
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED = 1,
|
||||||
|
};
|
||||||
|
#endif /* ZWP_POINTER_CONSTRAINTS_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
* constraint lifetime
|
||||||
|
*
|
||||||
|
* These values represent different lifetime semantics. They are passed
|
||||||
|
* as arguments to the factory requests to specify how the constraint
|
||||||
|
* lifetimes should be managed.
|
||||||
|
*/
|
||||||
|
enum zwp_pointer_constraints_v1_lifetime {
|
||||||
|
/**
|
||||||
|
* the pointer constraint is defunct once deactivated
|
||||||
|
*
|
||||||
|
* A oneshot pointer constraint will never reactivate once it has
|
||||||
|
* been deactivated. See the corresponding deactivation event
|
||||||
|
* (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined)
|
||||||
|
* for details.
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT = 1,
|
||||||
|
/**
|
||||||
|
* the pointer constraint may reactivate
|
||||||
|
*
|
||||||
|
* A persistent pointer constraint may again reactivate once it
|
||||||
|
* has been deactivated. See the corresponding deactivation event
|
||||||
|
* (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined)
|
||||||
|
* for details.
|
||||||
|
*/
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ENUM */
|
||||||
|
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY 0
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER 1
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER 2
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_pointer_constraints_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_pointer_constraints_v1_set_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_pointer_constraints_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_pointer_constraints_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_pointer_constraints_v1_get_user_data(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_pointer_constraints_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_pointer_constraints_v1_get_version(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* Used by the client to notify the server that it will no longer use this
|
||||||
|
* pointer constraints object.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_pointer_constraints_v1_destroy(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* The lock_pointer request lets the client request to disable movements of
|
||||||
|
* the virtual pointer (i.e. the cursor), effectively locking the pointer
|
||||||
|
* to a position. This request may not take effect immediately; in the
|
||||||
|
* future, when the compositor deems implementation-specific constraints
|
||||||
|
* are satisfied, the pointer lock will be activated and the compositor
|
||||||
|
* sends a locked event.
|
||||||
|
*
|
||||||
|
* The protocol provides no guarantee that the constraints are ever
|
||||||
|
* satisfied, and does not require the compositor to send an error if the
|
||||||
|
* constraints cannot ever be satisfied. It is thus possible to request a
|
||||||
|
* lock that will never activate.
|
||||||
|
*
|
||||||
|
* There may not be another pointer constraint of any kind requested or
|
||||||
|
* active on the surface for any of the wl_pointer objects of the seat of
|
||||||
|
* the passed pointer when requesting a lock. If there is, an error will be
|
||||||
|
* raised. See general pointer lock documentation for more details.
|
||||||
|
*
|
||||||
|
* The intersection of the region passed with this request and the input
|
||||||
|
* region of the surface is used to determine where the pointer must be
|
||||||
|
* in order for the lock to activate. It is up to the compositor whether to
|
||||||
|
* warp the pointer or require some kind of user interaction for the lock
|
||||||
|
* to activate. If the region is null the surface input region is used.
|
||||||
|
*
|
||||||
|
* A surface may receive pointer focus without the lock being activated.
|
||||||
|
*
|
||||||
|
* The request creates a new object wp_locked_pointer which is used to
|
||||||
|
* interact with the lock as well as receive updates about its state. See
|
||||||
|
* the the description of wp_locked_pointer for further information.
|
||||||
|
*
|
||||||
|
* Note that while a pointer is locked, the wl_pointer objects of the
|
||||||
|
* corresponding seat will not emit any wl_pointer.motion events, but
|
||||||
|
* relative motion events will still be emitted via wp_relative_pointer
|
||||||
|
* objects of the same seat. wl_pointer.axis and wl_pointer.button events
|
||||||
|
* are unaffected.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_locked_pointer_v1 *
|
||||||
|
zwp_pointer_constraints_v1_lock_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LOCK_POINTER, &zwp_locked_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime);
|
||||||
|
|
||||||
|
return (struct zwp_locked_pointer_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_pointer_constraints_v1
|
||||||
|
*
|
||||||
|
* The confine_pointer request lets the client request to confine the
|
||||||
|
* pointer cursor to a given region. This request may not take effect
|
||||||
|
* immediately; in the future, when the compositor deems implementation-
|
||||||
|
* specific constraints are satisfied, the pointer confinement will be
|
||||||
|
* activated and the compositor sends a confined event.
|
||||||
|
*
|
||||||
|
* The intersection of the region passed with this request and the input
|
||||||
|
* region of the surface is used to determine where the pointer must be
|
||||||
|
* in order for the confinement to activate. It is up to the compositor
|
||||||
|
* whether to warp the pointer or require some kind of user interaction for
|
||||||
|
* the confinement to activate. If the region is null the surface input
|
||||||
|
* region is used.
|
||||||
|
*
|
||||||
|
* The request will create a new object wp_confined_pointer which is used
|
||||||
|
* to interact with the confinement as well as receive updates about its
|
||||||
|
* state. See the the description of wp_confined_pointer for further
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
static inline struct zwp_confined_pointer_v1 *
|
||||||
|
zwp_pointer_constraints_v1_confine_pointer(struct zwp_pointer_constraints_v1 *zwp_pointer_constraints_v1, struct wl_surface *surface, struct wl_pointer *pointer, struct wl_region *region, uint32_t lifetime)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_pointer_constraints_v1,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_CONFINE_POINTER, &zwp_confined_pointer_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_pointer_constraints_v1), 0, NULL, surface, pointer, region, lifetime);
|
||||||
|
|
||||||
|
return (struct zwp_confined_pointer_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
* @struct zwp_locked_pointer_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwp_locked_pointer_v1_listener {
|
||||||
|
/**
|
||||||
|
* lock activation event
|
||||||
|
*
|
||||||
|
* Notification that the pointer lock of the seat's pointer is
|
||||||
|
* activated.
|
||||||
|
*/
|
||||||
|
void (*locked)(void *data,
|
||||||
|
struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
|
||||||
|
/**
|
||||||
|
* lock deactivation event
|
||||||
|
*
|
||||||
|
* Notification that the pointer lock of the seat's pointer is no
|
||||||
|
* longer active. If this is a oneshot pointer lock (see
|
||||||
|
* wp_pointer_constraints.lifetime) this object is now defunct and
|
||||||
|
* should be destroyed. If this is a persistent pointer lock (see
|
||||||
|
* wp_pointer_constraints.lifetime) this pointer lock may again
|
||||||
|
* reactivate in the future.
|
||||||
|
*/
|
||||||
|
void (*unlocked)(void *data,
|
||||||
|
struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwp_locked_pointer_v1_add_listener(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1,
|
||||||
|
const struct zwp_locked_pointer_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_DESTROY 0
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT 1
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_REGION 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_LOCKED_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_UNLOCKED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_LOCKED_POINTER_V1_SET_REGION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_locked_pointer_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_locked_pointer_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_locked_pointer_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_locked_pointer_v1_get_user_data(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_locked_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_locked_pointer_v1_get_version(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Destroy the locked pointer object. If applicable, the compositor will
|
||||||
|
* unlock the pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_destroy(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Set the cursor position hint relative to the top left corner of the
|
||||||
|
* surface.
|
||||||
|
*
|
||||||
|
* If the client is drawing its own cursor, it should update the position
|
||||||
|
* hint to the position of its own cursor. A compositor may use this
|
||||||
|
* information to warp the pointer upon unlock in order to avoid pointer
|
||||||
|
* jumps.
|
||||||
|
*
|
||||||
|
* The cursor position hint is double buffered. The new hint will only take
|
||||||
|
* effect when the associated surface gets it pending state applied. See
|
||||||
|
* wl_surface.commit for details.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_cursor_position_hint(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, wl_fixed_t surface_x, wl_fixed_t surface_y)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_SET_CURSOR_POSITION_HINT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, surface_x, surface_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_locked_pointer_v1
|
||||||
|
*
|
||||||
|
* Set a new region used to lock the pointer.
|
||||||
|
*
|
||||||
|
* The new lock region is double-buffered. The new lock region will
|
||||||
|
* only take effect when the associated surface gets its pending state
|
||||||
|
* applied. See wl_surface.commit for details.
|
||||||
|
*
|
||||||
|
* For details about the lock region, see wp_locked_pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_locked_pointer_v1_set_region(struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1, struct wl_region *region)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_locked_pointer_v1,
|
||||||
|
ZWP_LOCKED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_locked_pointer_v1), 0, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
* @struct zwp_confined_pointer_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwp_confined_pointer_v1_listener {
|
||||||
|
/**
|
||||||
|
* pointer confined
|
||||||
|
*
|
||||||
|
* Notification that the pointer confinement of the seat's
|
||||||
|
* pointer is activated.
|
||||||
|
*/
|
||||||
|
void (*confined)(void *data,
|
||||||
|
struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
|
||||||
|
/**
|
||||||
|
* pointer unconfined
|
||||||
|
*
|
||||||
|
* Notification that the pointer confinement of the seat's
|
||||||
|
* pointer is no longer active. If this is a oneshot pointer
|
||||||
|
* confinement (see wp_pointer_constraints.lifetime) this object is
|
||||||
|
* now defunct and should be destroyed. If this is a persistent
|
||||||
|
* pointer confinement (see wp_pointer_constraints.lifetime) this
|
||||||
|
* pointer confinement may again reactivate in the future.
|
||||||
|
*/
|
||||||
|
void (*unconfined)(void *data,
|
||||||
|
struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwp_confined_pointer_v1_add_listener(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1,
|
||||||
|
const struct zwp_confined_pointer_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_DESTROY 0
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_SET_REGION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_CONFINED_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_UNCONFINED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*/
|
||||||
|
#define ZWP_CONFINED_POINTER_V1_SET_REGION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_confined_pointer_v1 */
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_set_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_confined_pointer_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwp_confined_pointer_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwp_confined_pointer_v1_get_user_data(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_confined_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_confined_pointer_v1_get_version(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*
|
||||||
|
* Destroy the confined pointer object. If applicable, the compositor will
|
||||||
|
* unconfine the pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_destroy(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
ZWP_CONFINED_POINTER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwp_confined_pointer_v1
|
||||||
|
*
|
||||||
|
* Set a new region used to confine the pointer.
|
||||||
|
*
|
||||||
|
* The new confine region is double-buffered. The new confine region will
|
||||||
|
* only take effect when the associated surface gets its pending state
|
||||||
|
* applied. See wl_surface.commit for details.
|
||||||
|
*
|
||||||
|
* If the confinement is active when the new confinement region is applied
|
||||||
|
* and the pointer ends up outside of newly applied region, the pointer may
|
||||||
|
* warped to a position within the new confinement region. If warped, a
|
||||||
|
* wl_pointer.motion event will be emitted, but no
|
||||||
|
* wp_relative_pointer.relative_motion event.
|
||||||
|
*
|
||||||
|
* The compositor may also, instead of using the new region, unconfine the
|
||||||
|
* pointer.
|
||||||
|
*
|
||||||
|
* For details about the confine region, see wp_confined_pointer.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwp_confined_pointer_v1_set_region(struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1, struct wl_region *region)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zwp_confined_pointer_v1,
|
||||||
|
ZWP_CONFINED_POINTER_V1_SET_REGION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_confined_pointer_v1), 0, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
66
src/cmd/devdraw/wayland-xdg-decoration.c
Normal file
66
src/cmd/devdraw/wayland-xdg-decoration.c
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* Generated by wayland-scanner 1.23.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2018 Simon Ser
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_decoration_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
&zxdg_toplevel_decoration_v1_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface zxdg_decoration_manager_v1_interface = {
|
||||||
|
"zxdg_decoration_manager_v1", 1,
|
||||||
|
2, zxdg_decoration_manager_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "set_mode", "u", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
{ "unset_mode", "", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
|
||||||
|
{ "configure", "u", xdg_decoration_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
|
||||||
|
"zxdg_toplevel_decoration_v1", 1,
|
||||||
|
3, zxdg_toplevel_decoration_v1_requests,
|
||||||
|
1, zxdg_toplevel_decoration_v1_events,
|
||||||
|
};
|
||||||
|
|
||||||
377
src/cmd/devdraw/wayland-xdg-decoration.h
Normal file
377
src/cmd/devdraw/wayland-xdg-decoration.h
Normal file
|
|
@ -0,0 +1,377 @@
|
||||||
|
/* Generated by wayland-scanner 1.23.0 */
|
||||||
|
|
||||||
|
#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol
|
||||||
|
* @section page_ifaces_xdg_decoration_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager
|
||||||
|
* - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface
|
||||||
|
* @section page_copyright_xdg_decoration_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2018 Simon Ser
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct xdg_toplevel;
|
||||||
|
struct zxdg_decoration_manager_v1;
|
||||||
|
struct zxdg_toplevel_decoration_v1;
|
||||||
|
|
||||||
|
#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1
|
||||||
|
* @section page_iface_zxdg_decoration_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* This interface allows a compositor to announce support for server-side
|
||||||
|
* decorations.
|
||||||
|
*
|
||||||
|
* A window decoration is a set of window controls as deemed appropriate by
|
||||||
|
* the party managing them, such as user interface components used to move,
|
||||||
|
* resize and change a window's state.
|
||||||
|
*
|
||||||
|
* A client can use this protocol to request being decorated by a supporting
|
||||||
|
* compositor.
|
||||||
|
*
|
||||||
|
* If compositor and client do not negotiate the use of a server-side
|
||||||
|
* decoration using this protocol, clients continue to self-decorate as they
|
||||||
|
* see fit.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
* @section page_iface_zxdg_decoration_manager_v1_api API
|
||||||
|
* See @ref iface_zxdg_decoration_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface
|
||||||
|
*
|
||||||
|
* This interface allows a compositor to announce support for server-side
|
||||||
|
* decorations.
|
||||||
|
*
|
||||||
|
* A window decoration is a set of window controls as deemed appropriate by
|
||||||
|
* the party managing them, such as user interface components used to move,
|
||||||
|
* resize and change a window's state.
|
||||||
|
*
|
||||||
|
* A client can use this protocol to request being decorated by a supporting
|
||||||
|
* compositor.
|
||||||
|
*
|
||||||
|
* If compositor and client do not negotiate the use of a server-side
|
||||||
|
* decoration using this protocol, clients continue to self-decorate as they
|
||||||
|
* see fit.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is experimental and
|
||||||
|
* backward incompatible changes may be made. Backward compatible changes
|
||||||
|
* may be added together with the corresponding interface version bump.
|
||||||
|
* Backward incompatible changes are done by bumping the version number in
|
||||||
|
* the protocol and interface names and resetting the interface version.
|
||||||
|
* Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
* version number in the protocol and interface names are removed and the
|
||||||
|
* interface version number is reset.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_decoration_manager_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1
|
||||||
|
* @section page_iface_zxdg_toplevel_decoration_v1_desc Description
|
||||||
|
*
|
||||||
|
* The decoration object allows the compositor to toggle server-side window
|
||||||
|
* decorations for a toplevel surface. The client can request to switch to
|
||||||
|
* another mode.
|
||||||
|
*
|
||||||
|
* The xdg_toplevel_decoration object must be destroyed before its
|
||||||
|
* xdg_toplevel.
|
||||||
|
* @section page_iface_zxdg_toplevel_decoration_v1_api API
|
||||||
|
* See @ref iface_zxdg_toplevel_decoration_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface
|
||||||
|
*
|
||||||
|
* The decoration object allows the compositor to toggle server-side window
|
||||||
|
* decorations for a toplevel surface. The client can request to switch to
|
||||||
|
* another mode.
|
||||||
|
*
|
||||||
|
* The xdg_toplevel_decoration object must be destroyed before its
|
||||||
|
* xdg_toplevel.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_decoration_manager_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*
|
||||||
|
* Destroy the decoration manager. This doesn't destroy objects created
|
||||||
|
* with the manager.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||||
|
ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_decoration_manager_v1
|
||||||
|
*
|
||||||
|
* Create a new decoration object associated with the given toplevel.
|
||||||
|
*
|
||||||
|
* Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
|
||||||
|
* buffer attached or committed is a client error, and any attempts by a
|
||||||
|
* client to attach or manipulate a buffer prior to the first
|
||||||
|
* xdg_toplevel_decoration.configure event must also be treated as
|
||||||
|
* errors.
|
||||||
|
*/
|
||||||
|
static inline struct zxdg_toplevel_decoration_v1 *
|
||||||
|
zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
|
||||||
|
ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel);
|
||||||
|
|
||||||
|
return (struct zxdg_toplevel_decoration_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
|
||||||
|
enum zxdg_toplevel_decoration_v1_error {
|
||||||
|
/**
|
||||||
|
* xdg_toplevel has a buffer attached before configure
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0,
|
||||||
|
/**
|
||||||
|
* xdg_toplevel already has a decoration object
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1,
|
||||||
|
/**
|
||||||
|
* xdg_toplevel destroyed before the decoration object
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
* window decoration modes
|
||||||
|
*
|
||||||
|
* These values describe window decoration modes.
|
||||||
|
*/
|
||||||
|
enum zxdg_toplevel_decoration_v1_mode {
|
||||||
|
/**
|
||||||
|
* no server-side window decoration
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
|
||||||
|
/**
|
||||||
|
* server-side window decoration
|
||||||
|
*/
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
* @struct zxdg_toplevel_decoration_v1_listener
|
||||||
|
*/
|
||||||
|
struct zxdg_toplevel_decoration_v1_listener {
|
||||||
|
/**
|
||||||
|
* notify a decoration mode change
|
||||||
|
*
|
||||||
|
* The configure event configures the effective decoration mode.
|
||||||
|
* The configured state should not be applied immediately. Clients
|
||||||
|
* must send an ack_configure in response to this event. See
|
||||||
|
* xdg_surface.configure and xdg_surface.ack_configure for details.
|
||||||
|
*
|
||||||
|
* A configure event can be sent at any time. The specified mode
|
||||||
|
* must be obeyed by the client.
|
||||||
|
* @param mode the decoration mode
|
||||||
|
*/
|
||||||
|
void (*configure)(void *data,
|
||||||
|
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||||
|
uint32_t mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||||
|
const struct zxdg_toplevel_decoration_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Switch back to a mode without any server-side decorations at the next
|
||||||
|
* commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Set the toplevel surface decoration mode. This informs the compositor
|
||||||
|
* that the client prefers the provided decoration mode.
|
||||||
|
*
|
||||||
|
* After requesting a decoration mode, the compositor will respond by
|
||||||
|
* emitting an xdg_surface.configure event. The client should then update
|
||||||
|
* its content, drawing it without decorations if the received mode is
|
||||||
|
* server-side decorations. The client must also acknowledge the configure
|
||||||
|
* when committing the new content (see xdg_surface.ack_configure).
|
||||||
|
*
|
||||||
|
* The compositor can decide not to use the client's mode and enforce a
|
||||||
|
* different mode instead.
|
||||||
|
*
|
||||||
|
* Clients whose decoration mode depend on the xdg_toplevel state may send
|
||||||
|
* a set_mode request in response to an xdg_surface.configure event and wait
|
||||||
|
* for the next xdg_surface.configure event to prevent unwanted state.
|
||||||
|
* Such clients are responsible for preventing configure loops and must
|
||||||
|
* make sure not to send multiple successive set_mode requests with the
|
||||||
|
* same decoration mode.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_toplevel_decoration_v1
|
||||||
|
*
|
||||||
|
* Unset the toplevel surface decoration mode. This informs the compositor
|
||||||
|
* that the client doesn't prefer a particular decoration mode.
|
||||||
|
*
|
||||||
|
* This request has the same semantics as set_mode.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
174
src/cmd/devdraw/wayland-xdg-shell.c
Normal file
174
src/cmd/devdraw/wayland-xdg-shell.c
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
/* Generated by wayland-scanner 1.23.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2013 Kristian Høgsberg
|
||||||
|
* Copyright © 2013 Rafael Antognolli
|
||||||
|
* Copyright © 2013 Jasper St. Pierre
|
||||||
|
* Copyright © 2010-2013 Intel Corporation
|
||||||
|
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||||
|
* Copyright © 2015-2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface xdg_positioner_interface;
|
||||||
|
extern const struct wl_interface xdg_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_shell_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||||
|
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||||
|
{ "pong", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_events[] = {
|
||||||
|
{ "ping", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface xdg_wm_base_interface = {
|
||||||
|
"xdg_wm_base", 6,
|
||||||
|
4, xdg_wm_base_requests,
|
||||||
|
1, xdg_wm_base_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_positioner_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface xdg_positioner_interface = {
|
||||||
|
"xdg_positioner", 6,
|
||||||
|
10, xdg_positioner_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||||
|
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||||
|
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_events[] = {
|
||||||
|
{ "configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface xdg_surface_interface = {
|
||||||
|
"xdg_surface", 6,
|
||||||
|
5, xdg_surface_requests,
|
||||||
|
1, xdg_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||||
|
{ "set_title", "s", xdg_shell_types + 0 },
|
||||||
|
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||||
|
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||||
|
{ "move", "ou", xdg_shell_types + 16 },
|
||||||
|
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||||
|
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||||
|
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_events[] = {
|
||||||
|
{ "configure", "iia", xdg_shell_types + 0 },
|
||||||
|
{ "close", "", xdg_shell_types + 0 },
|
||||||
|
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||||
|
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface xdg_toplevel_interface = {
|
||||||
|
"xdg_toplevel", 6,
|
||||||
|
14, xdg_toplevel_requests,
|
||||||
|
4, xdg_toplevel_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "grab", "ou", xdg_shell_types + 22 },
|
||||||
|
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_events[] = {
|
||||||
|
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "popup_done", "", xdg_shell_types + 0 },
|
||||||
|
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_EXPORT const struct wl_interface xdg_popup_interface = {
|
||||||
|
"xdg_popup", 6,
|
||||||
|
3, xdg_popup_requests,
|
||||||
|
3, xdg_popup_events,
|
||||||
|
};
|
||||||
|
|
||||||
2327
src/cmd/devdraw/wayland-xdg-shell.h
Normal file
2327
src/cmd/devdraw/wayland-xdg-shell.h
Normal file
File diff suppressed because it is too large
Load diff
986
src/cmd/devdraw/wayland.c
Normal file
986
src/cmd/devdraw/wayland.c
Normal file
|
|
@ -0,0 +1,986 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <memdraw.h>
|
||||||
|
#include <memlayer.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
#include "bigarrow.h"
|
||||||
|
#include "devdraw.h"
|
||||||
|
#include "wayland-pointer-constraints.h"
|
||||||
|
#include "wayland-xdg-decoration.h"
|
||||||
|
#include "wayland-xdg-shell.h"
|
||||||
|
|
||||||
|
// alt+click and ctl+click are mapped to mouse buttons
|
||||||
|
// to support single button mice.
|
||||||
|
#define ALT_BUTTON 1
|
||||||
|
#define CTL_BUTTON 2
|
||||||
|
|
||||||
|
struct WaylandBuffer {
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int size;
|
||||||
|
char *data;
|
||||||
|
struct wl_buffer* wl_buffer;
|
||||||
|
};
|
||||||
|
typedef struct WaylandBuffer WaylandBuffer;
|
||||||
|
|
||||||
|
struct WaylandClient {
|
||||||
|
// The screen image written to by the client, and read by this driver.
|
||||||
|
Memimage *memimage;
|
||||||
|
|
||||||
|
// The current mouse coordinates and a bitmask of held buttons.
|
||||||
|
int mouse_x;
|
||||||
|
int mouse_y;
|
||||||
|
int buttons;
|
||||||
|
|
||||||
|
// Booleans indicating whether control or alt are currently held.
|
||||||
|
int ctl;
|
||||||
|
int alt;
|
||||||
|
|
||||||
|
// State for key repeat for keyboard keys.
|
||||||
|
int repeat_rune;
|
||||||
|
int repeat_next_ms;
|
||||||
|
|
||||||
|
// State for "key repeat" for the mouse scroll wheel.
|
||||||
|
// This allows touchpad devices to have accelerated scrolling.
|
||||||
|
int repeat_scroll_button;
|
||||||
|
int repeat_scroll_count;
|
||||||
|
int repeat_scroll_rate_ms;
|
||||||
|
int repeat_scroll_next_ms;
|
||||||
|
|
||||||
|
// The Wayland surface for this window
|
||||||
|
// and its corresponding xdg objects.
|
||||||
|
struct wl_surface *wl_surface;
|
||||||
|
struct xdg_surface *xdg_surface;
|
||||||
|
struct xdg_toplevel *xdg_toplevel;
|
||||||
|
|
||||||
|
// A callback when wl_surface is ready for the next frame.
|
||||||
|
// Currently this is not used for drawing,
|
||||||
|
// but as a hack for implementing key repeat
|
||||||
|
// without needing to implement our own timer thread/events.
|
||||||
|
struct wl_callback *wl_callback;
|
||||||
|
|
||||||
|
// The mouse pointer and the surface for the current cursor.
|
||||||
|
struct wl_pointer *wl_pointer;
|
||||||
|
struct wl_surface *wl_surface_cursor;
|
||||||
|
|
||||||
|
// The keyboard and xkb state used
|
||||||
|
// for mapping scan codes to key codes.
|
||||||
|
struct wl_keyboard *wl_keyboard;
|
||||||
|
struct xkb_context *xkb_context;
|
||||||
|
struct xkb_keymap *xkb_keymap;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
};
|
||||||
|
typedef struct WaylandClient WaylandClient;
|
||||||
|
|
||||||
|
static QLock wayland_lock;
|
||||||
|
|
||||||
|
// Required globals wayland objects.
|
||||||
|
static struct wl_display *wl_display;
|
||||||
|
static struct wl_output *wl_output;
|
||||||
|
static struct wl_registry *wl_registry;
|
||||||
|
static struct wl_shm *wl_shm;
|
||||||
|
static struct wl_compositor *wl_compositor;
|
||||||
|
static struct xdg_wm_base *xdg_wm_base;
|
||||||
|
static struct wl_seat *wl_seat;
|
||||||
|
|
||||||
|
// Optional global wayland objects.
|
||||||
|
// Need to NULL check them before using.
|
||||||
|
static struct zxdg_decoration_manager_v1 *decoration_manager;
|
||||||
|
static struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||||
|
|
||||||
|
// The wl output scale factor reported by wl_output.
|
||||||
|
// We only set it if we get th event before entering the graphics loop.
|
||||||
|
// Once we enter the loop, we never change it to avoid the need
|
||||||
|
// to reason about which scale a buffer was created with.
|
||||||
|
int wl_output_scale_factor = 1;
|
||||||
|
int entered_gfx_loop = 0;
|
||||||
|
|
||||||
|
// The delay in ms which a key must be held to begin repeating..
|
||||||
|
int key_repeat_delay_ms = 500;
|
||||||
|
// The number of ms between repeats of a repeating key.
|
||||||
|
int key_repeat_ms = 100;
|
||||||
|
// The maximum number of ms between repeats of a scroll.
|
||||||
|
// This is scaled by the number of repeating scrolls pending.
|
||||||
|
int scroll_repeat_ms = 100;
|
||||||
|
|
||||||
|
// A pool of xrgb888 buffers used for drawing to the screen.
|
||||||
|
// When drawing, we give ownership of the buffer's memory to the compositor.
|
||||||
|
// The compositor notifies us asynchronously when it is done reading the buffer.
|
||||||
|
// In the case that we need to draw (rpc_flush) before the buffer is ready,
|
||||||
|
// we will need to allocate a whole new buffer to draw to.
|
||||||
|
// We use this pool to avoid the need to setup a new shared memory buffer
|
||||||
|
// each time this happens.
|
||||||
|
#define N_XRGB8888_BUFFERS 3
|
||||||
|
struct WaylandBuffer *xrgb8888_buffers[N_XRGB8888_BUFFERS];
|
||||||
|
|
||||||
|
int wayland_debug = 0;
|
||||||
|
|
||||||
|
#define DEBUG(...) \
|
||||||
|
do { \
|
||||||
|
if (wayland_debug) { \
|
||||||
|
fprint(2, __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
static void registry_global(void *data, struct wl_registry *wl_registry,
|
||||||
|
uint32_t name, const char *interface, uint32_t version) {
|
||||||
|
if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
|
wl_output = wl_registry_bind(wl_registry, name, &wl_output_interface, 2);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||||
|
wl_shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
|
wl_compositor = wl_registry_bind(wl_registry, name,
|
||||||
|
&wl_compositor_interface, 4);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
|
||||||
|
xdg_wm_base = wl_registry_bind(wl_registry, name,
|
||||||
|
&xdg_wm_base_interface, 1);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
|
wl_seat = wl_registry_bind(wl_registry, name, &wl_seat_interface, 1);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) {
|
||||||
|
decoration_manager = wl_registry_bind(wl_registry, name,
|
||||||
|
&zxdg_decoration_manager_v1_interface, 1);
|
||||||
|
|
||||||
|
} else if (strcmp(interface, zwp_pointer_constraints_v1_interface.name) == 0) {
|
||||||
|
pointer_constraints = wl_registry_bind(wl_registry, name,
|
||||||
|
&zwp_pointer_constraints_v1_interface, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registry_global_remove(void *data, struct wl_registry *wl_registry,
|
||||||
|
uint32_t name) {}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener wl_registry_listener = {
|
||||||
|
.global = registry_global,
|
||||||
|
.global_remove = registry_global_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
void wl_output_geometry(void *data, struct wl_output *wl_output,
|
||||||
|
int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
|
||||||
|
int32_t subpixel, const char *make, const char *model, int32_t transform) {}
|
||||||
|
|
||||||
|
void wl_output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
||||||
|
int32_t width, int32_t height, int32_t refresh) {}
|
||||||
|
|
||||||
|
void wl_output_done(void *data, struct wl_output *wl_output) {}
|
||||||
|
|
||||||
|
void wl_output_scale(void *data, struct wl_output *wl_output, int32_t factor) {
|
||||||
|
DEBUG("wl_output_scale(factor=%d)\n", factor);
|
||||||
|
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
if (!entered_gfx_loop) {
|
||||||
|
wl_output_scale_factor = factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_output_listener wl_output_listener = {
|
||||||
|
.geometry = wl_output_geometry,
|
||||||
|
.mode = wl_output_mode,
|
||||||
|
.done = wl_output_done,
|
||||||
|
.scale = wl_output_scale,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) {
|
||||||
|
xdg_wm_base_pong(xdg_wm_base, serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
||||||
|
.ping = xdg_wm_base_ping,
|
||||||
|
};
|
||||||
|
|
||||||
|
void delete_buffer(WaylandBuffer *b) {
|
||||||
|
munmap(b->data, b->size);
|
||||||
|
wl_buffer_destroy(b->wl_buffer);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_buffer_release(void *data, struct wl_buffer *wl_buffer) {
|
||||||
|
if (data == NULL) {
|
||||||
|
wl_buffer_destroy(wl_buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < N_XRGB8888_BUFFERS; i++) {
|
||||||
|
if (xrgb8888_buffers[i] == NULL) {
|
||||||
|
xrgb8888_buffers[i] = (WaylandBuffer*) data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete_buffer((WaylandBuffer*) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_buffer_listener wl_buffer_listener = {
|
||||||
|
.release = wl_buffer_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) {
|
||||||
|
DEBUG("xdg_surface_configure\n");
|
||||||
|
const Client* c = data;
|
||||||
|
const WaylandClient *wl = c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
xdg_surface_ack_configure(wl->xdg_surface, serial);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
DEBUG("xdg_surface_configure: returned\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||||
|
.configure = xdg_surface_configure,
|
||||||
|
};
|
||||||
|
|
||||||
|
void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||||
|
int32_t width, int32_t height, struct wl_array *states) {
|
||||||
|
DEBUG("xdg_toplevel_configure(width=%d, height=%d)\n", width, height);
|
||||||
|
if (width == 0 || height == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
width *= wl_output_scale_factor;
|
||||||
|
height *= wl_output_scale_factor;
|
||||||
|
Rectangle r = Rect(0, 0, width, height);
|
||||||
|
if (eqrect(r, wl->memimage->r)) {
|
||||||
|
// The size didn't change, so nothing to do.
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The size changed, so allocate a new Memimage and notify the client.
|
||||||
|
wl->memimage = _allocmemimage(r, XRGB32);
|
||||||
|
c->mouserect = r;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
gfx_replacescreenimage(c, wl->memimage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) {
|
||||||
|
DEBUG("xdg_toplevel_close\n");
|
||||||
|
threadexitsall(nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||||
|
.configure = xdg_toplevel_configure,
|
||||||
|
.close = xdg_toplevel_close,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_callback_listener wl_callback_listener;
|
||||||
|
|
||||||
|
// The callback is called per-frame.
|
||||||
|
// It is currently only used to implement key repeat.
|
||||||
|
static void wl_callback_done(void *data, struct wl_callback *wl_callback, uint32_t time) {
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
// Request another callback for the next frame.
|
||||||
|
// TODO: Only request a callback if we are still repeating a key.
|
||||||
|
wl_callback_destroy(wl_callback);
|
||||||
|
wl_callback = wl_surface_frame(wl->wl_surface);
|
||||||
|
wl_callback_add_listener(wl_callback, &wl_callback_listener, c);
|
||||||
|
wl_surface_commit(wl->wl_surface);
|
||||||
|
|
||||||
|
int repeat_rune = 0;
|
||||||
|
if (wl->repeat_rune && time >= wl->repeat_next_ms) {
|
||||||
|
repeat_rune = wl->repeat_rune;
|
||||||
|
wl->repeat_next_ms = time + key_repeat_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
int repeat_scroll_button = 0;
|
||||||
|
if (wl->repeat_scroll_button && time >= wl->repeat_scroll_next_ms) {
|
||||||
|
repeat_scroll_button = wl->repeat_scroll_button | wl->buttons;
|
||||||
|
wl->repeat_scroll_count--;
|
||||||
|
if (wl->repeat_scroll_count == 0) {
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
}
|
||||||
|
wl->repeat_scroll_next_ms = time + scroll_repeat_ms/wl->repeat_scroll_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
if (repeat_rune) {
|
||||||
|
gfx_keystroke(c, repeat_rune);
|
||||||
|
}
|
||||||
|
if (repeat_scroll_button) {
|
||||||
|
gfx_mousetrack(c, x, y, repeat_scroll_button, (uint) time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_callback_listener wl_callback_listener = {
|
||||||
|
.done = wl_callback_done,
|
||||||
|
};
|
||||||
|
|
||||||
|
void wl_pointer_enter(void *data,struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
|
struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->mouse_x = wl_fixed_to_int(surface_x) * wl_output_scale_factor;
|
||||||
|
wl->mouse_y = wl_fixed_to_int(surface_y) * wl_output_scale_factor;
|
||||||
|
|
||||||
|
wl_pointer_set_cursor(wl->wl_pointer, serial, wl->wl_surface_cursor, 0, 0);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
// We don't call gfx_mousetrack here, since we don't have the time.
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t serial, struct wl_surface *surface) {
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->buttons = 0;
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
|
wl_fixed_t surface_x, wl_fixed_t surface_y){
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
wl->repeat_scroll_count = 0;
|
||||||
|
wl->mouse_x = wl_fixed_to_int(surface_x) * wl_output_scale_factor;
|
||||||
|
wl->mouse_y = wl_fixed_to_int(surface_y) * wl_output_scale_factor;
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
int b = wl->buttons;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
gfx_mousetrack(c, x, y, b, (uint) time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
|
uint32_t time, uint32_t button, uint32_t state) {
|
||||||
|
DEBUG("wl_pointer_button(button=%d)\n", (int) button);
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
wl->repeat_scroll_count = 0;
|
||||||
|
|
||||||
|
int mask = 0;
|
||||||
|
switch (button) {
|
||||||
|
case BTN_LEFT:
|
||||||
|
mask = 1<<0;
|
||||||
|
break;
|
||||||
|
case BTN_MIDDLE:
|
||||||
|
mask = 1<<1;
|
||||||
|
break;
|
||||||
|
case BTN_RIGHT:
|
||||||
|
mask = 1<<2;
|
||||||
|
break;
|
||||||
|
case BTN_4:
|
||||||
|
mask = 1<<3;
|
||||||
|
break;
|
||||||
|
case BTN_5:
|
||||||
|
mask = 1<<4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG("wl_pointer_button: unknown button: %d\n", button);
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (button == BTN_LEFT) {
|
||||||
|
if (wl->ctl) {
|
||||||
|
mask = 1 << CTL_BUTTON;
|
||||||
|
} else if (wl->alt) {
|
||||||
|
mask = 1 << ALT_BUTTON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG("wl_pointer_button: mask=%x\n", mask);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||||
|
wl->buttons |= mask;
|
||||||
|
break;
|
||||||
|
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||||
|
wl->buttons &= ~mask;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprint(2, "Unknown button state: %d\n", state);
|
||||||
|
}
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
int b = wl->buttons;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
DEBUG("wl_pointer_button: gfx_trackmouse(x=%d, y=%d, b=%d)\n", x, y, b);
|
||||||
|
gfx_mousetrack(c, x, y, b, (uint) time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
|
uint32_t axis, wl_fixed_t value_fixed) {
|
||||||
|
double value = wl_fixed_to_double(value_fixed);
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
wl->repeat_scroll_count = 0;
|
||||||
|
|
||||||
|
int b = 0;
|
||||||
|
if (value < 0) {
|
||||||
|
b |= 1 << 3;
|
||||||
|
} else if (value > 0) {
|
||||||
|
b |= 1 << 4;
|
||||||
|
}
|
||||||
|
int mag = fabs(value);
|
||||||
|
if (mag > 1) {
|
||||||
|
wl->repeat_scroll_button = b;
|
||||||
|
wl->repeat_scroll_count = mag;
|
||||||
|
wl->repeat_scroll_next_ms = time + scroll_repeat_ms/wl->repeat_scroll_count;
|
||||||
|
}
|
||||||
|
b |= wl->buttons;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
gfx_mousetrack(c, x, y, b, (uint) time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
|
.enter = wl_pointer_enter,
|
||||||
|
.leave = wl_pointer_leave,
|
||||||
|
.motion = wl_pointer_motion,
|
||||||
|
.button = wl_pointer_button,
|
||||||
|
.axis = wl_pointer_axis,
|
||||||
|
};
|
||||||
|
|
||||||
|
void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
uint32_t format, int32_t fd, uint32_t size) {
|
||||||
|
DEBUG("wl_keyboard_keymap\n");
|
||||||
|
char *keymap = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
if (wl->xkb_keymap != NULL) {
|
||||||
|
xkb_keymap_unref(wl->xkb_keymap);
|
||||||
|
}
|
||||||
|
wl->xkb_keymap = xkb_keymap_new_from_string(wl->xkb_context, keymap,
|
||||||
|
XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||||
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
if (wl->xkb_state != NULL) {
|
||||||
|
xkb_state_unref(wl->xkb_state);
|
||||||
|
}
|
||||||
|
wl->xkb_state = xkb_state_new(wl->xkb_keymap);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
munmap(keymap, size);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
|
||||||
|
DEBUG("wl_keyboard_enter\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
uint32_t serial, struct wl_surface *surface) {
|
||||||
|
DEBUG("wl_keyboard_leave\n");
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->ctl = 0;
|
||||||
|
wl->alt = 0;
|
||||||
|
wl->repeat_rune = 0;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
wl->repeat_rune = 0;
|
||||||
|
wl->repeat_scroll_button = 0;
|
||||||
|
wl->repeat_scroll_count = 0;
|
||||||
|
|
||||||
|
key += 8; // Add 8 to translate Linux scan code to xkb code.
|
||||||
|
uint32_t rune = xkb_state_key_get_utf32(wl->xkb_state, key);
|
||||||
|
xkb_keysym_t keysym = xkb_state_key_get_one_sym(wl->xkb_state, key);
|
||||||
|
|
||||||
|
if (wayland_debug) {
|
||||||
|
char name[256];
|
||||||
|
xkb_keysym_get_name(keysym, &name[0], 256);
|
||||||
|
char *state_str = WL_KEYBOARD_KEY_STATE_PRESSED ? "down" : "up";
|
||||||
|
DEBUG("wl_keyboard_key: keysym=%s, rune=0x%x, state=%s\n",
|
||||||
|
name, rune, state_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (keysym) {
|
||||||
|
case XKB_KEY_Return:
|
||||||
|
rune = '\n';
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Alt_L:
|
||||||
|
case XKB_KEY_Alt_R:
|
||||||
|
rune = Kalt;
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
wl->alt = 1;
|
||||||
|
} else {
|
||||||
|
wl->alt = 0;
|
||||||
|
}
|
||||||
|
if (wl->buttons) {
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
wl->buttons |= 1 << ALT_BUTTON;
|
||||||
|
} else {
|
||||||
|
wl->buttons &= ~(1 << ALT_BUTTON);
|
||||||
|
}
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
int b = wl->buttons;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
gfx_mousetrack(c, x, y, b, (uint) time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Control_L:
|
||||||
|
case XKB_KEY_Control_R:
|
||||||
|
// For some reason, Kctl is not used;
|
||||||
|
// it results in drawing a replacement character.
|
||||||
|
// Common ctl combos still work.
|
||||||
|
// For example ctl+w sends rune 0x17
|
||||||
|
// which erases the previous word.
|
||||||
|
rune = 0; // Kctl;
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
wl->ctl = 1;
|
||||||
|
} else {
|
||||||
|
wl->ctl = 0;
|
||||||
|
}
|
||||||
|
if (wl->buttons) {
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
wl->buttons |= 1 << CTL_BUTTON;
|
||||||
|
} else {
|
||||||
|
wl->buttons &= ~(1 << CTL_BUTTON);
|
||||||
|
}
|
||||||
|
int x = wl->mouse_x;
|
||||||
|
int y = wl->mouse_y;
|
||||||
|
int b = wl->buttons;
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
gfx_mousetrack(c, x, y, b, (uint) time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Delete:
|
||||||
|
rune = Kdel;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Escape:
|
||||||
|
rune = Kesc;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Home:
|
||||||
|
rune = Khome;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_End:
|
||||||
|
rune = Kend;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Prior:
|
||||||
|
rune = Kpgup;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Next:
|
||||||
|
rune = Kpgdown;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Up:
|
||||||
|
rune = Kup;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Down:
|
||||||
|
rune = Kdown;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Left:
|
||||||
|
rune = Kleft;
|
||||||
|
break;
|
||||||
|
case XKB_KEY_Right:
|
||||||
|
rune = Kright;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED && rune != 0) {
|
||||||
|
wl->repeat_rune = rune;
|
||||||
|
wl->repeat_next_ms = time + key_repeat_delay_ms;
|
||||||
|
gfx_keystroke(c, rune);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
|
||||||
|
uint32_t mods_locked, uint32_t group) {
|
||||||
|
DEBUG("wl_keyboard_modifiers\n");
|
||||||
|
Client* c = data;
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
xkb_state_update_mask(wl->xkb_state, mods_depressed,
|
||||||
|
mods_latched, mods_locked, 0, 0, group);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use this to set key repeat.
|
||||||
|
// Currently we don't bind the keyboard with the correct version to get this event.
|
||||||
|
void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
int32_t rate, int32_t delay) {
|
||||||
|
DEBUG("wl_keyboard_repeat_info(rate=%d, delay=%d)\n",
|
||||||
|
(int) rate, (int) delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_keyboard_listener keyboard_listener = {
|
||||||
|
.keymap = wl_keyboard_keymap,
|
||||||
|
.enter = wl_keyboard_enter,
|
||||||
|
.leave = wl_keyboard_leave,
|
||||||
|
.key = wl_keyboard_key,
|
||||||
|
.modifiers = wl_keyboard_modifiers,
|
||||||
|
.repeat_info = wl_keyboard_repeat_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
void gfx_main(void) {
|
||||||
|
DEBUG("gfx_main called\n");
|
||||||
|
|
||||||
|
wl_display = wl_display_connect(NULL);
|
||||||
|
wl_registry = wl_display_get_registry(wl_display);
|
||||||
|
wl_registry_add_listener(wl_registry, &wl_registry_listener, NULL);
|
||||||
|
wl_display_roundtrip(wl_display);
|
||||||
|
|
||||||
|
// Ensure required globals were correctly bound.
|
||||||
|
if (wl_display == NULL) {
|
||||||
|
sysfatal("Unable to get Wayland display");
|
||||||
|
}
|
||||||
|
if (wl_registry == NULL) {
|
||||||
|
sysfatal("Unable to get Wayland registry");
|
||||||
|
}
|
||||||
|
if (wl_output == NULL) {
|
||||||
|
sysfatal("Unable to bind wl_output");
|
||||||
|
}
|
||||||
|
if (wl_shm == NULL) {
|
||||||
|
sysfatal("Unable to bind wl_shm");
|
||||||
|
}
|
||||||
|
if (wl_compositor == NULL) {
|
||||||
|
sysfatal("Unable to bind wl_compositor");
|
||||||
|
}
|
||||||
|
if (xdg_wm_base == NULL) {
|
||||||
|
sysfatal("Unable to bind xdg_wm_base");
|
||||||
|
}
|
||||||
|
if (wl_seat == NULL) {
|
||||||
|
sysfatal("Unable to bind wl_seat");
|
||||||
|
}
|
||||||
|
wl_output_add_listener(wl_output, &wl_output_listener, NULL);
|
||||||
|
xdg_wm_base_add_listener(xdg_wm_base, &xdg_wm_base_listener, NULL);
|
||||||
|
wl_display_roundtrip(wl_display);
|
||||||
|
|
||||||
|
entered_gfx_loop = 1;
|
||||||
|
gfx_started();
|
||||||
|
DEBUG("gfx_main: entering loop\n");
|
||||||
|
while (wl_display_dispatch(wl_display))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_resizeimg(Client*) {
|
||||||
|
DEBUG("rpc_resizeimg\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_resizewindow(Client*, Rectangle) {
|
||||||
|
DEBUG("rpc_resizewindow\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int next_shm = 0;
|
||||||
|
|
||||||
|
WaylandBuffer *new_buffer(int w, int h, int format) {
|
||||||
|
int stride = w * 4;
|
||||||
|
int size = stride * h;
|
||||||
|
|
||||||
|
// Create an anonymous shared memory file.
|
||||||
|
char name[128];
|
||||||
|
snprintf(name, 128, "/acme_wl_shm-%d-%d", getpid(), next_shm++);
|
||||||
|
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
if (fd < 0) {
|
||||||
|
sysfatal("shm_open failed");
|
||||||
|
}
|
||||||
|
shm_unlink(name);
|
||||||
|
|
||||||
|
// Set the file's size.
|
||||||
|
int ret;
|
||||||
|
do {
|
||||||
|
ret = ftruncate(fd, size);
|
||||||
|
} while (ret < 0 && errno == EINTR);
|
||||||
|
if (ret < 0) {
|
||||||
|
sysfatal("ftruncate failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *d = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (d == MAP_FAILED) {
|
||||||
|
sysfatal("mmap failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
WaylandBuffer *b = malloc(sizeof(WaylandBuffer));
|
||||||
|
b->w = w;
|
||||||
|
b->h = h;
|
||||||
|
b->size = size;
|
||||||
|
b->data = d;
|
||||||
|
struct wl_shm_pool *p = wl_shm_create_pool(wl_shm, fd, size);
|
||||||
|
b->wl_buffer = wl_shm_pool_create_buffer(p, 0, w, h, stride, format);
|
||||||
|
wl_shm_pool_destroy(p);
|
||||||
|
close(fd);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wayland_set_cursor(WaylandClient *wl, Cursor *cursor) {
|
||||||
|
// Convert bitmap to ARGB.
|
||||||
|
// Yes, this is super clunky. Sorry about that.
|
||||||
|
const uint32_t fg = 0xFF000000;
|
||||||
|
const uint32_t a = 0x00FFFFFF;
|
||||||
|
uint32_t data[8*32];
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
char c = cursor->set[i];
|
||||||
|
data[j++] = (c >>7) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 6) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 5) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 4) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 3) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 2) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 1) & 1 == 1 ? fg : a;
|
||||||
|
data[j++] = (c >> 0) & 1 == 1 ? fg : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
WaylandBuffer *b = new_buffer(16, 16, WL_SHM_FORMAT_ARGB8888);
|
||||||
|
memcpy(b->data, (char*) &data[0], b->size);
|
||||||
|
|
||||||
|
// We don't want to bother saving this buffer in xrgb8888_buffers.
|
||||||
|
// Unmap and use NULL for it's listener data.
|
||||||
|
// This will cause it to be destroyed when it is released.
|
||||||
|
munmap(b->data, b->size);
|
||||||
|
wl_buffer_add_listener(b->wl_buffer, &wl_buffer_listener, NULL);
|
||||||
|
|
||||||
|
wl_surface_attach(wl->wl_surface_cursor, b->wl_buffer, 0, 0);
|
||||||
|
wl_surface_damage_buffer(wl->wl_surface_cursor, 0, 0, 16, 16);
|
||||||
|
wl_surface_commit(wl->wl_surface_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_setcursor(Client *c, Cursor *cursor, Cursor2*) {
|
||||||
|
DEBUG("rpc_setcursor\n");
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
if (cursor == NULL) {
|
||||||
|
cursor = &bigarrow;
|
||||||
|
}
|
||||||
|
wayland_set_cursor(wl, cursor);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_setlabel(Client *c, char *label) {
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
xdg_toplevel_set_title(wl->xdg_toplevel, label);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_setmouse(Client *c, Point p) {
|
||||||
|
if (pointer_constraints == NULL) {
|
||||||
|
// If there is no pointer constraints extension,
|
||||||
|
// we cannot warp the mouse.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
// Wayland does not directly support warping the pointer.
|
||||||
|
// Instead, we use (misuse?) the pointer constraints extension,
|
||||||
|
// which allows sending the compositor a new pointer location
|
||||||
|
// hint when the pointer is unlocked.
|
||||||
|
// We lock the pointer, and immediately unlock it with a hint
|
||||||
|
// of the desired wrap location.
|
||||||
|
|
||||||
|
struct zwp_locked_pointer_v1 *lock = zwp_pointer_constraints_v1_lock_pointer(
|
||||||
|
pointer_constraints, wl->wl_surface, wl->wl_pointer, NULL,
|
||||||
|
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||||
|
int x = wl_fixed_from_int(p.x / wl_output_scale_factor);
|
||||||
|
int y = wl_fixed_from_int(p.y / wl_output_scale_factor);
|
||||||
|
zwp_locked_pointer_v1_set_cursor_position_hint(lock, x, y);
|
||||||
|
wl_surface_commit(wl->wl_surface);
|
||||||
|
zwp_locked_pointer_v1_destroy(lock);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_topwin(Client*) {
|
||||||
|
DEBUG("rpc_topwin\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_bouncemouse(Client*, Mouse) {
|
||||||
|
DEBUG("rpc_bouncemouse\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be called with the lock held.
|
||||||
|
WaylandBuffer *get_xrgb8888_buffer(int w, int h) {
|
||||||
|
for (int i = 0; i < N_XRGB8888_BUFFERS; i++) {
|
||||||
|
if (xrgb8888_buffers[i] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Delete any cached buffers that are not the right size.
|
||||||
|
if (xrgb8888_buffers[i]->w != w || xrgb8888_buffers[i]->h != h) {
|
||||||
|
delete_buffer(xrgb8888_buffers[i]);
|
||||||
|
xrgb8888_buffers[i] = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
WaylandBuffer *b = xrgb8888_buffers[i];
|
||||||
|
xrgb8888_buffers[i] = NULL;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
WaylandBuffer *b = new_buffer(w, h, WL_SHM_FORMAT_XRGB8888);
|
||||||
|
wl_buffer_add_listener(b->wl_buffer, &wl_buffer_listener, b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_flush(Client *c, Rectangle r) {
|
||||||
|
WaylandClient *wl = (WaylandClient*) c->view;
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
int w = Dx(wl->memimage->r);
|
||||||
|
int h = Dy(wl->memimage->r);
|
||||||
|
WaylandBuffer *b = get_xrgb8888_buffer(w, h);
|
||||||
|
memcpy(b->data, (char*) wl->memimage->data->bdata, b->size);
|
||||||
|
wl_surface_attach(wl->wl_surface, b->wl_buffer, 0, 0);
|
||||||
|
wl_surface_damage_buffer(wl->wl_surface, r.min.x, r.min.y, Dx(r), Dy(r));
|
||||||
|
wl_surface_commit(wl->wl_surface);
|
||||||
|
wl_display_flush(wl_display);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClientImpl wayland_impl = {
|
||||||
|
rpc_resizeimg,
|
||||||
|
rpc_resizewindow,
|
||||||
|
rpc_setcursor,
|
||||||
|
rpc_setlabel,
|
||||||
|
rpc_setmouse,
|
||||||
|
rpc_topwin,
|
||||||
|
rpc_bouncemouse,
|
||||||
|
rpc_flush
|
||||||
|
};
|
||||||
|
|
||||||
|
Memimage *rpc_attach(Client *c, char *label, char *winsize) {
|
||||||
|
DEBUG("rpc_attach(%s)\n", label);
|
||||||
|
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
|
||||||
|
WaylandClient *wl = calloc(1, sizeof(WaylandClient));
|
||||||
|
c->impl = &wayland_impl;
|
||||||
|
c->view = wl;
|
||||||
|
|
||||||
|
wl->wl_surface = wl_compositor_create_surface(wl_compositor);
|
||||||
|
|
||||||
|
wl->xdg_surface = xdg_wm_base_get_xdg_surface(xdg_wm_base, wl->wl_surface);
|
||||||
|
xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, c);
|
||||||
|
|
||||||
|
wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface);
|
||||||
|
xdg_toplevel_add_listener(wl->xdg_toplevel, &xdg_toplevel_listener, c);
|
||||||
|
xdg_toplevel_set_title(wl->xdg_toplevel, label);
|
||||||
|
|
||||||
|
wl->wl_callback = wl_surface_frame(wl->wl_surface);
|
||||||
|
wl_callback_add_listener(wl->wl_callback, &wl_callback_listener, c);
|
||||||
|
|
||||||
|
wl->wl_pointer = wl_seat_get_pointer(wl_seat);
|
||||||
|
wl_pointer_add_listener(wl->wl_pointer, &pointer_listener, c);
|
||||||
|
wl->wl_surface_cursor = wl_compositor_create_surface(wl_compositor);
|
||||||
|
wayland_set_cursor(wl, &bigarrow);
|
||||||
|
|
||||||
|
wl->wl_keyboard = wl_seat_get_keyboard(wl_seat);
|
||||||
|
wl_keyboard_add_listener(wl->wl_keyboard, &keyboard_listener, c);
|
||||||
|
wl->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
|
||||||
|
// If the xdg decorations extension is available,
|
||||||
|
// enable server-side decorations.
|
||||||
|
// Otherwise there will be no window decorations
|
||||||
|
// (title, resize, buttons, etc.).
|
||||||
|
if (decoration_manager != NULL) {
|
||||||
|
struct zxdg_toplevel_decoration_v1 *d =
|
||||||
|
zxdg_decoration_manager_v1_get_toplevel_decoration(
|
||||||
|
decoration_manager, wl->xdg_toplevel);
|
||||||
|
zxdg_toplevel_decoration_v1_set_mode(d,
|
||||||
|
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: parse winsize.
|
||||||
|
int w = 640*wl_output_scale_factor;
|
||||||
|
int h = 480*wl_output_scale_factor;
|
||||||
|
Rectangle r = Rect(0, 0, w, h);
|
||||||
|
wl->memimage = _allocmemimage(r, XRGB32);
|
||||||
|
c->mouserect = r;
|
||||||
|
c->displaydpi = 110 * wl_output_scale_factor;
|
||||||
|
wl_surface_set_buffer_scale(wl->wl_surface, wl_output_scale_factor);
|
||||||
|
wl_surface_commit(wl->wl_surface);
|
||||||
|
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
return wl->memimage;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *rpc_getsnarf(void) {
|
||||||
|
DEBUG("rpc_getsnarf\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_putsnarf(char*) {
|
||||||
|
DEBUG("rpc_putsnarf\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_shutdown(void) {
|
||||||
|
DEBUG("rpc_shutdown\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_gfxdrawlock(void) {
|
||||||
|
qlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_gfxdrawunlock(void) {
|
||||||
|
qunlock(&wayland_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
|
||||||
|
return _cloadmemimage(i, r, data, ndata);
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
|
||||||
|
return _loadmemimage(i, r, data, ndata);
|
||||||
|
}
|
||||||
|
|
||||||
|
int unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) {
|
||||||
|
return _unloadmemimage(i, r, data, ndata);
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<$PLAN9/src/mkhdr
|
<$PLAN9/src/mkhdr
|
||||||
<|osxvers
|
<|osxvers
|
||||||
<|sh ../devdraw/mkwsysrules.sh
|
<|sh mkwsysrules.sh
|
||||||
<|sh freetyperules.sh $WSYSTYPE $X11H
|
<|sh freetyperules.sh $WSYSTYPE $X11H
|
||||||
|
|
||||||
TARG=fontsrv
|
TARG=fontsrv
|
||||||
|
|
|
||||||
63
src/cmd/fontsrv/mkwsysrules.sh
Normal file
63
src/cmd/fontsrv/mkwsysrules.sh
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ -f $PLAN9/config ] && . $PLAN9/config
|
||||||
|
|
||||||
|
if [ "x$X11" = "x" ]; then
|
||||||
|
if [ -d /usr/X11R6 ]; then
|
||||||
|
X11=/usr/X11R6
|
||||||
|
elif [ -d /usr/local/X11R6 ]; then
|
||||||
|
X11=/usr/local/X11R6
|
||||||
|
elif [ -d /usr/X11R7 ]; then
|
||||||
|
X11=/usr/X11R7
|
||||||
|
elif [ -d /usr/X ]; then
|
||||||
|
X11=/usr/X
|
||||||
|
elif [ -d /usr/openwin ]; then # for Sun
|
||||||
|
X11=/usr/openwin
|
||||||
|
elif [ -d /usr/include/X11 ]; then
|
||||||
|
X11=/usr
|
||||||
|
elif [ -d /usr/local/include/X11 ]; then
|
||||||
|
X11=/usr/local
|
||||||
|
else
|
||||||
|
X11=noX11dir
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$WSYSTYPE" = "x" ]; then
|
||||||
|
if [ "x`uname`" = "xDarwin" ]; then
|
||||||
|
if sw_vers | egrep 'ProductVersion: (10\.[0-9]\.|10\.1[012])$' >/dev/null; then
|
||||||
|
echo 1>&2 'OS X 10.12 and older are not supported'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
WSYSTYPE=mac
|
||||||
|
elif [ -d "$X11" ]; then
|
||||||
|
WSYSTYPE=x11
|
||||||
|
else
|
||||||
|
WSYSTYPE=nowsys
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$WSYSTYPE" = "xx11" -a "x$X11H" = "x" ]; then
|
||||||
|
if [ -d "$X11/include" ]; then
|
||||||
|
X11H="-I$X11/include"
|
||||||
|
else
|
||||||
|
X11H=""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'WSYSTYPE='$WSYSTYPE
|
||||||
|
echo 'X11='$X11
|
||||||
|
echo 'X11H='$X11H
|
||||||
|
|
||||||
|
if [ $WSYSTYPE = x11 ]; then
|
||||||
|
echo 'CFLAGS=$CFLAGS '$X11H
|
||||||
|
echo 'HFILES=$HFILES $XHFILES'
|
||||||
|
XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'`
|
||||||
|
echo 'WSYSOFILES=$WSYSOFILES '$XO
|
||||||
|
echo 'WSYSHFILES=x11-inc.h x11-keysym2ucs.h x11-memdraw.h'
|
||||||
|
elif [ $WSYSTYPE = mac ]; then
|
||||||
|
echo 'WSYSOFILES=$WSYSOFILES mac-draw.o mac-screen.o'
|
||||||
|
echo 'WSYSHFILES='
|
||||||
|
echo 'MACARGV=macargv.o'
|
||||||
|
elif [ $WSYSTYPE = nowsys ]; then
|
||||||
|
echo 'WSYSOFILES=nowsys.o'
|
||||||
|
fi
|
||||||
Loading…
Add table
Add a link
Reference in a new issue