wayland backend: refactor code, split into categories

This commit is contained in:
Riccardo Canalicchio 2021-10-25 07:16:22 -04:00
parent 7b87b268e3
commit 30ceacc90d
9 changed files with 1001 additions and 928 deletions

5
Headers/wayland/WaylandServer.h Normal file → Executable file
View file

@ -109,7 +109,8 @@ struct window {
int window_id;
struct wl_list link;
BOOL configured; // surface has been configured once
BOOL buffer_needs_attach; // surface has been configured once
BOOL buffer_needs_attach; // there is a new buffer avaialble for the surface
BOOL terminated; // there is a new buffer avaialble for the surface
float pos_x;
float pos_y;
@ -140,5 +141,7 @@ struct window {
BOOL _mouseInitialized;
}
@end
@interface WaylandServer(Cursor)
@end
#endif /* _XGServer_h_INCLUDE */

View file

@ -45,6 +45,12 @@ wlr-layer-shell-protocol.c \
# The Objective-C source files to be compiled
wayland_OBJC_FILES = \
WaylandServer.m \
WaylandServer+Output.m \
WaylandServer+Cursor.m \
WaylandServer+Keyboard.m \
WaylandServer+Seat.m \
WaylandServer+Xdgshell.m \
WaylandServer+Layershell.m \
-include GNUmakefile.preamble

View file

@ -0,0 +1,446 @@
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
#include <linux/input.h>
static void
pointer_handle_enter(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface,
wl_fixed_t sx_w, wl_fixed_t sy_w)
{
NSDebugLog(@"pointer_handle_enter");
if (!surface) {
NSDebugLog(@"no surface");
return;
}
WaylandConfig *wlconfig = data;
struct window *window = wl_surface_get_user_data(surface);
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
[GSCurrentServer() initializeMouseIfRequired];
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
wlconfig->pointer.focus = window;
// FIXME: Send NSMouseEntered event.
}
static void
pointer_handle_leave(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface)
{
NSDebugLog(@"pointer_handle_leave");
if (!surface) {
NSDebugLog(@"no surface");
return;
}
WaylandConfig *wlconfig = data;
struct window *window = wl_surface_get_user_data(surface);
[GSCurrentServer() initializeMouseIfRequired];
if (wlconfig->pointer.focus->window_id == window->window_id) {
wlconfig->pointer.focus = NULL;
wlconfig->pointer.serial = 0;
}
// FIXME: Send NSMouseExited event.
}
// triggered when the cursor is over a surface
static void
pointer_handle_motion(void *data, struct wl_pointer *pointer,
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
{
WaylandConfig *wlconfig = data;
struct window *window;
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
NSDebugLog(@"pointer_handle_motion: %fx%f", sx, sy);
[GSCurrentServer() initializeMouseIfRequired];
if (wlconfig->pointer.focus && wlconfig->pointer.serial) {
window = wlconfig->pointer.focus;
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = sx - window->wlconfig->pointer.x;
float deltaY = sy - window->wlconfig->pointer.y;
// NSDebugLog(@"obtaining locations: wayland=%fx%f pointer=%fx%f",
// sx, sy, window->wlconfig->pointer.x, window->wlconfig->pointer.y);
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(sx,
window->height - sy);
eventFlags = 0;
eventType = NSLeftMouseDragged;
// NSDebugLog(@"sending pointer delta: %fx%f, window=%d", deltaX, deltaY, window->window_id);
event = [NSEvent mouseEventWithType: eventType
location: eventLocation
modifierFlags: eventFlags
timestamp: (NSTimeInterval) time / 1000.0
windowNumber: (int)window->window_id
context: gcontext
eventNumber: time
clickCount: 1
pressure: 1.0
buttonNumber: 0 /* FIXME */
deltaX: deltaX
deltaY: deltaY
deltaZ: 0.];
[GSCurrentServer() postEvent: event atStart: NO];
}
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
}
static void
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state_w)
{
NSDebugLog(@"pointer_handle_button: button=%d", button);
WaylandConfig *wlconfig = data;
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = 0.0;
float deltaY = 0.0;
int clickCount = 1;
int tick;
int buttonNumber;
enum wl_pointer_button_state state = state_w;
struct window *window = wlconfig->pointer.focus;
[GSCurrentServer() initializeMouseIfRequired];
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(wlconfig->pointer.x,
window->height - wlconfig->pointer.y);
eventFlags = 0;
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
if (button == wlconfig->pointer.last_click_button &&
time - wlconfig->pointer.last_click_time < 300 &&
abs(wlconfig->pointer.x - wlconfig->pointer.last_click_x) < 3 &&
abs(wlconfig->pointer.y - wlconfig->pointer.last_click_y) < 3) {
NSDebugLog(@"handle_button HIT: b=%d t=%d x=%f y=%f", button, time, wlconfig->pointer.x, wlconfig->pointer.y);
wlconfig->pointer.last_click_time = 0;
clickCount++;
} else {
NSDebugLog(@"handle_button MISS: b=%d t=%d x=%f y=%f", button, time, wlconfig->pointer.x, wlconfig->pointer.y);
wlconfig->pointer.last_click_button = button;
wlconfig->pointer.last_click_time = time;
wlconfig->pointer.last_click_x = wlconfig->pointer.x;
wlconfig->pointer.last_click_y = wlconfig->pointer.y;
}
switch (button) {
case BTN_LEFT:
eventType = NSLeftMouseDown;
break;
case BTN_RIGHT:
eventType = NSRightMouseDown;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseDown;
break;
// TODO: handle BTN_SIDE, BTN_EXTRA, BTN_FORWARD, BTN_BACK and other
// constants in libinput.
// We may just want to send NSOtherMouseDown and populate buttonNumber
// with the libinput constant?
}
wlconfig->pointer.serial = serial;
} else if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
switch (button) {
case BTN_LEFT:
eventType = NSLeftMouseUp;
break;
case BTN_RIGHT:
eventType = NSRightMouseUp;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseUp;
break;
}
wlconfig->pointer.serial = 0;
} else {
NSDebugLog(@"unhandled wayland pointer state 0x%02x", state);
return;
}
/* FIXME: unlike in _motion and _axis handlers, the argument used in _button
is the "serial" of the event, not passed and unavailable in _motion and
_axis handlers. Is it allowed to pass "serial" as the eventNumber: in
_button handler, but "time" as the eventNumber: in the _motion and _axis
handlers? */
tick = serial;
NSDebugLog(@"sending pointer event at: %fx%f, window=%d", wlconfig->pointer.x, wlconfig->pointer.y, window->window_id);
/* FIXME: X11 backend uses the XGetPointerMapping()-returned values from
its map_return argument as constants for buttonNumber. As the variant
with buttonNumber: seems to be a GNUstep extension, and the value
internal, it might be ok to just provide libinput constant as we're doing
here. If this is truly correct, please update this comment to document
the correctness of doing so. */
buttonNumber = button;
event = [NSEvent mouseEventWithType: eventType
location: eventLocation
modifierFlags: eventFlags
timestamp: (NSTimeInterval) time / 1000.0
windowNumber: (int)window->window_id
context: gcontext
eventNumber: tick
clickCount: clickCount
pressure: 1.0
buttonNumber: buttonNumber
deltaX: deltaX /* FIXME unused */
deltaY: deltaY /* FIXME unused */
deltaZ: 0.];
[GSCurrentServer() postEvent: event atStart: NO];
}
static void
pointer_handle_axis(void *data, struct wl_pointer *pointer,
uint32_t time, uint32_t axis, wl_fixed_t value)
{
NSDebugLog(@"pointer_handle_axis: axis=%d value=%g", axis, wl_fixed_to_double(value));
WaylandConfig *wlconfig = data;
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = 0.0;
float deltaY = 0.0;
int clickCount = 1;
int buttonNumber;
struct window *window = wlconfig->pointer.focus;
[GSCurrentServer() initializeMouseIfRequired];
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(wlconfig->pointer.x,
window->height - wlconfig->pointer.y);
eventFlags = 0;
/* FIXME: we should get axis_source out of wl_pointer; however, the wl_pointer
is not defined in wayland-client.h. How does one get the axis_source out of
it to confirm the source is the physical mouse wheel? */
#if 0
if (pointer->axis_source != WL_POINTER_AXIS_SOURCE_WHEEL)
return;
#endif
float mouse_scroll_multiplier = wlconfig->mouse_scroll_multiplier;
/* For smooth-scroll events, we're not doing any cross-event or delta
calculations, as is done in button event handling. */
switch(axis)
{
case WL_POINTER_AXIS_VERTICAL_SCROLL:
eventType = NSScrollWheel;
deltaY = wl_fixed_to_double(value) * wlconfig->mouse_scroll_multiplier;
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
eventType = NSScrollWheel;
deltaX = wl_fixed_to_double(value) * wlconfig->mouse_scroll_multiplier;
}
NSDebugLog(@"sending pointer scroll at: %fx%f, value %fx%f, window=%d", wlconfig->pointer.x, wlconfig->pointer.y, deltaX, deltaY, window->window_id);
/* FIXME: X11 backend uses the XGetPointerMapping()-returned values from
its map_return argument as constants for buttonNumber. As the variant
with buttonNumber: seems to be a GNUstep extension, and the value
internal, it might be ok to just not provide any value here.
If this is truly correct, please update this comment to document
the correctness of doing so. */
buttonNumber = 0;
event = [NSEvent mouseEventWithType: eventType
location: eventLocation
modifierFlags: eventFlags
timestamp: (NSTimeInterval) time / 1000.0
windowNumber: (int)window->window_id
context: gcontext
eventNumber: time
clickCount: clickCount
pressure: 1.0
buttonNumber: buttonNumber
deltaX: deltaX
deltaY: deltaY
deltaZ: 0.];
[GSCurrentServer() postEvent: event atStart: NO];
}
const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter,
pointer_handle_leave,
pointer_handle_motion,
pointer_handle_button,
pointer_handle_axis,
};
@implementation WaylandServer(Cursor)
- (NSPoint) mouselocation
{
int aScreen = -1;
struct output *output;
NSDebugLog(@"mouselocation");
// FIXME: find a cleaner way to get the first element of a wl_list
wl_list_for_each(output, &wlconfig->output_list, link) {
aScreen = output->server_output_id;
break;
}
if (aScreen < 0)
// No outputs in the wl_list.
return NSZeroPoint;
return [self mouseLocationOnScreen: aScreen window: NULL];
}
- (NSPoint) mouseLocationOnScreen: (int)aScreen window: (int *)win
{
// NSDebugLog(@"mouseLocationOnScreen: %d %fx%f", win,
// wlconfig->pointer.x, wlconfig->pointer.y);
struct window *window = wlconfig->pointer.focus;
struct output *output;
float x;
float y;
/*if (wlconfig->pointer.serial) {
NSDebugLog(@"captured");
x = wlconfig->pointer.captured_x;
y = wlconfig->pointer.captured_y;
} else*/ {
//NSDebugLog(@"NOT captured");
x = wlconfig->pointer.x;
y = wlconfig->pointer.y;
if (window) {
x += window->pos_x;
y += window->pos_y;
if (win) {
*win = &window->window_id;
}
}
}
wl_list_for_each(output, &wlconfig->output_list, link) {
if (output->server_output_id == aScreen) {
y = output->height - y;
break;
}
}
// NSDebugLog(@"mouseLocationOnScreen: returning %fx%f", x, y);
return NSMakePoint(x, y);
}
- (BOOL) capturemouse: (int) win
{
NSDebugLog(@"capturemouse: %d", win);
return NO;
}
- (void) releasemouse
{
NSDebugLog(@"releasemouse");
}
- (void) setMouseLocation: (NSPoint)mouseLocation onScreen: (int)aScreen
{
NSDebugLog(@"setMouseLocation");
}
- (void) hidecursor
{
NSDebugLog(@"hidecursor");
}
- (void) showcursor
{
NSDebugLog(@"showcursor");
}
- (void) standardcursor: (int) style : (void**) cid
{
NSDebugLog(@"standardcursor");
}
- (void) imagecursor: (NSPoint)hotp : (NSImage *) image : (void**) cid
{
NSDebugLog(@"imagecursor");
}
- (void) setcursorcolor: (NSColor *)fg : (NSColor *)bg : (void*) cid
{
NSLog(@"Call to obsolete method -setcursorcolor:::");
[self recolorcursor: fg : bg : cid];
[self setcursor: cid];
}
- (void) recolorcursor: (NSColor *)fg : (NSColor *)bg : (void*) cid
{
NSDebugLog(@"recolorcursor");
}
- (void) setcursor: (void*) cid
{
NSDebugLog(@"setcursor");
}
- (void) freecursor: (void*) cid
{
NSDebugLog(@"freecursor");
}
- (void) setIgnoreMouse: (BOOL)ignoreMouse : (int)win
{
NSDebugLog(@"setIgnoreMouse");
}
- (void) initializeMouseIfRequired
{
if (!_mouseInitialized)
[self initializeMouse];
}
- (void) initializeMouse
{
_mouseInitialized = YES;
[self mouseOptionsChanged: nil];
[[NSDistributedNotificationCenter defaultCenter]
addObserver: self
selector: @selector(mouseOptionsChanged:)
name: NSUserDefaultsDidChangeNotification
object: nil];
}
- (void) mouseOptionsChanged: (NSNotification *)aNotif
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
wlconfig->mouse_scroll_multiplier = [defs integerForKey:@"GSMouseScrollMultiplier"];
if (wlconfig->mouse_scroll_multiplier < 0.0001f)
wlconfig->mouse_scroll_multiplier = 1.0f;
}
@end

View file

@ -0,0 +1,192 @@
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
#include <linux/input.h>
#include <AppKit/NSText.h>
#include <sys/mman.h>
static void
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size)
{
NSDebugLog(@"keyboard_handle_keymap");
WaylandConfig *wlconfig = data;
struct xkb_keymap *keymap;
struct xkb_state *state;
char *map_str;
if (!data) {
close(fd);
return;
}
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
close(fd);
return;
}
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (map_str == MAP_FAILED) {
close(fd);
return;
}
wlconfig->xkb_context = xkb_context_new(0);
if (wlconfig->xkb_context == NULL) {
fprintf(stderr, "Failed to create XKB context\n");
return;
}
keymap = xkb_keymap_new_from_string(wlconfig->xkb_context,
map_str,
XKB_KEYMAP_FORMAT_TEXT_V1,
0);
munmap(map_str, size);
close(fd);
if (!keymap) {
fprintf(stderr, "failed to compile keymap\n");
return;
}
state = xkb_state_new(keymap);
if (!state) {
fprintf(stderr, "failed to create XKB state\n");
xkb_keymap_unref(keymap);
return;
}
xkb_keymap_unref(wlconfig->xkb.keymap);
xkb_state_unref(wlconfig->xkb.state);
wlconfig->xkb.keymap = keymap;
wlconfig->xkb.state = state;
wlconfig->xkb.control_mask =
1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Control");
wlconfig->xkb.alt_mask =
1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Mod1");
wlconfig->xkb.shift_mask =
1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Shift");
}
static void
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface,
struct wl_array *keys)
{
NSDebugLog(@"keyboard_handle_enter");
}
static void
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface)
{
NSDebugLog(@"keyboard_handle_leave");
}
static void
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{
NSDebugLog(@"keyboard_handle_modifiers");
WaylandConfig *wlconfig = data;
xkb_mod_mask_t mask;
/* If we're not using a keymap, then we don't handle PC-style modifiers */
if (!wlconfig->xkb.keymap)
return;
xkb_state_update_mask(wlconfig->xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
mask = xkb_state_serialize_mods(wlconfig->xkb.state,
XKB_STATE_MODS_DEPRESSED |
XKB_STATE_MODS_LATCHED);
wlconfig->modifiers = 0;
if (mask & wlconfig->xkb.control_mask)
wlconfig->modifiers |= NSCommandKeyMask;
if (mask & wlconfig->xkb.alt_mask)
wlconfig->modifiers |= NSAlternateKeyMask;
if (mask & wlconfig->xkb.shift_mask)
wlconfig->modifiers |= NSShiftKeyMask;
}
static void
keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t time, uint32_t key,
uint32_t state_w)
{
NSDebugLog(@"keyboard_handle_key: %d", key);
WaylandConfig *wlconfig = data;
uint32_t code, num_syms;
enum wl_keyboard_key_state state = state_w;
const xkb_keysym_t *syms;
xkb_keysym_t sym;
struct window *window = wlconfig->pointer.focus;
if (!window)
return;
code = 0;
if (key == 28) {
sym = NSCarriageReturnCharacter;
} else if (key == 14) {
sym = NSDeleteCharacter;
} else {
code = key + 8;
num_syms = xkb_state_key_get_syms(wlconfig->xkb.state, code, &syms);
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
sym = syms[0];
}
NSString *s = [NSString stringWithUTF8String: &sym];
NSEventType eventType;
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
eventType = NSKeyDown;
} else {
eventType = NSKeyUp;
}
NSEvent *ev = [NSEvent keyEventWithType: eventType
location: NSZeroPoint
modifierFlags: wlconfig->modifiers
timestamp: time / 1000.0
windowNumber: window->window_id
context: GSCurrentContext()
characters: s
charactersIgnoringModifiers: s
isARepeat: NO
keyCode: code];
[GSCurrentServer() postEvent: ev atStart: NO];
NSDebugLog(@"keyboard_handle_key: %@", s);
}
static void
keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
int32_t rate, int32_t delay)
{
NSDebugLog(@"keyboard_handle_repeat_info");
}
const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap,
keyboard_handle_enter,
keyboard_handle_leave,
keyboard_handle_key,
keyboard_handle_modifiers,
keyboard_handle_repeat_info
};
@implementation WaylandServer (KeyboardOps)
@end

View file

@ -0,0 +1,38 @@
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
static void layer_surface_configure(void *data,
struct zwlr_layer_surface_v1 *surface,
uint32_t serial, uint32_t w, uint32_t h) {
NSDebugLog(@"configure layer");
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
zwlr_layer_surface_v1_ack_configure(surface, serial);
window->configured = YES;
if(window->buffer_needs_attach) {
NSDebugLog(@"attach: win=%d layer", window->window_id);
wl_surface_attach(window->surface, window->buffer, 0, 0);
wl_surface_commit(window->surface);
}
}
static void layer_surface_closed(void *data,
struct zwlr_layer_surface_v1 *surface) {
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
NSDebugLog(@"layer_surface_closed %d", window->window_id);
//zwlr_layer_surface_v1_destroy(surface);
wl_surface_destroy(window->surface);
window->surface = NULL;
window->configured = NO;
window->layer_surface = NULL;
}
const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
.configure = layer_surface_configure,
.closed = layer_surface_closed,
};

View file

@ -0,0 +1,96 @@
#include "wayland/WaylandServer.h"
static void
handle_geometry(void *data,
struct wl_output *wl_output,
int x, int y,
int physical_width,
int physical_height,
int subpixel,
const char *make,
const char *model,
int transform)
{
NSDebugLog(@"handle_geometry");
struct output *output = data;
output->alloc_x = x;
output->alloc_y = y;
output->transform = transform;
if (output->make)
free(output->make);
output->make = strdup(make);
if (output->model)
free(output->model);
output->model = strdup(model);
}
static void
handle_done(void *data,
struct wl_output *wl_output)
{
NSDebugLog(@"handle_done");
}
static void
handle_scale(void *data,
struct wl_output *wl_output,
int32_t scale)
{
NSDebugLog(@"handle_scale");
struct output *output = data;
output->scale = scale;
}
static void
handle_mode(void *data,
struct wl_output *wl_output,
uint32_t flags,
int width,
int height,
int refresh)
{
NSDebugLog(@"handle_mode");
struct output *output = data;
if (flags & WL_OUTPUT_MODE_CURRENT) {
output->width = width;
output->height = height /*- 30*/;
NSDebugLog(@"handle_mode output=%dx%d", width, height);
// XXX - Should we implement this?
// if (display->output_configure_handler)
// (*display->output_configure_handler)
// (output, display->user_data);
//
}
}
/*
static void
destroy_output(WaylandConfig *wlconfig, uint32_t id)
{
struct output *output;
wl_list_for_each(output, &wlconfig->output_list, link) {
if (output->server_output_id == id) {
wl_output_destroy(output->output);
wl_list_remove(&output->link);
free(output);
wlconfig->output_count--;
break;
}
}
}
*/
const struct wl_output_listener output_listener = {
handle_geometry,
handle_mode,
handle_done,
handle_scale
};

View file

@ -0,0 +1,64 @@
#include "wayland/WaylandServer.h"
extern const struct wl_keyboard_listener keyboard_listener;
extern const struct wl_pointer_listener pointer_listener;
static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps)
{
WaylandConfig *wlconfig = data;
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlconfig->pointer.wlpointer) {
wlconfig->pointer.wlpointer = wl_seat_get_pointer(seat);
wl_pointer_set_user_data(wlconfig->pointer.wlpointer, wlconfig);
wl_pointer_add_listener(wlconfig->pointer.wlpointer, &pointer_listener,
wlconfig);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlconfig->pointer.wlpointer) {
if (wlconfig->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
wl_pointer_release(wlconfig->pointer.wlpointer);
else
wl_pointer_destroy(wlconfig->pointer.wlpointer);
wlconfig->pointer.wlpointer = NULL;
}
wl_display_dispatch_pending(wlconfig->display);
wl_display_flush(wlconfig->display);
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wlconfig->keyboard) {
wlconfig->keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_set_user_data(wlconfig->keyboard, wlconfig);
wl_keyboard_add_listener(wlconfig->keyboard, &keyboard_listener,
wlconfig);
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wlconfig->keyboard) {
if (wlconfig->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
wl_keyboard_release(wlconfig->keyboard);
else
wl_keyboard_destroy(wlconfig->keyboard);
wlconfig->keyboard = NULL;
}
#if 0
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
input->touch = wl_seat_get_touch(seat);
wl_touch_set_user_data(input->touch, input);
wl_touch_add_listener(input->touch, &touch_listener, input);
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
wl_touch_release(input->touch);
else
wl_touch_destroy(input->touch);
input->touch = NULL;
}
#endif
}
const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
};
@implementation WaylandServer (Seat)
@end

View file

@ -0,0 +1,129 @@
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
static void
xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial)
{
struct window *window = data;
NSDebugLog(@"xdg_surface_on_configure: win=%d", window->window_id);
if(window->terminated == YES) {
NSDebugLog(@"deleting window win=%d", window->window_id);
free(window);
return;
}
WaylandConfig *wlconfig = window->wlconfig;
NSEvent *ev = nil;
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
NSDebugLog(@"Acknowledging surface configure %p %d (window_id=%d)", xdg_surface, serial, window->window_id);
xdg_surface_ack_configure(xdg_surface, serial);
window->configured = YES;
if(window->buffer_needs_attach) {
NSDebugLog(@"attach: win=%d toplevel", window->window_id);
wl_surface_attach(window->surface, window->buffer, 0, 0);
wl_surface_commit(window->surface);
}
if (wlconfig->pointer.focus &&
wlconfig->pointer.focus->window_id == window->window_id) {
ev = [NSEvent otherEventWithType: NSAppKitDefined
location: NSZeroPoint
modifierFlags: 0
timestamp: 0
windowNumber: (int)window->window_id
context: GSCurrentContext()
subtype: GSAppKitWindowFocusIn
data1: 0
data2: 0];
[nswindow sendEvent: ev];
}
#if 0
struct window *window = data;
int moved = 0;
NSDebugLog(@"configure window=%d pos=%dx%d size=%dx%d",
window->window_id, x, y, width, height);
NSDebugLog(@"current values pos=%dx%d size=%dx%d",
window->pos_x, window->pos_y, window->width, window->height);
if (!window->is_out && (window->pos_x != x || window->pos_y != y)) {
window->pos_x = x;
window->pos_y = y;
moved = 1;
}
xdg_surface_ack_configure(window->xdg_surface, serial);
NSRect rect = NSMakeRect(0, 0,
window->width, window->height);
[window->instance flushwindowrect:rect :window->window_id];
wl_display_dispatch_pending(window->wlconfig->display);
wl_display_flush(window->wlconfig->display);
if (moved) {
NSDebugLog(@"window moved, notifying AppKit");
NSEvent *ev = nil;
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
ev = [NSEvent otherEventWithType: NSAppKitDefined
location: NSZeroPoint
modifierFlags: 0
timestamp: 0
windowNumber: (int)window->window_id
context: GSCurrentContext()
subtype: GSAppKitWindowMoved
data1: window->pos_x
data2: WaylandToNS(window, window->pos_y)];
[nswindow sendEvent: ev];
}
#endif
}
static void xdg_popup_configure(void *data, struct xdg_popup *xdg_popup,
int32_t x, int32_t y, int32_t width, int32_t height) {
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
window->width = width;
window->height = height;
}
static void xdg_popup_done(void *data, struct xdg_popup *xdg_popup) {
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
xdg_popup_destroy(xdg_popup);
wl_surface_destroy(window->surface);
}
static void wm_base_handle_ping(void *data, struct xdg_wm_base *xdg_wm_base,
uint32_t serial)
{
xdg_wm_base_pong(xdg_wm_base, serial);
}
const struct xdg_surface_listener xdg_surface_listener = {
xdg_surface_on_configure,
};
const struct xdg_wm_base_listener wm_base_listener = {
.ping = wm_base_handle_ping,
};
const struct xdg_popup_listener xdg_popup_listener = {
.configure = xdg_popup_configure,
.popup_done = xdg_popup_done,
};

953
Source/wayland/WaylandServer.m Normal file → Executable file

File diff suppressed because it is too large Load diff