Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abort on escape #25

Merged
merged 3 commits into from
Feb 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions include/slurp.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ struct slurp_state {
struct wl_compositor *compositor;
struct zwlr_layer_shell_v1 *layer_shell;
struct wl_list outputs; // slurp_output::link
struct wl_list pointers; // slurp_pointer::link
struct wl_list seats; // slurp_seat::link

struct {
Expand Down Expand Up @@ -59,25 +58,23 @@ struct slurp_output {
struct wl_cursor_image *cursor_image;
};

struct slurp_pointer {
struct slurp_seat {
struct wl_surface *cursor_surface;
struct slurp_state *state;
struct wl_pointer *wl_pointer;
struct wl_list link; // slurp_state::pointers
struct wl_seat *wl_seat;
struct wl_list link; // slurp_state::seats

int32_t x, y;
int32_t pressed_x, pressed_y;
// keyboard:
struct wl_keyboard *wl_keyboard;

// pointer:
struct wl_pointer *wl_pointer;
enum wl_pointer_button_state button_state;
struct slurp_output *current_output;

struct wl_surface *cursor_surface;
};

struct slurp_seat {
struct wl_seat *wl_seat;
struct wl_list link; // slurp_state::seats
int32_t x, y;
int32_t pressed_x, pressed_y;
};

void pointer_get_box(struct slurp_pointer *pointer, int *x, int *y,
int *width, int *height);
void seat_get_box(struct slurp_seat *seat, struct slurp_box *result);

#endif
138 changes: 71 additions & 67 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,67 +23,66 @@ static struct slurp_output *output_from_surface(struct slurp_state *state,
static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *surface,
wl_fixed_t surface_x, wl_fixed_t surface_y) {
struct slurp_pointer *pointer = data;
struct slurp_output *output = output_from_surface(pointer->state, surface);
struct slurp_seat *seat = data;
struct slurp_output *output = output_from_surface(seat->state, surface);
if (output == NULL) {
return;
}

pointer->x = wl_fixed_to_int(surface_x);
pointer->y = wl_fixed_to_int(surface_y);
seat->x = wl_fixed_to_int(surface_x);
seat->y = wl_fixed_to_int(surface_y);

// TODO: handle multiple overlapping outputs
pointer->current_output = output;
seat->current_output = output;

wl_surface_set_buffer_scale(pointer->cursor_surface, output->scale);
wl_surface_attach(pointer->cursor_surface,
wl_surface_set_buffer_scale(seat->cursor_surface, output->scale);
wl_surface_attach(seat->cursor_surface,
wl_cursor_image_get_buffer(output->cursor_image), 0, 0);
wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface,
wl_pointer_set_cursor(wl_pointer, serial, seat->cursor_surface,
output->cursor_image->hotspot_x / output->scale,
output->cursor_image->hotspot_y / output->scale);
wl_surface_commit(pointer->cursor_surface);
wl_surface_commit(seat->cursor_surface);
}

static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *surface) {
struct slurp_pointer *pointer = data;
struct slurp_seat *seat = data;

// TODO: handle multiple overlapping outputs
pointer->current_output = NULL;
seat->current_output = NULL;
}

static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
struct slurp_pointer *pointer = data;
struct slurp_seat *seat = data;

pointer->x = wl_fixed_to_int(surface_x);
pointer->y = wl_fixed_to_int(surface_y);
seat->x = wl_fixed_to_int(surface_x);
seat->y = wl_fixed_to_int(surface_y);

if (pointer->button_state == WL_POINTER_BUTTON_STATE_PRESSED &&
pointer->current_output != NULL) {
set_output_dirty(pointer->current_output);
if (seat->button_state == WL_POINTER_BUTTON_STATE_PRESSED &&
seat->current_output != NULL) {
set_output_dirty(seat->current_output);
}
}

static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button,
uint32_t button_state) {
struct slurp_pointer *pointer = data;
struct slurp_state *state = pointer->state;
struct slurp_seat *seat = data;
struct slurp_state *state = seat->state;

pointer->button_state = button_state;
seat->button_state = button_state;

switch (button_state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
pointer->pressed_x = pointer->x;
pointer->pressed_y = pointer->y;
seat->pressed_x = seat->x;
seat->pressed_y = seat->y;
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
pointer_get_box(pointer, &state->result.x, &state->result.y,
&state->result.width, &state->result.height);
if (pointer->current_output != NULL) {
state->result.x += pointer->current_output->geometry.x;
state->result.y += pointer->current_output->geometry.y;
seat_get_box(seat, &state->result);
if (seat->current_output != NULL) {
state->result.x += seat->current_output->geometry.x;
state->result.y += seat->current_output->geometry.y;
}
state->running = false;
break;
Expand All @@ -98,47 +97,48 @@ static const struct wl_pointer_listener pointer_listener = {
.axis = noop,
};

static void create_pointer(struct slurp_state *state,
struct wl_pointer *wl_pointer) {
struct slurp_pointer *pointer = calloc(1, sizeof(struct slurp_pointer));
if (pointer == NULL) {
fprintf(stderr, "allocation failed\n");
return;
}
pointer->state = state;
pointer->wl_pointer = wl_pointer;
wl_list_insert(&state->pointers, &pointer->link);

wl_pointer_add_listener(wl_pointer, &pointer_listener, pointer);
static int min(int a, int b) {
return (a < b) ? a : b;
}

static void destroy_pointer(struct slurp_pointer *pointer) {
wl_list_remove(&pointer->link);
wl_surface_destroy(pointer->cursor_surface);
wl_pointer_destroy(pointer->wl_pointer);
free(pointer);
void seat_get_box(struct slurp_seat *seat, struct slurp_box *result) {
result->x = min(seat->pressed_x, seat->x);
result->y = min(seat->pressed_y, seat->y);
result->width = abs(seat->x - seat->pressed_x);
result->height = abs(seat->y - seat->pressed_y);
}

static int min(int a, int b) {
return (a < b) ? a : b;
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, uint32_t time, uint32_t key, uint32_t key_state) {
struct slurp_seat *seat = data;
struct slurp_state *state = seat->state;
if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) {
if (key == KEY_ESC) {
state->running = false;
}
}
}

void pointer_get_box(struct slurp_pointer *pointer, int *x, int *y,
int *width, int *height) {
*x = min(pointer->pressed_x, pointer->x);
*y = min(pointer->pressed_y, pointer->y);
*width = abs(pointer->x - pointer->pressed_x);
*height = abs(pointer->y - pointer->pressed_y);
}
static const struct wl_keyboard_listener keyboard_listener = {
.keymap = noop,
.enter = noop,
.leave = noop,
.key = keyboard_handle_key,
.modifiers = noop,
};


static void seat_handle_capabilities(void *data, struct wl_seat *seat,
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
uint32_t capabilities) {
struct slurp_state *state = data;
struct slurp_seat *seat = data;

if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
struct wl_pointer *wl_pointer = wl_seat_get_pointer(seat);
create_pointer(state, wl_pointer);
seat->wl_pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
}
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
seat->wl_keyboard = wl_seat_get_keyboard(wl_seat);
wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener, seat);
}
}

Expand All @@ -152,13 +152,21 @@ static void create_seat(struct slurp_state *state, struct wl_seat *wl_seat) {
fprintf(stderr, "allocation failed\n");
return;
}
seat->state = state;
seat->wl_seat = wl_seat;
wl_list_insert(&state->seats, &seat->link);
wl_seat_add_listener(wl_seat, &seat_listener, state);
wl_seat_add_listener(wl_seat, &seat_listener, seat);
}

static void destroy_seat(struct slurp_seat *seat) {
wl_list_remove(&seat->link);
wl_surface_destroy(seat->cursor_surface);
if (seat->wl_pointer) {
wl_pointer_destroy(seat->wl_pointer);
}
if (seat->wl_keyboard) {
wl_keyboard_destroy(seat->wl_keyboard);
}
wl_seat_destroy(seat->wl_seat);
free(seat);
}
Expand Down Expand Up @@ -417,7 +425,6 @@ int main(int argc, char *argv[]) {
}

wl_list_init(&state.outputs);
wl_list_init(&state.pointers);
wl_list_init(&state.seats);

state.display = wl_display_connect(NULL);
Expand Down Expand Up @@ -464,6 +471,7 @@ int main(int argc, char *argv[]) {
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM);
zwlr_layer_surface_v1_set_keyboard_interactivity(output->layer_surface, true);
zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1);
wl_surface_commit(output->surface);

Expand All @@ -487,9 +495,9 @@ int main(int argc, char *argv[]) {
output->cursor_image = cursor->images[0];
}

struct slurp_pointer *pointer;
wl_list_for_each(pointer, &state.pointers, link) {
pointer->cursor_surface =
struct slurp_seat *seat;
wl_list_for_each(seat, &state.seats, link) {
seat->cursor_surface =
wl_compositor_create_surface(state.compositor);
}

Expand All @@ -498,15 +506,11 @@ int main(int argc, char *argv[]) {
// This space intentionally left blank
}

struct slurp_pointer *pointer_tmp;
wl_list_for_each_safe(pointer, pointer_tmp, &state.pointers, link) {
destroy_pointer(pointer);
}
struct slurp_output *output_tmp;
wl_list_for_each_safe(output, output_tmp, &state.outputs, link) {
destroy_output(output);
}
struct slurp_seat *seat, *seat_tmp;
struct slurp_seat *seat_tmp;
wl_list_for_each_safe(seat, seat_tmp, &state.seats, link) {
destroy_seat(seat);
}
Expand Down
25 changes: 13 additions & 12 deletions render.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,27 @@ void render(struct slurp_output *output) {
set_source_u32(cairo, state->colors.background);
cairo_paint(cairo);

struct slurp_pointer *pointer;
wl_list_for_each(pointer, &state->pointers, link) {
if (pointer->button_state != WL_POINTER_BUTTON_STATE_PRESSED ||
pointer->current_output != output) {
struct slurp_seat *seat;
wl_list_for_each(seat, &state->seats, link) {
if (!seat->wl_pointer) continue;
if (seat->button_state != WL_POINTER_BUTTON_STATE_PRESSED ||
seat->current_output != output) {
continue;
}

int x, y, width, height;
pointer_get_box(pointer, &x, &y, &width, &height);
struct slurp_box b;
seat_get_box(seat, &b);

// Draw border
set_source_u32(cairo, state->colors.selection);
cairo_rectangle(cairo, x * scale, y * scale,
width * scale, height * scale);
cairo_rectangle(cairo, b.x * scale, b.y * scale,
b.width * scale, b.height * scale);
cairo_fill(cairo);

set_source_u32(cairo, state->colors.border);
cairo_set_line_width(cairo, state->border_weight * scale);
cairo_rectangle(cairo, x * scale, y * scale,
width * scale, height * scale);
cairo_rectangle(cairo, b.x * scale, b.y * scale,
b.width * scale, b.height * scale);
cairo_stroke(cairo);

if (state->display_dimensions) {
Expand All @@ -53,8 +54,8 @@ void render(struct slurp_output *output) {
cairo_set_font_size(cairo, 14 * scale);
// buffer of 12 can hold selections up to 99999x99999
char dimensions[12];
snprintf(dimensions, sizeof(dimensions), "%ix%i", width, height);
cairo_move_to(cairo, (x + width + 10) * scale, (y + height + 20) * scale);
snprintf(dimensions, sizeof(dimensions), "%ix%i", b.width, b.height);
cairo_move_to(cairo, (b.x + b.width + 10) * scale, (b.y + b.height + 20) * scale);
cairo_show_text(cairo, dimensions);
}
}
Expand Down