logo

inaban

Unnamed repository; edit this file 'description' to name the repository.
commit: 69360ac7ec8c213186d52a66cb412fa784b40fa2
parent: 539e8d045995258d3aba6619bd2809e65c811ca8
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Mon,  1 Jul 2019 06:21:26 +0200

make format

Diffstat:

Minaban.c541++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
1 file changed, 305 insertions(+), 236 deletions(-)

diff --git a/inaban.c b/inaban.c @@ -2,15 +2,15 @@ #define _POSIX_C_SOURCE 200112L #include <getopt.h> #include <stdbool.h> -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> #include <time.h> #include <unistd.h> #include <wayland-server.h> #include <wlr/backend.h> #include <wlr/render/wlr_renderer.h> -#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_compositor.h> +#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_keyboard.h> @@ -25,13 +25,15 @@ #include <xkbcommon/xkbcommon.h> /* For brevity's sake, struct members are annotated where they are used. */ -enum inaban_cursor_mode { +enum inaban_cursor_mode +{ INABAN_CURSOR_PASSTHROUGH, INABAN_CURSOR_MOVE, INABAN_CURSOR_RESIZE, }; -struct inaban_server { +struct inaban_server +{ struct wl_display *wl_display; struct wlr_backend *backend; struct wlr_renderer *renderer; @@ -63,14 +65,16 @@ struct inaban_server { struct wl_listener new_output; }; -struct inaban_output { +struct inaban_output +{ struct wl_list link; struct inaban_server *server; struct wlr_output *wlr_output; struct wl_listener frame; }; -struct inaban_view { +struct inaban_view +{ struct wl_list link; struct inaban_server *server; struct wlr_xdg_surface *xdg_surface; @@ -83,7 +87,8 @@ struct inaban_view { int x, y; }; -struct inaban_keyboard { +struct inaban_keyboard +{ struct wl_list link; struct inaban_server *server; struct wlr_input_device *device; @@ -92,26 +97,31 @@ struct inaban_keyboard { struct wl_listener key; }; -static void focus_view(struct inaban_view *view, struct wlr_surface *surface) { +static void +focus_view(struct inaban_view *view, struct wlr_surface *surface) +{ /* Note: this function only deals with keyboard focus. */ - if (view == NULL) { + if(view == NULL) + { return; } - struct inaban_server *server = view->server; - struct wlr_seat *seat = server->seat; + struct inaban_server *server = view->server; + struct wlr_seat *seat = server->seat; struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface; - if (prev_surface == surface) { + if(prev_surface == surface) + { /* Don't re-focus an already focused surface. */ return; } - if (prev_surface) { + if(prev_surface) + { /* * Deactivate the previously focused surface. This lets the client know * it no longer has focus and the client will repaint accordingly, e.g. * stop displaying a caret. */ - struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface( - seat->keyboard_state.focused_surface); + struct wlr_xdg_surface *previous = + wlr_xdg_surface_from_wlr_surface(seat->keyboard_state.focused_surface); wlr_xdg_toplevel_set_activated(previous, false); } struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); @@ -125,16 +135,19 @@ static void focus_view(struct inaban_view *view, struct wlr_surface *surface) { * track of this and automatically send key events to the appropriate * clients without additional work on your part. */ - wlr_seat_keyboard_notify_enter(seat, view->xdg_surface->surface, - keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); + wlr_seat_keyboard_notify_enter(seat, + view->xdg_surface->surface, + keyboard->keycodes, + keyboard->num_keycodes, + &keyboard->modifiers); } -static void keyboard_handle_modifiers( - struct wl_listener *listener, void *data) { +static void +keyboard_handle_modifiers(struct wl_listener *listener, void *data) +{ /* This event is raised when a modifier key, such as shift or alt, is * pressed. We simply communicate this to the client. */ - struct inaban_keyboard *keyboard = - wl_container_of(listener, keyboard, modifiers); + struct inaban_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers); /* * A seat can only have one keyboard, but this is a limitation of the * Wayland protocol - not wlroots. We assign all connected keyboards to the @@ -144,10 +157,12 @@ static void keyboard_handle_modifiers( wlr_seat_set_keyboard(keyboard->server->seat, keyboard->device); /* Send modifiers to the client. */ wlr_seat_keyboard_notify_modifiers(keyboard->server->seat, - &keyboard->device->keyboard->modifiers); + &keyboard->device->keyboard->modifiers); } -static bool handle_keybinding(struct inaban_server *server, xkb_keysym_t sym) { +static bool +handle_keybinding(struct inaban_server *server, xkb_keysym_t sym) +{ /* * Here we handle compositor keybindings. This is when the compositor is * processing keys, rather than passing them on to the client for its own @@ -155,77 +170,74 @@ static bool handle_keybinding(struct inaban_server *server, xkb_keysym_t sym) { * * This function assumes Alt is held down. */ - switch (sym) { - case XKB_KEY_Escape: - wl_display_terminate(server->wl_display); - break; + switch(sym) + { + case XKB_KEY_Escape: wl_display_terminate(server->wl_display); break; case XKB_KEY_F1: /* Cycle to the next view */ - if (wl_list_length(&server->views) < 2) { + if(wl_list_length(&server->views) < 2) + { break; } - struct inaban_view *current_view = wl_container_of( - server->views.next, current_view, link); - struct inaban_view *next_view = wl_container_of( - current_view->link.next, next_view, link); + struct inaban_view *current_view = wl_container_of(server->views.next, current_view, link); + struct inaban_view *next_view = wl_container_of(current_view->link.next, next_view, link); focus_view(next_view, next_view->xdg_surface->surface); /* Move the previous view to the end of the list */ wl_list_remove(&current_view->link); wl_list_insert(server->views.prev, &current_view->link); break; - default: - return false; + default: return false; } return true; } -static void keyboard_handle_key( - struct wl_listener *listener, void *data) { +static void +keyboard_handle_key(struct wl_listener *listener, void *data) +{ /* This event is raised when a key is pressed or released. */ - struct inaban_keyboard *keyboard = - wl_container_of(listener, keyboard, key); - struct inaban_server *server = keyboard->server; + struct inaban_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct inaban_server *server = keyboard->server; struct wlr_event_keyboard_key *event = data; - struct wlr_seat *seat = server->seat; + struct wlr_seat *seat = server->seat; /* Translate libinput keycode -> xkbcommon */ uint32_t keycode = event->keycode + 8; /* Get a list of keysyms based on the keymap for this keyboard */ const xkb_keysym_t *syms; - int nsyms = xkb_state_key_get_syms( - keyboard->device->keyboard->xkb_state, keycode, &syms); + int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); - bool handled = false; + bool handled = false; uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if ((modifiers & WLR_MODIFIER_ALT) && event->state == WLR_KEY_PRESSED) { + if((modifiers & WLR_MODIFIER_ALT) && event->state == WLR_KEY_PRESSED) + { /* If alt is held down and this button was _pressed_, we attempt to * process it as a compositor keybinding. */ - for (int i = 0; i < nsyms; i++) { + for(int i = 0; i < nsyms; i++) + { handled = handle_keybinding(server, syms[i]); } } - if (!handled) { + if(!handled) + { /* Otherwise, we pass it along to the client. */ wlr_seat_set_keyboard(seat, keyboard->device); - wlr_seat_keyboard_notify_key(seat, event->time_msec, - event->keycode, event->state); + wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, event->state); } } -static void server_new_keyboard(struct inaban_server *server, - struct wlr_input_device *device) { - struct inaban_keyboard *keyboard = - calloc(1, sizeof(struct inaban_keyboard)); - keyboard->server = server; - keyboard->device = device; +static void +server_new_keyboard(struct inaban_server *server, struct wlr_input_device *device) +{ + struct inaban_keyboard *keyboard = calloc(1, sizeof(struct inaban_keyboard)); + keyboard->server = server; + keyboard->device = device; /* We need to prepare an XKB keymap and assign it to the keyboard. This * assumes the defaults (e.g. layout = "us"). */ - struct xkb_rule_names rules = { 0 }; + struct xkb_rule_names rules = {0}; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, - XKB_KEYMAP_COMPILE_NO_FLAGS); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); wlr_keyboard_set_keymap(device->keyboard, keymap); xkb_keymap_unref(keymap); @@ -244,8 +256,9 @@ static void server_new_keyboard(struct inaban_server *server, wl_list_insert(&server->keyboards, &keyboard->link); } -static void server_new_pointer(struct inaban_server *server, - struct wlr_input_device *device) { +static void +server_new_pointer(struct inaban_server *server, struct wlr_input_device *device) +{ /* We don't do anything special with pointers. All of our pointer handling * is proxied through wlr_cursor. On another compositor, you might take this * opportunity to do libinput configuration on the device to set @@ -253,54 +266,57 @@ static void server_new_pointer(struct inaban_server *server, wlr_cursor_attach_input_device(server->cursor, device); } -static void server_new_input(struct wl_listener *listener, void *data) { +static void +server_new_input(struct wl_listener *listener, void *data) +{ /* This event is raised by the backend when a new input device becomes * available. */ - struct inaban_server *server = - wl_container_of(listener, server, new_input); + struct inaban_server *server = wl_container_of(listener, server, new_input); struct wlr_input_device *device = data; - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - server_new_keyboard(server, device); - break; - case WLR_INPUT_DEVICE_POINTER: - server_new_pointer(server, device); - break; - default: - break; + switch(device->type) + { + case WLR_INPUT_DEVICE_KEYBOARD: server_new_keyboard(server, device); break; + case WLR_INPUT_DEVICE_POINTER: server_new_pointer(server, device); break; + default: break; } /* We need to let the wlr_seat know what our capabilities are, which is * communiciated to the client. In TinyWL we always have a cursor, even if * there are no pointer devices, so we always include that capability. */ uint32_t caps = WL_SEAT_CAPABILITY_POINTER; - if (!wl_list_empty(&server->keyboards)) { + if(!wl_list_empty(&server->keyboards)) + { caps |= WL_SEAT_CAPABILITY_KEYBOARD; } wlr_seat_set_capabilities(server->seat, caps); } -static void seat_request_cursor(struct wl_listener *listener, void *data) { - struct inaban_server *server = wl_container_of( - listener, server, request_cursor); +static void +seat_request_cursor(struct wl_listener *listener, void *data) +{ + struct inaban_server *server = wl_container_of(listener, server, request_cursor); /* This event is rasied by the seat when a client provides a cursor image */ struct wlr_seat_pointer_request_set_cursor_event *event = data; - struct wlr_seat_client *focused_client = - server->seat->pointer_state.focused_client; + struct wlr_seat_client *focused_client = server->seat->pointer_state.focused_client; /* This can be sent by any client, so we check to make sure this one is * actually has pointer focus first. */ - if (focused_client == event->seat_client) { + if(focused_client == event->seat_client) + { /* Once we've vetted the client, we can tell the cursor to use the * provided surface as the cursor image. It will set the hardware cursor * on the output that it's currently on and continue to do so as the * cursor moves between outputs. */ - wlr_cursor_set_surface(server->cursor, event->surface, - event->hotspot_x, event->hotspot_y); + wlr_cursor_set_surface(server->cursor, event->surface, event->hotspot_x, event->hotspot_y); } } -static bool view_at(struct inaban_view *view, - double lx, double ly, struct wlr_surface **surface, - double *sx, double *sy) { +static bool +view_at(struct inaban_view *view, + double lx, + double ly, + struct wlr_surface **surface, + double *sx, + double *sy) +{ /* * XDG toplevels may have nested surfaces, such as popup windows for context * menus or tooltips. This function tests if any of those are underneath the @@ -315,12 +331,12 @@ static bool view_at(struct inaban_view *view, double _sx, _sy; struct wlr_surface *_surface = NULL; - _surface = wlr_xdg_surface_surface_at( - view->xdg_surface, view_sx, view_sy, &_sx, &_sy); + _surface = wlr_xdg_surface_surface_at(view->xdg_surface, view_sx, view_sy, &_sx, &_sy); - if (_surface != NULL) { - *sx = _sx; - *sy = _sy; + if(_surface != NULL) + { + *sx = _sx; + *sy = _sy; *surface = _surface; return true; } @@ -328,27 +344,38 @@ static bool view_at(struct inaban_view *view, return false; } -static struct inaban_view *desktop_view_at( - struct inaban_server *server, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { +static struct inaban_view * +desktop_view_at(struct inaban_server *server, + double lx, + double ly, + struct wlr_surface **surface, + double *sx, + double *sy) +{ /* This iterates over all of our surfaces and attempts to find one under the * cursor. This relies on server->views being ordered from top-to-bottom. */ struct inaban_view *view; - wl_list_for_each(view, &server->views, link) { - if (view_at(view, lx, ly, surface, sx, sy)) { + wl_list_for_each(view, &server->views, link) + { + if(view_at(view, lx, ly, surface, sx, sy)) + { return view; } } return NULL; } -static void process_cursor_move(struct inaban_server *server, uint32_t time) { +static void +process_cursor_move(struct inaban_server *server, uint32_t time) +{ /* Move the grabbed view to the new position. */ server->grabbed_view->x = server->cursor->x - server->grab_x; server->grabbed_view->y = server->cursor->y - server->grab_y; } -static void process_cursor_resize(struct inaban_server *server, uint32_t time) { +static void +process_cursor_resize(struct inaban_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 @@ -360,28 +387,36 @@ static void process_cursor_resize(struct inaban_server *server, uint32_t time) { * commit any movement that was prepared. */ struct inaban_view *view = server->grabbed_view; - double dx = server->cursor->x - server->grab_x; - double dy = server->cursor->y - server->grab_y; - double x = view->x; - double y = view->y; - int width = server->grab_width; - int height = server->grab_height; - if (server->resize_edges & WLR_EDGE_TOP) { + double dx = server->cursor->x - server->grab_x; + double dy = server->cursor->y - server->grab_y; + double x = view->x; + double y = view->y; + int width = server->grab_width; + int height = server->grab_height; + if(server->resize_edges & WLR_EDGE_TOP) + { y = server->grab_y + dy; height -= dy; - if (height < 1) { + if(height < 1) + { y += height; } - } else if (server->resize_edges & WLR_EDGE_BOTTOM) { + } + else if(server->resize_edges & WLR_EDGE_BOTTOM) + { height += dy; } - if (server->resize_edges & WLR_EDGE_LEFT) { + if(server->resize_edges & WLR_EDGE_LEFT) + { x = server->grab_x + dx; width -= dx; - if (width < 1) { + if(width < 1) + { x += width; } - } else if (server->resize_edges & WLR_EDGE_RIGHT) { + } + else if(server->resize_edges & WLR_EDGE_RIGHT) + { width += dx; } view->x = x; @@ -389,30 +424,36 @@ static void process_cursor_resize(struct inaban_server *server, uint32_t time) { wlr_xdg_toplevel_set_size(view->xdg_surface, width, height); } -static void process_cursor_motion(struct inaban_server *server, uint32_t time) { +static void +process_cursor_motion(struct inaban_server *server, uint32_t time) +{ /* If the mode is non-passthrough, delegate to those functions. */ - if (server->cursor_mode == INABAN_CURSOR_MOVE) { + if(server->cursor_mode == INABAN_CURSOR_MOVE) + { process_cursor_move(server, time); return; - } else if (server->cursor_mode == INABAN_CURSOR_RESIZE) { + } + else if(server->cursor_mode == INABAN_CURSOR_RESIZE) + { process_cursor_resize(server, time); return; } /* Otherwise, find the view under the pointer and send the event along. */ double sx, sy; - struct wlr_seat *seat = server->seat; + struct wlr_seat *seat = server->seat; struct wlr_surface *surface = NULL; - struct inaban_view *view = desktop_view_at(server, - server->cursor->x, server->cursor->y, &surface, &sx, &sy); - if (!view) { + struct inaban_view *view = + desktop_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + if(!view) + { /* If there's no view under the cursor, set the cursor image to a * default. This is what makes the cursor image appear when you move it * around the screen, not over any views. */ - wlr_xcursor_manager_set_cursor_image( - server->cursor_mgr, "left_ptr", server->cursor); + wlr_xcursor_manager_set_cursor_image(server->cursor_mgr, "left_ptr", server->cursor); } - if (surface) { + if(surface) + { bool focus_changed = seat->pointer_state.focused_surface != surface; /* * "Enter" the surface if necessary. This lets the client know that the @@ -423,109 +464,122 @@ static void process_cursor_motion(struct inaban_server *server, uint32_t time) { * a window. */ wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - if (!focus_changed) { + if(!focus_changed) + { /* The enter event contains coordinates, so we only need to notify * on motion if the focus did not change. */ wlr_seat_pointer_notify_motion(seat, time, sx, sy); } - } else { + } + else + { /* Clear pointer focus so future button events and such are not sent to * the last client to have the cursor over it. */ wlr_seat_pointer_clear_focus(seat); } } -static void server_cursor_motion(struct wl_listener *listener, void *data) { +static void +server_cursor_motion(struct wl_listener *listener, void *data) +{ /* This event is forwarded by the cursor when a pointer emits a _relative_ * pointer motion event (i.e. a delta) */ - struct inaban_server *server = - wl_container_of(listener, server, cursor_motion); + struct inaban_server *server = wl_container_of(listener, server, cursor_motion); struct wlr_event_pointer_motion *event = data; /* The cursor doesn't move unless we tell it to. The cursor automatically * handles constraining the motion to the output layout, as well as any * special configuration applied for the specific input device which * generated the event. You can pass NULL for the device if you want to move * the cursor around without any input. */ - wlr_cursor_move(server->cursor, event->device, - event->delta_x, event->delta_y); + wlr_cursor_move(server->cursor, event->device, event->delta_x, event->delta_y); process_cursor_motion(server, event->time_msec); } -static void server_cursor_motion_absolute( - struct wl_listener *listener, void *data) { +static void +server_cursor_motion_absolute(struct wl_listener *listener, void *data) +{ /* This event is forwarded by the cursor when a pointer emits an _absolute_ * motion event, from 0..1 on each axis. This happens, for example, when * wlroots is running under a Wayland window rather than KMS+DRM, and you * move the mouse over the window. You could enter the window from any edge, * so we have to warp the mouse there. There is also some hardware which * emits these events. */ - struct inaban_server *server = - wl_container_of(listener, server, cursor_motion_absolute); + struct inaban_server *server = wl_container_of(listener, server, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; wlr_cursor_warp_absolute(server->cursor, event->device, event->x, event->y); process_cursor_motion(server, event->time_msec); } -static void server_cursor_button(struct wl_listener *listener, void *data) { +static void +server_cursor_button(struct wl_listener *listener, void *data) +{ /* This event is forwarded by the cursor when a pointer emits a button * event. */ - struct inaban_server *server = - wl_container_of(listener, server, cursor_button); + struct inaban_server *server = wl_container_of(listener, server, cursor_button); struct wlr_event_pointer_button *event = data; /* Notify the client with pointer focus that a button press has occurred */ - wlr_seat_pointer_notify_button(server->seat, - event->time_msec, event->button, event->state); + wlr_seat_pointer_notify_button(server->seat, event->time_msec, event->button, event->state); double sx, sy; struct wlr_seat *seat = server->seat; struct wlr_surface *surface; - struct inaban_view *view = desktop_view_at(server, - server->cursor->x, server->cursor->y, &surface, &sx, &sy); - if (event->state == WLR_BUTTON_RELEASED) { + struct inaban_view *view = + desktop_view_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy); + if(event->state == WLR_BUTTON_RELEASED) + { /* If you released any buttons, we exit interactive move/resize mode. */ server->cursor_mode = INABAN_CURSOR_PASSTHROUGH; - } else { + } + else + { /* Focus that client if the button was _pressed_ */ focus_view(view, surface); } } -static void server_cursor_axis(struct wl_listener *listener, void *data) { +static void +server_cursor_axis(struct wl_listener *listener, void *data) +{ /* This event is forwarded by the cursor when a pointer emits an axis event, * for example when you move the scroll wheel. */ - struct inaban_server *server = - wl_container_of(listener, server, cursor_axis); + struct inaban_server *server = wl_container_of(listener, server, cursor_axis); struct wlr_event_pointer_axis *event = data; /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(server->seat, - event->time_msec, event->orientation, event->delta, - event->delta_discrete, event->source); + event->time_msec, + event->orientation, + event->delta, + event->delta_discrete, + event->source); } -static void server_cursor_frame(struct wl_listener *listener, void *data) { +static void +server_cursor_frame(struct wl_listener *listener, void *data) +{ /* This event is forwarded by the cursor when a pointer emits an frame * event. Frame events are sent after regular pointer events to group * multiple events together. For instance, two axis events may happen at the * same time, in which case a frame event won't be sent in between. */ - struct inaban_server *server = - wl_container_of(listener, server, cursor_frame); + struct inaban_server *server = wl_container_of(listener, server, cursor_frame); /* Notify the client with pointer focus of the frame event. */ wlr_seat_pointer_notify_frame(server->seat); } /* Used to move all of the data necessary to render a surface from the top-level * frame handler to the per-surface render function. */ -struct render_data { +struct render_data +{ struct wlr_output *output; struct wlr_renderer *renderer; struct inaban_view *view; struct timespec *when; }; -static void render_surface(struct wlr_surface *surface, - int sx, int sy, void *data) { +static void +render_surface(struct wlr_surface *surface, int sx, int sy, void *data) +{ /* This function is called for every surface that needs to be rendered. */ struct render_data *rdata = data; - struct inaban_view *view = rdata->view; + struct inaban_view *view = rdata->view; struct wlr_output *output = rdata->output; /* We first obtain a wlr_texture, which is a GPU resource. wlroots @@ -534,7 +588,8 @@ static void render_surface(struct wlr_surface *surface, * could have sent a pixel buffer which we copied to the GPU, or a few other * means. You don't have to worry about this, wlroots takes care of it. */ struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (texture == NULL) { + if(texture == NULL) + { return; } @@ -543,17 +598,16 @@ static void render_surface(struct wlr_surface *surface, * have layout coordinates of 2000,100. We need to translate that to * output-local coordinates, or (2000 - 1920). */ double ox = 0, oy = 0; - wlr_output_layout_output_coords( - view->server->output_layout, output, &ox, &oy); + wlr_output_layout_output_coords(view->server->output_layout, output, &ox, &oy); 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. */ struct wlr_box box = { - .x = ox * output->scale, - .y = oy * output->scale, - .width = surface->current.width * output->scale, - .height = surface->current.height * output->scale, + .x = ox * output->scale, + .y = oy * output->scale, + .width = surface->current.width * output->scale, + .height = surface->current.height * output->scale, }; /* @@ -568,10 +622,8 @@ static void render_surface(struct wlr_surface *surface, * compositor. */ float matrix[9]; - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, &box, transform, 0, - output->transform_matrix); + enum wl_output_transform transform = wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, 0, output->transform_matrix); /* This takes our matrix, the texture, and an alpha, and performs the actual * rendering on the GPU. */ @@ -582,18 +634,20 @@ static void render_surface(struct wlr_surface *surface, wlr_surface_send_frame_done(surface, rdata->when); } -static void output_frame(struct wl_listener *listener, void *data) { +static void +output_frame(struct wl_listener *listener, void *data) +{ /* This function is called every time an output is ready to display a frame, * generally at the output's refresh rate (e.g. 60Hz). */ - struct inaban_output *output = - wl_container_of(listener, output, frame); + struct inaban_output *output = wl_container_of(listener, output, frame); struct wlr_renderer *renderer = output->server->renderer; struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); /* wlr_output_attach_render makes the OpenGL context current. */ - if (!wlr_output_attach_render(output->wlr_output, NULL)) { + if(!wlr_output_attach_render(output->wlr_output, NULL)) + { return; } /* The "effective" resolution can change if you rotate your outputs. */ @@ -608,21 +662,22 @@ static void output_frame(struct wl_listener *listener, void *data) { /* Each subsequent window we render is rendered on top of the last. Because * our view list is ordered front-to-back, we iterate over it backwards. */ struct inaban_view *view; - wl_list_for_each_reverse(view, &output->server->views, link) { - if (!view->mapped) { + wl_list_for_each_reverse(view, &output->server->views, link) + { + if(!view->mapped) + { /* An unmapped view should not be rendered. */ continue; } struct render_data rdata = { - .output = output->wlr_output, - .view = view, - .renderer = renderer, - .when = &now, + .output = output->wlr_output, + .view = view, + .renderer = renderer, + .when = &now, }; /* This calls our render_surface function for each surface among the * xdg_surface's toplevel and popups. */ - wlr_xdg_surface_for_each_surface(view->xdg_surface, - render_surface, &rdata); + wlr_xdg_surface_for_each_surface(view->xdg_surface, render_surface, &rdata); } /* Hardware cursors are rendered by the GPU on a separate plane, and can be @@ -639,11 +694,12 @@ static void output_frame(struct wl_listener *listener, void *data) { wlr_output_commit(output->wlr_output); } -static void server_new_output(struct wl_listener *listener, void *data) { +static void +server_new_output(struct wl_listener *listener, void *data) +{ /* This event is rasied by the backend when a new output (aka a display or * monitor) becomes available. */ - struct inaban_server *server = - wl_container_of(listener, server, new_output); + struct inaban_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; /* Some backends don't have modes. DRM+KMS does, and we need to set a mode @@ -651,17 +707,16 @@ static void server_new_output(struct wl_listener *listener, void *data) { * refresh rate), and each monitor supports only a specific set of modes. We * just pick the first, a more sophisticated compositor would let the user * configure it or pick the mode the display advertises as preferred. */ - if (!wl_list_empty(&wlr_output->modes)) { - struct wlr_output_mode *mode = - wl_container_of(wlr_output->modes.prev, mode, link); + if(!wl_list_empty(&wlr_output->modes)) + { + struct wlr_output_mode *mode = wl_container_of(wlr_output->modes.prev, mode, link); wlr_output_set_mode(wlr_output, mode); } /* Allocates and configures our state for this output */ - struct inaban_output *output = - calloc(1, sizeof(struct inaban_output)); - output->wlr_output = wlr_output; - output->server = server; + struct inaban_output *output = calloc(1, sizeof(struct inaban_output)); + output->wlr_output = wlr_output; + output->server = server; /* Sets up a listener for the frame notify event. */ output->frame.notify = output_frame; wl_signal_add(&wlr_output->events.frame, &output->frame); @@ -679,56 +734,67 @@ static void server_new_output(struct wl_listener *listener, void *data) { wlr_output_create_global(wlr_output); } -static void xdg_surface_map(struct wl_listener *listener, void *data) { +static void +xdg_surface_map(struct wl_listener *listener, void *data) +{ /* Called when the surface is mapped, or ready to display on-screen. */ struct inaban_view *view = wl_container_of(listener, view, map); - view->mapped = true; + view->mapped = true; focus_view(view, view->xdg_surface->surface); } -static void xdg_surface_unmap(struct wl_listener *listener, void *data) { +static void +xdg_surface_unmap(struct wl_listener *listener, void *data) +{ /* Called when the surface is unmapped, and should no longer be shown. */ struct inaban_view *view = wl_container_of(listener, view, unmap); - view->mapped = false; + view->mapped = false; } -static void xdg_surface_destroy(struct wl_listener *listener, void *data) { +static void +xdg_surface_destroy(struct wl_listener *listener, void *data) +{ /* Called when the surface is destroyed and should never be shown again. */ struct inaban_view *view = wl_container_of(listener, view, destroy); wl_list_remove(&view->link); free(view); } -static void begin_interactive(struct inaban_view *view, - enum inaban_cursor_mode mode, uint32_t edges) { +static void +begin_interactive(struct inaban_view *view, enum inaban_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 * consumes them itself, to move or resize windows. */ - struct inaban_server *server = view->server; - struct wlr_surface *focused_surface = - server->seat->pointer_state.focused_surface; - if (view->xdg_surface->surface != focused_surface) { + struct inaban_server *server = view->server; + struct wlr_surface *focused_surface = server->seat->pointer_state.focused_surface; + if(view->xdg_surface->surface != focused_surface) + { /* Deny move/resize requests from unfocused clients. */ return; } server->grabbed_view = view; - server->cursor_mode = mode; + server->cursor_mode = mode; struct wlr_box geo_box; wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box); - if (mode == INABAN_CURSOR_MOVE) { + if(mode == INABAN_CURSOR_MOVE) + { server->grab_x = server->cursor->x - view->x; server->grab_y = server->cursor->y - view->y; - } else { + } + else + { server->grab_x = server->cursor->x + geo_box.x; server->grab_y = server->cursor->y + geo_box.y; } - server->grab_width = geo_box.width; - server->grab_height = geo_box.height; + server->grab_width = geo_box.width; + server->grab_height = geo_box.height; server->resize_edges = edges; } -static void xdg_toplevel_request_move( - struct wl_listener *listener, void *data) { +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 @@ -738,33 +804,35 @@ static void xdg_toplevel_request_move( begin_interactive(view, INABAN_CURSOR_MOVE, 0); } -static void xdg_toplevel_request_resize( - struct wl_listener *listener, void *data) { +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. */ struct wlr_xdg_toplevel_resize_event *event = data; - struct inaban_view *view = wl_container_of(listener, view, request_resize); + struct inaban_view *view = wl_container_of(listener, view, request_resize); begin_interactive(view, INABAN_CURSOR_RESIZE, event->edges); } -static void server_new_xdg_surface(struct wl_listener *listener, void *data) { +static void +server_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 inaban_server *server = - wl_container_of(listener, server, new_xdg_surface); + struct inaban_server *server = wl_container_of(listener, server, new_xdg_surface); struct wlr_xdg_surface *xdg_surface = data; - if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + if(xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) + { return; } /* Allocate a inaban_view for this surface */ - struct inaban_view *view = - calloc(1, sizeof(struct inaban_view)); - view->server = server; - view->xdg_surface = xdg_surface; + struct inaban_view *view = calloc(1, sizeof(struct inaban_view)); + view->server = server; + view->xdg_surface = xdg_surface; /* Listen to the various events it can emit */ view->map.notify = xdg_surface_map; @@ -776,7 +844,7 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) { /* cotd */ struct wlr_xdg_toplevel *toplevel = xdg_surface->toplevel; - view->request_move.notify = xdg_toplevel_request_move; + view->request_move.notify = xdg_toplevel_request_move; wl_signal_add(&toplevel->events.request_move, &view->request_move); view->request_resize.notify = xdg_toplevel_request_resize; wl_signal_add(&toplevel->events.request_resize, &view->request_resize); @@ -785,22 +853,23 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) { wl_list_insert(&server->views, &view->link); } -int main(int argc, char *argv[]) { +int +main(int argc, char *argv[]) +{ wlr_log_init(WLR_DEBUG, NULL); char *startup_cmd = NULL; int c; - while ((c = getopt(argc, argv, "s:h")) != -1) { - switch (c) { - case 's': - startup_cmd = optarg; - break; - default: - printf("Usage: %s [-s startup command]\n", argv[0]); - return 0; + while((c = getopt(argc, argv, "s:h")) != -1) + { + switch(c) + { + case 's': startup_cmd = optarg; break; + default: printf("Usage: %s [-s startup command]\n", argv[0]); return 0; } } - if (optind < argc) { + if(optind < argc) + { printf("Usage: %s [-s startup command]\n", argv[0]); return 0; } @@ -849,10 +918,9 @@ int main(int argc, char *argv[]) { * https://drewdevault.com/2018/07/29/Wayland-shells.html */ wl_list_init(&server.views); - server.xdg_shell = wlr_xdg_shell_create(server.wl_display); + server.xdg_shell = wlr_xdg_shell_create(server.wl_display); server.new_xdg_surface.notify = server_new_xdg_surface; - wl_signal_add(&server.xdg_shell->events.new_surface, - &server.new_xdg_surface); + wl_signal_add(&server.xdg_shell->events.new_surface, &server.new_xdg_surface); /* * Creates a cursor, which is a wlroots utility for tracking the cursor @@ -883,8 +951,7 @@ int main(int argc, char *argv[]) { server.cursor_motion.notify = server_cursor_motion; wl_signal_add(&server.cursor->events.motion, &server.cursor_motion); server.cursor_motion_absolute.notify = server_cursor_motion_absolute; - wl_signal_add(&server.cursor->events.motion_absolute, - &server.cursor_motion_absolute); + wl_signal_add(&server.cursor->events.motion_absolute, &server.cursor_motion_absolute); server.cursor_button.notify = server_cursor_button; wl_signal_add(&server.cursor->events.button, &server.cursor_button); server.cursor_axis.notify = server_cursor_axis; @@ -901,21 +968,22 @@ int main(int argc, char *argv[]) { wl_list_init(&server.keyboards); server.new_input.notify = server_new_input; wl_signal_add(&server.backend->events.new_input, &server.new_input); - server.seat = wlr_seat_create(server.wl_display, "seat0"); + server.seat = wlr_seat_create(server.wl_display, "seat0"); server.request_cursor.notify = seat_request_cursor; - wl_signal_add(&server.seat->events.request_set_cursor, - &server.request_cursor); + wl_signal_add(&server.seat->events.request_set_cursor, &server.request_cursor); /* Add a Unix socket to the Wayland display. */ const char *socket = wl_display_add_socket_auto(server.wl_display); - if (!socket) { + if(!socket) + { wlr_backend_destroy(server.backend); return 1; } /* Start the backend. This will enumerate outputs and inputs, become the DRM * master, etc */ - if (!wlr_backend_start(server.backend)) { + if(!wlr_backend_start(server.backend)) + { wlr_backend_destroy(server.backend); wl_display_destroy(server.wl_display); return 1; @@ -924,8 +992,10 @@ int main(int argc, char *argv[]) { /* Set the WAYLAND_DISPLAY environment variable to our socket and run the * startup command if requested. */ setenv("WAYLAND_DISPLAY", socket, true); - if (startup_cmd) { - if (fork() == 0) { + if(startup_cmd) + { + if(fork() == 0) + { execl("/bin/sh", "/bin/sh", "-c", startup_cmd, (void *)NULL); } } @@ -933,8 +1003,7 @@ int main(int argc, char *argv[]) { * compositor. Starting the backend rigged up all of the necessary event * loop configuration to listen to libinput events, DRM events, generate * frame events at the refresh rate, and so on. */ - wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", - socket); + wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); wl_display_run(server.wl_display); /* Once wl_display_run returns, we shut down the server. */