mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 23:42:16 +00:00
Wayland server: code formatting
using clang-format from: https://github.com/gnustep/libs-base/blob/master/.clang-format
This commit is contained in:
parent
114743a5d0
commit
91a1479193
9 changed files with 1871 additions and 1629 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue