mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-31 22:25:25 -04:00
Merge branch 'master' of git://anongit.freedesktop.org/wayland
Conflicts: clients/terminal.c
This commit is contained in:
commit
9acdb50084
10 changed files with 334 additions and 221 deletions
|
|
@ -1,10 +1,20 @@
|
|||
noinst_PROGRAMS = gears flower screenshot terminal image view dnd smoke resizor
|
||||
noinst_PROGRAMS = \
|
||||
gears \
|
||||
flower \
|
||||
screenshot \
|
||||
terminal \
|
||||
image \
|
||||
$(poppler_programs) \
|
||||
dnd \
|
||||
smoke \
|
||||
resizor
|
||||
|
||||
noinst_LTLIBRARIES = libtoytoolkit.la
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/wayland \
|
||||
-I$(top_builddir)/wayland \
|
||||
$(CLIENT_CFLAGS) $(POPPLER_CFLAGS)
|
||||
$(CLIENT_CFLAGS)
|
||||
|
||||
LDADD = libtoytoolkit.la \
|
||||
$(top_builddir)/wayland/libwayland-client.la \
|
||||
|
|
@ -27,7 +37,6 @@ gears_SOURCES = gears.c
|
|||
screenshot_SOURCES = screenshot.c screenshooter-protocol.c
|
||||
terminal_SOURCES = terminal.c
|
||||
image_SOURCES = image.c
|
||||
view_SOURCES = view.c
|
||||
dnd_SOURCES = dnd.c
|
||||
resizor_SOURCES = resizor.c
|
||||
|
||||
|
|
@ -40,4 +49,10 @@ CLEANFILES = $(BUILT_SOURCES)
|
|||
include $(top_srcdir)/wayland/scanner.mk
|
||||
|
||||
terminal_LDADD = $(LDADD) -lutil
|
||||
|
||||
if HAVE_POPPLER
|
||||
poppler_programs = view
|
||||
view_SOURCES = view.c
|
||||
view_LDADD = $(LDADD) $(POPPLER_LIBS)
|
||||
view_CPPFLAGS = $(POPPLER_CFLAGS)
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -169,20 +169,20 @@ item_create(struct display *display, int x, int y, int seed)
|
|||
static void
|
||||
dnd_draw(struct dnd *dnd)
|
||||
{
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *wsurface, *surface;
|
||||
int i;
|
||||
|
||||
window_draw(dnd->window);
|
||||
|
||||
window_get_child_rectangle(dnd->window, &rectangle);
|
||||
window_get_child_allocation(dnd->window, &allocation);
|
||||
|
||||
wsurface = window_get_surface(dnd->window);
|
||||
surface = cairo_surface_create_similar(wsurface,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
rectangle.width,
|
||||
rectangle.height);
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
cairo_surface_destroy(wsurface);
|
||||
|
||||
cr = cairo_create(surface);
|
||||
|
|
@ -201,7 +201,7 @@ dnd_draw(struct dnd *dnd)
|
|||
|
||||
cairo_destroy(cr);
|
||||
|
||||
window_copy_surface(dnd->window, &rectangle, surface);
|
||||
window_copy_surface(dnd->window, &allocation, surface);
|
||||
cairo_surface_destroy(surface);
|
||||
window_flush(dnd->window);
|
||||
}
|
||||
|
|
@ -251,13 +251,13 @@ static struct item *
|
|||
dnd_get_item(struct dnd *dnd, int32_t x, int32_t y)
|
||||
{
|
||||
struct item *item;
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
int i;
|
||||
|
||||
window_get_child_rectangle(dnd->window, &rectangle);
|
||||
window_get_child_allocation(dnd->window, &allocation);
|
||||
|
||||
x -= rectangle.x;
|
||||
y -= rectangle.y;
|
||||
x -= allocation.x;
|
||||
y -= allocation.y;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
|
||||
item = dnd->items[i];
|
||||
|
|
@ -559,16 +559,16 @@ dnd_button_handler(struct window *window,
|
|||
struct dnd *dnd = data;
|
||||
int32_t x, y;
|
||||
struct item *item;
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
struct dnd_drag *dnd_drag;
|
||||
struct wl_drag *drag;
|
||||
int i;
|
||||
|
||||
window_get_child_rectangle(dnd->window, &rectangle);
|
||||
window_get_child_allocation(dnd->window, &allocation);
|
||||
input_get_position(input, &x, &y);
|
||||
item = dnd_get_item(dnd, x, y);
|
||||
x -= rectangle.x;
|
||||
y -= rectangle.y;
|
||||
x -= allocation.x;
|
||||
y -= allocation.y;
|
||||
|
||||
if (item && state == 1) {
|
||||
fprintf(stderr, "start drag, item %p\n", item);
|
||||
|
|
@ -624,7 +624,7 @@ dnd_create(struct display *display)
|
|||
struct dnd *dnd;
|
||||
gchar *title;
|
||||
int i, x, y;
|
||||
struct rectangle rectangle;
|
||||
int32_t width, height;
|
||||
|
||||
dnd = malloc(sizeof *dnd);
|
||||
if (dnd == NULL)
|
||||
|
|
@ -656,9 +656,9 @@ dnd_create(struct display *display)
|
|||
window_set_motion_handler(dnd->window,
|
||||
dnd_motion_handler);
|
||||
|
||||
rectangle.width = 4 * (item_width + item_padding) + item_padding;
|
||||
rectangle.height = 4 * (item_height + item_padding) + item_padding;
|
||||
window_set_child_size(dnd->window, &rectangle);
|
||||
width = 4 * (item_width + item_padding) + item_padding;
|
||||
height = 4 * (item_height + item_padding) + item_padding;
|
||||
window_set_child_size(dnd->window, width, height);
|
||||
|
||||
dnd_draw(dnd);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ struct gears {
|
|||
struct window *window;
|
||||
|
||||
struct display *d;
|
||||
struct rectangle rectangle;
|
||||
|
||||
EGLDisplay display;
|
||||
EGLContext context;
|
||||
|
|
@ -208,19 +207,8 @@ static void
|
|||
allocate_buffer(struct gears *gears)
|
||||
{
|
||||
EGLImageKHR image;
|
||||
struct rectangle allocation;
|
||||
|
||||
/* Constrain child size to be square and at least 300x300 */
|
||||
window_get_child_rectangle(gears->window, &gears->rectangle);
|
||||
if (gears->rectangle.width > gears->rectangle.height)
|
||||
gears->rectangle.height = gears->rectangle.width;
|
||||
else
|
||||
gears->rectangle.width = gears->rectangle.height;
|
||||
if (gears->rectangle.width < 300) {
|
||||
gears->rectangle.width = 300;
|
||||
gears->rectangle.height = 300;
|
||||
}
|
||||
|
||||
window_set_child_size(gears->window, &gears->rectangle);
|
||||
window_draw(gears->window);
|
||||
|
||||
gears->surface[gears->current] = window_get_surface(gears->window);
|
||||
|
|
@ -239,16 +227,18 @@ allocate_buffer(struct gears *gears)
|
|||
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo);
|
||||
window_get_child_allocation(gears->window, &allocation);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER_EXT,
|
||||
GL_DEPTH_COMPONENT,
|
||||
gears->rectangle.width + 20 + 32,
|
||||
gears->rectangle.height + 60 + 32);
|
||||
allocation.width + 20 + 32,
|
||||
allocation.height + 60 + 32);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_gears(struct gears *gears)
|
||||
{
|
||||
GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
struct rectangle allocation;
|
||||
|
||||
if (gears->surface[gears->current] == NULL)
|
||||
allocate_buffer(gears);
|
||||
|
|
@ -258,10 +248,11 @@ draw_gears(struct gears *gears)
|
|||
GL_RENDERBUFFER_EXT,
|
||||
gears->color_rbo[gears->current]);
|
||||
|
||||
glViewport(gears->rectangle.x, gears->rectangle.y,
|
||||
gears->rectangle.width, gears->rectangle.height);
|
||||
glScissor(gears->rectangle.x, gears->rectangle.y,
|
||||
gears->rectangle.width, gears->rectangle.height);
|
||||
window_get_child_allocation(gears->window, &allocation);
|
||||
glViewport(allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
glScissor(allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
|
@ -301,7 +292,8 @@ draw_gears(struct gears *gears)
|
|||
}
|
||||
|
||||
static void
|
||||
resize_handler(struct window *window, void *data)
|
||||
resize_handler(struct window *window,
|
||||
int32_t width, int32_t height, void *data)
|
||||
{
|
||||
struct gears *gears = data;
|
||||
|
||||
|
|
@ -309,6 +301,18 @@ resize_handler(struct window *window, void *data)
|
|||
gears->surface[0] = NULL;
|
||||
cairo_surface_destroy(gears->surface[1]);
|
||||
gears->surface[1] = NULL;
|
||||
|
||||
/* Constrain child size to be square and at least 300x300 */
|
||||
if (width > height)
|
||||
height = width;
|
||||
else
|
||||
width = height;
|
||||
if (width < 300) {
|
||||
width = 300;
|
||||
height = 300;
|
||||
}
|
||||
|
||||
window_set_child_size(gears->window, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -316,8 +320,10 @@ keyboard_focus_handler(struct window *window,
|
|||
struct input *device, void *data)
|
||||
{
|
||||
struct gears *gears = data;
|
||||
struct rectangle allocation;
|
||||
|
||||
resize_handler(window, gears);
|
||||
window_get_child_allocation(gears->window, &allocation);
|
||||
resize_handler(window, allocation.width, allocation.height, gears);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -137,18 +137,18 @@ set_source_pixbuf(cairo_t *cr,
|
|||
static void
|
||||
image_draw(struct image *image)
|
||||
{
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
GdkPixbuf *pb;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *wsurface, *surface;
|
||||
|
||||
window_draw(image->window);
|
||||
|
||||
window_get_child_rectangle(image->window, &rectangle);
|
||||
window_get_child_allocation(image->window, &allocation);
|
||||
|
||||
pb = gdk_pixbuf_new_from_file_at_size(image->filename,
|
||||
rectangle.width,
|
||||
rectangle.height,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
NULL);
|
||||
if (pb == NULL)
|
||||
return;
|
||||
|
|
@ -156,8 +156,8 @@ image_draw(struct image *image)
|
|||
wsurface = window_get_surface(image->window);
|
||||
surface = cairo_surface_create_similar(wsurface,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
rectangle.width,
|
||||
rectangle.height);
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
|
||||
cairo_surface_destroy(wsurface);
|
||||
cr = cairo_create(surface);
|
||||
|
|
@ -166,14 +166,14 @@ image_draw(struct image *image)
|
|||
cairo_paint(cr);
|
||||
set_source_pixbuf(cr, pb,
|
||||
0, 0,
|
||||
rectangle.width, rectangle.height);
|
||||
allocation.width, allocation.height);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_paint(cr);
|
||||
cairo_destroy(cr);
|
||||
|
||||
g_object_unref(pb);
|
||||
|
||||
window_copy_surface(image->window, &rectangle, surface);
|
||||
window_copy_surface(image->window, &allocation, surface);
|
||||
window_flush(image->window);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
struct resizor {
|
||||
struct display *display;
|
||||
struct window *window;
|
||||
struct rectangle child_allocation;
|
||||
int32_t width;
|
||||
|
||||
struct {
|
||||
double current;
|
||||
|
|
@ -71,9 +71,7 @@ frame_callback(void *data, uint32_t time)
|
|||
resizor->height.previous = 200;
|
||||
}
|
||||
|
||||
resizor->child_allocation.height = height + 0.5;
|
||||
window_set_child_size(resizor->window,
|
||||
&resizor->child_allocation);
|
||||
window_set_child_size(resizor->window, resizor->width, height + 0.5);
|
||||
|
||||
window_schedule_redraw(resizor->window);
|
||||
}
|
||||
|
|
@ -83,21 +81,21 @@ resizor_draw(struct resizor *resizor)
|
|||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
struct rectangle allocation;
|
||||
|
||||
window_draw(resizor->window);
|
||||
|
||||
window_get_child_rectangle(resizor->window,
|
||||
&resizor->child_allocation);
|
||||
window_get_child_allocation(resizor->window, &allocation);
|
||||
|
||||
surface = window_get_surface(resizor->window);
|
||||
|
||||
cr = cairo_create(surface);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_rectangle(cr,
|
||||
resizor->child_allocation.x,
|
||||
resizor->child_allocation.y,
|
||||
resizor->child_allocation.width,
|
||||
resizor->child_allocation.height);
|
||||
allocation.x,
|
||||
allocation.y,
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
|
||||
cairo_fill(cr);
|
||||
cairo_destroy(cr);
|
||||
|
|
@ -141,12 +139,10 @@ key_handler(struct window *window, uint32_t key, uint32_t sym,
|
|||
switch (sym) {
|
||||
case XK_Down:
|
||||
resizor->height.target = 400;
|
||||
resizor->height.current = resizor->child_allocation.height;
|
||||
frame_callback(resizor, 0);
|
||||
break;
|
||||
case XK_Up:
|
||||
resizor->height.target = 200;
|
||||
resizor->height.current = resizor->child_allocation.height;
|
||||
frame_callback(resizor, 0);
|
||||
break;
|
||||
}
|
||||
|
|
@ -156,6 +152,7 @@ static struct resizor *
|
|||
resizor_create(struct display *display)
|
||||
{
|
||||
struct resizor *resizor;
|
||||
int32_t height;
|
||||
|
||||
resizor = malloc(sizeof *resizor);
|
||||
if (resizor == NULL)
|
||||
|
|
@ -171,15 +168,13 @@ resizor_create(struct display *display)
|
|||
window_set_keyboard_focus_handler(resizor->window,
|
||||
keyboard_focus_handler);
|
||||
|
||||
resizor->child_allocation.x = 0;
|
||||
resizor->child_allocation.y = 0;
|
||||
resizor->child_allocation.width = 300;
|
||||
resizor->child_allocation.height = 400;
|
||||
resizor->width = 300;
|
||||
resizor->height.current = 400;
|
||||
resizor->height.previous = 400;
|
||||
resizor->height.target = 400;
|
||||
resizor->height.previous = resizor->height.current;
|
||||
resizor->height.target = resizor->height.current;
|
||||
height = resizor->height.current + 0.5;
|
||||
|
||||
window_set_child_size(resizor->window, &resizor->child_allocation);
|
||||
window_set_child_size(resizor->window, resizor->width, height);
|
||||
|
||||
resizor_draw(resizor);
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ struct attr {
|
|||
};
|
||||
struct color_scheme {
|
||||
struct terminal_color palette[16];
|
||||
struct terminal_color border;
|
||||
char border;
|
||||
struct attr default_attr;
|
||||
};
|
||||
|
||||
|
|
@ -389,7 +389,7 @@ struct terminal {
|
|||
struct color_scheme *color_scheme;
|
||||
struct terminal_color color_table[256];
|
||||
cairo_font_extents_t extents;
|
||||
cairo_font_face_t *font_normal, *font_bold;
|
||||
cairo_scaled_font_t *font_normal, *font_bold;
|
||||
};
|
||||
|
||||
/* Create default tab stops, every 8 characters */
|
||||
|
|
@ -473,7 +473,8 @@ terminal_get_row(struct terminal *terminal, int row)
|
|||
}
|
||||
|
||||
static struct attr*
|
||||
terminal_get_attr_row(struct terminal *terminal, int row) {
|
||||
terminal_get_attr_row(struct terminal *terminal, int row)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = (row + terminal->start) % terminal->height;
|
||||
|
|
@ -481,9 +482,54 @@ terminal_get_attr_row(struct terminal *terminal, int row) {
|
|||
return &terminal->data_attr[index * terminal->width];
|
||||
}
|
||||
|
||||
static struct attr
|
||||
terminal_get_attr(struct terminal *terminal, int row, int col) {
|
||||
return terminal_get_attr_row(terminal, row)[col];
|
||||
union decoded_attr {
|
||||
struct {
|
||||
unsigned char foreground;
|
||||
unsigned char background;
|
||||
unsigned char bold;
|
||||
unsigned char underline;
|
||||
};
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
static void
|
||||
terminal_decode_attr(struct terminal *terminal, int row, int col,
|
||||
union decoded_attr *decoded)
|
||||
{
|
||||
struct attr attr;
|
||||
int foreground, background, tmp;
|
||||
|
||||
/* get the attributes for this character cell */
|
||||
attr = terminal_get_attr_row(terminal, row)[col];
|
||||
if ((attr.a & ATTRMASK_INVERSE) ||
|
||||
((terminal->mode & MODE_SHOW_CURSOR) &&
|
||||
terminal->focused && terminal->row == row &&
|
||||
terminal->column == col)) {
|
||||
foreground = attr.bg;
|
||||
background = attr.fg;
|
||||
if (attr.a & ATTRMASK_BOLD) {
|
||||
if (foreground <= 16) foreground |= 0x08;
|
||||
if (background <= 16) background &= 0x07;
|
||||
}
|
||||
} else {
|
||||
foreground = attr.fg;
|
||||
background = attr.bg;
|
||||
}
|
||||
|
||||
if (terminal->mode & MODE_INVERSE) {
|
||||
tmp = foreground;
|
||||
foreground = background;
|
||||
background = tmp;
|
||||
if (attr.a & ATTRMASK_BOLD) {
|
||||
if (foreground <= 16) foreground |= 0x08;
|
||||
if (background <= 16) background &= 0x07;
|
||||
}
|
||||
}
|
||||
|
||||
decoded->foreground = foreground;
|
||||
decoded->background = background;
|
||||
decoded->bold = attr.a & (ATTRMASK_BOLD | ATTRMASK_BLINK);
|
||||
decoded->underline = attr.a & ATTRMASK_UNDERLINE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -610,12 +656,28 @@ terminal_resize(struct terminal *terminal, int width, int height)
|
|||
char *tab_ruler;
|
||||
int data_pitch, attr_pitch;
|
||||
int i, l, total_rows, start;
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
struct winsize ws;
|
||||
int32_t pixel_width, pixel_height;
|
||||
|
||||
if (width < 1)
|
||||
width = 1;
|
||||
if (height < 1)
|
||||
height = 1;
|
||||
if (terminal->width == width && terminal->height == height)
|
||||
return;
|
||||
|
||||
if (!terminal->fullscreen) {
|
||||
pixel_width = width *
|
||||
terminal->extents.max_x_advance + 2 * terminal->margin;
|
||||
pixel_height = height *
|
||||
terminal->extents.height + 2 * terminal->margin;
|
||||
window_set_child_size(terminal->window,
|
||||
pixel_width, pixel_height);
|
||||
}
|
||||
|
||||
window_schedule_redraw (terminal->window);
|
||||
|
||||
data_pitch = width * sizeof(union utf8_char);
|
||||
size = data_pitch * height;
|
||||
data = malloc(size);
|
||||
|
|
@ -664,26 +726,12 @@ terminal_resize(struct terminal *terminal, int width, int height)
|
|||
terminal->tab_ruler = tab_ruler;
|
||||
terminal_init_tabs(terminal);
|
||||
|
||||
if (terminal->row >= terminal->height)
|
||||
terminal->row = terminal->height - 1;
|
||||
if (terminal->column >= terminal->width)
|
||||
terminal->column = terminal->width - 1;
|
||||
terminal->start = 0;
|
||||
|
||||
if (!terminal->fullscreen) {
|
||||
rectangle.width = terminal->width *
|
||||
terminal->extents.max_x_advance + 2 * terminal->margin;
|
||||
rectangle.height = terminal->height *
|
||||
terminal->extents.height + 2 * terminal->margin;
|
||||
window_set_child_size(terminal->window, &rectangle);
|
||||
}
|
||||
|
||||
/* Update the window size */
|
||||
ws.ws_row = terminal->height;
|
||||
ws.ws_col = terminal->width;
|
||||
window_get_child_rectangle(terminal->window, &rectangle);
|
||||
ws.ws_xpixel = rectangle.width;
|
||||
ws.ws_ypixel = rectangle.height;
|
||||
window_get_child_allocation(terminal->window, &allocation);
|
||||
ws.ws_xpixel = allocation.width;
|
||||
ws.ws_ypixel = allocation.height;
|
||||
ioctl(terminal->master, TIOCSWINSZ, &ws);
|
||||
}
|
||||
|
||||
|
|
@ -706,92 +754,125 @@ struct color_scheme DEFAULT_COLORS = {
|
|||
{0.33, 1, 1, 1}, /* high cyan */
|
||||
{1, 1, 1, 1} /* white */
|
||||
},
|
||||
{0, 0, 0, 1}, /* black border */
|
||||
0, /* black border */
|
||||
{7, 0, 0, } /* bg:black (0), fg:light gray (7) */
|
||||
};
|
||||
|
||||
static void
|
||||
terminal_set_color(struct terminal *terminal, cairo_t *cr, int index)
|
||||
{
|
||||
cairo_set_source_rgba(cr,
|
||||
terminal->color_table[index].r,
|
||||
terminal->color_table[index].g,
|
||||
terminal->color_table[index].b,
|
||||
terminal->color_table[index].a);
|
||||
}
|
||||
|
||||
struct glyph_run {
|
||||
struct terminal *terminal;
|
||||
cairo_t *cr;
|
||||
int count;
|
||||
union decoded_attr attr;
|
||||
cairo_glyph_t glyphs[256], *g;
|
||||
};
|
||||
|
||||
static void
|
||||
glyph_run_init(struct glyph_run *run, struct terminal *terminal, cairo_t *cr)
|
||||
{
|
||||
run->terminal = terminal;
|
||||
run->cr = cr;
|
||||
run->g = run->glyphs;
|
||||
run->count = 0;
|
||||
run->attr.key = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_run_flush(struct glyph_run *run, union decoded_attr attr)
|
||||
{
|
||||
cairo_scaled_font_t *font;
|
||||
|
||||
if (run->count == 0)
|
||||
run->attr = attr;
|
||||
if (run->count > ARRAY_LENGTH(run->glyphs) - 10 ||
|
||||
(attr.key != run->attr.key)) {
|
||||
if (run->attr.bold)
|
||||
font = run->terminal->font_bold;
|
||||
else
|
||||
font = run->terminal->font_normal;
|
||||
cairo_set_scaled_font(run->cr, font);
|
||||
terminal_set_color(run->terminal, run->cr,
|
||||
run->attr.foreground);
|
||||
|
||||
cairo_show_glyphs (run->cr, run->glyphs, run->count);
|
||||
run->g = run->glyphs;
|
||||
run->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
glyph_run_add(struct glyph_run *run, int x, int y, union utf8_char *c)
|
||||
{
|
||||
int num_glyphs;
|
||||
cairo_scaled_font_t *font;
|
||||
|
||||
num_glyphs = ARRAY_LENGTH(run->glyphs) - run->count;
|
||||
|
||||
if (run->attr.bold)
|
||||
font = run->terminal->font_bold;
|
||||
else
|
||||
font = run->terminal->font_normal;
|
||||
|
||||
cairo_move_to(run->cr, x, y);
|
||||
cairo_scaled_font_text_to_glyphs (font, x, y,
|
||||
(char *) c->byte, 4,
|
||||
&run->g, &num_glyphs,
|
||||
NULL, NULL, NULL);
|
||||
run->g += num_glyphs;
|
||||
run->count += num_glyphs;
|
||||
}
|
||||
|
||||
static void
|
||||
terminal_draw_contents(struct terminal *terminal)
|
||||
{
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
cairo_t *cr;
|
||||
cairo_font_extents_t extents;
|
||||
int top_margin, side_margin;
|
||||
int row, col;
|
||||
struct attr attr;
|
||||
union utf8_char *p_row;
|
||||
struct utf8_chars {
|
||||
union utf8_char c;
|
||||
char null;
|
||||
} toShow;
|
||||
int foreground, background, bold, underline, concealed, tmp;
|
||||
union decoded_attr attr;
|
||||
int text_x, text_y;
|
||||
cairo_surface_t *surface;
|
||||
double d;
|
||||
struct glyph_run run;
|
||||
|
||||
toShow.null = 0;
|
||||
window_get_child_allocation(terminal->window, &allocation);
|
||||
|
||||
window_get_child_rectangle(terminal->window, &rectangle);
|
||||
|
||||
surface = display_create_surface(terminal->display, &rectangle);
|
||||
surface = display_create_surface(terminal->display, &allocation);
|
||||
cr = cairo_create(surface);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_rgba(cr,
|
||||
terminal->color_scheme->border.r,
|
||||
terminal->color_scheme->border.g,
|
||||
terminal->color_scheme->border.b,
|
||||
terminal->color_scheme->border.a);
|
||||
terminal_set_color(terminal, cr, terminal->color_scheme->border);
|
||||
cairo_paint(cr);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
cairo_set_font_face(cr, terminal->font_normal);
|
||||
cairo_set_font_size(cr, 14);
|
||||
cairo_set_scaled_font(cr, terminal->font_normal);
|
||||
|
||||
cairo_font_extents(cr, &extents);
|
||||
side_margin = (rectangle.width - terminal->width * extents.max_x_advance) / 2;
|
||||
top_margin = (rectangle.height - terminal->height * extents.height) / 2;
|
||||
side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 2;
|
||||
top_margin = (allocation.height - terminal->height * extents.height) / 2;
|
||||
|
||||
cairo_set_line_width(cr, 1.0);
|
||||
|
||||
/* paint the background */
|
||||
for (row = 0; row < terminal->height; row++) {
|
||||
p_row = terminal_get_row(terminal, row);
|
||||
for (col = 0; col < terminal->width; col++) {
|
||||
/* get the attributes for this character cell */
|
||||
attr = terminal_get_attr(terminal, row, col);
|
||||
if ((attr.a & ATTRMASK_INVERSE) ||
|
||||
((terminal->mode & MODE_SHOW_CURSOR) &&
|
||||
terminal->focused && terminal->row == row &&
|
||||
terminal->column == col))
|
||||
{
|
||||
foreground = attr.bg;
|
||||
background = attr.fg;
|
||||
if (attr.a & ATTRMASK_BOLD) {
|
||||
if (foreground <= 16) foreground |= 0x08;
|
||||
if (background <= 16) background &= 0x07;
|
||||
}
|
||||
} else {
|
||||
foreground = attr.fg;
|
||||
background = attr.bg;
|
||||
}
|
||||
if (terminal->mode & MODE_INVERSE) {
|
||||
tmp = foreground;
|
||||
foreground = background;
|
||||
background = tmp;
|
||||
if (attr.a & ATTRMASK_BOLD) {
|
||||
if (foreground <= 16) foreground |= 0x08;
|
||||
if (background <= 16) background &= 0x07;
|
||||
}
|
||||
}
|
||||
bold = attr.a & (ATTRMASK_BOLD | ATTRMASK_BLINK);
|
||||
underline = attr.a & ATTRMASK_UNDERLINE;
|
||||
concealed = attr.a & ATTRMASK_CONCEALED;
|
||||
terminal_decode_attr(terminal, row, col, &attr);
|
||||
|
||||
/* paint the background */
|
||||
cairo_set_source_rgba(cr,
|
||||
terminal->color_table[background].r,
|
||||
terminal->color_table[background].g,
|
||||
terminal->color_table[background].b,
|
||||
terminal->color_table[background].a);
|
||||
if (attr.background == terminal->color_scheme->border)
|
||||
continue;
|
||||
|
||||
terminal_set_color(terminal, cr, attr.background);
|
||||
cairo_move_to(cr, side_margin + (col * extents.max_x_advance),
|
||||
top_margin + (row * extents.height));
|
||||
cairo_rel_line_to(cr, extents.max_x_advance, 0);
|
||||
|
|
@ -799,33 +880,36 @@ terminal_draw_contents(struct terminal *terminal)
|
|||
cairo_rel_line_to(cr, -extents.max_x_advance, 0);
|
||||
cairo_close_path(cr);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
}
|
||||
|
||||
/* paint the foreground */
|
||||
if (concealed) continue;
|
||||
if (bold)
|
||||
cairo_set_font_face(cr, terminal->font_bold);
|
||||
else
|
||||
cairo_set_font_face(cr, terminal->font_normal);
|
||||
cairo_set_source_rgba(cr,
|
||||
terminal->color_table[foreground].r,
|
||||
terminal->color_table[foreground].g,
|
||||
terminal->color_table[foreground].b,
|
||||
terminal->color_table[foreground].a);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
/* paint the foreground */
|
||||
glyph_run_init(&run, terminal, cr);
|
||||
for (row = 0; row < terminal->height; row++) {
|
||||
p_row = terminal_get_row(terminal, row);
|
||||
for (col = 0; col < terminal->width; col++) {
|
||||
/* get the attributes for this character cell */
|
||||
terminal_decode_attr(terminal, row, col, &attr);
|
||||
|
||||
glyph_run_flush(&run, attr);
|
||||
|
||||
text_x = side_margin + col * extents.max_x_advance;
|
||||
text_y = top_margin + extents.ascent + row * extents.height;
|
||||
if (underline) {
|
||||
if (attr.underline) {
|
||||
cairo_move_to(cr, text_x, (double)text_y + 1.5);
|
||||
cairo_line_to(cr, text_x + extents.max_x_advance, (double) text_y + 1.5);
|
||||
cairo_stroke(cr);
|
||||
}
|
||||
cairo_move_to(cr, text_x, text_y);
|
||||
|
||||
toShow.c = p_row[col];
|
||||
cairo_show_text(cr, (char *) toShow.c.byte);
|
||||
|
||||
glyph_run_add(&run, text_x, text_y, &p_row[col]);
|
||||
}
|
||||
}
|
||||
|
||||
attr.key = ~0;
|
||||
glyph_run_flush(&run, attr);
|
||||
|
||||
if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) {
|
||||
d = 0.5;
|
||||
|
||||
|
|
@ -842,31 +926,29 @@ terminal_draw_contents(struct terminal *terminal)
|
|||
|
||||
cairo_destroy(cr);
|
||||
|
||||
window_copy_surface(terminal->window,
|
||||
&rectangle,
|
||||
surface);
|
||||
window_copy_surface(terminal->window, &allocation, surface);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
static void
|
||||
terminal_draw(struct terminal *terminal)
|
||||
resize_handler(struct window *window,
|
||||
int32_t pixel_width, int32_t pixel_height, void *data)
|
||||
{
|
||||
struct rectangle rectangle;
|
||||
struct terminal *terminal = data;
|
||||
int32_t width, height;
|
||||
|
||||
window_get_child_rectangle(terminal->window, &rectangle);
|
||||
|
||||
width = (rectangle.width - 2 * terminal->margin) /
|
||||
width = (pixel_width - 2 * terminal->margin) /
|
||||
(int32_t) terminal->extents.max_x_advance;
|
||||
height = (rectangle.height - 2 * terminal->margin) /
|
||||
height = (pixel_height - 2 * terminal->margin) /
|
||||
(int32_t) terminal->extents.height;
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
return;
|
||||
|
||||
terminal_resize(terminal, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
terminal_draw(struct terminal *terminal)
|
||||
{
|
||||
window_draw(terminal->window);
|
||||
terminal_draw_contents(terminal);
|
||||
window_flush(terminal->window);
|
||||
|
|
@ -1960,6 +2042,7 @@ terminal_create(struct display *display, int fullscreen)
|
|||
window_set_fullscreen(terminal->window, terminal->fullscreen);
|
||||
window_set_user_data(terminal->window, terminal);
|
||||
window_set_redraw_handler(terminal->window, redraw_handler);
|
||||
window_set_resize_handler(terminal->window, resize_handler);
|
||||
|
||||
window_set_key_handler(terminal->window, key_handler);
|
||||
window_set_keyboard_focus_handler(terminal->window,
|
||||
|
|
@ -1967,16 +2050,19 @@ terminal_create(struct display *display, int fullscreen)
|
|||
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
|
||||
cr = cairo_create(surface);
|
||||
terminal->font_bold = cairo_toy_font_face_create ("mono",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_BOLD);
|
||||
cairo_font_face_reference(terminal->font_bold);
|
||||
terminal->font_normal = cairo_toy_font_face_create ("mono",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_font_face_reference(terminal->font_normal);
|
||||
cairo_set_font_face(cr, terminal->font_normal);
|
||||
cairo_set_font_size(cr, 14);
|
||||
cairo_select_font_face (cr, "mono",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_BOLD);
|
||||
terminal->font_bold = cairo_get_scaled_font (cr);
|
||||
cairo_scaled_font_reference(terminal->font_bold);
|
||||
|
||||
cairo_select_font_face (cr, "mono",
|
||||
CAIRO_FONT_SLANT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
terminal->font_normal = cairo_get_scaled_font (cr);
|
||||
cairo_scaled_font_reference(terminal->font_normal);
|
||||
|
||||
cairo_font_extents(cr, &terminal->extents);
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(surface);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct view {
|
|||
static void
|
||||
view_draw(struct view *view)
|
||||
{
|
||||
struct rectangle rectangle;
|
||||
struct rectangle allocation;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
PopplerPage *page;
|
||||
|
|
@ -65,15 +65,15 @@ view_draw(struct view *view)
|
|||
|
||||
window_draw(view->window);
|
||||
|
||||
window_get_child_rectangle(view->window, &rectangle);
|
||||
window_get_child_allocation(view->window, &allocation);
|
||||
|
||||
page = poppler_document_get_page(view->document, view->page);
|
||||
|
||||
surface = window_get_surface(view->window);
|
||||
|
||||
cr = cairo_create(surface);
|
||||
cairo_rectangle(cr, rectangle.x, rectangle.y,
|
||||
rectangle.width, rectangle.height);
|
||||
cairo_rectangle(cr, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
cairo_clip(cr);
|
||||
|
||||
cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
|
||||
|
|
@ -81,16 +81,16 @@ view_draw(struct view *view)
|
|||
cairo_paint(cr);
|
||||
poppler_page_get_size(page, &width, &height);
|
||||
doc_aspect = width / height;
|
||||
window_aspect = (double) rectangle.width / rectangle.height;
|
||||
window_aspect = (double) allocation.width / allocation.height;
|
||||
if (doc_aspect < window_aspect)
|
||||
scale = rectangle.height / height;
|
||||
scale = allocation.height / height;
|
||||
else
|
||||
scale = rectangle.width / width;
|
||||
cairo_translate(cr, rectangle.x, rectangle.y);
|
||||
scale = allocation.width / width;
|
||||
cairo_translate(cr, allocation.x, allocation.y);
|
||||
cairo_scale(cr, scale, scale);
|
||||
cairo_translate(cr,
|
||||
(rectangle.width - width * scale) / 2 / scale,
|
||||
(rectangle.height - height * scale) / 2 / scale);
|
||||
(allocation.width - width * scale) / 2 / scale,
|
||||
(allocation.height - height * scale) / 2 / scale);
|
||||
cairo_rectangle(cr, 0, 0, width, height);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_source_rgb(cr, 1, 1, 1);
|
||||
|
|
|
|||
|
|
@ -1042,15 +1042,23 @@ handle_configure(void *data, struct wl_shell *shell,
|
|||
struct wl_surface *surface, int32_t width, int32_t height)
|
||||
{
|
||||
struct window *window = wl_surface_get_user_data(surface);
|
||||
int32_t child_width, child_height;
|
||||
|
||||
window->resize_edges = edges;
|
||||
window->allocation.width = width;
|
||||
window->allocation.height = height;
|
||||
if (window->resize_handler) {
|
||||
child_width = width - 20 - window->margin * 2;
|
||||
child_height = height - 60 - window->margin * 2;
|
||||
|
||||
if (window->resize_handler)
|
||||
(*window->resize_handler)(window, window->user_data);
|
||||
if (window->redraw_handler)
|
||||
window_schedule_redraw(window);
|
||||
(*window->resize_handler)(window,
|
||||
child_width, child_height,
|
||||
window->user_data);
|
||||
} else {
|
||||
window->resize_edges = edges;
|
||||
window->allocation.width = width;
|
||||
window->allocation.height = height;
|
||||
|
||||
if (window->redraw_handler)
|
||||
window_schedule_redraw(window);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_shell_listener shell_listener = {
|
||||
|
|
@ -1058,28 +1066,27 @@ static const struct wl_shell_listener shell_listener = {
|
|||
};
|
||||
|
||||
void
|
||||
window_get_child_rectangle(struct window *window,
|
||||
struct rectangle *rectangle)
|
||||
window_get_child_allocation(struct window *window,
|
||||
struct rectangle *allocation)
|
||||
{
|
||||
if (window->fullscreen && !window->decoration) {
|
||||
*rectangle = window->allocation;
|
||||
*allocation = window->allocation;
|
||||
} else {
|
||||
rectangle->x = window->margin + 10;
|
||||
rectangle->y = window->margin + 50;
|
||||
rectangle->width = window->allocation.width - 20 - window->margin * 2;
|
||||
rectangle->height = window->allocation.height - 60 - window->margin * 2;
|
||||
allocation->x = window->margin + 10;
|
||||
allocation->y = window->margin + 50;
|
||||
allocation->width =
|
||||
window->allocation.width - 20 - window->margin * 2;
|
||||
allocation->height =
|
||||
window->allocation.height - 60 - window->margin * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
window_set_child_size(struct window *window,
|
||||
struct rectangle *rectangle)
|
||||
window_set_child_size(struct window *window, int32_t width, int32_t height)
|
||||
{
|
||||
if (!window->fullscreen) {
|
||||
window->allocation.width =
|
||||
rectangle->width + 20 + window->margin * 2;
|
||||
window->allocation.height =
|
||||
rectangle->height + 60 + window->margin * 2;
|
||||
window->allocation.width = width + 20 + window->margin * 2;
|
||||
window->allocation.height = height + 60 + window->margin * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ enum pointer_type {
|
|||
POINTER_HAND1,
|
||||
};
|
||||
|
||||
typedef void (*window_resize_handler_t)(struct window *window, void *data);
|
||||
typedef void (*window_resize_handler_t)(struct window *window,
|
||||
int32_t width, int32_t height,
|
||||
void *data);
|
||||
typedef void (*window_redraw_handler_t)(struct window *window, void *data);
|
||||
typedef void (*window_frame_handler_t)(struct window *window, uint32_t frame, uint32_t timestamp, void *data);
|
||||
typedef void (*window_key_handler_t)(struct window *window, uint32_t key, uint32_t unicode,
|
||||
|
|
@ -135,11 +137,10 @@ window_move(struct window *window, struct input *input, uint32_t time);
|
|||
void
|
||||
window_draw(struct window *window);
|
||||
void
|
||||
window_get_child_rectangle(struct window *window,
|
||||
struct rectangle *rectangle);
|
||||
window_get_child_allocation(struct window *window,
|
||||
struct rectangle *allocation);
|
||||
void
|
||||
window_set_child_size(struct window *window,
|
||||
struct rectangle *rectangle);
|
||||
window_set_child_size(struct window *window, int32_t width, int32_t height);
|
||||
void
|
||||
window_copy_image(struct window *window,
|
||||
struct rectangle *rectangle,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ PKG_CHECK_MODULES(FFI, [libffi])
|
|||
PKG_CHECK_MODULES(COMPOSITOR,
|
||||
[egl glesv2 gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.17] xcb-dri2 xcb-xfixes)
|
||||
PKG_CHECK_MODULES(CLIENT, [egl gl cairo gdk-pixbuf-2.0 glib-2.0 gobject-2.0 xkbcommon libdrm])
|
||||
PKG_CHECK_MODULES(POPPLER, [poppler-glib gdk-2.0])
|
||||
PKG_CHECK_MODULES(POPPLER, [poppler-glib gdk-2.0],
|
||||
[have_poppler=yes], [have_poppler=no])
|
||||
AM_CONDITIONAL(HAVE_POPPLER, test "x$have_poppler" = "xyes")
|
||||
|
||||
PKG_CHECK_MODULES(CAIRO_GL, [cairo-gl],
|
||||
[have_cairo_gl=yes], [have_cairo_gl=no])
|
||||
AS_IF([test "x$have_cairo_gl" = "xyes"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue