add lock mode
Introducing `lock` mode. This turns the screen locker into a mode which adds some more modularity to the code. Visible views on sheet 0 are also displayed on the lock screen allowing for a customizable setup without the needs for extra plugins. An indicator adds feedback for typing and verification.
This commit is contained in:
parent
18e775a7f8
commit
515499e8da
3
Makefile
3
Makefile
|
@ -29,6 +29,8 @@ OBJS = \
|
|||
layout.o \
|
||||
layout_config.o \
|
||||
layout_select_mode.o \
|
||||
lock_indicator.o \
|
||||
lock_mode.o \
|
||||
main.o \
|
||||
mark.o \
|
||||
mark_assign_mode.o \
|
||||
|
@ -48,7 +50,6 @@ OBJS = \
|
|||
sheet_assign_mode.o \
|
||||
split.o \
|
||||
tile.o \
|
||||
unlocker.o \
|
||||
view.o \
|
||||
view_autoconf.o \
|
||||
workspace.o \
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#if !defined(HIKARI_LOCK_INDICATOR_H)
|
||||
#define HIKARI_LOCK_INDICATOR_H
|
||||
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
|
||||
struct hikari_output;
|
||||
struct hikari_render_data;
|
||||
|
||||
struct hikari_lock_indicator {
|
||||
struct wlr_texture *wait;
|
||||
struct wlr_texture *type;
|
||||
struct wlr_texture *verify;
|
||||
struct wlr_texture *deny;
|
||||
|
||||
struct wlr_texture *current;
|
||||
|
||||
struct wl_event_source *reset_state;
|
||||
};
|
||||
|
||||
void
|
||||
hikari_lock_indicator_init(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_fini(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_wait(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_type(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_verify(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_deny(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_clear(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_damage(struct hikari_lock_indicator *lock_indicator);
|
||||
|
||||
void
|
||||
hikari_lock_indicator_render(struct hikari_lock_indicator *lock_indicator,
|
||||
struct hikari_render_data *render_data);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
#if !defined(HIKARI_LOCK_MODE_H)
|
||||
#define HIKARI_LOCK_MODE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include <hikari/lock_indicator.h>
|
||||
#include <hikari/mode.h>
|
||||
|
||||
struct hikari_lock_mode {
|
||||
struct hikari_mode mode;
|
||||
struct wl_event_source *disable_outputs;
|
||||
struct hikari_lock_indicator *lock_indicator;
|
||||
|
||||
bool outputs_disabled;
|
||||
};
|
||||
|
||||
void
|
||||
hikari_lock_mode_init(struct hikari_lock_mode *lock_mode);
|
||||
|
||||
void
|
||||
hikari_lock_mode_fini(struct hikari_lock_mode *lock_mode);
|
||||
|
||||
void
|
||||
hikari_lock_mode_enter(void);
|
||||
|
||||
static inline bool
|
||||
hikari_lock_mode_are_outputs_disabled(struct hikari_lock_mode *lock_mode)
|
||||
{
|
||||
return lock_mode->outputs_disabled;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <hikari/output_config.h>
|
||||
|
||||
struct hikari_render_data;
|
||||
|
||||
struct hikari_output {
|
||||
struct wlr_output *wlr_output;
|
||||
struct wlr_output_damage *damage;
|
||||
|
@ -59,11 +61,26 @@ hikari_output_disable(struct hikari_output *output);
|
|||
void
|
||||
hikari_output_enable(struct hikari_output *output);
|
||||
|
||||
void
|
||||
hikari_output_enable_content(struct hikari_output *output);
|
||||
|
||||
void
|
||||
hikari_output_disable_content(struct hikari_output *output);
|
||||
|
||||
void
|
||||
hikari_output_load_background(struct hikari_output *output,
|
||||
const char *path,
|
||||
enum hikari_background_fit background_fit);
|
||||
|
||||
void
|
||||
hikari_output_render_background(struct hikari_output *output,
|
||||
struct hikari_render_data *render_data,
|
||||
float alpha);
|
||||
|
||||
void
|
||||
hikari_output_render_sticky(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data);
|
||||
|
||||
void
|
||||
hikari_output_move(struct hikari_output *output, double lx, double ly);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <hikari/input_grab_mode.h>
|
||||
#include <hikari/layer_shell.h>
|
||||
#include <hikari/layout_select_mode.h>
|
||||
#include <hikari/lock_mode.h>
|
||||
#include <hikari/mark_assign_mode.h>
|
||||
#include <hikari/mark_select_mode.h>
|
||||
#include <hikari/move_mode.h>
|
||||
|
@ -27,7 +28,6 @@ struct hikari_output;
|
|||
struct hikari_group;
|
||||
|
||||
struct hikari_server {
|
||||
bool locked;
|
||||
bool cycling;
|
||||
#ifndef NDEBUG
|
||||
bool track_damage;
|
||||
|
@ -95,6 +95,7 @@ struct hikari_server {
|
|||
struct hikari_group_assign_mode group_assign_mode;
|
||||
struct hikari_input_grab_mode input_grab_mode;
|
||||
struct hikari_layout_select_mode layout_select_mode;
|
||||
struct hikari_lock_mode lock_mode;
|
||||
struct hikari_mark_assign_mode mark_assign_mode;
|
||||
struct hikari_mark_select_mode mark_select_mode;
|
||||
struct hikari_move_mode move_mode;
|
||||
|
@ -173,9 +174,6 @@ hikari_server_reload(void *arg);
|
|||
void
|
||||
hikari_server_execute_command(void *arg);
|
||||
|
||||
void
|
||||
hikari_server_unlock(void);
|
||||
|
||||
struct hikari_group *
|
||||
hikari_server_find_group(const char *group_name);
|
||||
|
||||
|
@ -354,6 +352,7 @@ hikari_server_clear_workspace(void *arg)
|
|||
MODE(group_assign)
|
||||
MODE(input_grab)
|
||||
MODE(layout_select)
|
||||
MODE(lock)
|
||||
MODE(mark_assign)
|
||||
MODE(mark_select)
|
||||
MODE(move)
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#if !defined(HIKARI_UNLOCKER_H)
|
||||
#define HIKARI_UNLOCKER_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
void
|
||||
hikari_unlocker_init(void);
|
||||
|
||||
void
|
||||
hikari_unlocker_fini(void);
|
||||
|
||||
void
|
||||
hikari_unlocker_start(void);
|
||||
|
||||
void
|
||||
hikari_unlocker_key_handler(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif
|
|
@ -164,6 +164,8 @@ General actions
|
|||
needs pam.conf(5) to be aware of its existence, therefore there must be a
|
||||
_hikari-unlocker_ service file in _pam.d_.
|
||||
|
||||
The lock screen displays all visible sheets that are a member of sheet 0.
|
||||
|
||||
* **quit**
|
||||
|
||||
Quit **hikari**.
|
||||
|
|
21
src/cursor.c
21
src/cursor.c
|
@ -79,9 +79,8 @@ hikari_cursor_deactivate(struct hikari_cursor *cursor)
|
|||
wl_list_remove(&cursor->button.link);
|
||||
wl_list_remove(&cursor->axis.link);
|
||||
wl_list_remove(&cursor->request_set_cursor.link);
|
||||
wl_list_remove(&cursor->surface_destroy.link);
|
||||
|
||||
wl_list_init(&cursor->surface_destroy.link);
|
||||
hikari_cursor_set_image(cursor, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -90,8 +89,12 @@ hikari_cursor_set_image(struct hikari_cursor *cursor, const char *path)
|
|||
wl_list_remove(&cursor->surface_destroy.link);
|
||||
wl_list_init(&cursor->surface_destroy.link);
|
||||
|
||||
wlr_xcursor_manager_set_cursor_image(
|
||||
hikari_server.cursor_mgr, path, cursor->wlr_cursor);
|
||||
if (path != NULL) {
|
||||
wlr_xcursor_manager_set_cursor_image(
|
||||
hikari_server.cursor_mgr, path, cursor->wlr_cursor);
|
||||
} else {
|
||||
wlr_cursor_set_image(cursor->wlr_cursor, NULL, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -111,7 +114,7 @@ motion_absolute_handler(struct wl_listener *listener, void *data)
|
|||
struct hikari_cursor *cursor =
|
||||
wl_container_of(listener, cursor, motion_absolute);
|
||||
|
||||
assert(!hikari_server.locked);
|
||||
assert(!hikari_server_in_lock_mode());
|
||||
|
||||
struct wlr_event_pointer_motion_absolute *event = data;
|
||||
|
||||
|
@ -124,7 +127,7 @@ motion_absolute_handler(struct wl_listener *listener, void *data)
|
|||
static void
|
||||
frame_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
assert(!hikari_server.locked);
|
||||
assert(!hikari_server_in_lock_mode());
|
||||
|
||||
wlr_seat_pointer_notify_frame(hikari_server.seat);
|
||||
}
|
||||
|
@ -134,7 +137,7 @@ motion_handler(struct wl_listener *listener, void *data)
|
|||
{
|
||||
struct hikari_cursor *cursor = wl_container_of(listener, cursor, motion);
|
||||
|
||||
assert(!hikari_server.locked);
|
||||
assert(!hikari_server_in_lock_mode());
|
||||
|
||||
struct wlr_event_pointer_motion *event = data;
|
||||
|
||||
|
@ -147,7 +150,7 @@ motion_handler(struct wl_listener *listener, void *data)
|
|||
static void
|
||||
button_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
assert(!hikari_server.locked);
|
||||
assert(!hikari_server_in_lock_mode());
|
||||
|
||||
hikari_server.mode->button_handler(listener, data);
|
||||
}
|
||||
|
@ -155,7 +158,7 @@ button_handler(struct wl_listener *listener, void *data)
|
|||
static void
|
||||
axis_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
assert(!hikari_server.locked);
|
||||
assert(!hikari_server_in_lock_mode());
|
||||
|
||||
struct wlr_event_pointer_axis *event = data;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <hikari/memory.h>
|
||||
#include <hikari/mode.h>
|
||||
#include <hikari/server.h>
|
||||
#include <hikari/unlocker.h>
|
||||
|
||||
static void
|
||||
update_mod_state(struct hikari_keyboard *keyboard)
|
||||
|
@ -30,11 +29,6 @@ key_handler(struct wl_listener *listener, void *data)
|
|||
{
|
||||
struct hikari_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||
|
||||
if (hikari_server.locked) {
|
||||
hikari_unlocker_key_handler(listener, data);
|
||||
return;
|
||||
}
|
||||
|
||||
hikari_server.mode->key_handler(listener, data);
|
||||
}
|
||||
|
||||
|
@ -46,10 +40,6 @@ modifiers_handler(struct wl_listener *listener, void *data)
|
|||
|
||||
update_mod_state(keyboard);
|
||||
|
||||
if (hikari_server.locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
hikari_server.mode->modifier_handler(listener, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
#include <hikari/lock_indicator.h>
|
||||
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
|
||||
#include <hikari/configuration.h>
|
||||
#include <hikari/geometry.h>
|
||||
#include <hikari/output.h>
|
||||
#include <hikari/render_data.h>
|
||||
#include <hikari/server.h>
|
||||
|
||||
static struct wlr_texture *
|
||||
init_indicator_circle(float color[static 4])
|
||||
{
|
||||
const int size = 100;
|
||||
|
||||
struct wlr_texture *texture;
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(hikari_server.backend);
|
||||
|
||||
cairo_surface_t *surface =
|
||||
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
|
||||
|
||||
cairo_t *cairo = cairo_create(surface);
|
||||
PangoLayout *layout = pango_cairo_create_layout(cairo);
|
||||
|
||||
float *border_inactive = hikari_configuration->border_active;
|
||||
cairo_set_source_rgba(cairo,
|
||||
border_inactive[0],
|
||||
border_inactive[1],
|
||||
border_inactive[2],
|
||||
border_inactive[3]);
|
||||
cairo_set_line_width(cairo, 5);
|
||||
cairo_translate(cairo, size / 2, size / 2);
|
||||
cairo_arc(cairo, 0, 0, (size - 5) / 2, 0, 2 * M_PI);
|
||||
cairo_stroke_preserve(cairo);
|
||||
cairo_set_source_rgba(cairo, color[0], color[1], color[2], color[3]);
|
||||
cairo_fill(cairo);
|
||||
|
||||
cairo_surface_flush(surface);
|
||||
|
||||
unsigned char *data = cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, size);
|
||||
|
||||
texture = wlr_texture_from_pixels(
|
||||
renderer, WL_SHM_FORMAT_ARGB8888, stride, size, size, data);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
g_object_unref(layout);
|
||||
cairo_destroy(cairo);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static int
|
||||
reset_state_handler(void *data)
|
||||
{
|
||||
struct hikari_lock_indicator *lock_indicator = data;
|
||||
|
||||
if (lock_indicator->current == lock_indicator->deny) {
|
||||
hikari_lock_indicator_clear(lock_indicator);
|
||||
} else {
|
||||
hikari_lock_indicator_set_wait(lock_indicator);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_init(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->wait = init_indicator_circle(hikari_configuration->clear);
|
||||
lock_indicator->type =
|
||||
init_indicator_circle(hikari_configuration->indicator_insert);
|
||||
lock_indicator->verify =
|
||||
init_indicator_circle(hikari_configuration->indicator_selected);
|
||||
lock_indicator->deny =
|
||||
init_indicator_circle(hikari_configuration->indicator_conflict);
|
||||
|
||||
lock_indicator->current = NULL;
|
||||
|
||||
lock_indicator->reset_state = wl_event_loop_add_timer(
|
||||
hikari_server.event_loop, reset_state_handler, lock_indicator);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_fini(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
wlr_texture_destroy(lock_indicator->wait);
|
||||
wlr_texture_destroy(lock_indicator->type);
|
||||
wlr_texture_destroy(lock_indicator->verify);
|
||||
wlr_texture_destroy(lock_indicator->deny);
|
||||
|
||||
wl_event_source_remove(lock_indicator->reset_state);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_type(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->current = lock_indicator->type;
|
||||
hikari_lock_indicator_damage(lock_indicator);
|
||||
wl_event_source_timer_update(lock_indicator->reset_state, 100);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_verify(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->current = lock_indicator->verify;
|
||||
hikari_lock_indicator_damage(lock_indicator);
|
||||
wl_event_source_timer_update(lock_indicator->reset_state, 0);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_deny(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->current = lock_indicator->deny;
|
||||
hikari_lock_indicator_damage(lock_indicator);
|
||||
wl_event_source_timer_update(lock_indicator->reset_state, 1000);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_set_wait(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->current = lock_indicator->wait;
|
||||
hikari_lock_indicator_damage(lock_indicator);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_clear(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
lock_indicator->current = NULL;
|
||||
hikari_lock_indicator_damage(lock_indicator);
|
||||
wl_event_source_timer_update(lock_indicator->reset_state, 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
get_geometry(struct hikari_output *output, struct wlr_box *geometry)
|
||||
{
|
||||
const int size = 100;
|
||||
|
||||
geometry->width = size;
|
||||
geometry->height = size;
|
||||
|
||||
hikari_geometry_position_center(
|
||||
geometry, &output->geometry, &geometry->x, &geometry->y);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_render(struct hikari_lock_indicator *lock_indicator,
|
||||
struct hikari_render_data *render_data)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
struct wlr_texture *texture = lock_indicator->current;
|
||||
|
||||
if (texture == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
float matrix[9];
|
||||
struct wlr_renderer *renderer = render_data->renderer;
|
||||
struct wlr_output *output = render_data->output;
|
||||
|
||||
struct wlr_box geometry;
|
||||
get_geometry(output->data, &geometry);
|
||||
wlr_renderer_scissor(renderer, &geometry);
|
||||
wlr_matrix_project_box(matrix, &geometry, 0, 0, output->transform_matrix);
|
||||
|
||||
wlr_render_texture_with_matrix(renderer, texture, matrix, 1);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_indicator_damage(struct hikari_lock_indicator *lock_indicator)
|
||||
{
|
||||
assert(lock_indicator != NULL);
|
||||
|
||||
struct wlr_box geometry;
|
||||
|
||||
struct hikari_output *output;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
get_geometry(output, &geometry);
|
||||
hikari_output_add_damage(output, &geometry);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,369 @@
|
|||
#include <hikari/lock_mode.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
|
||||
#include <hikari/cursor.h>
|
||||
#include <hikari/keyboard.h>
|
||||
#include <hikari/lock_indicator.h>
|
||||
#include <hikari/output.h>
|
||||
#include <hikari/render_data.h>
|
||||
#include <hikari/server.h>
|
||||
#include <hikari/utf8.h>
|
||||
#include <hikari/view.h>
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
static char input_buffer[BUFFER_SIZE];
|
||||
static int cursor = 0;
|
||||
static int locker_pipe[2][2] = { { -1, -1 }, { -1, -1 } };
|
||||
|
||||
static struct hikari_lock_mode *
|
||||
get_mode(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = &hikari_server.lock_mode;
|
||||
|
||||
assert(mode == (struct hikari_lock_mode *)hikari_server.mode);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_buffer(void)
|
||||
{
|
||||
cursor = 0;
|
||||
memset(input_buffer, 0, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_password(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
clear_buffer();
|
||||
hikari_lock_indicator_clear(mode->lock_indicator);
|
||||
}
|
||||
|
||||
static void
|
||||
start_unlocker(void)
|
||||
{
|
||||
pipe(locker_pipe[0]);
|
||||
pipe(locker_pipe[1]);
|
||||
|
||||
pid_t locker = fork();
|
||||
|
||||
if (locker == 0) {
|
||||
close(locker_pipe[0][1]);
|
||||
close(locker_pipe[1][0]);
|
||||
close(0);
|
||||
close(1);
|
||||
dup2(locker_pipe[0][0], 0);
|
||||
dup2(locker_pipe[1][1], 1);
|
||||
execl("/bin/sh", "/bin/sh", "-c", "hikari-unlocker", NULL);
|
||||
exit(0);
|
||||
} else {
|
||||
close(locker_pipe[0][0]);
|
||||
close(locker_pipe[1][1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
put_char(uint32_t codepoint)
|
||||
{
|
||||
size_t length = utf8_chsize(codepoint);
|
||||
|
||||
if (cursor + length < BUFFER_SIZE) {
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
hikari_lock_indicator_set_type(mode->lock_indicator);
|
||||
utf8_encode(&input_buffer[cursor], length, codepoint);
|
||||
cursor += length;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_char(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
if (cursor == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
hikari_lock_indicator_set_type(mode->lock_indicator);
|
||||
|
||||
input_buffer[--cursor] = '\0';
|
||||
|
||||
if (cursor == 0) {
|
||||
hikari_lock_indicator_clear(mode->lock_indicator);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
submit_password(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
size_t password_length = strnlen(input_buffer, 1023) + 1;
|
||||
bool success = false;
|
||||
|
||||
hikari_lock_indicator_set_verify(mode->lock_indicator);
|
||||
write(locker_pipe[0][1], input_buffer, password_length);
|
||||
clear_buffer();
|
||||
read(locker_pipe[1][0], &success, sizeof(bool));
|
||||
|
||||
if (success) {
|
||||
int status;
|
||||
close(locker_pipe[1][0]);
|
||||
close(locker_pipe[0][1]);
|
||||
wait(&status);
|
||||
|
||||
hikari_server_enter_normal_mode(NULL);
|
||||
} else {
|
||||
|
||||
hikari_lock_indicator_set_deny(mode->lock_indicator);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disable_outputs(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
wl_event_source_timer_update(mode->disable_outputs, 0);
|
||||
|
||||
struct hikari_output *output;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
if (output->enabled) {
|
||||
hikari_output_disable(output);
|
||||
}
|
||||
|
||||
hikari_output_damage_whole(output);
|
||||
}
|
||||
|
||||
mode->outputs_disabled = true;
|
||||
|
||||
clear_password();
|
||||
}
|
||||
|
||||
static void
|
||||
enable_outputs(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
if (!mode->outputs_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(cursor == 0);
|
||||
|
||||
struct hikari_output *output;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
if (!output->enabled) {
|
||||
hikari_output_disable_content(output);
|
||||
hikari_output_enable(output);
|
||||
}
|
||||
}
|
||||
|
||||
mode->outputs_disabled = false;
|
||||
}
|
||||
|
||||
static void
|
||||
key_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||
struct wlr_event_keyboard_key *event = data;
|
||||
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
if (event->state == WLR_KEY_PRESSED) {
|
||||
const xkb_keysym_t *syms;
|
||||
uint32_t keycode = event->keycode + 8;
|
||||
uint32_t codepoint;
|
||||
|
||||
int nsyms = xkb_state_key_get_syms(
|
||||
keyboard->device->keyboard->xkb_state, keycode, &syms);
|
||||
|
||||
enable_outputs();
|
||||
|
||||
for (int i = 0; i < nsyms; i++) {
|
||||
switch (syms[i]) {
|
||||
case XKB_KEY_Caps_Lock:
|
||||
case XKB_KEY_Shift_L:
|
||||
case XKB_KEY_Shift_R:
|
||||
case XKB_KEY_Control_L:
|
||||
case XKB_KEY_Control_R:
|
||||
case XKB_KEY_Meta_L:
|
||||
case XKB_KEY_Meta_R:
|
||||
case XKB_KEY_Alt_L:
|
||||
case XKB_KEY_Alt_R:
|
||||
case XKB_KEY_Super_L:
|
||||
case XKB_KEY_Super_R:
|
||||
break;
|
||||
|
||||
case XKB_KEY_Escape:
|
||||
clear_password();
|
||||
break;
|
||||
|
||||
case XKB_KEY_BackSpace:
|
||||
delete_char();
|
||||
break;
|
||||
|
||||
case XKB_KEY_Return:
|
||||
submit_password();
|
||||
break;
|
||||
|
||||
case XKB_KEY_c:
|
||||
if (hikari_keyboard_check_modifier(keyboard, WLR_MODIFIER_CTRL)) {
|
||||
disable_outputs();
|
||||
return;
|
||||
}
|
||||
default:
|
||||
codepoint = hikari_keyboard_get_codepoint(keyboard, keycode);
|
||||
|
||||
if (codepoint) {
|
||||
put_char(codepoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode->disable_outputs != NULL) {
|
||||
wl_event_source_timer_update(mode->disable_outputs, 10 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
modifier_handler(struct wl_listener *listener, void *data)
|
||||
{}
|
||||
|
||||
static void
|
||||
button_handler(struct wl_listener *listener, void *data)
|
||||
{}
|
||||
|
||||
static void
|
||||
render(struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
hikari_output_render_background(output, render_data, 0.1);
|
||||
hikari_output_render_sticky(output, render_data);
|
||||
hikari_lock_indicator_render(mode->lock_indicator, render_data);
|
||||
}
|
||||
|
||||
static void
|
||||
cancel(void)
|
||||
{
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
wl_event_source_remove(mode->disable_outputs);
|
||||
mode->disable_outputs = NULL;
|
||||
|
||||
struct hikari_output *output;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
hikari_output_enable_content(output);
|
||||
if (!output->enabled) {
|
||||
hikari_output_enable(output);
|
||||
}
|
||||
}
|
||||
|
||||
hikari_lock_indicator_fini(mode->lock_indicator);
|
||||
hikari_free(mode->lock_indicator);
|
||||
mode->lock_indicator = NULL;
|
||||
|
||||
hikari_cursor_activate(&hikari_server.cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_move(uint32_t time_msec)
|
||||
{}
|
||||
|
||||
static int
|
||||
disable_outputs_handler(void *data)
|
||||
{
|
||||
assert(hikari_server_in_lock_mode());
|
||||
|
||||
disable_outputs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_mode_init(struct hikari_lock_mode *lock_mode)
|
||||
{
|
||||
lock_mode->mode.key_handler = key_handler;
|
||||
lock_mode->mode.button_handler = button_handler;
|
||||
lock_mode->mode.modifier_handler = modifier_handler;
|
||||
lock_mode->mode.render = render;
|
||||
lock_mode->mode.cancel = cancel;
|
||||
lock_mode->mode.cursor_move = cursor_move;
|
||||
|
||||
lock_mode->lock_indicator = NULL;
|
||||
|
||||
mlock(input_buffer, BUFFER_SIZE);
|
||||
clear_buffer();
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_mode_fini(struct hikari_lock_mode *lock_mode)
|
||||
{
|
||||
munlock(input_buffer, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_lock_mode_enter(void)
|
||||
{
|
||||
struct hikari_workspace *workspace = hikari_server.workspace;
|
||||
struct hikari_view *focus_view = workspace->focus_view;
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
struct hikari_layer *focus_layer = workspace->focus_layer;
|
||||
|
||||
if (focus_layer != NULL) {
|
||||
assert(focus_view == NULL);
|
||||
workspace->focus_layer = NULL;
|
||||
wlr_seat_pointer_clear_focus(hikari_server.seat);
|
||||
} else if (focus_view != NULL) {
|
||||
assert(focus_layer != NULL);
|
||||
hikari_workspace_focus_view(workspace, NULL);
|
||||
}
|
||||
#else
|
||||
if (focus_view != NULL) {
|
||||
hikari_workspace_focus_view(workspace, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct hikari_output *output;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
hikari_output_disable_content(output);
|
||||
}
|
||||
|
||||
hikari_cursor_deactivate(&hikari_server.cursor);
|
||||
|
||||
hikari_server.mode = (struct hikari_mode *)&hikari_server.lock_mode;
|
||||
|
||||
struct hikari_lock_mode *mode = get_mode();
|
||||
|
||||
assert(mode->lock_indicator == NULL);
|
||||
|
||||
mode->lock_indicator = hikari_malloc(sizeof(struct hikari_lock_indicator));
|
||||
|
||||
hikari_lock_indicator_init(mode->lock_indicator);
|
||||
|
||||
clear_buffer();
|
||||
start_unlocker();
|
||||
|
||||
mode->disable_outputs = wl_event_loop_add_timer(
|
||||
hikari_server.event_loop, disable_outputs_handler, NULL);
|
||||
|
||||
wl_event_source_timer_update(mode->disable_outputs, 1000);
|
||||
}
|
325
src/output.c
325
src/output.c
|
@ -31,7 +31,7 @@
|
|||
#include <hikari/xwayland_view.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
static inline void
|
||||
render_image_to_surface(cairo_surface_t *output,
|
||||
cairo_surface_t *image,
|
||||
enum hikari_background_fit fit)
|
||||
|
@ -123,13 +123,14 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
render_texture(struct wlr_output *output,
|
||||
pixman_region32_t *damage,
|
||||
struct wlr_texture *texture,
|
||||
struct wlr_renderer *renderer,
|
||||
const float matrix[static 9],
|
||||
struct wlr_box *box)
|
||||
struct wlr_box *box,
|
||||
float alpha)
|
||||
{
|
||||
pixman_region32_t local_damage;
|
||||
pixman_region32_init(&local_damage);
|
||||
|
@ -147,7 +148,7 @@ render_texture(struct wlr_output *output,
|
|||
pixman_box32_t *rects = pixman_region32_rectangles(&local_damage, &nrects);
|
||||
for (int i = 0; i < nrects; ++i) {
|
||||
hikari_output_scissor_render(output, renderer, &rects[i]);
|
||||
wlr_render_texture_with_matrix(renderer, texture, matrix, 1);
|
||||
wlr_render_texture_with_matrix(renderer, texture, matrix, alpha);
|
||||
}
|
||||
|
||||
damage_finish:
|
||||
|
@ -189,12 +190,14 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data)
|
|||
texture,
|
||||
render_data->renderer,
|
||||
matrix,
|
||||
&box);
|
||||
&box,
|
||||
1);
|
||||
}
|
||||
|
||||
static void
|
||||
render_background(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
static inline void
|
||||
render_background(struct hikari_output *output,
|
||||
struct hikari_render_data *render_data,
|
||||
float alpha)
|
||||
{
|
||||
if (output->background == NULL) {
|
||||
return;
|
||||
|
@ -214,11 +217,12 @@ render_background(
|
|||
output->background,
|
||||
render_data->renderer,
|
||||
matrix,
|
||||
&geometry);
|
||||
&geometry,
|
||||
alpha);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
static void
|
||||
static inline void
|
||||
layer_for_each(struct wl_list *layers,
|
||||
void (*func)(struct wlr_surface *, int, int, void *),
|
||||
void *data)
|
||||
|
@ -229,7 +233,7 @@ layer_for_each(struct wl_list *layers,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
render_layer(struct wl_list *layers, struct hikari_render_data *render_data)
|
||||
{
|
||||
struct hikari_layer *layer;
|
||||
|
@ -241,22 +245,86 @@ render_layer(struct wl_list *layers, struct hikari_render_data *render_data)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
render_output(struct hikari_output *output,
|
||||
pixman_region32_t *damage,
|
||||
struct timespec *now)
|
||||
void
|
||||
hikari_output_render_sticky(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
{
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct hikari_view *view;
|
||||
wl_list_for_each_reverse (
|
||||
view, &output->workspace->sheets[0].views, sheet_views) {
|
||||
if (!hikari_view_is_hidden(view)) {
|
||||
render_data->geometry = hikari_view_border_geometry(view);
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||
if (hikari_view_wants_border(view)) {
|
||||
hikari_border_render(&view->border, render_data);
|
||||
}
|
||||
|
||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||
render_data->geometry = hikari_view_geometry(view);
|
||||
|
||||
if (!pixman_region32_not_empty(damage)) {
|
||||
goto render_end;
|
||||
hikari_view_interface_for_each_surface(
|
||||
(struct hikari_view_interface *)view, render_surface, render_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
render_workspace(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
{
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_layer(
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], render_data);
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], render_data);
|
||||
#endif
|
||||
|
||||
struct hikari_view *view;
|
||||
wl_list_for_each_reverse (view, &output->workspace->views, workspace_views) {
|
||||
render_data->geometry = hikari_view_border_geometry(view);
|
||||
|
||||
if (hikari_view_wants_border(view)) {
|
||||
hikari_border_render(&view->border, render_data);
|
||||
}
|
||||
|
||||
render_data->geometry = hikari_view_geometry(view);
|
||||
|
||||
hikari_view_interface_for_each_surface(
|
||||
(struct hikari_view_interface *)view, render_surface, render_data);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], render_data);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XWAYLAND
|
||||
struct hikari_xwayland_unmanaged_view *xwayland_unmanaged_view;
|
||||
wl_list_for_each_reverse (xwayland_unmanaged_view,
|
||||
&output->unmanaged_xwayland_views,
|
||||
unmanaged_server_views) {
|
||||
|
||||
render_data->geometry = &xwayland_unmanaged_view->geometry;
|
||||
|
||||
wlr_surface_for_each_surface(
|
||||
xwayland_unmanaged_view->surface->surface, render_surface, render_data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
static inline void
|
||||
render_overlay(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
{
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], render_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
clear_output(struct hikari_render_data *render_data)
|
||||
{
|
||||
float *clear_color = hikari_configuration->clear;
|
||||
struct wlr_renderer *renderer = render_data->renderer;
|
||||
struct wlr_output *wlr_output = render_data->output;
|
||||
pixman_region32_t *damage = render_data->damage;
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (hikari_server.track_damage) {
|
||||
|
@ -272,59 +340,15 @@ render_output(struct hikari_output *output,
|
|||
hikari_output_scissor_render(wlr_output, renderer, &rects[i]);
|
||||
wlr_renderer_clear(renderer, clear_color);
|
||||
}
|
||||
}
|
||||
|
||||
struct hikari_render_data render_data = {
|
||||
.output = wlr_output, .renderer = renderer, .when = now, .damage = damage
|
||||
};
|
||||
static inline void
|
||||
renderer_end(
|
||||
struct hikari_output *output, struct hikari_render_data *render_data)
|
||||
{
|
||||
struct wlr_renderer *renderer = render_data->renderer;
|
||||
struct wlr_output *wlr_output = render_data->output;
|
||||
|
||||
render_background(output, &render_data);
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_layer(
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &render_data);
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &render_data);
|
||||
#endif
|
||||
|
||||
struct hikari_view *view = NULL;
|
||||
wl_list_for_each_reverse (view, &output->workspace->views, workspace_views) {
|
||||
render_data.geometry = hikari_view_border_geometry(view);
|
||||
|
||||
if (hikari_view_wants_border(view)) {
|
||||
hikari_border_render(&view->border, &render_data);
|
||||
}
|
||||
|
||||
render_data.geometry = hikari_view_geometry(view);
|
||||
|
||||
hikari_view_interface_for_each_surface(
|
||||
(struct hikari_view_interface *)view, render_surface, &render_data);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &render_data);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XWAYLAND
|
||||
struct hikari_xwayland_unmanaged_view *xwayland_unmanaged_view = NULL;
|
||||
wl_list_for_each_reverse (xwayland_unmanaged_view,
|
||||
&output->unmanaged_xwayland_views,
|
||||
unmanaged_server_views) {
|
||||
|
||||
render_data.geometry = &xwayland_unmanaged_view->geometry;
|
||||
|
||||
wlr_surface_for_each_surface(xwayland_unmanaged_view->surface->surface,
|
||||
render_surface,
|
||||
&render_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
hikari_server.mode->render(output, &render_data);
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_layer(
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &render_data);
|
||||
#endif
|
||||
|
||||
render_end:
|
||||
wlr_renderer_scissor(renderer, NULL);
|
||||
wlr_output_render_software_cursors(wlr_output, NULL);
|
||||
wlr_renderer_end(renderer);
|
||||
|
@ -346,6 +370,59 @@ render_end:
|
|||
wlr_output_commit(wlr_output);
|
||||
}
|
||||
|
||||
static inline void
|
||||
render_output(struct hikari_output *output,
|
||||
pixman_region32_t *damage,
|
||||
struct timespec *now)
|
||||
{
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||
|
||||
struct hikari_render_data render_data = {
|
||||
.output = wlr_output, .renderer = renderer, .when = now, .damage = damage
|
||||
};
|
||||
|
||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||
|
||||
if (pixman_region32_not_empty(damage)) {
|
||||
clear_output(&render_data);
|
||||
|
||||
render_background(output, &render_data, 1);
|
||||
render_workspace(output, &render_data);
|
||||
|
||||
hikari_server.mode->render(output, &render_data);
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
render_overlay(output, &render_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
renderer_end(output, &render_data);
|
||||
}
|
||||
|
||||
static inline void
|
||||
render_empty_output(struct hikari_output *output,
|
||||
pixman_region32_t *damage,
|
||||
struct timespec *now)
|
||||
{
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||
|
||||
struct hikari_render_data render_data = {
|
||||
.output = wlr_output, .renderer = renderer, .when = now, .damage = damage
|
||||
};
|
||||
|
||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||
|
||||
if (pixman_region32_not_empty(damage)) {
|
||||
clear_output(&render_data);
|
||||
|
||||
hikari_server.mode->render(output, &render_data);
|
||||
}
|
||||
|
||||
renderer_end(output, &render_data);
|
||||
}
|
||||
|
||||
static void
|
||||
send_frame_done(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||
{
|
||||
|
@ -355,55 +432,80 @@ send_frame_done(struct wlr_surface *surface, int sx, int sy, void *data)
|
|||
wlr_surface_send_frame_done(surface, now);
|
||||
}
|
||||
|
||||
static void
|
||||
damage_frame_handler(struct wl_listener *listener, void *data)
|
||||
static inline void
|
||||
frame_done(struct hikari_output *output, struct timespec *now)
|
||||
{
|
||||
assert(!hikari_server.locked);
|
||||
|
||||
bool needs_frame;
|
||||
struct timespec now;
|
||||
struct hikari_output *output =
|
||||
wl_container_of(listener, output, damage_frame);
|
||||
|
||||
pixman_region32_t buffer_damage;
|
||||
pixman_region32_init(&buffer_damage);
|
||||
|
||||
if (!wlr_output_damage_attach_render(
|
||||
output->damage, &needs_frame, &buffer_damage)) {
|
||||
goto buffer_damage_end;
|
||||
}
|
||||
|
||||
if (needs_frame) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
render_output(output, &buffer_damage, &now);
|
||||
}
|
||||
|
||||
buffer_damage_end:
|
||||
pixman_region32_fini(&buffer_damage);
|
||||
|
||||
struct hikari_view *view = NULL;
|
||||
struct hikari_view *view;
|
||||
wl_list_for_each_reverse (view, &output->views, output_views) {
|
||||
hikari_view_interface_for_each_surface(
|
||||
(struct hikari_view_interface *)view, send_frame_done, &now);
|
||||
(struct hikari_view_interface *)view, send_frame_done, now);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XWAYLAND
|
||||
struct hikari_xwayland_unmanaged_view *xwayland_unmanaged_view = NULL;
|
||||
struct hikari_xwayland_unmanaged_view *xwayland_unmanaged_view;
|
||||
wl_list_for_each_reverse (xwayland_unmanaged_view,
|
||||
&output->unmanaged_xwayland_views,
|
||||
unmanaged_server_views) {
|
||||
wlr_surface_for_each_surface(
|
||||
xwayland_unmanaged_view->surface->surface, send_frame_done, &now);
|
||||
xwayland_unmanaged_view->surface->surface, send_frame_done, now);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
for (int i = 0; i < 4; i++) {
|
||||
layer_for_each(&output->layers[i], send_frame_done, &now);
|
||||
layer_for_each(&output->layers[i], send_frame_done, now);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DAMAGE_HANDLER(name, render) \
|
||||
static void name##_handler(struct wl_listener *listener, void *data) \
|
||||
{ \
|
||||
bool needs_frame; \
|
||||
struct timespec now; \
|
||||
struct hikari_output *output = \
|
||||
wl_container_of(listener, output, damage_frame); \
|
||||
\
|
||||
pixman_region32_t buffer_damage; \
|
||||
pixman_region32_init(&buffer_damage); \
|
||||
\
|
||||
clock_gettime(CLOCK_MONOTONIC, &now); \
|
||||
\
|
||||
if (wlr_output_damage_attach_render( \
|
||||
output->damage, &needs_frame, &buffer_damage) && \
|
||||
needs_frame) { \
|
||||
render(output, &buffer_damage, &now); \
|
||||
} \
|
||||
\
|
||||
pixman_region32_fini(&buffer_damage); \
|
||||
\
|
||||
frame_done(output, &now); \
|
||||
}
|
||||
|
||||
DAMAGE_HANDLER(damage_frame, render_output)
|
||||
DAMAGE_HANDLER(damage_empty_frame, render_empty_output)
|
||||
#undef DAMAGE_HANDLER
|
||||
|
||||
void
|
||||
hikari_output_disable_content(struct hikari_output *output)
|
||||
{
|
||||
wl_list_remove(&output->damage_frame.link);
|
||||
output->damage_frame.notify = damage_empty_frame_handler;
|
||||
wl_signal_add(&output->damage->events.frame, &output->damage_frame);
|
||||
|
||||
hikari_output_damage_whole(output);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_output_enable_content(struct hikari_output *output)
|
||||
{
|
||||
wl_list_remove(&output->damage_frame.link);
|
||||
output->damage_frame.notify = damage_frame_handler;
|
||||
wl_signal_add(&output->damage->events.frame, &output->damage_frame);
|
||||
|
||||
hikari_output_damage_whole(output);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_output_damage_whole(struct hikari_output *output)
|
||||
{
|
||||
|
@ -421,6 +523,7 @@ hikari_output_disable(struct hikari_output *output)
|
|||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
wl_list_remove(&output->damage_frame.link);
|
||||
wl_list_init(&output->damage_frame.link);
|
||||
|
||||
wlr_output_rollback(wlr_output);
|
||||
wlr_output_enable(wlr_output, false);
|
||||
|
@ -437,8 +540,6 @@ hikari_output_enable(struct hikari_output *output)
|
|||
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
|
||||
output->damage_frame.notify = damage_frame_handler;
|
||||
wl_signal_add(&output->damage->events.frame, &output->damage_frame);
|
||||
|
||||
wlr_output_enable(wlr_output, true);
|
||||
wlr_output_commit(wlr_output);
|
||||
|
@ -592,8 +693,16 @@ hikari_output_init(struct hikari_output *output, struct wlr_output *wlr_output)
|
|||
wlr_output_set_mode(wlr_output, mode);
|
||||
}
|
||||
|
||||
if (!hikari_server.locked) {
|
||||
wl_list_init(&output->damage_frame.link);
|
||||
|
||||
if (!hikari_server_in_lock_mode()) {
|
||||
hikari_output_enable_content(output);
|
||||
hikari_output_enable(output);
|
||||
} else {
|
||||
hikari_output_disable_content(output);
|
||||
if (hikari_lock_mode_are_outputs_disabled(&hikari_server.lock_mode)) {
|
||||
hikari_output_disable(output);
|
||||
}
|
||||
}
|
||||
|
||||
struct hikari_output_config *output_config =
|
||||
|
@ -655,3 +764,11 @@ hikari_output_move(struct hikari_output *output, double lx, double ly)
|
|||
wlr_output_layout_move(
|
||||
hikari_server.output_layout, output->wlr_output, lx, ly);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_output_render_background(struct hikari_output *output,
|
||||
struct hikari_render_data *render_data,
|
||||
float alpha)
|
||||
{
|
||||
render_background(output, render_data, alpha);
|
||||
}
|
||||
|
|
41
src/server.c
41
src/server.c
|
@ -51,7 +51,6 @@
|
|||
#include <hikari/pointer.h>
|
||||
#include <hikari/pointer_config.h>
|
||||
#include <hikari/sheet.h>
|
||||
#include <hikari/unlocker.h>
|
||||
#include <hikari/workspace.h>
|
||||
#include <hikari/xdg_view.h>
|
||||
|
||||
|
@ -342,10 +341,6 @@ hikari_server_view_interface_at(double x,
|
|||
void
|
||||
hikari_server_cursor_focus(void)
|
||||
{
|
||||
if (!hikari_server_in_normal_mode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec now;
|
||||
uint32_t time_msec = (uint32_t)clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
hikari_server.mode->cursor_move(time_msec);
|
||||
|
@ -744,7 +739,6 @@ server_init(struct hikari_server *server, char *config_path)
|
|||
server->keyboard_state.mod_changed = false;
|
||||
server->keyboard_state.mod_pressed = false;
|
||||
|
||||
server->locked = false;
|
||||
server->cycling = false;
|
||||
server->workspace = NULL;
|
||||
|
||||
|
@ -753,8 +747,6 @@ server_init(struct hikari_server *server, char *config_path)
|
|||
|
||||
wl_list_init(&server->outputs);
|
||||
|
||||
hikari_unlocker_init();
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
server->renderer = wlr_backend_get_renderer(server->backend);
|
||||
|
@ -823,6 +815,7 @@ server_init(struct hikari_server *server, char *config_path)
|
|||
hikari_group_assign_mode_init(&server->group_assign_mode);
|
||||
hikari_input_grab_mode_init(&server->input_grab_mode);
|
||||
hikari_layout_select_mode_init(&server->layout_select_mode);
|
||||
hikari_lock_mode_init(&server->lock_mode);
|
||||
hikari_mark_assign_mode_init(&server->mark_assign_mode);
|
||||
hikari_mark_select_mode_init(&server->mark_select_mode);
|
||||
hikari_move_mode_init(&server->move_mode);
|
||||
|
@ -885,6 +878,7 @@ hikari_server_stop(void)
|
|||
|
||||
hikari_cursor_fini(&hikari_server.cursor);
|
||||
hikari_indicator_fini(&hikari_server.indicator);
|
||||
hikari_lock_mode_fini(&hikari_server.lock_mode);
|
||||
hikari_mark_assign_mode_fini(&hikari_server.mark_assign_mode);
|
||||
|
||||
wlr_seat_destroy(hikari_server.seat);
|
||||
|
@ -928,22 +922,7 @@ hikari_server_find_or_create_group(const char *group_name)
|
|||
void
|
||||
hikari_server_lock(void *arg)
|
||||
{
|
||||
hikari_unlocker_start();
|
||||
|
||||
hikari_server.locked = true;
|
||||
|
||||
hikari_cursor_deactivate(&hikari_server.cursor);
|
||||
|
||||
if (hikari_server.workspace->focus_view != NULL) {
|
||||
hikari_workspace_focus_view(hikari_server.workspace, NULL);
|
||||
}
|
||||
|
||||
wlr_seat_pointer_clear_focus(hikari_server.seat);
|
||||
|
||||
struct hikari_output *output = NULL;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
hikari_output_disable(output);
|
||||
}
|
||||
hikari_lock_mode_enter();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -952,20 +931,6 @@ hikari_server_reload(void *arg)
|
|||
hikari_configuration_reload(hikari_server.config_path);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_server_unlock(void)
|
||||
{
|
||||
hikari_server.locked = false;
|
||||
|
||||
struct hikari_output *output = NULL;
|
||||
wl_list_for_each (output, &hikari_server.outputs, server_outputs) {
|
||||
hikari_output_enable(output);
|
||||
}
|
||||
|
||||
hikari_cursor_activate(&hikari_server.cursor);
|
||||
hikari_server_cursor_focus();
|
||||
}
|
||||
|
||||
#define CYCLE_VIEW(name, link) \
|
||||
static struct hikari_view *cycle_##name##_view(void) \
|
||||
{ \
|
||||
|
|
152
src/unlocker.c
152
src/unlocker.c
|
@ -1,152 +0,0 @@
|
|||
#include <hikari/unlocker.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
|
||||
#include <hikari/keyboard.h>
|
||||
#include <hikari/server.h>
|
||||
#include <hikari/utf8.h>
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
static char input_buffer[BUFFER_SIZE];
|
||||
static int cursor = 0;
|
||||
static int locker_pipe[2][2] = { { -1, -1 }, { -1, -1 } };
|
||||
|
||||
void
|
||||
hikari_unlocker_init(void)
|
||||
{
|
||||
mlock(input_buffer, BUFFER_SIZE);
|
||||
memset(input_buffer, 0, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_unlocker_start(void)
|
||||
{
|
||||
cursor = 0;
|
||||
memset(input_buffer, 0, BUFFER_SIZE);
|
||||
|
||||
pipe(locker_pipe[0]);
|
||||
pipe(locker_pipe[1]);
|
||||
|
||||
pid_t locker = fork();
|
||||
|
||||
if (locker == 0) {
|
||||
close(locker_pipe[0][1]);
|
||||
close(locker_pipe[1][0]);
|
||||
close(0);
|
||||
close(1);
|
||||
dup2(locker_pipe[0][0], 0);
|
||||
dup2(locker_pipe[1][1], 1);
|
||||
execl("/bin/sh", "/bin/sh", "-c", "hikari-unlocker", NULL);
|
||||
exit(0);
|
||||
} else {
|
||||
close(locker_pipe[0][0]);
|
||||
close(locker_pipe[1][1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
put_char(uint32_t codepoint)
|
||||
{
|
||||
size_t length = utf8_chsize(codepoint);
|
||||
|
||||
if (cursor + length < BUFFER_SIZE) {
|
||||
utf8_encode(&input_buffer[cursor], length, codepoint);
|
||||
cursor += length;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_char(void)
|
||||
{
|
||||
if (cursor == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
input_buffer[--cursor] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
submit_password(void)
|
||||
{
|
||||
size_t password_length = strnlen(input_buffer, 1023) + 1;
|
||||
bool success = false;
|
||||
|
||||
write(locker_pipe[0][1], input_buffer, password_length);
|
||||
memset(input_buffer, 0, BUFFER_SIZE);
|
||||
cursor = 0;
|
||||
read(locker_pipe[1][0], &success, sizeof(bool));
|
||||
|
||||
if (success) {
|
||||
int status;
|
||||
hikari_server_unlock();
|
||||
close(locker_pipe[1][0]);
|
||||
close(locker_pipe[0][1]);
|
||||
wait(&status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hikari_unlocker_key_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||
struct wlr_event_keyboard_key *event = data;
|
||||
|
||||
if (event->state == WLR_KEY_PRESSED) {
|
||||
const xkb_keysym_t *syms;
|
||||
uint32_t keycode = event->keycode + 8;
|
||||
uint32_t codepoint;
|
||||
|
||||
int nsyms = xkb_state_key_get_syms(
|
||||
keyboard->device->keyboard->xkb_state, keycode, &syms);
|
||||
|
||||
for (int i = 0; i < nsyms; i++) {
|
||||
switch (syms[i]) {
|
||||
case XKB_KEY_Caps_Lock:
|
||||
case XKB_KEY_Shift_L:
|
||||
case XKB_KEY_Shift_R:
|
||||
case XKB_KEY_Control_L:
|
||||
case XKB_KEY_Control_R:
|
||||
case XKB_KEY_Meta_L:
|
||||
case XKB_KEY_Meta_R:
|
||||
case XKB_KEY_Alt_L:
|
||||
case XKB_KEY_Alt_R:
|
||||
case XKB_KEY_Super_L:
|
||||
case XKB_KEY_Super_R:
|
||||
break;
|
||||
|
||||
case XKB_KEY_BackSpace:
|
||||
delete_char();
|
||||
break;
|
||||
|
||||
case XKB_KEY_Return:
|
||||
submit_password();
|
||||
break;
|
||||
|
||||
default:
|
||||
codepoint = hikari_keyboard_get_codepoint(keyboard, keycode);
|
||||
|
||||
if (codepoint) {
|
||||
put_char(codepoint);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hikari_unlocker_fini(void)
|
||||
{
|
||||
munlock(input_buffer, BUFFER_SIZE);
|
||||
}
|
|
@ -50,6 +50,7 @@ static void
|
|||
move_to_top(struct hikari_view *view)
|
||||
{
|
||||
assert(view != NULL);
|
||||
assert(hikari_view_is_mapped(view));
|
||||
|
||||
wl_list_remove(&view->sheet_views);
|
||||
wl_list_insert(&view->sheet->views, &view->sheet_views);
|
||||
|
|
Loading…
Reference in New Issue