feat: add screencopy_v1 support + refactor wayland code
This commit is contained in:
@@ -42,6 +42,7 @@ wl_protocols = [
|
||||
'protocols/wlr-foreign-toplevel-management-unstable-v1',
|
||||
'protocols/virtual-keyboard-unstable-v1',
|
||||
'protocols/wlr-output-power-management-unstable-v1',
|
||||
'protocols/wlr-screencopy-unstable-v1',
|
||||
]
|
||||
|
||||
foreach proto : wl_protocols
|
||||
|
||||
232
protocols/wlr-screencopy-unstable-v1.xml
Normal file
232
protocols/wlr-screencopy-unstable-v1.xml
Normal file
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_screencopy_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2018 Simon Ser
|
||||
Copyright © 2019 Andri Yngvason
|
||||
|
||||
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.
|
||||
</copyright>
|
||||
|
||||
<description summary="screen content capturing on client buffers">
|
||||
This protocol allows clients to ask the compositor to copy part of the
|
||||
screen content to a client buffer.
|
||||
|
||||
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.
|
||||
</description>
|
||||
|
||||
<interface name="zwlr_screencopy_manager_v1" version="3">
|
||||
<description summary="manager to inform clients and begin capturing">
|
||||
This object is a manager which offers requests to start capturing from a
|
||||
source.
|
||||
</description>
|
||||
|
||||
<request name="capture_output">
|
||||
<description summary="capture an output">
|
||||
Capture the next frame of an entire output.
|
||||
</description>
|
||||
<arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/>
|
||||
<arg name="overlay_cursor" type="int"
|
||||
summary="composite cursor onto the frame"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
|
||||
<request name="capture_output_region">
|
||||
<description summary="capture an output's region">
|
||||
Capture the next frame of an output's region.
|
||||
|
||||
The region is given in output logical coordinates, see
|
||||
xdg_output.logical_size. The region will be clipped to the output's
|
||||
extents.
|
||||
</description>
|
||||
<arg name="frame" type="new_id" interface="zwlr_screencopy_frame_v1"/>
|
||||
<arg name="overlay_cursor" type="int"
|
||||
summary="composite cursor onto the frame"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the manager">
|
||||
All objects created by the manager will still remain valid, until their
|
||||
appropriate destroy request has been called.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_screencopy_frame_v1" version="3">
|
||||
<description summary="a frame ready for copy">
|
||||
This object represents a single frame.
|
||||
|
||||
When created, a series of buffer events will be sent, each representing a
|
||||
supported buffer type. The "buffer_done" event is sent afterwards to
|
||||
indicate that all supported buffer types have been enumerated. The client
|
||||
will then be able to send a "copy" request. If the capture is successful,
|
||||
the compositor will send a "flags" followed by a "ready" event.
|
||||
|
||||
For objects version 2 or lower, wl_shm buffers are always supported, ie.
|
||||
the "buffer" event is guaranteed to be sent.
|
||||
|
||||
If the capture failed, the "failed" event is sent. This can happen anytime
|
||||
before the "ready" event.
|
||||
|
||||
Once either a "ready" or a "failed" event is received, the client should
|
||||
destroy the frame.
|
||||
</description>
|
||||
|
||||
<event name="buffer">
|
||||
<description summary="wl_shm buffer information">
|
||||
Provides information about wl_shm buffer parameters that need to be
|
||||
used for this frame. This event is sent once after the frame is created
|
||||
if wl_shm buffers are supported.
|
||||
</description>
|
||||
<arg name="format" type="uint" enum="wl_shm.format" summary="buffer format"/>
|
||||
<arg name="width" type="uint" summary="buffer width"/>
|
||||
<arg name="height" type="uint" summary="buffer height"/>
|
||||
<arg name="stride" type="uint" summary="buffer stride"/>
|
||||
</event>
|
||||
|
||||
<request name="copy">
|
||||
<description summary="copy the frame">
|
||||
Copy the frame to the supplied buffer. The buffer must have a the
|
||||
correct size, see zwlr_screencopy_frame_v1.buffer and
|
||||
zwlr_screencopy_frame_v1.linux_dmabuf. The buffer needs to have a
|
||||
supported format.
|
||||
|
||||
If the frame is successfully copied, a "flags" and a "ready" events are
|
||||
sent. Otherwise, a "failed" event is sent.
|
||||
</description>
|
||||
<arg name="buffer" type="object" interface="wl_buffer"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_used" value="0"
|
||||
summary="the object has already been used to copy a wl_buffer"/>
|
||||
<entry name="invalid_buffer" value="1"
|
||||
summary="buffer attributes are invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="flags" bitfield="true">
|
||||
<entry name="y_invert" value="1" summary="contents are y-inverted"/>
|
||||
</enum>
|
||||
|
||||
<event name="flags">
|
||||
<description summary="frame flags">
|
||||
Provides flags about the frame. This event is sent once before the
|
||||
"ready" event.
|
||||
</description>
|
||||
<arg name="flags" type="uint" enum="flags" summary="frame flags"/>
|
||||
</event>
|
||||
|
||||
<event name="ready">
|
||||
<description summary="indicates frame is available for reading">
|
||||
Called as soon as the frame is copied, indicating it is available
|
||||
for reading. This event includes the time at which presentation happened
|
||||
at.
|
||||
|
||||
The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples,
|
||||
each component being an unsigned 32-bit value. Whole seconds are in
|
||||
tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo,
|
||||
and the additional fractional part in tv_nsec as nanoseconds. Hence,
|
||||
for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part
|
||||
may have an arbitrary offset at start.
|
||||
|
||||
After receiving this event, the client should destroy the object.
|
||||
</description>
|
||||
<arg name="tv_sec_hi" type="uint"
|
||||
summary="high 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_sec_lo" type="uint"
|
||||
summary="low 32 bits of the seconds part of the timestamp"/>
|
||||
<arg name="tv_nsec" type="uint"
|
||||
summary="nanoseconds part of the timestamp"/>
|
||||
</event>
|
||||
|
||||
<event name="failed">
|
||||
<description summary="frame copy failed">
|
||||
This event indicates that the attempted frame copy has failed.
|
||||
|
||||
After receiving this event, the client should destroy the object.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="delete this object, used or not">
|
||||
Destroys the frame. This request can be sent at any time by the client.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
<request name="copy_with_damage" since="2">
|
||||
<description summary="copy the frame when it's damaged">
|
||||
Same as copy, except it waits until there is damage to copy.
|
||||
</description>
|
||||
<arg name="buffer" type="object" interface="wl_buffer"/>
|
||||
</request>
|
||||
|
||||
<event name="damage" since="2">
|
||||
<description summary="carries the coordinates of the damaged region">
|
||||
This event is sent right before the ready event when copy_with_damage is
|
||||
requested. It may be generated multiple times for each copy_with_damage
|
||||
request.
|
||||
|
||||
The arguments describe a box around an area that has changed since the
|
||||
last copy request that was derived from the current screencopy manager
|
||||
instance.
|
||||
|
||||
The union of all regions received between the call to copy_with_damage
|
||||
and a ready event is the total damage since the prior ready event.
|
||||
</description>
|
||||
<arg name="x" type="uint" summary="damaged x coordinates"/>
|
||||
<arg name="y" type="uint" summary="damaged y coordinates"/>
|
||||
<arg name="width" type="uint" summary="current width"/>
|
||||
<arg name="height" type="uint" summary="current height"/>
|
||||
</event>
|
||||
|
||||
<!-- Version 3 additions -->
|
||||
<event name="linux_dmabuf" since="3">
|
||||
<description summary="linux-dmabuf buffer information">
|
||||
Provides information about linux-dmabuf buffer parameters that need to
|
||||
be used for this frame. This event is sent once after the frame is
|
||||
created if linux-dmabuf buffers are supported.
|
||||
</description>
|
||||
<arg name="format" type="uint" summary="fourcc pixel format"/>
|
||||
<arg name="width" type="uint" summary="buffer width"/>
|
||||
<arg name="height" type="uint" summary="buffer height"/>
|
||||
</event>
|
||||
|
||||
<event name="buffer_done" since="3">
|
||||
<description summary="all buffer types reported">
|
||||
This event is sent once after all buffer events have been sent.
|
||||
|
||||
The client should proceed to create a buffer of one of the supported
|
||||
types, and send a "copy" request.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
||||
@@ -327,13 +327,6 @@ static const struct zwlr_foreign_toplevel_manager_v1_listener g_toplevel_manager
|
||||
.finished = toplevel_manager_handle_finished,
|
||||
};
|
||||
|
||||
void diya_session_shell_foreign_toplevel_register(gpointer mngr, DiyaShell *shell)
|
||||
{
|
||||
DiyaSessionShell* session_shell = DIYA_SESSION_SHELL(shell);
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(mngr, &g_toplevel_manager_impl, (void *)session_shell);
|
||||
}
|
||||
|
||||
|
||||
DiyaShell* diya_foreign_window_get_shell(DiyaForeignWindow* self)
|
||||
{
|
||||
assert(self);
|
||||
@@ -437,4 +430,14 @@ DiyaForeignWindow* diya_foreign_window_get_top_level(DiyaForeignWindow* self)
|
||||
win = win->parent_win;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
void diya_session_shell_foreign_toplevel_register(DiyaShell *shell)
|
||||
{
|
||||
gpointer mngr = diya_wayland_request_service(diya_shell_get_wayland(shell), DIYA_WAYLAND_FOREIGN_TOP_LEVEL);
|
||||
if(!mngr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(mngr, &g_toplevel_manager_impl, (void *)shell);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ enum diya_win_state
|
||||
USE_CLASS(DiyaShell);
|
||||
USE_CLASS(GAppInfo);
|
||||
|
||||
void diya_session_shell_foreign_toplevel_register(gpointer mngr, DiyaShell * shell);
|
||||
void diya_session_shell_foreign_toplevel_register(DiyaShell * shell);
|
||||
|
||||
DiyaShell* diya_foreign_window_get_shell(DiyaForeignWindow* window);
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ static const struct ext_idle_notification_v1_listener g_idle_listener_impl =
|
||||
DiyaIdleNotification* diya_shell_get_idle_notification(DiyaShell* shell, guint timeout_ms)
|
||||
{
|
||||
DiyaWayland *wayland = diya_shell_get_wayland(shell);
|
||||
struct ext_idle_notifier_v1* mngr = diya_wayland_get_idle_mngr(wayland);
|
||||
struct ext_idle_notifier_v1* mngr = diya_wayland_request_service(wayland, DIYA_WAYLAND_IDLE_NOTIF);
|
||||
if(!mngr)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -11,7 +11,6 @@ G_DECLARE_FINAL_TYPE (DiyaIdleNotification, diya_idle_notification, DIYA, IDLE_N
|
||||
|
||||
USE_CLASS(DiyaShell);
|
||||
|
||||
void diya_idle_manager_register(gpointer mngr, DiyaShell *shell);
|
||||
DiyaIdleNotification* diya_shell_get_idle_notification(DiyaShell* shell, guint timeout_ms);
|
||||
guint diya_idle_notification_get_timeout(DiyaIdleNotification* self);
|
||||
#endif /* DIYAC_IDLE_H */
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "session-lock.h"
|
||||
#include "idle.h"
|
||||
#include "widgets/base-widgets.h"
|
||||
#include "wayland.h"
|
||||
|
||||
#define compiled_schema_path() (g_strconcat(g_getenv("GSETTINGS_SCHEMA_DIR"), "/gschemas.compiled", NULL))
|
||||
|
||||
@@ -163,6 +164,7 @@ void diya_session_init_settings(DiyaSessionShell* self)
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_set(self,DIYA_PROP_SHELL_IDLE_TIMEOUT,DEFAULT_IDLE_TIMEOUT, NULL);
|
||||
g_warning("Unable to find schema ID %s", SESSION_SHELL_SCHEMA_ID);
|
||||
}
|
||||
}
|
||||
@@ -170,7 +172,7 @@ void diya_session_init_settings(DiyaSessionShell* self)
|
||||
static void diya_session_shell_startup(DiyaShell *shell)
|
||||
{
|
||||
DiyaSessionShell* self = DIYA_SESSION_SHELL(shell);
|
||||
|
||||
|
||||
const gchar* const* dirs = g_get_system_config_dirs();
|
||||
|
||||
gchar* path = NULL;
|
||||
@@ -208,16 +210,28 @@ static void diya_session_shell_active(DiyaShell *shell)
|
||||
diya_shell_monitor_input(shell);
|
||||
}
|
||||
|
||||
static void diya_session_service_register(DiyaShell* shell, int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DIYA_WAYLAND_FOREIGN_TOP_LEVEL:
|
||||
diya_session_shell_foreign_toplevel_register(shell);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_session_shell_class_init(DiyaSessionShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
// DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
|
||||
DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class);
|
||||
base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
|
||||
base_shell_class->startup_handle = diya_session_shell_startup;
|
||||
base_shell_class->active_handle = diya_session_shell_active;
|
||||
base_shell_class->build_lock_window = diya_session_lock_create;
|
||||
base_shell_class->on_wayland_service_registered = diya_session_service_register;
|
||||
/// base_class->to_string = diya_session_shell_to_string;
|
||||
gobject_class->dispose = diya_session_shell_dispose;
|
||||
gobject_class->finalize = diya_session_shell_finalize;
|
||||
|
||||
@@ -18,7 +18,13 @@ static void session_unlocked(DiyaSessionShell* shell, void* data)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
DiyaSessionShell *shell = DIYA_SESSION_SHELL(g_object_new(DIYA_TYPE_SESSION_SHELL, "name","dev.iohub.diya.session", NULL));
|
||||
DiyaSessionShell *shell = DIYA_SESSION_SHELL(
|
||||
g_object_new(
|
||||
DIYA_TYPE_SESSION_SHELL,
|
||||
"name","dev.iohub.diya.session",
|
||||
DIYA_PROP_SHELL_ENABLE_FOREIGN_MNGR, true,
|
||||
DIYA_PROP_SHELL_ENABLE_SCREEN_COPY, true,
|
||||
NULL));
|
||||
g_signal_connect(shell, DIYA_SIGNAL_SHELL_LOCKED, G_CALLBACK(session_locked), NULL);
|
||||
g_signal_connect(shell, DIYA_SIGNAL_SHELL_UNLOCKED, G_CALLBACK(session_unlocked), NULL);
|
||||
return diya_shell_run(DIYA_SHELL(shell), argc, argv);
|
||||
|
||||
26
src/shell.c
26
src/shell.c
@@ -21,6 +21,8 @@ enum
|
||||
PROP_SHELL_THEME,
|
||||
PROP_SHELL_IDLE_TO,
|
||||
PROP_SHELL_LOCK,
|
||||
PROP_SHELL_ENABLE_FOREIGN_MNGR,
|
||||
PROP_SHELL_ENABLE_SCREEN_COPY,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
@@ -39,6 +41,8 @@ typedef struct _DiyaShellPrivate
|
||||
gchar *theme;
|
||||
DiyaIdleNotification *idle_notif;
|
||||
GtkSessionLockInstance *lock;
|
||||
gboolean enable_foreign;
|
||||
gboolean enable_screen_copy;
|
||||
} DiyaShellPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT);
|
||||
@@ -278,6 +282,12 @@ static void diya_shell_set_property(GObject *object, guint property_id, const GV
|
||||
priv->name = g_strdup(g_value_get_string(value));
|
||||
init_gtk_application(self);
|
||||
break;
|
||||
case PROP_SHELL_ENABLE_FOREIGN_MNGR:
|
||||
priv->enable_foreign = g_value_get_boolean(value);
|
||||
break;
|
||||
case PROP_SHELL_ENABLE_SCREEN_COPY:
|
||||
priv->enable_screen_copy = g_value_get_boolean(value);
|
||||
break;
|
||||
case PROP_SHELL_IDLE_TO:
|
||||
if(priv->idle_notif)
|
||||
{
|
||||
@@ -338,6 +348,12 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue *
|
||||
// assert(priv->lock);
|
||||
g_value_set_pointer(value, priv->lock);
|
||||
break;
|
||||
case PROP_SHELL_ENABLE_FOREIGN_MNGR:
|
||||
g_value_set_boolean(value, priv->enable_foreign);
|
||||
break;
|
||||
case PROP_SHELL_ENABLE_SCREEN_COPY:
|
||||
g_value_set_boolean(value, priv->enable_screen_copy);
|
||||
break;
|
||||
case PROP_SHELL_IDLE_TO:
|
||||
if(priv->idle_notif)
|
||||
{
|
||||
@@ -420,6 +436,8 @@ static void diya_shell_init(DiyaShell *self)
|
||||
priv->theme = NULL;
|
||||
priv->idle_notif = NULL;
|
||||
priv->lock = NULL;
|
||||
priv->enable_foreign = false;
|
||||
priv->enable_screen_copy = false;
|
||||
}
|
||||
|
||||
DiyaWayland *diya_shell_get_wayland(DiyaShell *shell)
|
||||
@@ -458,12 +476,11 @@ static void diya_shell_class_init(DiyaShellClass *class)
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
base_class->to_string = diya_shell_to_string;
|
||||
|
||||
class->foreign_register = NULL;
|
||||
class->virtual_keyboard_register = diya_virtual_keyboard_register;
|
||||
class->build_lock_window = NULL;
|
||||
class->startup_handle = NULL;
|
||||
class->active_handle = NULL;
|
||||
class->reload_handle = NULL;
|
||||
class->on_wayland_service_registered = NULL;
|
||||
|
||||
shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer(DIYA_PROP_SHELL_WAYLAND, NULL, "Shell wayland", G_PARAM_READABLE); //
|
||||
shell_properties[PROP_SHELL_NAME] = g_param_spec_string(DIYA_PROP_SHELL_NAME, NULL, "Shell name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
@@ -471,6 +488,9 @@ static void diya_shell_class_init(DiyaShellClass *class)
|
||||
shell_properties[PROP_SHELL_THEME] = g_param_spec_string(DIYA_PROP_SHELL_THEME, NULL, "Shell theme", NULL, G_PARAM_READWRITE);
|
||||
shell_properties[PROP_SHELL_IDLE_TO] = g_param_spec_uint(DIYA_PROP_SHELL_IDLE_TIMEOUT, NULL, "Shell IDLE timeout", 0, UINT32_MAX ,DEFAULT_IDLE_TIMEOUT, G_PARAM_READWRITE);
|
||||
shell_properties[PROP_SHELL_LOCK] = g_param_spec_pointer(DIYA_PROP_SHELL_LOCK, NULL, "Shell lock", G_PARAM_READABLE);
|
||||
// enable wayland feature
|
||||
shell_properties[PROP_SHELL_ENABLE_FOREIGN_MNGR] = g_param_spec_boolean(DIYA_PROP_SHELL_ENABLE_FOREIGN_MNGR, NULL, "Enable shell foreign window manager", false, G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
shell_properties[PROP_SHELL_ENABLE_SCREEN_COPY] = g_param_spec_boolean(DIYA_PROP_SHELL_ENABLE_SCREEN_COPY, NULL, "Enable shell screen copy", false, G_PARAM_READWRITE| G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties(gobject_class, N_PROPERTIES, shell_properties);
|
||||
|
||||
@@ -778,7 +798,7 @@ void diya_shell_launch(DiyaShell *self, GAppInfo *app)
|
||||
void diya_shell_power_display(DiyaShell* self, gboolean mode)
|
||||
{
|
||||
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
|
||||
struct zwlr_output_power_manager_v1 * mngr = diya_wayland_get_output_mngr(priv->wayland);
|
||||
struct zwlr_output_power_manager_v1 * mngr = diya_wayland_request_service(priv->wayland, DIYA_WAYLAND_OUTPUT_POWER_MNRG);
|
||||
if(!mngr)
|
||||
{
|
||||
g_warning("Output power manager protocol is not available");
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define DIYA_PROP_SHELL_THEME "theme"
|
||||
#define DIYA_PROP_SHELL_IDLE_TIMEOUT "idle-timeout"
|
||||
#define DIYA_PROP_SHELL_LOCK "lock"
|
||||
#define DIYA_PROP_SHELL_ENABLE_FOREIGN_MNGR "enable-wayland-foreign-toplevel"
|
||||
#define DIYA_PROP_SHELL_ENABLE_SCREEN_COPY "enable-wayland-screen-copy"
|
||||
|
||||
#define DIYA_SIGNAL_SHELL_KEYBOARD_ENTER "keyboard-enter"
|
||||
#define DIYA_SIGNAL_SHELL_KEYBOARD_LEAVE "keyboard-leave"
|
||||
@@ -34,14 +36,11 @@ G_DECLARE_DERIVABLE_TYPE(DiyaShell, diya_shell, DIYA, SHELL, DiyaObject)
|
||||
|
||||
struct wl_registry;
|
||||
|
||||
typedef void (*wl_protocol_manager_register_t)(gpointer,DiyaShell*);
|
||||
|
||||
struct _DiyaShellClass
|
||||
{
|
||||
DiyaObjectClass parent_class;
|
||||
wl_protocol_manager_register_t foreign_register;
|
||||
wl_protocol_manager_register_t virtual_keyboard_register;
|
||||
GtkWindow* (*build_lock_window)(DiyaShell*);
|
||||
void (*on_wayland_service_registered)(DiyaShell*, int);
|
||||
void (*startup_handle)(DiyaShell*);
|
||||
void (*active_handle)(DiyaShell*);
|
||||
void (*reload_handle)(DiyaShell*);
|
||||
|
||||
@@ -303,6 +303,8 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
struct xkb_context *vkb_ctx = NULL;
|
||||
struct xkb_keymap *vkb_keymap = NULL;
|
||||
gsize len = 0;
|
||||
|
||||
|
||||
vkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!vkb_ctx)
|
||||
{
|
||||
@@ -379,28 +381,23 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
strcpy((char *)ptr, content);
|
||||
free(content);
|
||||
|
||||
|
||||
DiyaVirtualKeyboard *vkb = g_object_new(DIYA_TYPE_VIRTUAL_KEYBOARD, "shell", shell, NULL);
|
||||
vkb->vkb_ctx = vkb_ctx;
|
||||
vkb->vkb_keymap = vkb_keymap;
|
||||
DiyaWayland *wayland = diya_shell_get_wayland(shell);
|
||||
struct wl_seat *seat = diya_wayland_get_seat(wayland);
|
||||
struct zwp_virtual_keyboard_manager_v1* mngr = diya_wayland_get_virtual_keyboard_mngr(wayland);
|
||||
struct zwp_virtual_keyboard_manager_v1* mngr = diya_wayland_request_service( diya_shell_get_wayland(shell),DIYA_WAYLAND_VIRTUAL_KEYBOARD);
|
||||
if(!mngr)
|
||||
{
|
||||
g_object_unref(vkb);
|
||||
return NULL;
|
||||
}
|
||||
vkb->keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(mngr, seat);
|
||||
vkb->keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(
|
||||
mngr,
|
||||
diya_wayland_get_seat(diya_shell_get_wayland(shell)));
|
||||
zwp_virtual_keyboard_v1_keymap(vkb->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, len);
|
||||
|
||||
return vkb;
|
||||
}
|
||||
|
||||
void diya_virtual_keyboard_register(gpointer mngr, DiyaShell *shell)
|
||||
{
|
||||
(void) shell;
|
||||
(void) mngr;
|
||||
}
|
||||
|
||||
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard *self, DiyaVkbKey* key, diya_vkb_state_t state)
|
||||
{
|
||||
guint32 old_mods = self->key_mods;
|
||||
|
||||
@@ -26,7 +26,6 @@ gboolean diya_vkb_key_is_modifier(DiyaVkbKey* key);
|
||||
|
||||
DiyaVirtualKeyboard* diya_virtual_keyboard_new(DiyaShell* shell, const gchar* keymap_file);
|
||||
|
||||
void diya_virtual_keyboard_register(gpointer mngr, DiyaShell *shell);
|
||||
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard* vkb, DiyaVkbKey* key, diya_vkb_state_t state);
|
||||
|
||||
DiyaVkbKey* diya_virtual_keyboard_get_key(DiyaVirtualKeyboard* vkb, uint32_t key);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "virtual-keyboard-unstable-v1.h"
|
||||
#include "ext-idle-notify-v1.h"
|
||||
#include "wlr-output-power-management-unstable-v1.h"
|
||||
#include "wlr-screencopy-unstable-v1.h"
|
||||
#include "wayland.h"
|
||||
#include "shell.h"
|
||||
|
||||
@@ -19,6 +20,7 @@ struct _DiyaWayland
|
||||
struct zwp_virtual_keyboard_manager_v1 * virtual_keyboard_mngr;
|
||||
struct ext_idle_notifier_v1 * idle_notifier_mngr;
|
||||
struct zwlr_output_power_manager_v1 * zwlr_output_power_manager_v1;
|
||||
struct zwlr_screencopy_manager_v1* screencopy_manager_v1;
|
||||
};
|
||||
G_DEFINE_FINAL_TYPE(DiyaWayland, diya_wayland, DIYA_TYPE_SHELL_OBJECT)
|
||||
|
||||
@@ -46,6 +48,11 @@ static void diya_wayland_finalize(GObject* object)
|
||||
zwlr_output_power_manager_v1_destroy(self->zwlr_output_power_manager_v1);
|
||||
self->zwlr_output_power_manager_v1 = NULL;
|
||||
}
|
||||
if(self->screencopy_manager_v1)
|
||||
{
|
||||
zwlr_screencopy_manager_v1_destroy(self->screencopy_manager_v1);
|
||||
self->screencopy_manager_v1 = NULL;
|
||||
}
|
||||
g_debug("diya_wayland_finalize: %s", diya_object_to_string(object));
|
||||
G_OBJECT_CLASS(diya_wayland_parent_class)->finalize(object);
|
||||
}
|
||||
@@ -67,6 +74,7 @@ static void diya_wayland_init(DiyaWayland * self)
|
||||
self->virtual_keyboard_mngr = NULL;
|
||||
self->idle_notifier_mngr = NULL;
|
||||
self->zwlr_output_power_manager_v1 = NULL;
|
||||
self->screencopy_manager_v1 = NULL;
|
||||
}
|
||||
|
||||
static const gchar* diya_wayland_to_string(DiyaObject* object)
|
||||
@@ -102,31 +110,33 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
|
||||
(void) version;
|
||||
DiyaWayland *wayland = data;
|
||||
DiyaShell * shell = diya_shell_object_get_shell(data);
|
||||
|
||||
DiyaShellClass* class = DIYA_SHELL_GET_CLASS(shell);
|
||||
assert(DIYA_IS_WAYLAND(wayland));
|
||||
assert(DIYA_IS_SHELL(shell));
|
||||
|
||||
DiyaShellClass * class = DIYA_SHELL_GET_CLASS(shell);
|
||||
g_debug("WAYLAND GLOBAL: %s", interface);
|
||||
gboolean enable_foreign, enable_screencopy;
|
||||
g_object_get(shell,
|
||||
DIYA_PROP_SHELL_ENABLE_FOREIGN_MNGR, &enable_foreign,
|
||||
DIYA_PROP_SHELL_ENABLE_SCREEN_COPY, &enable_screencopy,
|
||||
NULL
|
||||
);
|
||||
diya_wayland_service_t service_type = DIYA_WAYLAND_UNEXPORTED;
|
||||
g_debug("WAYLAND GLOBAL: %s version %d", interface, version);
|
||||
if (!wayland->foreign_toplevel_mngr && g_strcmp0(interface, zwlr_foreign_toplevel_manager_v1_interface.name) == 0)
|
||||
{
|
||||
if(class->foreign_register)
|
||||
if(enable_foreign)
|
||||
{
|
||||
//diya_session_shell_foreign_toplevel_register(registry, name, data);
|
||||
g_debug("Wayland: register shell foreign top level manager");
|
||||
wayland->foreign_toplevel_mngr = wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 3);
|
||||
class->foreign_register(wayland->foreign_toplevel_mngr, shell);
|
||||
service_type = DIYA_WAYLAND_FOREIGN_TOP_LEVEL;
|
||||
}
|
||||
}
|
||||
if (!wayland->virtual_keyboard_mngr && g_strcmp0(interface, zwp_virtual_keyboard_manager_v1_interface.name) == 0)
|
||||
{
|
||||
if(class->virtual_keyboard_register)
|
||||
{
|
||||
//diya_session_shell_foreign_toplevel_register(registry, name, data);
|
||||
g_debug("Wayland: register virtual keyboard manager");
|
||||
wayland->virtual_keyboard_mngr = wl_registry_bind(registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
|
||||
class->virtual_keyboard_register(wayland->virtual_keyboard_mngr, shell);
|
||||
}
|
||||
//diya_session_shell_foreign_toplevel_register(registry, name, data);
|
||||
g_debug("Wayland: register virtual keyboard manager");
|
||||
wayland->virtual_keyboard_mngr = wl_registry_bind(registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
|
||||
service_type = DIYA_WAYLAND_VIRTUAL_KEYBOARD;
|
||||
}
|
||||
/*
|
||||
else if(!g_strcmp0(interface, ext_session_lock_manager_v1_interface.name))
|
||||
@@ -149,13 +159,27 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
|
||||
else if(!wayland->idle_notifier_mngr && g_strcmp0(interface, ext_idle_notifier_v1_interface.name) == 0)
|
||||
{
|
||||
g_debug("Wayland: register ext_idle_notifier_v1_interface");
|
||||
wayland->idle_notifier_mngr = wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 1);;
|
||||
wayland->idle_notifier_mngr = wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 2);
|
||||
service_type = DIYA_WAYLAND_IDLE_NOTIF;
|
||||
}
|
||||
else if (!wayland->zwlr_output_power_manager_v1 && g_strcmp0(interface, zwlr_output_power_manager_v1_interface.name) == 0)
|
||||
{
|
||||
g_debug("Wayland: register zwlr_output_power_manager_v1_interface");
|
||||
wayland->zwlr_output_power_manager_v1 = wl_registry_bind(registry, name, &zwlr_output_power_manager_v1_interface, 1);
|
||||
//class->power_manager_register(wayland->zwlr_output_power_manager_v1, shell);
|
||||
service_type = DIYA_WAYLAND_OUTPUT_POWER_MNRG;
|
||||
}
|
||||
else if(!wayland->screencopy_manager_v1 && g_strcmp0(interface, zwlr_screencopy_manager_v1_interface.name) == 0)
|
||||
{
|
||||
if(enable_screencopy)
|
||||
{
|
||||
g_debug("Wayland: register zwlr_screencopy_manager_v1");
|
||||
wayland->screencopy_manager_v1 = wl_registry_bind(registry, name, &zwlr_screencopy_manager_v1_interface, 3);
|
||||
service_type = DIYA_WAYLAND_SCREEN_COPY;
|
||||
}
|
||||
}
|
||||
if(service_type != DIYA_WAYLAND_UNEXPORTED && class->on_wayland_service_registered)
|
||||
{
|
||||
class->on_wayland_service_registered(shell, service_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,17 +255,32 @@ struct wl_seat* diya_wayland_get_seat(DiyaWayland* self)
|
||||
return self->seat;
|
||||
}
|
||||
|
||||
struct zwp_virtual_keyboard_manager_v1* diya_wayland_get_virtual_keyboard_mngr(DiyaWayland* self)
|
||||
gpointer diya_wayland_request_service(DiyaWayland* self, diya_wayland_service_t type)
|
||||
{
|
||||
return self->virtual_keyboard_mngr;
|
||||
}
|
||||
|
||||
struct ext_idle_notifier_v1* diya_wayland_get_idle_mngr(DiyaWayland* self)
|
||||
{
|
||||
return self->idle_notifier_mngr;
|
||||
}
|
||||
|
||||
struct zwlr_output_power_manager_v1 * diya_wayland_get_output_mngr(DiyaWayland* self)
|
||||
{
|
||||
return self->zwlr_output_power_manager_v1;
|
||||
gpointer service = NULL;
|
||||
switch (type)
|
||||
{
|
||||
case DIYA_WAYLAND_FOREIGN_TOP_LEVEL:
|
||||
service = self->foreign_toplevel_mngr;
|
||||
break;
|
||||
case DIYA_WAYLAND_SCREEN_COPY:
|
||||
service = self->screencopy_manager_v1;
|
||||
break;
|
||||
case DIYA_WAYLAND_IDLE_NOTIF:
|
||||
service = self->idle_notifier_mngr;
|
||||
break;
|
||||
case DIYA_WAYLAND_VIRTUAL_KEYBOARD:
|
||||
service = self->virtual_keyboard_mngr;
|
||||
break;
|
||||
case DIYA_WAYLAND_OUTPUT_POWER_MNRG:
|
||||
service = self->zwlr_output_power_manager_v1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(!service)
|
||||
{
|
||||
g_critical("Unable to request wayland service %d: service unavailable or unregistered/disabled", type);
|
||||
return NULL;
|
||||
}
|
||||
return service;
|
||||
}
|
||||
@@ -5,6 +5,17 @@
|
||||
|
||||
USE_CLASS(DiyaShell);
|
||||
|
||||
typedef void (*wl_protocol_manager_register_t)(gpointer,gpointer);
|
||||
|
||||
typedef enum {
|
||||
DIYA_WAYLAND_UNEXPORTED,
|
||||
DIYA_WAYLAND_FOREIGN_TOP_LEVEL,
|
||||
DIYA_WAYLAND_SCREEN_COPY,
|
||||
DIYA_WAYLAND_IDLE_NOTIF,
|
||||
DIYA_WAYLAND_OUTPUT_POWER_MNRG,
|
||||
DIYA_WAYLAND_VIRTUAL_KEYBOARD,
|
||||
} diya_wayland_service_t;
|
||||
|
||||
#define DIYA_TYPE_WAYLAND (diya_wayland_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaWayland, diya_wayland, DIYA, WAYLAND, DiyaShellObject)
|
||||
|
||||
@@ -12,8 +23,7 @@ struct wl_surface* diya_wayland_create_surface(DiyaWayland * self);
|
||||
struct wl_output* diya_wayland_get_output(DiyaWayland * self, int index);
|
||||
struct wl_shm_pool * diya_wayland_create_shm_pool(DiyaWayland * self, int fd, guint size);
|
||||
struct wl_seat* diya_wayland_get_seat(DiyaWayland* self);
|
||||
struct zwp_virtual_keyboard_manager_v1* diya_wayland_get_virtual_keyboard_mngr(DiyaWayland* self);
|
||||
struct ext_idle_notifier_v1* diya_wayland_get_idle_mngr(DiyaWayland* self);
|
||||
struct zwlr_output_power_manager_v1 * diya_wayland_get_output_mngr(DiyaWayland* self);
|
||||
|
||||
gpointer diya_wayland_request_service(DiyaWayland* self, diya_wayland_service_t type);
|
||||
DiyaWayland* diya_wayland_new(DiyaShell *shell);
|
||||
#endif
|
||||
Reference in New Issue
Block a user