Render selection

dev
Kristian Høgsberg 14 years ago
parent 23c03ad981
commit 5982658d62
  1. 106
      clients/terminal.c
  2. 5
      clients/window.c

@ -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…
Cancel
Save