Wayland server: code formatting

using clang-format from:
https://github.com/gnustep/libs-base/blob/master/.clang-format
This commit is contained in:
Riccardo Canalicchio 2021-11-15 17:05:12 -05:00
parent 114743a5d0
commit 91a1479193
9 changed files with 1871 additions and 1629 deletions

View file

@ -5,6 +5,7 @@
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Sergio L. Pascual <slp@sinrega.org>
Rewrite: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: February 2016
This file is part of the GNUstep Backend.
@ -40,110 +41,115 @@
#include "wayland/xdg-shell-client-protocol.h"
#include "wayland/wlr-layer-shell-client-protocol.h"
struct pointer {
struct wl_pointer *wlpointer;
float x;
float y;
uint32_t last_click_button;
uint32_t last_click_time;
float last_click_x;
float last_click_y;
struct pointer
{
struct wl_pointer *wlpointer;
float x;
float y;
uint32_t last_click_button;
uint32_t last_click_time;
float last_click_x;
float last_click_y;
uint32_t serial;
struct window *focus;
uint32_t serial;
struct window *focus;
};
typedef struct _WaylandConfig {
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
struct wl_seat *seat;
struct wl_keyboard *keyboard;
struct xdg_wm_base *wm_base;
struct zwlr_layer_shell_v1 *layer_shell;
typedef struct _WaylandConfig
{
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
struct wl_seat *seat;
struct wl_keyboard *keyboard;
struct xdg_wm_base *wm_base;
struct zwlr_layer_shell_v1 *layer_shell;
struct wl_list output_list;
int output_count;
struct wl_list window_list;
int window_count;
int last_window_id;
struct wl_list output_list;
int output_count;
struct wl_list window_list;
int window_count;
int last_window_id;
struct pointer pointer;
struct xkb_context *xkb_context;
struct {
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
} xkb;
int modifiers;
struct pointer pointer;
struct xkb_context *xkb_context;
struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
} xkb;
int modifiers;
int seat_version;
int seat_version;
float mouse_scroll_multiplier;
float mouse_scroll_multiplier;
} WaylandConfig;
struct output {
WaylandConfig *wlconfig;
struct wl_output *output;
uint32_t server_output_id;
struct wl_list link;
int alloc_x;
int alloc_y;
int width;
int height;
int transform;
int scale;
char *make;
char *model;
struct output
{
WaylandConfig *wlconfig;
struct wl_output *output;
uint32_t server_output_id;
struct wl_list link;
int alloc_x;
int alloc_y;
int width;
int height;
int transform;
int scale;
char *make;
char *model;
void *user_data;
void *user_data;
};
struct window {
WaylandConfig *wlconfig;
id instance;
int window_id;
struct wl_list link;
BOOL configured; // surface has been configured once
BOOL buffer_needs_attach; // there is a new buffer avaialble for the surface
BOOL terminated;
BOOL moving;
BOOL resizing;
struct window
{
WaylandConfig *wlconfig;
id instance;
int window_id;
struct wl_list link;
BOOL configured; // surface has been configured once
BOOL buffer_needs_attach; // there is a new buffer avaialble for the surface
BOOL terminated;
BOOL moving;
BOOL resizing;
float pos_x;
float pos_y;
float width;
float height;
float saved_pos_x;
float saved_pos_y;
int is_out;
int level;
float pos_x;
float pos_y;
float width;
float height;
float saved_pos_x;
float saved_pos_y;
int is_out;
int level;
unsigned char *data;
struct wl_buffer *buffer;
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *toplevel;
struct xdg_popup *popup;
struct xdg_positioner *positioner;
struct zwlr_layer_surface_v1 *layer_surface;
struct output *output;
WaylandCairoSurface *wcs;
unsigned char *data;
struct wl_buffer *buffer;
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *toplevel;
struct xdg_popup *popup;
struct xdg_positioner *positioner;
struct zwlr_layer_surface_v1 *layer_surface;
struct output *output;
WaylandCairoSurface *wcs;
};
@interface WaylandServer : GSDisplayServer
{
WaylandConfig *wlconfig;
WaylandConfig *wlconfig;
BOOL _mouseInitialized;
BOOL _mouseInitialized;
}
@end
@interface WaylandServer(Cursor)
@interface
WaylandServer (Cursor)
@end
#endif /* _XGServer_h_INCLUDE */
#endif /* _WaylandServer_h_INCLUDE */

View file

@ -1,10 +1,13 @@
/* -*- mode:ObjC -*-
/* WaylandCairoSurface
WaylandCairoSurface - Draw with Cairo onto Wayland surfaces
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Sergio L. Pascual <slp@sinrega.org>
Date: February 2016
Rewrite: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
@ -36,43 +39,45 @@
#include <fcntl.h>
#include <sys/mman.h>
#define GSWINDEVICE ((struct window *)gsDevice)
#define GSWINDEVICE ((struct window *) gsDevice)
/* Linux specific version */
static int
os_create_anonymous_file(off_t size)
{
static const char template[] = "/weston-shared-XXXXXX";
const char *path;
char *name;
int fd;
static const char template[] = "/gnustep-shared-XXXXXX";
const char *path;
char *name;
int fd;
path = getenv("XDG_RUNTIME_DIR");
if (!path) {
errno = ENOENT;
return -1;
path = getenv("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}
name = malloc(strlen(path) + sizeof(template));
if (!name)
return -1;
name = malloc(strlen(path) + sizeof(template));
if (!name)
return -1;
strcpy(name, path);
strcat(name, template);
strcpy(name, path);
strcat(name, template);
fd = memfd_create(name, MFD_CLOEXEC);
fd = memfd_create(name, MFD_CLOEXEC);
free(name);
free(name);
if (fd < 0)
return -1;
if (fd < 0)
return -1;
if (ftruncate(fd, size) != 0) {
close(fd);
return -1;
if (ftruncate(fd, size) != 0)
{
close(fd);
return -1;
}
return fd;
return fd;
}
static inline size_t
@ -84,141 +89,148 @@ shm_buffer_stride(struct window *window)
static inline size_t
shm_buffer_size(struct window *window)
{
return shm_buffer_stride(window) * window->height;
return shm_buffer_stride(window) * window->height;
}
static cairo_surface_t *
create_shm_buffer(struct window *window)
{
struct wl_shm_pool *pool;
cairo_surface_t *surface;
int fd, size, stride;
struct wl_shm_pool *pool;
cairo_surface_t *surface;
int fd, size, stride;
stride = shm_buffer_stride(window);
size = shm_buffer_size(window);
stride = shm_buffer_stride(window);
size = shm_buffer_size(window);
NSDebugLog(@"WaylandCairoSurface: creating shm buffer of %d bytes", size);
fd = os_create_anonymous_file(size);
if (fd < 0) {
NSLog(@"creating a buffer file for surface failed");
return NULL;
NSDebugLog(@"WaylandCairoSurface: creating shm buffer of %d bytes", size);
fd = os_create_anonymous_file(size);
if (fd < 0)
{
NSLog(@"creating a buffer file for surface failed");
return NULL;
}
window->data =
mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (window->data == MAP_FAILED) {
NSLog(@"error mapping anonymous file");
close(fd);
return NULL;
window->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (window->data == MAP_FAILED)
{
NSLog(@"error mapping anonymous file");
close(fd);
return NULL;
}
pool = wl_shm_create_pool(window->wlconfig->shm, fd, size);
pool = wl_shm_create_pool(window->wlconfig->shm, fd, size);
surface = cairo_image_surface_create_for_data(window->data,
CAIRO_FORMAT_ARGB32,
window->width,
window->height,
stride);
surface
= cairo_image_surface_create_for_data(window->data, CAIRO_FORMAT_ARGB32,
window->width, window->height,
stride);
window->buffer =
wl_shm_pool_create_buffer(pool, 0,
window->width, window->height, stride,
WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool);
window->buffer
= wl_shm_pool_create_buffer(pool, 0, window->width, window->height, stride,
WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool);
close(fd);
close(fd);
return surface;
return surface;
}
@implementation WaylandCairoSurface
- (id) initWithDevice: (void*)device
- (id)initWithDevice:(void *)device
{
struct window *window = (struct window *) device;
NSDebugLog(@"WaylandCairoSurface: initWithDevice win=%d", window->window_id);
struct window *window = (struct window *) device;
NSDebugLog(@"WaylandCairoSurface: initWithDevice win=%d", window->window_id);
gsDevice = device;
gsDevice = device;
_surface = create_shm_buffer(window);
window->buffer_needs_attach = YES;
if (_surface == NULL) {
NSDebugLog(@"can't create cairo surface");
return 0;
_surface = create_shm_buffer(window);
window->buffer_needs_attach = YES;
if (_surface == NULL)
{
NSDebugLog(@"can't create cairo surface");
return 0;
}
if(window->configured) {
// if the window has a toplevel then it should appear on screen
// we can attach a buffer only if the xdg surface is configured
NSDebugLog(@"wl_surface_attach: win=%d toplevel_surface", window->window_id);
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, window->buffer, 0, 0);
wl_surface_commit(window->surface);
if (window->configured)
{
// we can attach a buffer to the surface only if the surface is configured
// this is usually done in the configure event handler
// in case of resize of an already configured surface
// we should reattach the new allocated buffer
NSDebugLog(@"wl_surface_attach: win=%d toplevel_surface",
window->window_id);
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, window->buffer, 0, 0);
wl_surface_commit(window->surface);
}
window->wcs = self;
window->wcs = self;
return self;
return self;
}
- (void) dealloc
- (void)dealloc
{
struct window *window = (struct window*) gsDevice;
NSDebugLog(@"WaylandCairoSurface: dealloc win=%d", window->window_id);
struct window *window = (struct window *) gsDevice;
NSDebugLog(@"WaylandCairoSurface: dealloc win=%d", window->window_id);
// FIXME: This is leaking memory. We need to *correctly* implement
// the counterpart to create_shm_buffer.
//
// For instance, this is the wrong place to destroy the cairo surface:
// cairo_surface_destroy(window->surface);
// window->surface = NULL;
// and likely to unmap the data, and destroy/release the buffer.
// "Destroying the wl_buffer after wl_buffer.release does not change
// the surface contents. However, if the client destroys the wl_buffer
// before receiving the wl_buffer.release event, the surface contents
// become undefined immediately."
// Hence also skipping:
// munmap(window->data, shm_buffer_size(window));
// FIXME: This is leaking memory. We need to *correctly* implement
// the counterpart to create_shm_buffer.
//
// For instance, this is the wrong place to destroy the cairo surface:
// cairo_surface_destroy(window->surface);
// window->surface = NULL;
// and likely to unmap the data, and destroy/release the buffer.
// "Destroying the wl_buffer after wl_buffer.release does not change
// the surface contents. However, if the client destroys the wl_buffer
// before receiving the wl_buffer.release event, the surface contents
// become undefined immediately."
// Hence also skipping:
// munmap(window->data, shm_buffer_size(window));
[super dealloc];
[super dealloc];
}
- (NSSize) size
- (NSSize)size
{
// NSDebugLog(@"WaylandCairoSurface: size");
struct window *window = (struct window*) gsDevice;
return NSMakeSize(window->width, window->height);
// NSDebugLog(@"WaylandCairoSurface: size");
struct window *window = (struct window *) gsDevice;
return NSMakeSize(window->width, window->height);
}
- (void) setSurface: (cairo_surface_t*)surface
- (void)setSurface:(cairo_surface_t *)surface
{
// NSDebugLog(@"WaylandCairoSurface: setSurface");
_surface = surface;
// NSDebugLog(@"WaylandCairoSurface: setSurface");
_surface = surface;
}
- (void) handleExposeRect: (NSRect)rect
- (void)handleExposeRect:(NSRect)rect
{
struct window *window = (struct window*) gsDevice;
NSDebugLog(@"[CairoSurface handleExposeRect] %d", window->window_id);
struct window *window = (struct window *) gsDevice;
NSDebugLog(@"[CairoSurface handleExposeRect] %d", window->window_id);
int x = NSMinX(rect);
int y = NSMinY(rect);
int width = NSWidth(rect);
int height = NSHeight(rect);
int x = NSMinX(rect);
int y = NSMinY(rect);
int width = NSWidth(rect);
int height = NSHeight(rect);
window->buffer_needs_attach = YES;
if (window->configured) {
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, window->buffer, 0, 0);
NSDebugLog(@"[%d] updating region: %d,%d %dx%d", window->window_id, 0, 0, window->width, window->height);
// FIXME we should update only the damaged area define as x,y,width,height
// at the moment it doesnt work
wl_surface_damage(window->surface, 0, 0, window->width, window->height);
wl_surface_commit(window->surface);
wl_display_dispatch_pending(window->wlconfig->display);
wl_display_flush(window->wlconfig->display);
window->buffer_needs_attach = YES;
if (window->configured)
{
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, window->buffer, 0, 0);
NSDebugLog(@"[%d] updating region: %d,%d %dx%d", window->window_id, 0, 0,
window->width, window->height);
// FIXME we should update only the damaged area define as x,y,width,height
// at the moment it doesnt work
wl_surface_damage(window->surface, 0, 0, window->width, window->height);
wl_surface_commit(window->surface);
wl_display_dispatch_pending(window->wlconfig->display);
wl_display_flush(window->wlconfig->display);
}
//NSDebugLog(@"[CairoSurface handleExposeRect end]");
// NSDebugLog(@"[CairoSurface handleExposeRect end]");
}
@end

View file

@ -1,3 +1,30 @@
/*
WaylandServer - Cursor Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSView.h>
@ -8,354 +35,406 @@
#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)
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)
{
if (!surface) {
NSDebugLog(@"no surface");
return;
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];
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;
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
wlconfig->pointer.focus = window;
// FIXME: Send NSMouseEntered event.
// FIXME: Send NSMouseEntered event.
}
static void
pointer_handle_leave(void *data, struct wl_pointer *pointer,
uint32_t serial, struct wl_surface *surface)
pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial,
struct wl_surface *surface)
{
if (!surface) {
NSDebugLog(@"no surface");
return;
if (!surface)
{
NSDebugLog(@"no surface");
return;
}
WaylandConfig *wlconfig = data;
struct window *window = wl_surface_get_user_data(surface);
[GSCurrentServer() initializeMouseIfRequired];
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;
if (wlconfig->pointer.focus->window_id == window->window_id)
{
wlconfig->pointer.focus = NULL;
wlconfig->pointer.serial = 0;
}
// FIXME: Send NSMouseExited event.
// 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)
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;
if(window->moving || window->resizing) {
return;
WaylandConfig *wlconfig = data;
struct window *window;
if (window->moving || window->resizing)
{
return;
}
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
[GSCurrentServer() initializeMouseIfRequired];
[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;
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);
// 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);
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(sx, window->height - sy);
eventFlags = 0;
eventType = NSLeftMouseDragged;
eventFlags = 0;
eventType = NSLeftMouseDragged;
// NSDebugLog(@"sending pointer delta: %fx%f, window=%d", deltaX, deltaY, window->window_id);
// 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.];
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];
[GSCurrentServer() postEvent:event atStart:NO];
}
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
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)
{
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;
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];
[GSCurrentServer() initializeMouseIfRequired];
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(wlconfig->pointer.x,
window->height - wlconfig->pointer.y);
eventFlags = 0;
gcontext = GSCurrentContext();
eventLocation
= NSMakePoint(wlconfig->pointer.x, window->height - wlconfig->pointer.y);
eventFlags = 0;
if(window->toplevel) {
// if the window is a toplevel we check if the event is for resizing or moving the window
// these actions are delegated to the compositor and therefore we skip forwarding the events
// to the NSWindow / NSView
if (window->toplevel)
{
// if the window is a toplevel we check if the event is for resizing or
// moving the window these actions are delegated to the compositor and
// therefore we skip forwarding the events to the NSWindow / NSView
NSWindow * nswindow = GSWindowWithNumber(window->window_id);
if(nswindow != nil) {
GSWindowDecorationView * wd = [GSWindowDecorationView windowDecorator];
// NSPoint p = [[nswindow contentView] convertPoint: eventLocation fromView: nil];
GSTheme *theme = [GSTheme theme];
CGFloat titleHeight = [theme titlebarHeight];
CGFloat resizebarHeight = [theme resizebarHeight];
NSRect windowframe = [nswindow frame];
NSDebugLog(@"[%d] titleHeight: %f", window->window_id, titleHeight);
NSDebugLog(@"[%d] resizebarHeight: %f", window->window_id, resizebarHeight);
NSDebugLog(@"[%d] windowframe: %f,%f %fx%f", windowframe.origin.x, windowframe.origin.y,
windowframe.size.width, windowframe.size.height);
NSDebugLog(@"[%d] eventLocation: %f,%f", window->window_id, eventLocation.x, eventLocation.y);
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
if (nswindow != nil)
{
GSWindowDecorationView *wd = [GSWindowDecorationView windowDecorator];
// NSPoint p = [[nswindow contentView] convertPoint:
// eventLocation fromView: nil];
GSTheme *theme = [GSTheme theme];
CGFloat titleHeight = [theme titlebarHeight];
CGFloat resizebarHeight = [theme resizebarHeight];
NSRect windowframe = [nswindow frame];
NSDebugLog(@"[%d] titleHeight: %f", window->window_id, titleHeight);
NSDebugLog(@"[%d] resizebarHeight: %f", window->window_id,
resizebarHeight);
NSDebugLog(@"[%d] windowframe: %f,%f %fx%f", windowframe.origin.x,
windowframe.origin.y, windowframe.size.width,
windowframe.size.height);
NSDebugLog(@"[%d] eventLocation: %f,%f", window->window_id,
eventLocation.x, eventLocation.y);
NSRect titleBarRect = NSZeroRect;
NSRect resizeBarRect = NSZeroRect;
NSRect closeButtonRect = NSZeroRect;
NSRect miniaturizeButtonRect = NSZeroRect;
NSUInteger styleMask = [nswindow styleMask];
bool hasTitleBar = NO;
bool hasResizeBar = NO;
bool hasCloseButton = NO;
bool hasMiniaturizeButton = NO;
NSRect titleBarRect = NSZeroRect;
NSRect resizeBarRect = NSZeroRect;
NSRect closeButtonRect = NSZeroRect;
NSRect miniaturizeButtonRect = NSZeroRect;
NSUInteger styleMask = [nswindow styleMask];
bool hasTitleBar = NO;
bool hasResizeBar = NO;
bool hasCloseButton = NO;
bool hasMiniaturizeButton = NO;
// wayland controls the window move / resize
// wayland controls the window move / resize
if (styleMask
& (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)) {
hasTitleBar = YES;
titleBarRect = NSMakeRect(0.0, windowframe.size.height - titleHeight,
windowframe.size.width, titleHeight);
if (styleMask
& (NSTitledWindowMask | NSClosableWindowMask
| NSMiniaturizableWindowMask))
{
hasTitleBar = YES;
titleBarRect
= NSMakeRect(0.0, windowframe.size.height - titleHeight,
windowframe.size.width, titleHeight);
NSDebugLog(@"[%d] titleBarRect: %f,%f %fx%f", titleBarRect.origin.x, titleBarRect.origin.y,
titleBarRect.size.width, titleBarRect.size.height);
}
NSDebugLog(@"[%d] titleBarRect: %f,%f %fx%f",
titleBarRect.origin.x, titleBarRect.origin.y,
titleBarRect.size.width, titleBarRect.size.height);
}
if (styleMask & NSResizableWindowMask) {
hasResizeBar = YES;
float padding = 10.0;
resizeBarRect = NSMakeRect(-padding, -padding, windowframe.size.width + padding * 2, resizebarHeight + padding * 2);
if (styleMask & NSResizableWindowMask)
{
hasResizeBar = YES;
float padding = 10.0;
resizeBarRect = NSMakeRect(-padding, -padding,
windowframe.size.width + padding * 2,
resizebarHeight + padding * 2);
NSDebugLog(@"[%d] resizeBarRect: %f,%f %fx%f", resizeBarRect.origin.x, resizeBarRect.origin.y,
resizeBarRect.size.width, resizeBarRect.size.height);
}
NSDebugLog(@"[%d] resizeBarRect: %f,%f %fx%f",
resizeBarRect.origin.x, resizeBarRect.origin.y,
resizeBarRect.size.width, resizeBarRect.size.height);
}
if (styleMask & NSClosableWindowMask) {
hasCloseButton = YES;
if (styleMask & NSClosableWindowMask)
{
hasCloseButton = YES;
closeButtonRect = NSMakeRect(windowframe.size.width - [theme titlebarButtonSize] -
[theme titlebarPaddingRight], windowframe.size.height -
[theme titlebarButtonSize] - [theme titlebarPaddingTop],
[theme titlebarButtonSize], [theme titlebarButtonSize]);
closeButtonRect
= NSMakeRect(windowframe.size.width - [theme titlebarButtonSize]
- [theme titlebarPaddingRight],
windowframe.size.height -
[theme titlebarButtonSize] -
[theme titlebarPaddingTop],
[theme titlebarButtonSize],
[theme titlebarButtonSize]);
}
}
if (styleMask & NSMiniaturizableWindowMask)
{
hasMiniaturizeButton = YES;
miniaturizeButtonRect = NSMakeRect([theme titlebarPaddingLeft],
windowframe.size.height -
[theme titlebarButtonSize] -
[theme titlebarPaddingTop],
[theme titlebarButtonSize],
[theme titlebarButtonSize]);
}
if (styleMask & NSMiniaturizableWindowMask) {
hasMiniaturizeButton = YES;
miniaturizeButtonRect = NSMakeRect([theme titlebarPaddingLeft], windowframe.size.height -
[theme titlebarButtonSize] - [theme titlebarPaddingTop],
[theme titlebarButtonSize], [theme titlebarButtonSize]);
}
if (hasTitleBar && !NSPointInRect(eventLocation, closeButtonRect)
&& !NSPointInRect(eventLocation, miniaturizeButtonRect)
&& NSPointInRect(eventLocation, titleBarRect))
{
NSDebugLog(@"[%d] point in titleBarRect [%f,%f] [%f,%f %fx%f]",
window->window_id, eventLocation.x, eventLocation.y,
titleBarRect.origin.x, titleBarRect.origin.y,
titleBarRect.size.width, titleBarRect.size.height);
if (hasTitleBar &&
!NSPointInRect(eventLocation, closeButtonRect) &&
!NSPointInRect(eventLocation, miniaturizeButtonRect) &&
NSPointInRect(eventLocation, titleBarRect)) {
NSDebugLog(@"[%d] point in titleBarRect [%f,%f] [%f,%f %fx%f]",
window->window_id,
eventLocation.x, eventLocation.y,
titleBarRect.origin.x, titleBarRect.origin.y,
titleBarRect.size.width, titleBarRect.size.height);
if (state == WL_POINTER_BUTTON_STATE_PRESSED)
{
xdg_toplevel_move(window->toplevel, wlconfig->seat, serial);
window->moving = YES;
return;
}
else
{
window->moving = NO;
}
}
if (hasResizeBar && NSPointInRect(eventLocation, resizeBarRect))
{
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
NSDebugLog(@"[%d] point in resizeBarRect [%f,%f] [%f,%f %fx%f]",
window->window_id, eventLocation.x, eventLocation.y,
resizeBarRect.origin.x, resizeBarRect.origin.y,
resizeBarRect.size.width, resizeBarRect.size.height);
if(state == WL_POINTER_BUTTON_STATE_PRESSED) {
xdg_toplevel_move(window->toplevel, wlconfig->seat, serial);
window->moving = YES;
return;
} else {
window->moving = NO;
if (resizeBarRect.size.width < 30 * 2
&& eventLocation.x < resizeBarRect.size.width / 2)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
}
else if (eventLocation.x > resizeBarRect.size.width - 30)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
}
else if (eventLocation.x < 29)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
}
else
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
}
}
}
if (hasResizeBar && NSPointInRect(eventLocation, resizeBarRect)) {
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
NSDebugLog(@"[%d] point in resizeBarRect [%f,%f] [%f,%f %fx%f]",
window->window_id,
eventLocation.x, eventLocation.y,
resizeBarRect.origin.x, resizeBarRect.origin.y,
resizeBarRect.size.width, resizeBarRect.size.height);
if (resizeBarRect.size.width < 30 * 2
&& eventLocation.x < resizeBarRect.size.width / 2) {
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
} else if (eventLocation.x > resizeBarRect.size.width - 30) {
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
} else if (eventLocation.x < 29) {
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
} else {
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
}
if(state == WL_POINTER_BUTTON_STATE_PRESSED) {
xdg_toplevel_resize(window->toplevel, wlconfig->seat, serial, edges);
window->resizing = YES;
return;
} else {
window->resizing = NO;
}
}
}
if (state == WL_POINTER_BUTTON_STATE_PRESSED)
{
xdg_toplevel_resize(window->toplevel, wlconfig->seat, serial,
edges);
window->resizing = YES;
return;
}
else
{
window->resizing = NO;
}
}
}
} // endif window->toplevel
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) {
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;
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)
{
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) {
switch (button)
{
case BTN_LEFT:
eventType = NSLeftMouseDown;
break;
eventType = NSLeftMouseDown;
break;
case BTN_RIGHT:
eventType = NSRightMouseDown;
break;
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?
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) {
wlconfig->pointer.serial = serial;
}
else if (state == WL_POINTER_BUTTON_STATE_RELEASED)
{
switch (button)
{
case BTN_LEFT:
eventType = NSLeftMouseUp;
break;
eventType = NSLeftMouseUp;
break;
case BTN_RIGHT:
eventType = NSRightMouseUp;
break;
eventType = NSRightMouseUp;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseUp;
break;
eventType = NSOtherMouseUp;
break;
}
wlconfig->pointer.serial = 0;
} else {
wlconfig->pointer.serial = 0;
}
else
{
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;
/* 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);
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;
/* 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.];
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];
[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)
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;
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;
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);
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
@ -369,7 +448,7 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
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)
switch (axis)
{
case WL_POINTER_AXIS_VERTICAL_SCROLL:
eventType = NSScrollWheel;
@ -379,7 +458,9 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
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);
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
@ -389,41 +470,40 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
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.];
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];
[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,
pointer_handle_enter, pointer_handle_leave, pointer_handle_motion,
pointer_handle_button, pointer_handle_axis,
};
@implementation WaylandServer(Cursor)
- (NSPoint) mouselocation
@implementation
WaylandServer (Cursor)
- (NSPoint)mouselocation
{
int aScreen = -1;
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) {
wl_list_for_each(output, &wlconfig->output_list, link)
{
aScreen = output->server_output_id;
break;
}
@ -431,133 +511,139 @@ const struct wl_pointer_listener pointer_listener = {
// No outputs in the wl_list.
return NSZeroPoint;
return [self mouseLocationOnScreen: aScreen window: NULL];
return [self mouseLocationOnScreen:aScreen window:NULL];
}
- (NSPoint) mouseLocationOnScreen: (int)aScreen window: (int *)win
- (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;
// 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 (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;
}
}
}
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;
}
}
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);
// NSDebugLog(@"mouseLocationOnScreen: returning %fx%f", x, y);
return NSMakePoint(x, y);
return NSMakePoint(x, y);
}
- (BOOL) capturemouse: (int) win
- (BOOL)capturemouse:(int)win
{
NSDebugLog(@"capturemouse: %d", win);
return NO;
NSDebugLog(@"capturemouse: %d", win);
return NO;
}
- (void) releasemouse
- (void)releasemouse
{
NSDebugLog(@"releasemouse");
NSDebugLog(@"releasemouse");
}
- (void) setMouseLocation: (NSPoint)mouseLocation onScreen: (int)aScreen
- (void)setMouseLocation:(NSPoint)mouseLocation onScreen:(int)aScreen
{
NSDebugLog(@"setMouseLocation");
NSDebugLog(@"setMouseLocation");
}
- (void) hidecursor
- (void)hidecursor
{
NSDebugLog(@"hidecursor");
NSDebugLog(@"hidecursor");
}
- (void) showcursor
- (void)showcursor
{
NSDebugLog(@"showcursor");
NSDebugLog(@"showcursor");
}
- (void) standardcursor: (int) style : (void**) cid
- (void)standardcursor:(int)style:(void **)cid
{
NSDebugLog(@"standardcursor");
NSDebugLog(@"standardcursor");
}
- (void) imagecursor: (NSPoint)hotp : (NSImage *) image : (void**) cid
- (void)imagecursor:(NSPoint)hotp:(NSImage *)image:(void **)cid
{
NSDebugLog(@"imagecursor");
NSDebugLog(@"imagecursor");
}
- (void) setcursorcolor: (NSColor *)fg : (NSColor *)bg : (void*) cid
- (void)setcursorcolor:(NSColor *)fg:(NSColor *)bg:(void *)cid
{
NSLog(@"Call to obsolete method -setcursorcolor:::");
[self recolorcursor: fg : bg : cid];
[self setcursor: cid];
NSLog(@"Call to obsolete method -setcursorcolor:::");
[self recolorcursor:fg:bg:cid];
[self setcursor:cid];
}
- (void) recolorcursor: (NSColor *)fg : (NSColor *)bg : (void*) cid
- (void)recolorcursor:(NSColor *)fg:(NSColor *)bg:(void *)cid
{
NSDebugLog(@"recolorcursor");
NSDebugLog(@"recolorcursor");
}
- (void) setcursor: (void*) cid
- (void)setcursor:(void *)cid
{
NSDebugLog(@"setcursor");
NSDebugLog(@"setcursor");
}
- (void) freecursor: (void*) cid
- (void)freecursor:(void *)cid
{
NSDebugLog(@"freecursor");
NSDebugLog(@"freecursor");
}
- (void) setIgnoreMouse: (BOOL)ignoreMouse : (int)win
- (void)setIgnoreMouse:(BOOL)ignoreMouse:(int)win
{
NSDebugLog(@"setIgnoreMouse");
NSDebugLog(@"setIgnoreMouse");
}
- (void) initializeMouseIfRequired
- (void)initializeMouseIfRequired
{
if (!_mouseInitialized)
[self initializeMouse];
}
- (void) initializeMouse
- (void)initializeMouse
{
_mouseInitialized = YES;
[self mouseOptionsChanged: nil];
[self mouseOptionsChanged:nil];
[[NSDistributedNotificationCenter defaultCenter]
addObserver: self
selector: @selector(mouseOptionsChanged:)
name: NSUserDefaultsDidChangeNotification
object: nil];
addObserver:self
selector:@selector(mouseOptionsChanged:)
name:NSUserDefaultsDidChangeNotification
object:nil];
}
- (void) mouseOptionsChanged: (NSNotification *)aNotif
- (void)mouseOptionsChanged:(NSNotification *)aNotif
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
wlconfig->mouse_scroll_multiplier = [defs integerForKey:@"GSMouseScrollMultiplier"];
wlconfig->mouse_scroll_multiplier =
[defs integerForKey:@"GSMouseScrollMultiplier"];
if (wlconfig->mouse_scroll_multiplier < 0.0001f)
wlconfig->mouse_scroll_multiplier = 1.0f;
}

View file

@ -1,3 +1,30 @@
/*
WaylandServer - Keyboard Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
@ -5,84 +32,86 @@
#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;
NSDebugLog(@"keyboard_handle_keymap");
WaylandConfig *wlconfig = data;
struct xkb_keymap *keymap;
struct xkb_state *state;
char *map_str;
if (!data) {
close(fd);
return;
if (!data)
{
close(fd);
return;
}
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
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;
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;
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);
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;
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;
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;
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");
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)
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface, struct wl_array *keys)
{
//NSDebugLog(@"keyboard_handle_enter");
// NSDebugLog(@"keyboard_handle_enter");
}
static void
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
uint32_t serial, struct wl_surface *surface)
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface)
{
//NSDebugLog(@"keyboard_handle_leave");
// NSDebugLog(@"keyboard_handle_leave");
}
static void
@ -91,102 +120,104 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{
//NSDebugLog(@"keyboard_handle_modifiers");
WaylandConfig *wlconfig = data;
xkb_mod_mask_t mask;
// 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;
/* 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;
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)
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;
// 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;
if (!window)
return;
code = 0;
if (key == 28) {
sym = NSCarriageReturnCharacter;
} else if (key == 14) {
sym = NSDeleteCharacter;
} else {
code = key + 8;
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);
num_syms = xkb_state_key_get_syms(wlconfig->xkb.state, code, &syms);
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
sym = syms[0];
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
sym = syms[0];
}
NSString *s = [NSString stringWithUTF8String: &sym];
NSEventType eventType;
NSString *s = [NSString stringWithUTF8String:&sym];
NSEventType eventType;
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
eventType = NSKeyDown;
} else {
eventType = NSKeyUp;
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];
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];
[GSCurrentServer() postEvent:ev atStart:NO];
//NSDebugLog(@"keyboard_handle_key: %@", s);
// 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");
// 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
};
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)
@implementation
WaylandServer (KeyboardOps)
@end

View file

@ -1,38 +1,65 @@
/*
WaylandServer - LayerShell Protocol Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#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) {
struct window *window = data;
NSDebugLog(@"[%d] layer_surface_configure", window->window_id);
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_configure(void *data, struct zwlr_layer_surface_v1 *surface,
uint32_t serial, uint32_t w, uint32_t h)
{
struct window *window = data;
NSDebugLog(@"[%d] layer_surface_configure", window->window_id);
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;
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,
.configure = layer_surface_configure,
.closed = layer_surface_closed,
};

View file

@ -1,96 +1,88 @@
/*
WaylandServer - Output Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#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)
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;
NSDebugLog(@"handle_geometry");
struct output *output = data;
output->alloc_x = x;
output->alloc_y = y;
output->transform = transform;
output->alloc_x = x;
output->alloc_y = y;
output->transform = transform;
if (output->make)
free(output->make);
output->make = strdup(make);
if (output->make)
free(output->make);
output->make = strdup(make);
if (output->model)
free(output->model);
output->model = strdup(model);
if (output->model)
free(output->model);
output->model = strdup(model);
}
static void
handle_done(void *data,
struct wl_output *wl_output)
handle_done(void *data, struct wl_output *wl_output)
{
NSDebugLog(@"handle_done");
NSDebugLog(@"handle_done");
}
static void
handle_scale(void *data,
struct wl_output *wl_output,
int32_t scale)
handle_scale(void *data, struct wl_output *wl_output, int32_t scale)
{
NSDebugLog(@"handle_scale");
struct output *output = data;
NSDebugLog(@"handle_scale");
struct output *output = data;
output->scale = scale;
output->scale = scale;
}
static void
handle_mode(void *data,
struct wl_output *wl_output,
uint32_t flags,
int width,
int height,
int refresh)
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;
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);
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;
}
// XXX - Should we implement this?
// if (display->output_configure_handler)
// (*display->output_configure_handler)
// (output, display->user_data);
//
}
}
*/
const struct wl_output_listener output_listener = {
handle_geometry,
handle_mode,
handle_done,
handle_scale
};
const struct wl_output_listener output_listener
= {handle_geometry, handle_mode, handle_done, handle_scale};

View file

@ -1,3 +1,30 @@
/*
WaylandServer - Seat Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
extern const struct wl_keyboard_listener keyboard_listener;
@ -8,35 +35,41 @@ static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps)
{
WaylandConfig *wlconfig = data;
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;
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);
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 ((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
@ -55,10 +88,5 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
}
const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
seat_handle_capabilities,
};
@implementation WaylandServer (Seat)
@end

View file

@ -1,3 +1,30 @@
/*
WaylandServer - XdgShell Protocol Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
@ -6,128 +33,137 @@ static void
xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial)
{
struct window *window = data;
struct window *window = data;
NSDebugLog(@"xdg_surface_on_configure: win=%d", window->window_id);
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;
if (window->terminated == YES)
{
NSDebugLog(@"deleting window win=%d", window->window_id);
free(window);
return;
}
WaylandConfig *wlconfig = window->wlconfig;
WaylandConfig *wlconfig = window->wlconfig;
NSEvent *ev = nil;
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
NSEvent *ev = nil;
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
//NSDebugLog(@"Acknowledging surface configure %p %d (window_id=%d)", xdg_surface, serial, 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;
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 (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];
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];
[nswindow sendEvent:ev];
}
}
static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states) {
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
NSDebugLog(@"[%d] xdg_toplevel_configure %ldx%ld",
window->window_id, width, height);
// the compositor can send 0.0x0.0
if(width == 0 || height == 0) {
return;
}
if(window->width != width || window->height != height) {
window->width = width;
window->height = height;
xdg_surface_set_window_geometry(window->xdg_surface,
0,
0,
window->width,
window->height);
NSEvent *ev = [NSEvent otherEventWithType: NSAppKitDefined
location: NSMakePoint(0.0, 0.0)
modifierFlags: 0
timestamp: 0
windowNumber: window->window_id
context: GSCurrentContext()
subtype: GSAppKitWindowResized
data1: window->width
data2: window->height];
[(GSWindowWithNumber(window->window_id)) sendEvent: ev];
}
NSDebugLog(@"[%d] notify resize from backend=%ldx%ld", window->window_id, width, height);
}
static void xdg_toplevel_close_handler(void *data, struct zxdg_toplevel_v6 *xdg_toplevel) {
NSDebugLog(@"xdg_toplevel_close_handler");
}
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;
NSDebugLog(@"xdg_popup_configure");
}
static void xdg_popup_done(void *data, struct xdg_popup *xdg_popup) {
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
window->terminated = YES;
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)
static void
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states)
{
NSDebugLog(@"wm_base_handle_ping");
xdg_wm_base_pong(xdg_wm_base, serial);
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
NSDebugLog(@"[%d] xdg_toplevel_configure %ldx%ld", window->window_id, width,
height);
// the compositor can send 0.0x0.0
if (width == 0 || height == 0)
{
return;
}
if (window->width != width || window->height != height)
{
window->width = width;
window->height = height;
xdg_surface_set_window_geometry(window->xdg_surface, 0, 0, window->width,
window->height);
NSEvent *ev = [NSEvent otherEventWithType:NSAppKitDefined
location:NSMakePoint(0.0, 0.0)
modifierFlags:0
timestamp:0
windowNumber:window->window_id
context:GSCurrentContext()
subtype:GSAppKitWindowResized
data1:window->width
data2:window->height];
[(GSWindowWithNumber(window->window_id)) sendEvent:ev];
}
NSDebugLog(@"[%d] notify resize from backend=%ldx%ld", window->window_id,
width, height);
}
static void
xdg_toplevel_close_handler(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
{
NSDebugLog(@"xdg_toplevel_close_handler");
}
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;
NSDebugLog(@"xdg_popup_configure");
}
static void
xdg_popup_done(void *data, struct xdg_popup *xdg_popup)
{
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
window->terminated = YES;
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)
{
NSDebugLog(@"wm_base_handle_ping");
xdg_wm_base_pong(xdg_wm_base, serial);
}
const struct xdg_surface_listener xdg_surface_listener = {
xdg_surface_on_configure,
xdg_surface_on_configure,
};
const struct xdg_wm_base_listener wm_base_listener = {
.ping = wm_base_handle_ping,
.ping = wm_base_handle_ping,
};
const struct xdg_popup_listener xdg_popup_listener = {
.configure = xdg_popup_configure,
.popup_done = xdg_popup_done,
.configure = xdg_popup_configure,
.popup_done = xdg_popup_done,
};
const struct xdg_toplevel_listener xdg_toplevel_listener = {
.configure = xdg_toplevel_configure,
.close = xdg_toplevel_close_handler,
.configure = xdg_toplevel_configure,
.close = xdg_toplevel_close_handler,
};

File diff suppressed because it is too large Load diff