mirror of
https://codeberg.org/vyivel/dulcepan/
synced 2025-03-12 18:59:15 +02:00
More scale changes :3
Surely this has no bugs in it
This commit is contained in:
parent
8794cbdeb2
commit
bc97934371
@ -92,7 +92,7 @@ struct dp_seat {
|
||||
// The output the pointer is on
|
||||
struct dp_output *ptr_output;
|
||||
// In buffer space
|
||||
int ptr_x, ptr_y;
|
||||
double ptr_x, ptr_y;
|
||||
|
||||
struct wl_list link;
|
||||
};
|
||||
@ -114,15 +114,15 @@ enum dp_resize_edges {
|
||||
|
||||
struct dp_selection {
|
||||
struct dp_output *output; // May be NULL
|
||||
int x, y, width, height;
|
||||
double x, y, width, height;
|
||||
|
||||
enum dp_selection_action action;
|
||||
bool action_active;
|
||||
// Pointer offset to apply during movement
|
||||
int ptr_off_x, ptr_off_y;
|
||||
double ptr_off_x, ptr_off_y;
|
||||
int resize_edges;
|
||||
// Resize anchor
|
||||
int resize_x, resize_y;
|
||||
double resize_x, resize_y;
|
||||
};
|
||||
|
||||
enum dp_file_format {
|
||||
@ -213,12 +213,12 @@ void dp_output_hide_surface(struct dp_output *output);
|
||||
void dp_seat_create(struct dp_state *state, uint32_t name, struct wl_seat *wl_seat);
|
||||
void dp_seat_destroy(struct dp_seat *seat);
|
||||
|
||||
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, int x,
|
||||
int y, bool modify_existing);
|
||||
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
|
||||
double y, bool modify_existing);
|
||||
void dp_select_stop_interactive(struct dp_selection *selection);
|
||||
|
||||
void dp_select_notify_pointer_position(
|
||||
struct dp_selection *selection, struct dp_output *output, int x, int y);
|
||||
struct dp_selection *selection, struct dp_output *output, double x, double y);
|
||||
|
||||
void dp_select_whole(struct dp_selection *selection, struct dp_output *output);
|
||||
|
||||
|
39
src/output.c
39
src/output.c
@ -272,8 +272,8 @@ static inline uint32_t get_time_msec(void) {
|
||||
return (uint32_t)(now.tv_sec * 1000 + now.tv_nsec / 1000000);
|
||||
}
|
||||
|
||||
static void setup_linear_gradient(cairo_t *cairo, struct dp_state *state) {
|
||||
struct dp_selection *selection = &state->selection;
|
||||
static void setup_linear_gradient(
|
||||
cairo_t *cairo, struct dp_state *state, double x, double y, double width, double height) {
|
||||
struct dp_config *config = &state->config;
|
||||
|
||||
cairo_matrix_t matrix;
|
||||
@ -285,25 +285,25 @@ static void setup_linear_gradient(cairo_t *cairo, struct dp_state *state) {
|
||||
matrix = state->precomputed_linear_matrix;
|
||||
}
|
||||
|
||||
cairo_matrix_scale(&matrix, 1.0 / selection->width, 1.0 / selection->height);
|
||||
cairo_matrix_translate(&matrix, -selection->x, -selection->y);
|
||||
cairo_matrix_scale(&matrix, 1.0 / width, 1.0 / height);
|
||||
cairo_matrix_translate(&matrix, -x, -y);
|
||||
|
||||
cairo_pattern_set_matrix(state->border_pattern, &matrix);
|
||||
cairo_set_source(cairo, state->border_pattern);
|
||||
}
|
||||
|
||||
static void setup_loop_gradient(cairo_t *cairo, struct dp_state *state) {
|
||||
static void setup_loop_gradient(
|
||||
cairo_t *cairo, struct dp_state *state, double x, double y, double width, double height) {
|
||||
struct dp_selection *selection = &state->selection;
|
||||
struct dp_config *config = &state->config;
|
||||
|
||||
double scale = state->loop_step_scale / selection->output->scale;
|
||||
|
||||
double offset =
|
||||
(selection->x + selection->y + (selection->width + selection->height) / 2.0) * scale;
|
||||
double offset = (x + y + (width + height) / 2.0) * state->loop_step_scale;
|
||||
if (config->animation_duration != 0) {
|
||||
offset += (double)get_time_msec() * state->time_multiplier / selection->output->scale;
|
||||
offset += (double)get_time_msec() * state->time_multiplier;
|
||||
}
|
||||
|
||||
double scale = state->loop_step_scale / selection->output->scale;
|
||||
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_init(&matrix, scale, 0, 0, scale, fmod(offset, 2.0), 0);
|
||||
|
||||
@ -345,31 +345,34 @@ static void redraw(struct dp_output *output) {
|
||||
cairo_paint(buffer->cairo);
|
||||
|
||||
if (output == selection->output) {
|
||||
double scale = output->scale;
|
||||
double x = selection->x * scale, y = selection->y * scale;
|
||||
double width = selection->width * scale, height = selection->height * scale;
|
||||
|
||||
int border_size = config->border_size;
|
||||
if (border_size != 0 && selection->width != 0 && selection->height != 0) {
|
||||
double scaled_size = border_size * output->scale;
|
||||
if (border_size != 0 && width != 0 && height != 0) {
|
||||
double scaled_size = border_size * scale;
|
||||
cairo_set_line_width(buffer->cairo, scaled_size);
|
||||
double off = scaled_size / 2.0;
|
||||
cairo_rectangle(buffer->cairo, selection->x - off, selection->y - off,
|
||||
selection->width + scaled_size, selection->height + scaled_size);
|
||||
cairo_rectangle(
|
||||
buffer->cairo, x - off, y - off, width + scaled_size, height + scaled_size);
|
||||
|
||||
switch (config->border_gradient) {
|
||||
case DP_BORDER_GRADIENT_NONE:
|
||||
set_cairo_color(buffer->cairo, config->border_color);
|
||||
break;
|
||||
case DP_BORDER_GRADIENT_LINEAR:
|
||||
setup_linear_gradient(buffer->cairo, state);
|
||||
setup_linear_gradient(buffer->cairo, state, x, y, width, height);
|
||||
break;
|
||||
case DP_BORDER_GRADIENT_LOOP:
|
||||
setup_loop_gradient(buffer->cairo, state);
|
||||
setup_loop_gradient(buffer->cairo, state, x, y, width, height);
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_stroke(buffer->cairo);
|
||||
}
|
||||
|
||||
cairo_rectangle(
|
||||
buffer->cairo, selection->x, selection->y, selection->width, selection->height);
|
||||
cairo_rectangle(buffer->cairo, x, y, width, height);
|
||||
set_cairo_color(buffer->cairo, config->selected_color);
|
||||
cairo_fill(buffer->cairo);
|
||||
|
||||
|
@ -28,7 +28,7 @@ void dp_persistent_load(struct dp_state *state) {
|
||||
}
|
||||
|
||||
char name[32];
|
||||
int x, y, width, height;
|
||||
double x, y, width, height;
|
||||
int n_read = 0;
|
||||
|
||||
fgets(name, sizeof(name), fp);
|
||||
@ -36,7 +36,7 @@ void dp_persistent_load(struct dp_state *state) {
|
||||
if (name[name_len - 1] == '\n') {
|
||||
name[--name_len] = '\0';
|
||||
}
|
||||
n_read += fscanf(fp, "%d %d %d %d", &x, &y, &width, &height);
|
||||
n_read += fscanf(fp, "%lf %lf %lf %lf", &x, &y, &width, &height);
|
||||
|
||||
bool ok = ferror(fp) == 0 && n_read == 4;
|
||||
fclose(fp);
|
||||
@ -61,8 +61,8 @@ void dp_persistent_load(struct dp_state *state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x < 0 || y < 0 || x + width > selection_output->transformed_width ||
|
||||
y + height > selection_output->transformed_height) {
|
||||
if (x < 0 || y < 0 || x + width > selection_output->effective_width ||
|
||||
y + height > selection_output->effective_height) {
|
||||
dp_log_error("Persistent state: invalid selection geometry", name);
|
||||
return;
|
||||
}
|
||||
@ -84,7 +84,7 @@ void dp_persistent_save(struct dp_state *state) {
|
||||
} else {
|
||||
fprintf(fp,
|
||||
"%s\n"
|
||||
"%d %d %d %d\n",
|
||||
"%lf %lf %lf %lf\n",
|
||||
selection->output->name, selection->x, selection->y, selection->width,
|
||||
selection->height);
|
||||
fclose(fp);
|
||||
|
18
src/save.c
18
src/save.c
@ -140,10 +140,15 @@ void dp_save(struct dp_state *state) {
|
||||
|
||||
pixman_image_set_transform(frame_image, &frame_transform);
|
||||
|
||||
pixman_image_t *out_image =
|
||||
pixman_image_create_bits(PIXMAN_a8b8g8r8, selection->width, selection->height, NULL, 0);
|
||||
pixman_image_composite32(PIXMAN_OP_SRC, frame_image, NULL, out_image, selection->x,
|
||||
selection->y, 0, 0, 0, 0, selection->width, selection->height);
|
||||
double scale = output->scale;
|
||||
|
||||
int x = (int)round(selection->x * scale), y = (int)round(selection->y * scale);
|
||||
int width = (int)round(selection->width * scale),
|
||||
height = (int)round(selection->height * scale);
|
||||
|
||||
pixman_image_t *out_image = pixman_image_create_bits(PIXMAN_a8b8g8r8, width, height, NULL, 0);
|
||||
pixman_image_composite32(
|
||||
PIXMAN_OP_SRC, frame_image, NULL, out_image, x, y, 0, 0, 0, 0, width, height);
|
||||
pixman_image_unref(frame_image);
|
||||
|
||||
FILE *fp = NULL;
|
||||
@ -160,11 +165,10 @@ void dp_save(struct dp_state *state) {
|
||||
case DP_FILE_UNKNOWN:
|
||||
abort(); // Unreachable
|
||||
case DP_FILE_PNG:
|
||||
write_png(
|
||||
fp, out_image, selection->width, selection->height, state->config.png_compression);
|
||||
write_png(fp, out_image, width, height, state->config.png_compression);
|
||||
break;
|
||||
case DP_FILE_PPM:
|
||||
write_ppm(fp, out_image, selection->width, selection->height);
|
||||
write_ppm(fp, out_image, width, height);
|
||||
break;
|
||||
}
|
||||
|
||||
|
11
src/seat.c
11
src/seat.c
@ -111,9 +111,10 @@ static enum wp_cursor_shape_device_v1_shape get_cursor_shape(struct dp_selection
|
||||
}
|
||||
break;
|
||||
case DP_SELECTION_ACTION_MOVING:
|
||||
// XXX: this might have rounding issues but whatever
|
||||
if (selection->x == 0 && selection->y == 0 &&
|
||||
selection->width == selection->output->width &&
|
||||
selection->height == selection->output->height) {
|
||||
selection->width == selection->output->effective_width &&
|
||||
selection->height == selection->output->effective_height) {
|
||||
// Moving is impossible
|
||||
return WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
|
||||
}
|
||||
@ -129,10 +130,8 @@ static void update_cursor(struct dp_seat *seat, uint32_t serial) {
|
||||
|
||||
static void process_position(struct dp_seat *seat, wl_fixed_t x, wl_fixed_t y, uint32_t serial) {
|
||||
struct dp_output *output = seat->ptr_output;
|
||||
seat->ptr_x =
|
||||
(int)(wl_fixed_to_double(x) * output->transformed_width / output->effective_width);
|
||||
seat->ptr_y =
|
||||
(int)(wl_fixed_to_double(y) * output->transformed_height / output->effective_height);
|
||||
seat->ptr_x = wl_fixed_to_double(x);
|
||||
seat->ptr_y = wl_fixed_to_double(y);
|
||||
dp_select_notify_pointer_position(&seat->state->selection, output, seat->ptr_x, seat->ptr_y);
|
||||
update_cursor(seat, serial);
|
||||
}
|
||||
|
67
src/select.c
67
src/select.c
@ -20,31 +20,30 @@ static void set_selected_output(struct dp_selection *selection, struct dp_output
|
||||
}
|
||||
}
|
||||
|
||||
static void update_action(struct dp_selection *selection, struct dp_output *output, int x, int y) {
|
||||
static void update_action(
|
||||
struct dp_selection *selection, struct dp_output *output, double x, double y) {
|
||||
if (output == selection->output) {
|
||||
int sx = x - selection->x;
|
||||
int sy = y - selection->y;
|
||||
double sx = x - selection->x;
|
||||
double sy = y - selection->y;
|
||||
|
||||
int inner = (int)ceil(RESIZE_INNER_SIZE * output->scale);
|
||||
int outer = (int)ceil(RESIZE_OUTER_SIZE * output->scale);
|
||||
int threshold = (int)ceil(RESIZE_THRESHOLD * output->scale);
|
||||
|
||||
if (sx >= inner && sy >= inner && sx < selection->width - inner &&
|
||||
sy <= selection->height - inner) {
|
||||
if (sx >= RESIZE_INNER_SIZE && sy >= RESIZE_INNER_SIZE &&
|
||||
sx < selection->width - RESIZE_INNER_SIZE &&
|
||||
sy <= selection->height - RESIZE_INNER_SIZE) {
|
||||
selection->action = DP_SELECTION_ACTION_MOVING;
|
||||
return;
|
||||
} else if (sx >= -outer && sy >= -outer && sx < selection->width + outer &&
|
||||
sy < selection->height + outer) {
|
||||
} else if (sx >= -RESIZE_OUTER_SIZE && sy >= -RESIZE_OUTER_SIZE &&
|
||||
sx < selection->width + RESIZE_OUTER_SIZE &&
|
||||
sy < selection->height + RESIZE_OUTER_SIZE) {
|
||||
int edges = DP_EDGE_NONE;
|
||||
|
||||
if (sx >= selection->width - threshold && sx >= selection->width / 2) {
|
||||
if (sx >= selection->width - RESIZE_THRESHOLD && sx >= selection->width / 2) {
|
||||
edges |= DP_EDGE_RIGHT;
|
||||
} else if (sx < threshold) {
|
||||
} else if (sx < RESIZE_THRESHOLD) {
|
||||
edges |= DP_EDGE_LEFT;
|
||||
}
|
||||
if (sy >= selection->height - threshold && sy >= selection->height / 2) {
|
||||
if (sy >= selection->height - RESIZE_THRESHOLD && sy >= selection->height / 2) {
|
||||
edges |= DP_EDGE_BOTTOM;
|
||||
} else if (sy < threshold) {
|
||||
} else if (sy < RESIZE_THRESHOLD) {
|
||||
edges |= DP_EDGE_TOP;
|
||||
}
|
||||
|
||||
@ -59,20 +58,20 @@ static void update_action(struct dp_selection *selection, struct dp_output *outp
|
||||
selection->action = DP_SELECTION_ACTION_NONE;
|
||||
}
|
||||
|
||||
static void do_resize(struct dp_selection *selection, int x, int y) {
|
||||
int ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y;
|
||||
static void do_resize(struct dp_selection *selection, double x, double y) {
|
||||
double ptr_x = x - selection->ptr_off_x, ptr_y = y - selection->ptr_off_y;
|
||||
if (ptr_x < 0) {
|
||||
ptr_x = 0;
|
||||
} else if (ptr_x > selection->output->transformed_width) {
|
||||
ptr_x = selection->output->transformed_width;
|
||||
} else if (ptr_x > selection->output->effective_width) {
|
||||
ptr_x = selection->output->effective_width;
|
||||
}
|
||||
if (ptr_y < 0) {
|
||||
ptr_y = 0;
|
||||
} else if (ptr_y > selection->output->transformed_height) {
|
||||
ptr_y = selection->output->transformed_height;
|
||||
} else if (ptr_y > selection->output->effective_height) {
|
||||
ptr_y = selection->output->effective_height;
|
||||
}
|
||||
|
||||
int width = selection->width, height = selection->height;
|
||||
double width = selection->width, height = selection->height;
|
||||
|
||||
retry_horiz:
|
||||
if ((selection->resize_edges & DP_EDGE_LEFT) != 0) {
|
||||
@ -117,18 +116,18 @@ retry_verti:
|
||||
dp_output_redraw(selection->output);
|
||||
}
|
||||
|
||||
static void do_move(struct dp_selection *selection, int x, int y) {
|
||||
int new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y;
|
||||
static void do_move(struct dp_selection *selection, double x, double y) {
|
||||
double new_x = x - selection->ptr_off_x, new_y = y - selection->ptr_off_y;
|
||||
|
||||
if (new_x < 0) {
|
||||
new_x = 0;
|
||||
} else if (new_x > selection->output->transformed_width - selection->width) {
|
||||
new_x = selection->output->transformed_width - selection->width;
|
||||
} else if (new_x > selection->output->effective_width - selection->width) {
|
||||
new_x = selection->output->effective_width - selection->width;
|
||||
}
|
||||
if (new_y < 0) {
|
||||
new_y = 0;
|
||||
} else if (new_y > selection->output->transformed_height - selection->height) {
|
||||
new_y = selection->output->transformed_height - selection->height;
|
||||
} else if (new_y > selection->output->effective_height - selection->height) {
|
||||
new_y = selection->output->effective_height - selection->height;
|
||||
}
|
||||
|
||||
if (new_x == selection->x && new_y == selection->y) {
|
||||
@ -140,7 +139,7 @@ static void do_move(struct dp_selection *selection, int x, int y) {
|
||||
dp_output_redraw(selection->output);
|
||||
}
|
||||
|
||||
static void init_resize(struct dp_selection *selection, int x, int y) {
|
||||
static void init_resize(struct dp_selection *selection, double x, double y) {
|
||||
if ((selection->resize_edges & DP_EDGE_RIGHT) != 0) {
|
||||
selection->ptr_off_x = x - selection->x - selection->width;
|
||||
selection->resize_x = selection->x;
|
||||
@ -157,8 +156,8 @@ static void init_resize(struct dp_selection *selection, int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, int x,
|
||||
int y, bool modify_existing) {
|
||||
void dp_select_start_interactive(struct dp_selection *selection, struct dp_output *output, double x,
|
||||
double y, bool modify_existing) {
|
||||
update_action(selection, output, x, y);
|
||||
selection->action_active = true;
|
||||
|
||||
@ -195,7 +194,7 @@ void dp_select_stop_interactive(struct dp_selection *selection) {
|
||||
}
|
||||
|
||||
void dp_select_notify_pointer_position(
|
||||
struct dp_selection *selection, struct dp_output *output, int x, int y) {
|
||||
struct dp_selection *selection, struct dp_output *output, double x, double y) {
|
||||
if (selection->action_active) {
|
||||
switch (selection->action) {
|
||||
case DP_SELECTION_ACTION_NONE:
|
||||
@ -217,8 +216,8 @@ void dp_select_whole(struct dp_selection *selection, struct dp_output *output) {
|
||||
|
||||
selection->x = 0;
|
||||
selection->y = 0;
|
||||
selection->width = output->transformed_width;
|
||||
selection->height = output->transformed_height;
|
||||
selection->width = output->effective_width;
|
||||
selection->height = output->effective_height;
|
||||
|
||||
dp_output_redraw(output);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user