Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ drm = dependency('libdrm', version: '>= 2.4.0')
gbm = dependency('gbm', version: '>= 24.1.0')
libudev = dependency('libudev', version: '>= 256')
pixman = dependency('pixman-1', version: '>= 0.43.0')
xkbcommon = dependency('xkbcommon', version: '>= 1.7.0')

shoyu_shells = []

Expand Down
5 changes: 5 additions & 0 deletions protocols/shoyu-shell.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<arg name="output" type="object" interface="wl_output" />
</request>

<request name="clear_focus">
</request>

<event name="toplevel_added">
<arg name="toplevel" type="new_id" interface="shoyu_shell_toplevel" />
</event>
Expand Down Expand Up @@ -64,6 +67,8 @@
<arg name="width" type="uint" summary="width" />
<arg name="height" type="uint" summary="height" />
</request>
<request name="set_focus">
</request>
<event name="configure">
<arg name="x" type="uint" />
<arg name="y" type="uint" />
Expand Down
21 changes: 21 additions & 0 deletions shoyu-compositor/compositor-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_shell.h>

struct _ShoyuCompositor {
Expand All @@ -30,6 +32,8 @@ struct _ShoyuCompositor {
struct wlr_output_layout *output_layout;

struct wlr_compositor *wlr_compositor;
struct wlr_seat *wlr_seat;
struct wlr_xcursor_manager *wlr_xcursor_manager;

GList *surfaces;
struct wl_listener new_surface;
Expand Down Expand Up @@ -63,6 +67,20 @@ struct _ShoyuCompositorClass {
*/
GType input_type;

/**
* ShoyuCompositor:input_type_keyboard:
*
* The type to create when a #ShoyuKeyboardInput is being created.
*/
GType input_type_keyboard;

/**
* ShoyuCompositor:input_type_pointer:
*
* The type to create when a #ShoyuPointerInput is being created.
*/
GType input_type_pointer;

/**
* ShoyuCompositor:surface_type:
*
Expand Down Expand Up @@ -229,6 +247,9 @@ struct _ShoyuCompositorClass {
void (*started)(ShoyuCompositor *self);
};

ShoyuXdgToplevel *
shoyu_compositor_get_focused_xdg_toplevel(ShoyuCompositor *self);

ShoyuOutput *shoyu_compositor_get_output(ShoyuCompositor *self,
struct wlr_output *wlr_output);
ShoyuSurface *shoyu_compositor_get_surface(ShoyuCompositor *self,
Expand Down
50 changes: 48 additions & 2 deletions shoyu-compositor/compositor.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include "wayland-event-source.h"
#include "xdg-toplevel-private.h"

#include "keyboard-input.h"
#include "pointer-input.h"

#include <glib/gi18n-lib.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h>
Expand Down Expand Up @@ -184,7 +187,8 @@ static void shoyu_compositor_new_input(struct wl_listener *listener,
g_debug("Inputs changed (old: %u, new: %u)", len, new_len);
g_assert(new_len > len);

g_debug("Created ShoyuInput#%p", input);
g_debug("Created %s as ShoyuInput#%p", g_type_name(G_OBJECT_TYPE(input)),
input);
g_signal_emit(self, shoyu_compositor_sigs[SIG_INPUT_ADDED], 0, input);
}

Expand Down Expand Up @@ -298,6 +302,9 @@ static void shoyu_compositor_finalize(GObject *object) {

g_clear_object(&self->shell);

g_clear_pointer(&self->wlr_xcursor_manager,
(GDestroyNotify)wlr_xcursor_manager_destroy);
g_clear_pointer(&self->wlr_seat, (GDestroyNotify)wlr_seat_destroy);
g_clear_pointer(&self->wlr_allocator, (GDestroyNotify)wlr_allocator_destroy);
g_clear_pointer(&self->wlr_renderer, (GDestroyNotify)wlr_renderer_destroy);
g_clear_pointer(&self->wlr_backend, (GDestroyNotify)wlr_backend_destroy);
Expand Down Expand Up @@ -379,8 +386,26 @@ shoyu_compositor_real_create_input(ShoyuCompositor *self,
struct wlr_input_device *input_device) {
ShoyuCompositorClass *class = SHOYU_COMPOSITOR_GET_CLASS(self);

ShoyuInput *input = g_object_new(class->input_type, "compositor", self, NULL);
uint32_t caps = self->wlr_seat->capabilities;
GType input_type = class->input_type;

switch (input_device->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
input_type = class->input_type_keyboard;
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
break;
case WLR_INPUT_DEVICE_POINTER:
input_type = class->input_type_pointer;
caps |= WL_SEAT_CAPABILITY_POINTER;
break;
default:
break;
}

ShoyuInput *input = g_object_new(input_type, "compositor", self, NULL);
g_return_val_if_fail(input != NULL, NULL);

wlr_seat_set_capabilities(self->wlr_seat, caps);
return input;
}

Expand Down Expand Up @@ -415,6 +440,8 @@ static void shoyu_compositor_class_init(ShoyuCompositorClass *class) {

class->output_type = SHOYU_TYPE_OUTPUT;
class->input_type = SHOYU_TYPE_INPUT;
class->input_type_keyboard = SHOYU_TYPE_KEYBOARD_INPUT;
class->input_type_pointer = SHOYU_TYPE_POINTER_INPUT;
class->surface_type = SHOYU_TYPE_SURFACE;
class->xdg_toplevel_type = SHOYU_TYPE_XDG_TOPLEVEL;

Expand Down Expand Up @@ -553,6 +580,12 @@ static void shoyu_compositor_init(ShoyuCompositor *self) {
self->output_layout = wlr_output_layout_create(self->wl_display);
g_assert(self->output_layout != NULL);

self->wlr_seat = wlr_seat_create(self->wl_display, "seat0");
g_assert(self->wlr_seat != NULL);

self->wlr_xcursor_manager = wlr_xcursor_manager_create(NULL, 24);
g_assert(self->wlr_xcursor_manager != NULL);

self->shell = shoyu_shell_new(self);
g_assert(self->shell != NULL);

Expand Down Expand Up @@ -647,6 +680,19 @@ ShoyuShell *shoyu_compositor_get_shell(ShoyuCompositor *self) {
return self->shell;
}

ShoyuXdgToplevel *
shoyu_compositor_get_focused_xdg_toplevel(ShoyuCompositor *self) {
g_return_val_if_fail(SHOYU_IS_COMPOSITOR(self), NULL);

for (GList *item = self->xdg_toplevels; item != NULL; item = item->next) {
ShoyuXdgToplevel *xdg_toplevel = SHOYU_XDG_TOPLEVEL(item->data);
if (xdg_toplevel->is_focused)
return xdg_toplevel;
}

return NULL;
}

ShoyuOutput *shoyu_compositor_get_output(ShoyuCompositor *self,
struct wlr_output *wlr_output) {
g_return_val_if_fail(SHOYU_IS_COMPOSITOR(self), NULL);
Expand Down
18 changes: 18 additions & 0 deletions shoyu-compositor/keyboard-input-private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "input-private.h"
#include "keyboard-input.h"

#include <wlr/types/wlr_keyboard.h>

struct _ShoyuKeyboardInput {
ShoyuInput parent_instance;
struct xkb_keymap *xkb_keymap;

struct wl_listener modifiers;
struct wl_listener key;
};

struct _ShoyuKeyboardInputClass {
ShoyuInputClass parent_class;
};
94 changes: 94 additions & 0 deletions shoyu-compositor/keyboard-input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "compositor-private.h"
#include "keyboard-input-private.h"
#include "output-private.h"
#include "xdg-toplevel-private.h"

/**
* ShoyuKeyboardInput:
*
* An input which represents a keyboard for #ShoyuCompositor.
*/

G_DEFINE_TYPE(ShoyuKeyboardInput, shoyu_keyboard_input, SHOYU_TYPE_INPUT)

static void shoyu_keyboard_input_modifiers(struct wl_listener *listener,
void *data) {
ShoyuKeyboardInput *self = wl_container_of(listener, self, modifiers);
ShoyuInput *input = SHOYU_INPUT(self);

struct wlr_keyboard *wlr_keyboard =
wlr_keyboard_from_input_device(input->wlr_input_device);

wlr_seat_set_keyboard(input->compositor->wlr_seat, wlr_keyboard);
wlr_seat_keyboard_notify_modifiers(input->compositor->wlr_seat,
&wlr_keyboard->modifiers);
}

static void shoyu_keyboard_input_key(struct wl_listener *listener, void *data) {
ShoyuKeyboardInput *self = wl_container_of(listener, self, key);
ShoyuInput *input = SHOYU_INPUT(self);

struct wlr_keyboard_key_event *event = data;

struct wlr_keyboard *wlr_keyboard =
wlr_keyboard_from_input_device(input->wlr_input_device);

wlr_seat_set_keyboard(input->compositor->wlr_seat, wlr_keyboard);

wlr_seat_keyboard_notify_key(input->compositor->wlr_seat, event->time_msec,
event->keycode, event->state);
}

static void shoyu_keyboard_input_finalize(GObject *object) {
ShoyuKeyboardInput *self = SHOYU_KEYBOARD_INPUT(object);

g_clear_pointer(&self->xkb_keymap, (GDestroyNotify)xkb_keymap_unref);

G_OBJECT_CLASS(shoyu_keyboard_input_parent_class)->finalize(object);
}

static void
shoyu_keyboard_input_realized(ShoyuInput *input,
struct wlr_input_device *wlr_input_device) {
ShoyuKeyboardInput *self = SHOYU_KEYBOARD_INPUT(input);

struct wlr_keyboard *wlr_keyboard =
wlr_keyboard_from_input_device(wlr_input_device);

wlr_keyboard_set_keymap(wlr_keyboard, self->xkb_keymap);
wlr_keyboard_set_repeat_info(wlr_keyboard, 25, 600);

self->modifiers.notify = shoyu_keyboard_input_modifiers;
wl_signal_add(&wlr_keyboard->events.modifiers, &self->modifiers);

self->key.notify = shoyu_keyboard_input_key;
wl_signal_add(&wlr_keyboard->events.key, &self->key);

wlr_seat_set_keyboard(input->compositor->wlr_seat, wlr_keyboard);
}

static void shoyu_keyboard_input_unrealized(ShoyuInput *input) {
ShoyuKeyboardInput *self = SHOYU_KEYBOARD_INPUT(input);

wl_list_remove(&self->modifiers.link);
wl_list_remove(&self->key.link);
}

static void shoyu_keyboard_input_class_init(ShoyuKeyboardInputClass *class) {
GObjectClass *object_class = G_OBJECT_CLASS(class);
ShoyuInputClass *input_class = SHOYU_INPUT_CLASS(class);

object_class->finalize = shoyu_keyboard_input_finalize;

input_class->realized = shoyu_keyboard_input_realized;
input_class->unrealized = shoyu_keyboard_input_unrealized;
}

static void shoyu_keyboard_input_init(ShoyuKeyboardInput *self) {
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);

self->xkb_keymap =
xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);

xkb_context_unref(context);
}
36 changes: 36 additions & 0 deletions shoyu-compositor/keyboard-input.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#if !defined(__SHOYU_COMPOSITOR_H_INSIDE__) && !defined(SHOYU_COMPILATION)
#error "Only <shoyu-compositor/shoyu-compositor.h> can be included directly."
#endif

#include <shoyu-compositor/input.h>

G_BEGIN_DECLS

#ifdef SHOYU_COMPILATION
typedef struct _ShoyuKeyboardInput ShoyuKeyboardInput;
#else
typedef ShoyuInput ShoyuKeyboardInput;
#endif
typedef struct _ShoyuKeyboardInputClass ShoyuKeyboardInputClass;

#define SHOYU_TYPE_KEYBOARD_INPUT (shoyu_keyboard_input_get_type())
#define SHOYU_KEYBOARD_INPUT(object) \
(G_TYPE_CHECK_INSTANCE_CAST((object), SHOYU_TYPE_KEYBOARD_INPUT, \
ShoyuKeyboardInput))
#define SHOYU_KEYBOARD_INPUT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), SHOYU_TYPE_KEYBOARD_INPUT, \
ShoyuKeyboardInputClass))
#define SHOYU_IS_KEYBOARD_INPUT(object) \
(G_TYPE_CHECK_INSTANCE_TYPE((object), SHOYU_TYPE_KEYBOARD_INPUT))
#define SHOYU_IS_KEYBOARD_INPUT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), SHOYU_TYPE_KEYBOARD_INPUT))
#define SHOYU_KEYBOARD_INPUT_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), SHOYU_TYPE_KEYBOARD_INPUT, \
ShoyuKeyboardInputClass))

SHOYU_AVAILABLE_IN_ALL
GType shoyu_keyboard_input_get_type(void) G_GNUC_CONST;

G_END_DECLS
7 changes: 7 additions & 0 deletions shoyu-compositor/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ libcompositor_private_sources = files([
libcompositor_private_h_sources = files([
'compositor-private.h',
'input-private.h',
'keyboard-input-private.h',
'output-private.h',
'pointer-input-private.h',
'shell-private.h',
'shell-output-private.h',
'shell-toplevel-private.h',
Expand All @@ -27,8 +29,10 @@ libcompositor_private_h_sources = files([
libcompositor_public_sources = files([
'compositor.c',
'input.c',
'keyboard-input.c',
'main.c',
'output.c',
'pointer-input.c',
'shell.c',
'surface.c',
'version.c',
Expand All @@ -39,8 +43,10 @@ libcompositor_public_sources = files([
libcompositor_public_headers = files([
'compositor.h',
'input.h',
'keyboard-input.h',
'main.h',
'output.h',
'pointer-input.h',
'shell.h',
'shoyu-compositor.h',
'surface.h',
Expand Down Expand Up @@ -97,6 +103,7 @@ libcompositor_deps = [
wlroots,
wayland_server,
pixman,
xkbcommon,
]

darwin_versions = [
Expand Down
23 changes: 23 additions & 0 deletions shoyu-compositor/pointer-input-private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include "input-private.h"
#include "pointer-input.h"

#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_pointer.h>

struct _ShoyuPointerInput {
ShoyuInput parent_instance;

struct wlr_cursor *cursor;

struct wl_listener cursor_motion;
struct wl_listener cursor_motion_absolute;
struct wl_listener cursor_button;
struct wl_listener cursor_axis;
struct wl_listener cursor_frame;
};

struct _ShoyuPointerInputClass {
ShoyuInputClass parent_class;
};
Loading