This commit is contained in:
Keith Bowes 2020-02-22 07:13:43 -05:00
parent 43fcf1ebf1
commit 8bc4352eb8
9 changed files with 62 additions and 124 deletions

View file

@ -6,12 +6,19 @@
#include "waybox/server.h"
enum wb_cursor_mode {
WB_CURSOR_PASSTHROUGH,
WB_CURSOR_MOVE,
WB_CURSOR_RESIZE,
};
struct wb_cursor {
struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager;
struct wb_server *server;
enum wb_cursor_mode cursor_mode;
struct wl_listener cursor_motion;
struct wl_listener cursor_motion_absolute;

View file

@ -7,21 +7,21 @@
#include "waybox/server.h"
struct wb_seat {
struct wlr_seat * seat;
struct wlr_seat *seat;
struct wl_list keyboards;
};
struct wb_keyboard {
struct wl_list link;
struct wb_server * server;
struct wlr_input_device * device;
struct wb_server *server;
struct wlr_input_device *device;
struct wl_listener modifiers;
struct wl_listener key;
};
struct wb_server;
struct wb_seat * wb_seat_create(struct wb_server * server);
void wb_seat_destroy(struct wb_seat * seat);
struct wb_seat *wb_seat_create(struct wb_server *server);
void wb_seat_destroy(struct wb_seat *seat);
#endif

View file

@ -1,14 +1,13 @@
#ifndef SERVER_H
#define SERVER_H
//#ifndef _POSIX_C_SOURCE
//#define _POSIX_C_SOURCE 200809L
//#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200112L
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <wlr/backend.h>
#include <wlr/render/wlr_renderer.h>
@ -27,24 +26,18 @@
#include "waybox/cursor.h"
#include "waybox/seat.h"
enum wb_cursor_mode {
WB_CURSOR_PASSTHROUGH,
WB_CURSOR_MOVE,
WB_CURSOR_RESIZE,
};
struct wb_server {
struct wl_display *wl_display;
struct wl_event_loop *wl_event_loop;
struct wlr_backend *backend;
struct wlr_compositor *compositor;
struct wlr_renderer *renderer;
struct wlr_output_layout *layout;
struct wb_cursor *cursor;
struct wb_seat * seat;
struct wb_seat *seat;
enum wb_cursor_mode cursor_mode;
struct wb_view *grabbed_view;
double grab_x, grab_y;
int grab_width, grab_height;

View file

@ -9,16 +9,6 @@ static void process_cursor_move(struct wb_server *server, uint32_t time) {
}
static void process_cursor_resize(struct wb_server *server, uint32_t time) {
/*
* Resizing the grabbed view can be a little bit complicated, because we
* could be resizing from any corner or edge. This not only resizes the view
* on one or two axes, but can also move the view if you resize from the top
* or left edges (or top-left corner).
*
* Note that I took some shortcuts here. In a more fleshed-out compositor,
* you'd wait for the client to prepare a buffer at the new size, then
* commit any movement that was prepared.
*/
struct wb_view *view = server->grabbed_view;
double dx = server->cursor->cursor->x - server->grab_x;
double dy = server->cursor->cursor->y - server->grab_y;
@ -51,10 +41,10 @@ static void process_cursor_resize(struct wb_server *server, uint32_t time) {
static void process_cursor_motion(struct wb_server *server, uint32_t time) {
/* If the mode is non-passthrough, delegate to those functions. */
if (server->cursor_mode == WB_CURSOR_MOVE) {
if (server->cursor->cursor_mode == WB_CURSOR_MOVE) {
process_cursor_move(server, time);
return;
} else if (server->cursor_mode == WB_CURSOR_RESIZE) {
} else if (server->cursor->cursor_mode == WB_CURSOR_RESIZE) {
process_cursor_resize(server, time);
return;
}
@ -77,10 +67,6 @@ static void process_cursor_motion(struct wb_server *server, uint32_t time) {
/*
* "Enter" the surface if necessary. This lets the client know that the
* cursor has entered one of its surfaces.
*
* Note that this gives the surface "pointer focus", which is distinct
* from keyboard focus. You get pointer focus by moving the pointer over
* a window.
*/
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
if (!focus_changed) {
@ -124,7 +110,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
cursor->server->cursor->cursor->x, cursor->server->cursor->cursor->y, &surface, &sx, &sy);
if (event->state == WLR_BUTTON_RELEASED) {
/* If you released any buttons, we exit interactive move/resize mode. */
cursor->server->cursor_mode = WB_CURSOR_PASSTHROUGH;
cursor->cursor_mode = WB_CURSOR_PASSTHROUGH;
} else {
/* Focus that client if the button was _pressed_ */
focus_view(view, surface);
@ -158,6 +144,7 @@ struct wb_cursor *wb_cursor_create() {
struct wb_cursor *cursor = malloc(sizeof(struct wb_cursor));
cursor->cursor = wlr_cursor_create();
cursor->xcursor_manager = wlr_xcursor_manager_create("default", 24);
wlr_xcursor_manager_load(cursor->xcursor_manager, 1);
cursor->cursor_motion.notify = handle_cursor_motion;
wl_signal_add(&cursor->cursor->events.motion, &cursor->cursor_motion);

View file

@ -1,17 +1,12 @@
//#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wayland-server.h>
#include <wlr/backend.h>
#include "waybox/server.h"
//struct wl_display* display = NULL;
int main(int argc, char **argv){
char *startup_cmd;
char *startup_cmd = NULL;
if (argc > 0) {
int i;
for (i = 0; i < argc; i++)
@ -35,9 +30,6 @@ int main(int argc, char **argv){
struct wb_server server = {0};
// Global display
//display = server.wl_display;
if (init_wb(&server) == false) {
printf("Failed to create backend\n");
exit(EXIT_FAILURE);
@ -50,7 +42,7 @@ int main(int argc, char **argv){
}
if (startup_cmd) {
if (fork() == 0){
if (fork() == 0) {
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
}
}

View file

@ -1,4 +1,4 @@
#include <waybox/output.h>
#include "waybox/output.h"
struct render_data {
struct wlr_output *output;
@ -33,7 +33,7 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy, void *da
ox += view->x + sx, oy += view->y + sy;
/* We also have to apply the scale factor for HiDPI outputs. This is only
* part of the puzzle, TinyWL does not fully support HiDPI. */
* part of the puzzle, Waybox does not fully support HiDPI. */
struct wlr_box box = {
.x = ox * output->scale,
.y = oy * output->scale,
@ -42,7 +42,7 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy, void *da
};
/*
* Those familiar with OpenGL are also familiar with the role of matricies
* Those familiar with OpenGL are also familiar with the role of matrices
* in graphics programming. We need to prepare a matrix to render the view
* with. wlr_matrix_project_box is a helper which takes a box with a desired
* x, y coordinates, width and height, and an output geometry, then
@ -67,11 +67,8 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy, void *da
wlr_surface_send_frame_done(surface, rdata->when);
}
void output_frame_notify(struct wl_listener *listener, void *data) {
struct wb_output *output = wl_container_of(listener, output, frame);
// struct wlr_backend *backend = output->server->backend;
struct wlr_output *wlr_output = data;
struct wlr_renderer *renderer = wlr_backend_get_renderer(
wlr_output->backend);
@ -106,25 +103,6 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
wlr_xdg_surface_for_each_surface(view->xdg_surface, render_surface, &rdata);
}
/*struct wl_resource *_surface;
wl_resource_for_each(_surface, &output->server->compositor->surface_resources) {
struct wlr_surface *surface = wlr_surface_from_resource(_surface);
if (!wlr_surface_has_buffer(surface)) {
continue;
}
struct wlr_box render_box = {
.x = 20, .y = 20,
.width = surface->current.width,
.height = surface->current.height
};
float matrix[16];
wlr_matrix_project_box(matrix, &render_box, surface->current.transform,
0, wlr_output->transform_matrix);
struct wlr_texture *texture = wlr_surface_get_texture(surface);
wlr_render_texture_with_matrix(renderer, texture, matrix, 1.0f);
wlr_surface_send_frame_done(surface, &now);
}*/
wlr_renderer_end(renderer);
wlr_output_commit(wlr_output);
output->last_frame = now;
@ -153,7 +131,6 @@ void new_output_notify(struct wl_listener *listener, void *data) {
if (!wlr_output_commit(wlr_output)) {
return;
}
//wlr_output_create_global(wlr_output);
}
struct wb_output *output = calloc(1, sizeof(struct wb_output));
@ -169,6 +146,4 @@ void new_output_notify(struct wl_listener *listener, void *data) {
wlr_output_layout_add_auto(server->layout, wlr_output);
wlr_output_create_global(wlr_output);
wlr_xcursor_manager_load(server->cursor->xcursor_manager, output->wlr_output->scale);
wlr_xcursor_manager_set_cursor_image(server->cursor->xcursor_manager, "left_ptr", server->cursor->cursor);
}

View file

@ -3,14 +3,11 @@
#include "waybox/seat.h"
#include "waybox/xdg_shell.h"
/* Stolen from wltiny. Customizations will come later. */
static bool handle_keybinding(struct wb_server *server, xkb_keysym_t sym, uint32_t modifiers) {
/*
* Here we handle compositor keybindings. This is when the compositor is
* processing keys, rather than passing them on to the client for its own
* processing.
*
* This function assumes Alt is held down.
*/
if (modifiers & WLR_MODIFIER_CTRL && sym == XKB_KEY_Escape) {
@ -92,7 +89,7 @@ static void keyboard_handle_key(
}
}
static void server_new_keyboard(struct wb_server *server,
static void handle_new_keyboard(struct wb_server *server,
struct wlr_input_device *device) {
struct wb_keyboard *keyboard =
calloc(1, sizeof(struct wb_keyboard));
@ -133,7 +130,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
struct wb_server *server = wl_container_of(listener, server, new_input);
switch (device->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
server_new_keyboard(server, device);
handle_new_keyboard(server, device);
break;
case WLR_INPUT_DEVICE_POINTER:
wlr_cursor_attach_input_device(server->cursor->cursor, device);
@ -149,8 +146,8 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
wlr_seat_set_capabilities(server->seat->seat, caps);
}
struct wb_seat * wb_seat_create(struct wb_server * server) {
struct wb_seat * seat = malloc(sizeof(struct wb_seat));
struct wb_seat *wb_seat_create(struct wb_server *server) {
struct wb_seat *seat = malloc(sizeof(struct wb_seat));
wl_list_init(&seat->keyboards);
server->new_input.notify = new_input_notify;
@ -160,7 +157,7 @@ struct wb_seat * wb_seat_create(struct wb_server * server) {
return seat;
}
void wb_seat_destroy(struct wb_seat * seat) {
void wb_seat_destroy(struct wb_seat *seat) {
wlr_seat_destroy(seat->seat);
free(seat);
}

View file

@ -1,28 +1,26 @@
#define _POSIX_C_SOURCE 200112L
#include "waybox/seat.h"
#include "waybox/server.h"
#include "waybox/xdg_shell.h"
bool init_wb(struct wb_server* server) {
// create display
server->wl_display = wl_display_create();
// create display
server->wl_display = wl_display_create();
assert(server->wl_display);
// create shared memory
wl_display_init_shm(server->wl_display);
// event loop stuff
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
// event loop stuff
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
assert(server->wl_event_loop);
// create backend
// create backend
server->backend = wlr_backend_autocreate(server->wl_display, NULL);
assert(server->backend);
if(server->backend == NULL){
printf("Failed to create backend\n");
return false;
}
if (server->backend == NULL) {
printf("Failed to create backend\n");
return false;
}
server->renderer = wlr_backend_get_renderer(server->backend);
wlr_renderer_init_wl_display(server->renderer, server->wl_display);
server->layout = wlr_output_layout_create();
server->cursor = wb_cursor_create();
@ -30,52 +28,48 @@ bool init_wb(struct wb_server* server) {
wlr_cursor_attach_output_layout(server->cursor->cursor, server->layout);
server->seat = wb_seat_create(server);
return true;
return true;
}
bool start_wb(struct wb_server* server) {
wl_list_init(&server->outputs);
wl_list_init(&server->outputs);
server->new_output.notify = new_output_notify;
wl_signal_add(&server->backend->events.new_output, &server->new_output);
//server->new_input.notify = new_input_notify;
//wl_signal_add(&server->backend->events.new_input, &server->new_input);
const char *socket = wl_display_add_socket_auto(server->wl_display);
assert(socket);
if (!wlr_backend_start(server->backend)) {
if (!wlr_backend_start(server->backend)) {
fprintf(stderr, "Failed to start backend\n");
wl_display_destroy(server->wl_display);
return false;
}
printf("Running Wayland compositor on Wayland display '%s'\n", socket);
setenv("WAYLAND_DISPLAY", socket, true);
printf("Running Wayland compositor on Wayland display '%s'\n", socket);
setenv("WAYLAND_DISPLAY", socket, true);
wlr_gamma_control_manager_v1_create(server->wl_display);
wlr_gamma_control_manager_v1_create(server->wl_display);
wlr_screencopy_manager_v1_create(server->wl_display);
wlr_gtk_primary_selection_device_manager_create(server->wl_display);
wlr_idle_create(server->wl_display);
server->compositor = wlr_compositor_create(server->wl_display,
wlr_backend_get_renderer(server->backend));
server->renderer);
wlr_data_device_manager_create(server->wl_display);
wl_list_init(&server->views);
init_xdg_shell(server);
//wlr_idle_create(server->wl_display);
return true;
return true;
}
bool terminate_wb(struct wb_server* server) {
wb_cursor_destroy(server->cursor);
wb_seat_destroy(server->seat);
wlr_output_layout_destroy(server->layout);
wl_display_destroy(server->wl_display);
wl_display_destroy(server->wl_display);
printf("Display destroyed.\n");
printf("Display destroyed.\n");
return true;
}

View file

@ -65,7 +65,7 @@ static void xdg_surface_destroy(struct wl_listener *listener, void *data) {
static void begin_interactive(struct wb_view *view,
enum wb_cursor_mode mode, uint32_t edges) {
/* This function sets up an interactive move or resize operation, where the
* compositor stops propegating pointer events to clients and instead
* compositor stops propagating pointer events to clients and instead
* consumes them itself, to move or resize windows. */
struct wb_server *server = view->server;
struct wlr_surface *focused_surface =
@ -75,7 +75,7 @@ static void begin_interactive(struct wb_view *view,
return;
}
server->grabbed_view = view;
server->cursor_mode = mode;
server->cursor->cursor_mode = mode;
struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
if (mode == WB_CURSOR_MOVE) {
@ -94,9 +94,7 @@ static void xdg_toplevel_request_move(
struct wl_listener *listener, void *data) {
/* This event is raised when a client would like to begin an interactive
* move, typically because the user clicked on their client-side
* decorations. Note that a more sophisticated compositor should check the
* provied serial against a list of button press serials sent to this
* client, to prevent the client from requesting this whenever they want. */
* decorations. */
struct wb_view *view = wl_container_of(listener, view, request_move);
begin_interactive(view, WB_CURSOR_MOVE, 0);
}
@ -105,15 +103,13 @@ static void xdg_toplevel_request_resize(
struct wl_listener *listener, void *data) {
/* This event is raised when a client would like to begin an interactive
* resize, typically because the user clicked on their client-side
* decorations. Note that a more sophisticated compositor should check the
* provied serial against a list of button press serials sent to this
* client, to prevent the client from requesting this whenever they want. */
* decorations. */
struct wlr_xdg_toplevel_resize_event *event = data;
struct wb_view *view = wl_container_of(listener, view, request_resize);
begin_interactive(view, WB_CURSOR_RESIZE, event->edges);
}
static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
static void handle_new_xdg_surface(struct wl_listener *listener, void *data) {
/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
* client, either a toplevel (application window) or popup. */
struct wb_server *server =
@ -123,7 +119,7 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
return;
}
/* Allocate a tinywl_view for this surface */
/* Allocate a wb_view for this surface */
struct wb_view *view =
calloc(1, sizeof(struct wb_view));
view->server = server;
@ -137,7 +133,6 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
view->destroy.notify = xdg_surface_destroy;
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
/* cotd */
struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel;
view->request_move.notify = xdg_toplevel_request_move;
wl_signal_add(&toplevel->events.request_move, &view->request_move);
@ -161,8 +156,6 @@ bool view_at(struct wb_view *view,
double view_sx = lx - view->x;
double view_sy = ly - view->y;
//struct wlr_surface_state *state = &view->xdg_surface->surface->current;
double _sx, _sy;
struct wlr_surface *_surface = NULL;
_surface = wlr_xdg_surface_surface_at(
@ -194,6 +187,6 @@ struct wb_view *desktop_view_at(
void init_xdg_shell(struct wb_server *server) {
server->xdg_shell = wlr_xdg_shell_create(server->wl_display);
server->new_xdg_surface.notify = server_new_xdg_surface;
server->new_xdg_surface.notify = handle_new_xdg_surface;
wl_signal_add(&server->xdg_shell->events.new_surface, &server->new_xdg_surface);
}