mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-02 09:01:39 -05:00
Render selection
This commit is contained in:
parent
23c03ad981
commit
5982658d62
2 changed files with 105 additions and 6 deletions
|
|
@ -395,6 +395,9 @@ struct terminal {
|
||||||
struct wl_selection *selection;
|
struct wl_selection *selection;
|
||||||
struct wl_selection_offer *selection_offer;
|
struct wl_selection_offer *selection_offer;
|
||||||
uint32_t selection_offer_has_text;
|
uint32_t selection_offer_has_text;
|
||||||
|
int32_t dragging, selection_active;
|
||||||
|
int selection_start_x, selection_start_y;
|
||||||
|
int selection_end_x, selection_end_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create default tab stops, every 8 characters */
|
/* Create default tab stops, every 8 characters */
|
||||||
|
|
@ -492,16 +495,62 @@ union decoded_attr {
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
terminal_compare_position(struct terminal *terminal,
|
||||||
|
int x, int y, int32_t ref_row, int32_t ref_col)
|
||||||
|
{
|
||||||
|
struct rectangle allocation;
|
||||||
|
int top_margin, side_margin, col, row, ref_x;
|
||||||
|
|
||||||
|
window_get_child_allocation(terminal->window, &allocation);
|
||||||
|
side_margin = allocation.x + (allocation.width - terminal->width * terminal->extents.max_x_advance) / 2;
|
||||||
|
top_margin = allocation.y + (allocation.height - terminal->height * terminal->extents.height) / 2;
|
||||||
|
|
||||||
|
col = (x - side_margin) / terminal->extents.max_x_advance;
|
||||||
|
row = (y - top_margin) / terminal->extents.height;
|
||||||
|
|
||||||
|
ref_x = side_margin + ref_col * terminal->extents.max_x_advance +
|
||||||
|
terminal->extents.max_x_advance / 2;
|
||||||
|
|
||||||
|
if (row < ref_row)
|
||||||
|
return -1;
|
||||||
|
if (row == ref_row) {
|
||||||
|
if (col < ref_col)
|
||||||
|
return -1;
|
||||||
|
if (col == ref_col && x < ref_x)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
||||||
union decoded_attr *decoded)
|
union decoded_attr *decoded)
|
||||||
{
|
{
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
int foreground, background, tmp;
|
int foreground, background, tmp;
|
||||||
|
int inverse = 0, start_cmp, end_cmp;
|
||||||
|
|
||||||
|
start_cmp =
|
||||||
|
terminal_compare_position(terminal,
|
||||||
|
terminal->selection_start_x,
|
||||||
|
terminal->selection_start_y,
|
||||||
|
row, col);
|
||||||
|
end_cmp =
|
||||||
|
terminal_compare_position(terminal,
|
||||||
|
terminal->selection_end_x,
|
||||||
|
terminal->selection_end_y,
|
||||||
|
row, col);
|
||||||
|
if (start_cmp < 0 && end_cmp > 0)
|
||||||
|
inverse = 1;
|
||||||
|
else if (end_cmp < 0 && start_cmp > 0)
|
||||||
|
inverse = 1;
|
||||||
|
|
||||||
/* get the attributes for this character cell */
|
/* get the attributes for this character cell */
|
||||||
attr = terminal_get_attr_row(terminal, row)[col];
|
attr = terminal_get_attr_row(terminal, row)[col];
|
||||||
if ((attr.a & ATTRMASK_INVERSE) ||
|
if ((attr.a & ATTRMASK_INVERSE) ||
|
||||||
|
inverse ||
|
||||||
((terminal->mode & MODE_SHOW_CURSOR) &&
|
((terminal->mode & MODE_SHOW_CURSOR) &&
|
||||||
terminal->focused && terminal->row == row &&
|
terminal->focused && terminal->row == row &&
|
||||||
terminal->column == col)) {
|
terminal->column == col)) {
|
||||||
|
|
@ -835,7 +884,6 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
{
|
{
|
||||||
struct rectangle allocation;
|
struct rectangle allocation;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_font_extents_t extents;
|
|
||||||
int top_margin, side_margin;
|
int top_margin, side_margin;
|
||||||
int row, col;
|
int row, col;
|
||||||
union utf8_char *p_row;
|
union utf8_char *p_row;
|
||||||
|
|
@ -844,6 +892,7 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
double d;
|
double d;
|
||||||
struct glyph_run run;
|
struct glyph_run run;
|
||||||
|
cairo_font_extents_t extents;
|
||||||
|
|
||||||
window_get_child_allocation(terminal->window, &allocation);
|
window_get_child_allocation(terminal->window, &allocation);
|
||||||
|
|
||||||
|
|
@ -855,7 +904,7 @@ terminal_draw_contents(struct terminal *terminal)
|
||||||
|
|
||||||
cairo_set_scaled_font(cr, terminal->font_normal);
|
cairo_set_scaled_font(cr, terminal->font_normal);
|
||||||
|
|
||||||
cairo_font_extents(cr, &extents);
|
extents = terminal->extents;
|
||||||
side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 2;
|
side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 2;
|
||||||
top_margin = (allocation.height - terminal->height * extents.height) / 2;
|
top_margin = (allocation.height - terminal->height * extents.height) / 2;
|
||||||
|
|
||||||
|
|
@ -1880,19 +1929,16 @@ static void
|
||||||
selection_listener_send(void *data, struct wl_selection *selection,
|
selection_listener_send(void *data, struct wl_selection *selection,
|
||||||
const char *mime_type, int fd)
|
const char *mime_type, int fd)
|
||||||
{
|
{
|
||||||
struct terminal *terminal = data;
|
|
||||||
static const char msg[] = "selection data";
|
static const char msg[] = "selection data";
|
||||||
|
|
||||||
fprintf(stderr, "selection send, fd is %d\n", fd);
|
fprintf(stderr, "selection send, fd is %d\n", fd);
|
||||||
write(fd, msg, sizeof msg);
|
write(fd, msg, sizeof msg - 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
selection_listener_cancelled(void *data, struct wl_selection *selection)
|
selection_listener_cancelled(void *data, struct wl_selection *selection)
|
||||||
{
|
{
|
||||||
struct terminal *terminal = data;
|
|
||||||
|
|
||||||
fprintf(stderr, "selection cancelled\n");
|
fprintf(stderr, "selection cancelled\n");
|
||||||
wl_selection_destroy(selection);
|
wl_selection_destroy(selection);
|
||||||
}
|
}
|
||||||
|
|
@ -1914,6 +1960,8 @@ selection_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
|
||||||
len = read(fd, buffer, sizeof buffer);
|
len = read(fd, buffer, sizeof buffer);
|
||||||
fprintf(stderr, "read %d bytes: %.*s\n", len, len, buffer);
|
fprintf(stderr, "read %d bytes: %.*s\n", len, len, buffer);
|
||||||
|
|
||||||
|
write(terminal->master, buffer, len);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
g_source_remove(terminal->tag);
|
g_source_remove(terminal->tag);
|
||||||
|
|
||||||
|
|
@ -2102,6 +2150,50 @@ keyboard_focus_handler(struct window *window,
|
||||||
window_schedule_redraw(terminal->window);
|
window_schedule_redraw(terminal->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
button_handler(struct window *window,
|
||||||
|
struct input *input, uint32_t time,
|
||||||
|
int button, int state, void *data)
|
||||||
|
{
|
||||||
|
struct terminal *terminal = data;
|
||||||
|
|
||||||
|
switch (button) {
|
||||||
|
case 272:
|
||||||
|
if (state) {
|
||||||
|
terminal->dragging = 1;
|
||||||
|
terminal->selection_active = 0;
|
||||||
|
input_get_position(input,
|
||||||
|
&terminal->selection_start_x,
|
||||||
|
&terminal->selection_start_y);
|
||||||
|
terminal->selection_end_x = terminal->selection_start_x;
|
||||||
|
terminal->selection_end_y = terminal->selection_start_y;
|
||||||
|
window_schedule_redraw(window);
|
||||||
|
} else {
|
||||||
|
terminal->dragging = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
motion_handler(struct window *window,
|
||||||
|
struct input *input, uint32_t time,
|
||||||
|
int32_t x, int32_t y,
|
||||||
|
int32_t sx, int32_t sy, void *data)
|
||||||
|
{
|
||||||
|
struct terminal *terminal = data;
|
||||||
|
|
||||||
|
if (terminal->dragging) {
|
||||||
|
terminal->selection_active = 1;
|
||||||
|
input_get_position(input,
|
||||||
|
&terminal->selection_end_x,
|
||||||
|
&terminal->selection_end_y);
|
||||||
|
window_schedule_redraw(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
return POINTER_IBEAM;
|
||||||
|
}
|
||||||
|
|
||||||
static struct terminal *
|
static struct terminal *
|
||||||
terminal_create(struct display *display, int fullscreen)
|
terminal_create(struct display *display, int fullscreen)
|
||||||
{
|
{
|
||||||
|
|
@ -2136,6 +2228,8 @@ terminal_create(struct display *display, int fullscreen)
|
||||||
window_set_key_handler(terminal->window, key_handler);
|
window_set_key_handler(terminal->window, key_handler);
|
||||||
window_set_keyboard_focus_handler(terminal->window,
|
window_set_keyboard_focus_handler(terminal->window,
|
||||||
keyboard_focus_handler);
|
keyboard_focus_handler);
|
||||||
|
window_set_button_handler(terminal->window, button_handler);
|
||||||
|
window_set_motion_handler(terminal->window, motion_handler);
|
||||||
|
|
||||||
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
|
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
|
||||||
cr = cairo_create(surface);
|
cr = cairo_create(surface);
|
||||||
|
|
|
||||||
|
|
@ -941,6 +941,11 @@ window_handle_pointer_focus(void *data,
|
||||||
input->pointer_focus = wl_surface_get_user_data(surface);
|
input->pointer_focus = wl_surface_get_user_data(surface);
|
||||||
window = input->pointer_focus;
|
window = input->pointer_focus;
|
||||||
|
|
||||||
|
input->x = x;
|
||||||
|
input->y = y;
|
||||||
|
input->sx = sx;
|
||||||
|
input->sy = sy;
|
||||||
|
|
||||||
pointer = POINTER_LEFT_PTR;
|
pointer = POINTER_LEFT_PTR;
|
||||||
if (window->motion_handler)
|
if (window->motion_handler)
|
||||||
pointer = (*window->motion_handler)(window,
|
pointer = (*window->motion_handler)(window,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue