mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-31 22:25:25 -04: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_offer *selection_offer;
|
||||
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 */
|
||||
|
|
@ -492,16 +495,62 @@ union decoded_attr {
|
|||
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
|
||||
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
||||
union decoded_attr *decoded)
|
||||
{
|
||||
struct attr attr;
|
||||
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 */
|
||||
attr = terminal_get_attr_row(terminal, row)[col];
|
||||
if ((attr.a & ATTRMASK_INVERSE) ||
|
||||
inverse ||
|
||||
((terminal->mode & MODE_SHOW_CURSOR) &&
|
||||
terminal->focused && terminal->row == row &&
|
||||
terminal->column == col)) {
|
||||
|
|
@ -835,7 +884,6 @@ terminal_draw_contents(struct terminal *terminal)
|
|||
{
|
||||
struct rectangle allocation;
|
||||
cairo_t *cr;
|
||||
cairo_font_extents_t extents;
|
||||
int top_margin, side_margin;
|
||||
int row, col;
|
||||
union utf8_char *p_row;
|
||||
|
|
@ -844,6 +892,7 @@ terminal_draw_contents(struct terminal *terminal)
|
|||
cairo_surface_t *surface;
|
||||
double d;
|
||||
struct glyph_run run;
|
||||
cairo_font_extents_t extents;
|
||||
|
||||
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_font_extents(cr, &extents);
|
||||
extents = terminal->extents;
|
||||
side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 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,
|
||||
const char *mime_type, int fd)
|
||||
{
|
||||
struct terminal *terminal = data;
|
||||
static const char msg[] = "selection data";
|
||||
|
||||
fprintf(stderr, "selection send, fd is %d\n", fd);
|
||||
write(fd, msg, sizeof msg);
|
||||
write(fd, msg, sizeof msg - 1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void
|
||||
selection_listener_cancelled(void *data, struct wl_selection *selection)
|
||||
{
|
||||
struct terminal *terminal = data;
|
||||
|
||||
fprintf(stderr, "selection cancelled\n");
|
||||
wl_selection_destroy(selection);
|
||||
}
|
||||
|
|
@ -1914,6 +1960,8 @@ selection_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
|
|||
len = read(fd, buffer, sizeof buffer);
|
||||
fprintf(stderr, "read %d bytes: %.*s\n", len, len, buffer);
|
||||
|
||||
write(terminal->master, buffer, len);
|
||||
|
||||
close(fd);
|
||||
g_source_remove(terminal->tag);
|
||||
|
||||
|
|
@ -2102,6 +2150,50 @@ keyboard_focus_handler(struct window *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 *
|
||||
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_keyboard_focus_handler(terminal->window,
|
||||
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);
|
||||
cr = cairo_create(surface);
|
||||
|
|
|
|||
|
|
@ -941,6 +941,11 @@ window_handle_pointer_focus(void *data,
|
|||
input->pointer_focus = wl_surface_get_user_data(surface);
|
||||
window = input->pointer_focus;
|
||||
|
||||
input->x = x;
|
||||
input->y = y;
|
||||
input->sx = sx;
|
||||
input->sy = sy;
|
||||
|
||||
pointer = POINTER_LEFT_PTR;
|
||||
if (window->motion_handler)
|
||||
pointer = (*window->motion_handler)(window,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue