Merge branch 'master' of git://anongit.freedesktop.org/wayland

Conflicts:
	clients/terminal.c
dev
Callum Lowcay 14 years ago
commit 9acdb50084
  1. 21
      clients/Makefile.am
  2. 34
      clients/dnd.c
  3. 48
      clients/gears.c
  4. 16
      clients/image.c
  5. 33
      clients/resizor.c
  6. 322
      clients/terminal.c
  7. 20
      clients/view.c
  8. 47
      clients/window.c
  9. 11
      clients/window.h
  10. 5
      configure.ac

@ -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 noinst_LTLIBRARIES = libtoytoolkit.la
INCLUDES = \ INCLUDES = \
-I$(top_srcdir)/wayland \ -I$(top_srcdir)/wayland \
-I$(top_builddir)/wayland \ -I$(top_builddir)/wayland \
$(CLIENT_CFLAGS) $(POPPLER_CFLAGS) $(CLIENT_CFLAGS)
LDADD = libtoytoolkit.la \ LDADD = libtoytoolkit.la \
$(top_builddir)/wayland/libwayland-client.la \ $(top_builddir)/wayland/libwayland-client.la \
@ -27,7 +37,6 @@ gears_SOURCES = gears.c
screenshot_SOURCES = screenshot.c screenshooter-protocol.c screenshot_SOURCES = screenshot.c screenshooter-protocol.c
terminal_SOURCES = terminal.c terminal_SOURCES = terminal.c
image_SOURCES = image.c image_SOURCES = image.c
view_SOURCES = view.c
dnd_SOURCES = dnd.c dnd_SOURCES = dnd.c
resizor_SOURCES = resizor.c resizor_SOURCES = resizor.c
@ -40,4 +49,10 @@ CLEANFILES = $(BUILT_SOURCES)
include $(top_srcdir)/wayland/scanner.mk include $(top_srcdir)/wayland/scanner.mk
terminal_LDADD = $(LDADD) -lutil terminal_LDADD = $(LDADD) -lutil
if HAVE_POPPLER
poppler_programs = view
view_SOURCES = view.c
view_LDADD = $(LDADD) $(POPPLER_LIBS) 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 static void
dnd_draw(struct dnd *dnd) dnd_draw(struct dnd *dnd)
{ {
struct rectangle rectangle; struct rectangle allocation;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *wsurface, *surface; cairo_surface_t *wsurface, *surface;
int i; int i;
window_draw(dnd->window); window_draw(dnd->window);
window_get_child_rectangle(dnd->window, &rectangle); window_get_child_allocation(dnd->window, &allocation);
wsurface = window_get_surface(dnd->window); wsurface = window_get_surface(dnd->window);
surface = cairo_surface_create_similar(wsurface, surface = cairo_surface_create_similar(wsurface,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
rectangle.width, allocation.width,
rectangle.height); allocation.height);
cairo_surface_destroy(wsurface); cairo_surface_destroy(wsurface);
cr = cairo_create(surface); cr = cairo_create(surface);
@ -201,7 +201,7 @@ dnd_draw(struct dnd *dnd)
cairo_destroy(cr); cairo_destroy(cr);
window_copy_surface(dnd->window, &rectangle, surface); window_copy_surface(dnd->window, &allocation, surface);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
window_flush(dnd->window); window_flush(dnd->window);
} }
@ -251,13 +251,13 @@ static struct item *
dnd_get_item(struct dnd *dnd, int32_t x, int32_t y) dnd_get_item(struct dnd *dnd, int32_t x, int32_t y)
{ {
struct item *item; struct item *item;
struct rectangle rectangle; struct rectangle allocation;
int i; int i;
window_get_child_rectangle(dnd->window, &rectangle); window_get_child_allocation(dnd->window, &allocation);
x -= rectangle.x; x -= allocation.x;
y -= rectangle.y; y -= allocation.y;
for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) { for (i = 0; i < ARRAY_LENGTH(dnd->items); i++) {
item = dnd->items[i]; item = dnd->items[i];
@ -559,16 +559,16 @@ dnd_button_handler(struct window *window,
struct dnd *dnd = data; struct dnd *dnd = data;
int32_t x, y; int32_t x, y;
struct item *item; struct item *item;
struct rectangle rectangle; struct rectangle allocation;
struct dnd_drag *dnd_drag; struct dnd_drag *dnd_drag;
struct wl_drag *drag; struct wl_drag *drag;
int i; int i;
window_get_child_rectangle(dnd->window, &rectangle); window_get_child_allocation(dnd->window, &allocation);
input_get_position(input, &x, &y); input_get_position(input, &x, &y);
item = dnd_get_item(dnd, x, y); item = dnd_get_item(dnd, x, y);
x -= rectangle.x; x -= allocation.x;
y -= rectangle.y; y -= allocation.y;
if (item && state == 1) { if (item && state == 1) {
fprintf(stderr, "start drag, item %p\n", item); fprintf(stderr, "start drag, item %p\n", item);
@ -624,7 +624,7 @@ dnd_create(struct display *display)
struct dnd *dnd; struct dnd *dnd;
gchar *title; gchar *title;
int i, x, y; int i, x, y;
struct rectangle rectangle; int32_t width, height;
dnd = malloc(sizeof *dnd); dnd = malloc(sizeof *dnd);
if (dnd == NULL) if (dnd == NULL)
@ -656,9 +656,9 @@ dnd_create(struct display *display)
window_set_motion_handler(dnd->window, window_set_motion_handler(dnd->window,
dnd_motion_handler); dnd_motion_handler);
rectangle.width = 4 * (item_width + item_padding) + item_padding; width = 4 * (item_width + item_padding) + item_padding;
rectangle.height = 4 * (item_height + item_padding) + item_padding; height = 4 * (item_height + item_padding) + item_padding;
window_set_child_size(dnd->window, &rectangle); window_set_child_size(dnd->window, width, height);
dnd_draw(dnd); dnd_draw(dnd);

@ -49,7 +49,6 @@ struct gears {
struct window *window; struct window *window;
struct display *d; struct display *d;
struct rectangle rectangle;
EGLDisplay display; EGLDisplay display;
EGLContext context; EGLContext context;
@ -208,19 +207,8 @@ static void
allocate_buffer(struct gears *gears) allocate_buffer(struct gears *gears)
{ {
EGLImageKHR image; 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); window_draw(gears->window);
gears->surface[gears->current] = window_get_surface(gears->window); gears->surface[gears->current] = window_get_surface(gears->window);
@ -239,16 +227,18 @@ allocate_buffer(struct gears *gears)
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image); glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo);
window_get_child_allocation(gears->window, &allocation);
glRenderbufferStorage(GL_RENDERBUFFER_EXT, glRenderbufferStorage(GL_RENDERBUFFER_EXT,
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT,
gears->rectangle.width + 20 + 32, allocation.width + 20 + 32,
gears->rectangle.height + 60 + 32); allocation.height + 60 + 32);
} }
static void static void
draw_gears(struct gears *gears) draw_gears(struct gears *gears)
{ {
GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
struct rectangle allocation;
if (gears->surface[gears->current] == NULL) if (gears->surface[gears->current] == NULL)
allocate_buffer(gears); allocate_buffer(gears);
@ -258,10 +248,11 @@ draw_gears(struct gears *gears)
GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_EXT,
gears->color_rbo[gears->current]); gears->color_rbo[gears->current]);
glViewport(gears->rectangle.x, gears->rectangle.y, window_get_child_allocation(gears->window, &allocation);
gears->rectangle.width, gears->rectangle.height); glViewport(allocation.x, allocation.y,
glScissor(gears->rectangle.x, gears->rectangle.y, allocation.width, allocation.height);
gears->rectangle.width, gears->rectangle.height); glScissor(allocation.x, allocation.y,
allocation.width, allocation.height);
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -301,7 +292,8 @@ draw_gears(struct gears *gears)
} }
static void 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; struct gears *gears = data;
@ -309,6 +301,18 @@ resize_handler(struct window *window, void *data)
gears->surface[0] = NULL; gears->surface[0] = NULL;
cairo_surface_destroy(gears->surface[1]); cairo_surface_destroy(gears->surface[1]);
gears->surface[1] = NULL; 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 static void
@ -316,8 +320,10 @@ keyboard_focus_handler(struct window *window,
struct input *device, void *data) struct input *device, void *data)
{ {
struct gears *gears = 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 static void

@ -137,18 +137,18 @@ set_source_pixbuf(cairo_t *cr,
static void static void
image_draw(struct image *image) image_draw(struct image *image)
{ {
struct rectangle rectangle; struct rectangle allocation;
GdkPixbuf *pb; GdkPixbuf *pb;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *wsurface, *surface; cairo_surface_t *wsurface, *surface;
window_draw(image->window); 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, pb = gdk_pixbuf_new_from_file_at_size(image->filename,
rectangle.width, allocation.width,
rectangle.height, allocation.height,
NULL); NULL);
if (pb == NULL) if (pb == NULL)
return; return;
@ -156,8 +156,8 @@ image_draw(struct image *image)
wsurface = window_get_surface(image->window); wsurface = window_get_surface(image->window);
surface = cairo_surface_create_similar(wsurface, surface = cairo_surface_create_similar(wsurface,
CAIRO_CONTENT_COLOR_ALPHA, CAIRO_CONTENT_COLOR_ALPHA,
rectangle.width, allocation.width,
rectangle.height); allocation.height);
cairo_surface_destroy(wsurface); cairo_surface_destroy(wsurface);
cr = cairo_create(surface); cr = cairo_create(surface);
@ -166,14 +166,14 @@ image_draw(struct image *image)
cairo_paint(cr); cairo_paint(cr);
set_source_pixbuf(cr, pb, set_source_pixbuf(cr, pb,
0, 0, 0, 0,
rectangle.width, rectangle.height); allocation.width, allocation.height);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_paint(cr); cairo_paint(cr);
cairo_destroy(cr); cairo_destroy(cr);
g_object_unref(pb); g_object_unref(pb);
window_copy_surface(image->window, &rectangle, surface); window_copy_surface(image->window, &allocation, surface);
window_flush(image->window); window_flush(image->window);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} }

@ -38,7 +38,7 @@
struct resizor { struct resizor {
struct display *display; struct display *display;
struct window *window; struct window *window;
struct rectangle child_allocation; int32_t width;
struct { struct {
double current; double current;
@ -71,9 +71,7 @@ frame_callback(void *data, uint32_t time)
resizor->height.previous = 200; resizor->height.previous = 200;
} }
resizor->child_allocation.height = height + 0.5; window_set_child_size(resizor->window, resizor->width, height + 0.5);
window_set_child_size(resizor->window,
&resizor->child_allocation);
window_schedule_redraw(resizor->window); window_schedule_redraw(resizor->window);
} }
@ -83,21 +81,21 @@ resizor_draw(struct resizor *resizor)
{ {
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_t *cr; cairo_t *cr;
struct rectangle allocation;
window_draw(resizor->window); window_draw(resizor->window);
window_get_child_rectangle(resizor->window, window_get_child_allocation(resizor->window, &allocation);
&resizor->child_allocation);
surface = window_get_surface(resizor->window); surface = window_get_surface(resizor->window);
cr = cairo_create(surface); cr = cairo_create(surface);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(cr, cairo_rectangle(cr,
resizor->child_allocation.x, allocation.x,
resizor->child_allocation.y, allocation.y,
resizor->child_allocation.width, allocation.width,
resizor->child_allocation.height); allocation.height);
cairo_set_source_rgba(cr, 0, 0, 0, 0.8); cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
cairo_fill(cr); cairo_fill(cr);
cairo_destroy(cr); cairo_destroy(cr);
@ -141,12 +139,10 @@ key_handler(struct window *window, uint32_t key, uint32_t sym,
switch (sym) { switch (sym) {
case XK_Down: case XK_Down:
resizor->height.target = 400; resizor->height.target = 400;
resizor->height.current = resizor->child_allocation.height;
frame_callback(resizor, 0); frame_callback(resizor, 0);
break; break;
case XK_Up: case XK_Up:
resizor->height.target = 200; resizor->height.target = 200;
resizor->height.current = resizor->child_allocation.height;
frame_callback(resizor, 0); frame_callback(resizor, 0);
break; break;
} }
@ -156,6 +152,7 @@ static struct resizor *
resizor_create(struct display *display) resizor_create(struct display *display)
{ {
struct resizor *resizor; struct resizor *resizor;
int32_t height;
resizor = malloc(sizeof *resizor); resizor = malloc(sizeof *resizor);
if (resizor == NULL) if (resizor == NULL)
@ -171,15 +168,13 @@ resizor_create(struct display *display)
window_set_keyboard_focus_handler(resizor->window, window_set_keyboard_focus_handler(resizor->window,
keyboard_focus_handler); keyboard_focus_handler);
resizor->child_allocation.x = 0; resizor->width = 300;
resizor->child_allocation.y = 0;
resizor->child_allocation.width = 300;
resizor->child_allocation.height = 400;
resizor->height.current = 400; resizor->height.current = 400;
resizor->height.previous = 400; resizor->height.previous = resizor->height.current;
resizor->height.target = 400; 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); resizor_draw(resizor);

@ -323,7 +323,7 @@ struct attr {
}; };
struct color_scheme { struct color_scheme {
struct terminal_color palette[16]; struct terminal_color palette[16];
struct terminal_color border; char border;
struct attr default_attr; struct attr default_attr;
}; };
@ -389,7 +389,7 @@ struct terminal {
struct color_scheme *color_scheme; struct color_scheme *color_scheme;
struct terminal_color color_table[256]; struct terminal_color color_table[256];
cairo_font_extents_t extents; 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 */ /* Create default tab stops, every 8 characters */
@ -473,7 +473,8 @@ terminal_get_row(struct terminal *terminal, int row)
} }
static struct attr* static struct attr*
terminal_get_attr_row(struct terminal *terminal, int row) { terminal_get_attr_row(struct terminal *terminal, int row)
{
int index; int index;
index = (row + terminal->start) % terminal->height; 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]; return &terminal->data_attr[index * terminal->width];
} }
static struct attr union decoded_attr {
terminal_get_attr(struct terminal *terminal, int row, int col) { struct {
return terminal_get_attr_row(terminal, row)[col]; 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 static void
@ -610,12 +656,28 @@ terminal_resize(struct terminal *terminal, int width, int height)
char *tab_ruler; char *tab_ruler;
int data_pitch, attr_pitch; int data_pitch, attr_pitch;
int i, l, total_rows, start; int i, l, total_rows, start;
struct rectangle rectangle; struct rectangle allocation;
struct winsize ws; 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) if (terminal->width == width && terminal->height == height)
return; 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); data_pitch = width * sizeof(union utf8_char);
size = data_pitch * height; size = data_pitch * height;
data = malloc(size); data = malloc(size);
@ -664,26 +726,12 @@ terminal_resize(struct terminal *terminal, int width, int height)
terminal->tab_ruler = tab_ruler; terminal->tab_ruler = tab_ruler;
terminal_init_tabs(terminal); 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 */ /* Update the window size */
ws.ws_row = terminal->height; ws.ws_row = terminal->height;
ws.ws_col = terminal->width; ws.ws_col = terminal->width;
window_get_child_rectangle(terminal->window, &rectangle); window_get_child_allocation(terminal->window, &allocation);
ws.ws_xpixel = rectangle.width; ws.ws_xpixel = allocation.width;
ws.ws_ypixel = rectangle.height; ws.ws_ypixel = allocation.height;
ioctl(terminal->master, TIOCSWINSZ, &ws); ioctl(terminal->master, TIOCSWINSZ, &ws);
} }
@ -706,92 +754,125 @@ struct color_scheme DEFAULT_COLORS = {
{0.33, 1, 1, 1}, /* high cyan */ {0.33, 1, 1, 1}, /* high cyan */
{1, 1, 1, 1} /* white */ {1, 1, 1, 1} /* white */
}, },
{0, 0, 0, 1}, /* black border */ 0, /* black border */
{7, 0, 0, } /* bg:black (0), fg:light gray (7) */ {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 static void
terminal_draw_contents(struct terminal *terminal) terminal_draw_contents(struct terminal *terminal)
{ {
struct rectangle rectangle; struct rectangle allocation;
cairo_t *cr; cairo_t *cr;
cairo_font_extents_t extents; cairo_font_extents_t extents;
int top_margin, side_margin; int top_margin, side_margin;
int row, col; int row, col;
struct attr attr;
union utf8_char *p_row; union utf8_char *p_row;
struct utf8_chars { union decoded_attr attr;
union utf8_char c;
char null;
} toShow;
int foreground, background, bold, underline, concealed, tmp;
int text_x, text_y; int text_x, text_y;
cairo_surface_t *surface; cairo_surface_t *surface;
double d; 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); cr = cairo_create(surface);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, terminal_set_color(terminal, cr, terminal->color_scheme->border);
terminal->color_scheme->border.r,
terminal->color_scheme->border.g,
terminal->color_scheme->border.b,
terminal->color_scheme->border.a);
cairo_paint(cr); cairo_paint(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_font_face(cr, terminal->font_normal); cairo_set_scaled_font(cr, terminal->font_normal);
cairo_set_font_size(cr, 14);
cairo_font_extents(cr, &extents); cairo_font_extents(cr, &extents);
side_margin = (rectangle.width - terminal->width * extents.max_x_advance) / 2; side_margin = (allocation.width - terminal->width * extents.max_x_advance) / 2;
top_margin = (rectangle.height - terminal->height * extents.height) / 2; top_margin = (allocation.height - terminal->height * extents.height) / 2;
cairo_set_line_width(cr, 1.0); cairo_set_line_width(cr, 1.0);
/* paint the background */
for (row = 0; row < terminal->height; row++) { for (row = 0; row < terminal->height; row++) {
p_row = terminal_get_row(terminal, row); p_row = terminal_get_row(terminal, row);
for (col = 0; col < terminal->width; col++) { for (col = 0; col < terminal->width; col++) {
/* get the attributes for this character cell */ /* get the attributes for this character cell */
attr = terminal_get_attr(terminal, row, col); terminal_decode_attr(terminal, row, col, &attr);
if ((attr.a & ATTRMASK_INVERSE) ||
((terminal->mode & MODE_SHOW_CURSOR) && if (attr.background == terminal->color_scheme->border)
terminal->focused && terminal->row == row && continue;
terminal->column == col))
{ terminal_set_color(terminal, cr, attr.background);
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;
/* 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);
cairo_move_to(cr, side_margin + (col * extents.max_x_advance), cairo_move_to(cr, side_margin + (col * extents.max_x_advance),
top_margin + (row * extents.height)); top_margin + (row * extents.height));
cairo_rel_line_to(cr, extents.max_x_advance, 0); 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_rel_line_to(cr, -extents.max_x_advance, 0);
cairo_close_path(cr); cairo_close_path(cr);
cairo_fill(cr); cairo_fill(cr);
}
}
/* paint the foreground */ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
if (concealed) continue;
if (bold) /* paint the foreground */
cairo_set_font_face(cr, terminal->font_bold); glyph_run_init(&run, terminal, cr);
else for (row = 0; row < terminal->height; row++) {
cairo_set_font_face(cr, terminal->font_normal); p_row = terminal_get_row(terminal, row);
cairo_set_source_rgba(cr, for (col = 0; col < terminal->width; col++) {
terminal->color_table[foreground].r, /* get the attributes for this character cell */
terminal->color_table[foreground].g, terminal_decode_attr(terminal, row, col, &attr);
terminal->color_table[foreground].b,
terminal->color_table[foreground].a); glyph_run_flush(&run, attr);
text_x = side_margin + col * extents.max_x_advance; text_x = side_margin + col * extents.max_x_advance;
text_y = top_margin + extents.ascent + row * extents.height; 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_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_line_to(cr, text_x + extents.max_x_advance, (double) text_y + 1.5);
cairo_stroke(cr); cairo_stroke(cr);
} }
cairo_move_to(cr, text_x, text_y);
glyph_run_add(&run, text_x, text_y, &p_row[col]);
toShow.c = p_row[col];
cairo_show_text(cr, (char *) toShow.c.byte);
} }
} }
attr.key = ~0;
glyph_run_flush(&run, attr);
if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) { if ((terminal->mode & MODE_SHOW_CURSOR) && !terminal->focused) {
d = 0.5; d = 0.5;
@ -842,31 +926,29 @@ terminal_draw_contents(struct terminal *terminal)
cairo_destroy(cr); cairo_destroy(cr);
window_copy_surface(terminal->window, window_copy_surface(terminal->window, &allocation, surface);
&rectangle,
surface);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
} }
static void 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; int32_t width, height;
window_get_child_rectangle(terminal->window, &rectangle); width = (pixel_width - 2 * terminal->margin) /
width = (rectangle.width - 2 * terminal->margin) /
(int32_t) terminal->extents.max_x_advance; (int32_t) terminal->extents.max_x_advance;
height = (rectangle.height - 2 * terminal->margin) / height = (pixel_height - 2 * terminal->margin) /
(int32_t) terminal->extents.height; (int32_t) terminal->extents.height;
if (width < 0 || height < 0)
return;
terminal_resize(terminal, width, height); terminal_resize(terminal, width, height);
}
static void
terminal_draw(struct terminal *terminal)
{
window_draw(terminal->window); window_draw(terminal->window);
terminal_draw_contents(terminal); terminal_draw_contents(terminal);
window_flush(terminal->window); window_flush(terminal->window);
@ -1960,6 +2042,7 @@ terminal_create(struct display *display, int fullscreen)
window_set_fullscreen(terminal->window, terminal->fullscreen); window_set_fullscreen(terminal->window, terminal->fullscreen);
window_set_user_data(terminal->window, terminal); window_set_user_data(terminal->window, terminal);
window_set_redraw_handler(terminal->window, redraw_handler); 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_key_handler(terminal->window, key_handler);
window_set_keyboard_focus_handler(terminal->window, 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); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
cr = cairo_create(surface); 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_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_font_extents(cr, &terminal->extents);
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);

@ -57,7 +57,7 @@ struct view {
static void static void
view_draw(struct view *view) view_draw(struct view *view)
{ {
struct rectangle rectangle; struct rectangle allocation;
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_t *cr; cairo_t *cr;
PopplerPage *page; PopplerPage *page;
@ -65,15 +65,15 @@ view_draw(struct view *view)
window_draw(view->window); 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); page = poppler_document_get_page(view->document, view->page);
surface = window_get_surface(view->window); surface = window_get_surface(view->window);
cr = cairo_create(surface); cr = cairo_create(surface);
cairo_rectangle(cr, rectangle.x, rectangle.y, cairo_rectangle(cr, allocation.x, allocation.y,
rectangle.width, rectangle.height); allocation.width, allocation.height);
cairo_clip(cr); cairo_clip(cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0.8); cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
@ -81,16 +81,16 @@ view_draw(struct view *view)
cairo_paint(cr); cairo_paint(cr);
poppler_page_get_size(page, &width, &height); poppler_page_get_size(page, &width, &height);
doc_aspect = 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) if (doc_aspect < window_aspect)
scale = rectangle.height / height; scale = allocation.height / height;
else else
scale = rectangle.width / width; scale = allocation.width / width;
cairo_translate(cr, rectangle.x, rectangle.y); cairo_translate(cr, allocation.x, allocation.y);
cairo_scale(cr, scale, scale); cairo_scale(cr, scale, scale);
cairo_translate(cr, cairo_translate(cr,
(rectangle.width - width * scale) / 2 / scale, (allocation.width - width * scale) / 2 / scale,
(rectangle.height - height * scale) / 2 / scale); (allocation.height - height * scale) / 2 / scale);
cairo_rectangle(cr, 0, 0, width, height); cairo_rectangle(cr, 0, 0, width, height);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgb(cr, 1, 1, 1); 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 wl_surface *surface, int32_t width, int32_t height)
{ {
struct window *window = wl_surface_get_user_data(surface); struct window *window = wl_surface_get_user_data(surface);
int32_t child_width, child_height;
window->resize_edges = edges; if (window->resize_handler) {
window->allocation.width = width; child_width = width - 20 - window->margin * 2;
window->allocation.height = height; child_height = height - 60 - window->margin * 2;
(*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->resize_handler) if (window->redraw_handler)
(*window->resize_handler)(window, window->user_data); window_schedule_redraw(window);
if (window->redraw_handler) }
window_schedule_redraw(window);
} }
static const struct wl_shell_listener shell_listener = { static const struct wl_shell_listener shell_listener = {
@ -1058,28 +1066,27 @@ static const struct wl_shell_listener shell_listener = {
}; };
void void
window_get_child_rectangle(struct window *window, window_get_child_allocation(struct window *window,
struct rectangle *rectangle) struct rectangle *allocation)
{ {
if (window->fullscreen && !window->decoration) { if (window->fullscreen && !window->decoration) {
*rectangle = window->allocation; *allocation = window->allocation;
} else { } else {
rectangle->x = window->margin + 10; allocation->x = window->margin + 10;
rectangle->y = window->margin + 50; allocation->y = window->margin + 50;
rectangle->width = window->allocation.width - 20 - window->margin * 2; allocation->width =
rectangle->height = window->allocation.height - 60 - window->margin * 2; window->allocation.width - 20 - window->margin * 2;
allocation->height =
window->allocation.height - 60 - window->margin * 2;
} }
} }
void void
window_set_child_size(struct window *window, window_set_child_size(struct window *window, int32_t width, int32_t height)
struct rectangle *rectangle)
{ {
if (!window->fullscreen) { if (!window->fullscreen) {
window->allocation.width = window->allocation.width = width + 20 + window->margin * 2;
rectangle->width + 20 + window->margin * 2; window->allocation.height = height + 60 + window->margin * 2;
window->allocation.height =
rectangle->height + 60 + window->margin * 2;
} }
} }

@ -105,7 +105,9 @@ enum pointer_type {
POINTER_HAND1, 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_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_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, 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 void
window_draw(struct window *window); window_draw(struct window *window);
void void
window_get_child_rectangle(struct window *window, window_get_child_allocation(struct window *window,
struct rectangle *rectangle); struct rectangle *allocation);
void void
window_set_child_size(struct window *window, window_set_child_size(struct window *window, int32_t width, int32_t height);
struct rectangle *rectangle);
void void
window_copy_image(struct window *window, window_copy_image(struct window *window,
struct rectangle *rectangle, struct rectangle *rectangle,

@ -25,7 +25,10 @@ PKG_CHECK_MODULES(FFI, [libffi])
PKG_CHECK_MODULES(COMPOSITOR, PKG_CHECK_MODULES(COMPOSITOR,
[egl glesv2 gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.17] xcb-dri2 xcb-xfixes) [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(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], PKG_CHECK_MODULES(CAIRO_GL, [cairo-gl],
[have_cairo_gl=yes], [have_cairo_gl=no]) [have_cairo_gl=yes], [have_cairo_gl=no])
AS_IF([test "x$have_cairo_gl" = "xyes"], AS_IF([test "x$have_cairo_gl" = "xyes"],

Loading…
Cancel
Save