Compare commits

..

No commits in common. "3826cd605094eb7db1efda0217e52bdb944e3d3b" and "646d47d072caaa0754e2acd379be7fa2dca658ad" have entirely different histories.

5 changed files with 58 additions and 184 deletions

View File

@ -1,4 +1,4 @@
VERSION = 0.17
VERSION = 0.16.1
CFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=700
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man

170
drw.c
View File

@ -6,131 +6,34 @@
#include "shm_open.h"
#include "math.h"
void drwbuf_handle_release(void *data, struct wl_buffer *wl_buffer) {
struct drwsurf *ds = data;
ds->released = true;
};
const struct wl_buffer_listener buffer_listener = {
.release = drwbuf_handle_release
};
void drwsurf_handle_frame_cb(void* data, struct wl_callback* callback,
uint32_t time)
{
struct drwsurf *ds = data;
wl_callback_destroy(ds->frame_cb);
ds->frame_cb = NULL;
cairo_rectangle_int_t r = {0};
for (int i = 0; i < cairo_region_num_rectangles(ds->damage); i++) {
cairo_region_get_rectangle(ds->damage, i, &r);
wl_surface_damage(ds->surf, r.x, r.y, r.width, r.height);
};
cairo_region_subtract(ds->damage, ds->damage);
drwsurf_attach(ds);
}
const struct wl_callback_listener frame_listener = {
.done = drwsurf_handle_frame_cb
};
void drwsurf_register_frame_cb(struct drwsurf *ds)
{
if (ds->frame_cb)
return;
if (!ds->attached)
return;
ds->frame_cb = wl_surface_frame(ds->surf);
wl_callback_add_listener(ds->frame_cb, &frame_listener, ds);
wl_surface_commit(ds->surf);
}
void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
cairo_rectangle_int_t rect = { x, y, w, h };
cairo_region_union_rectangle(ds->damage, &rect);
cairo_region_union_rectangle(ds->backport_damage, &rect);
drwsurf_register_frame_cb(ds);
}
void
drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s)
{
if (ds->buf) {
munmap(ds->pool_data, ds->size);
wl_buffer_destroy(ds->buf);
ds->buf = NULL;
}
ds->scale = s;
ds->width = ceil(w * s);
ds->height = ceil(h * s);
if (ds->damage)
cairo_region_destroy(ds->damage);
ds->damage = cairo_region_create();
if (ds->backport_damage)
cairo_region_destroy(ds->backport_damage);
ds->backport_damage = cairo_region_create();
ds->released = true;
setup_buffer(ds, ds->back_buffer);
setup_buffer(ds, ds->display_buffer);
}
void
drwsurf_backport(struct drwsurf *ds)
{
cairo_save(ds->back_buffer->cairo);
cairo_scale(ds->back_buffer->cairo, 1/ds->scale, 1/ds->scale);
cairo_set_operator(ds->back_buffer->cairo, CAIRO_OPERATOR_SOURCE);
cairo_rectangle_int_t r = {0};
for (int i = 0; i < cairo_region_num_rectangles(ds->backport_damage); i++) {
cairo_region_get_rectangle(ds->backport_damage, i, &r);
cairo_set_source_surface(ds->back_buffer->cairo, ds->display_buffer->cairo_surf, 0, 0);
cairo_rectangle(
ds->back_buffer->cairo,
r.x * ds->scale,
r.y * ds->scale,
r.width * ds->scale,
r.height * ds->scale
);
cairo_fill(ds->back_buffer->cairo);
};
cairo_restore(ds->back_buffer->cairo);
cairo_region_subtract(ds->backport_damage, ds->backport_damage);
}
void
drwsurf_attach(struct drwsurf *ds)
{
wl_surface_attach(ds->surf, ds->back_buffer->buf, 0, 0);
wl_surface_commit(ds->surf);
ds->released = false;
ds->attached = true;
setup_buffer(ds);
}
void
drwsurf_flip(struct drwsurf *ds)
{
if (ds->released)
return;
ds->released = true;
struct drwbuf *tmp = ds->back_buffer;
ds->back_buffer = ds->display_buffer;
ds->display_buffer = tmp;
drwsurf_backport(ds);
wl_surface_attach(ds->surf, ds->buf, 0, 0);
wl_surface_commit(ds->surf);
}
void
drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description)
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
cairo_save(d->cairo);
@ -155,11 +58,8 @@ drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
}
void
drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
cairo_save(d->cairo);
cairo_set_operator(d->cairo, CAIRO_OPERATOR_CLEAR);
@ -170,12 +70,9 @@ drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
}
void
drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, bool over, int rounding)
{
drwsurf_flip(ds);
struct drwbuf *d = ds->back_buffer;
cairo_save(d->cairo);
if (over) {
@ -231,52 +128,41 @@ drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
}
uint32_t
setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf)
setup_buffer(struct drwsurf *drwsurf)
{
int prev_size = drwbuf->size;
int stride = drwsurf->width * 4;
drwbuf->size = stride * drwsurf->height;
drwsurf->size = stride * drwsurf->height;
int fd = allocate_shm_file(drwbuf->size);
int fd = allocate_shm_file(drwsurf->size);
if (fd == -1) {
return 1;
}
if (drwbuf->pool_data)
munmap(drwbuf->pool_data, prev_size);
drwbuf->pool_data =
mmap(NULL, drwbuf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (drwbuf->pool_data == MAP_FAILED) {
drwsurf->pool_data =
mmap(NULL, drwsurf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (drwsurf->pool_data == MAP_FAILED) {
close(fd);
return 1;
}
if (drwbuf->buf)
wl_buffer_destroy(drwbuf->buf);
struct wl_shm_pool *pool =
wl_shm_create_pool(drwsurf->ctx->shm, fd, drwbuf->size);
drwbuf->buf =
wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->size);
drwsurf->buf =
wl_shm_pool_create_buffer(pool, 0, drwsurf->width, drwsurf->height,
stride, WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool);
close(fd);
wl_buffer_add_listener(drwbuf->buf, &buffer_listener, drwsurf);
if (drwbuf->cairo_surf)
cairo_surface_destroy(drwbuf->cairo_surf);
drwbuf->cairo_surf = cairo_image_surface_create_for_data(
drwbuf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width,
cairo_surface_t *s = cairo_image_surface_create_for_data(
drwsurf->pool_data, CAIRO_FORMAT_ARGB32, drwsurf->width,
drwsurf->height, stride);
if (drwbuf->cairo)
cairo_destroy(drwbuf->cairo);
drwbuf->cairo = cairo_create(drwbuf->cairo_surf);
cairo_scale(drwbuf->cairo, drwsurf->scale, drwsurf->scale);
cairo_set_antialias(drwbuf->cairo, CAIRO_ANTIALIAS_NONE);
drwbuf->layout = pango_cairo_create_layout(drwbuf->cairo);
pango_layout_set_auto_dir(drwbuf->layout, false);
cairo_save(drwbuf->cairo);
drwsurf->cairo = cairo_create(s);
cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
cairo_set_antialias(drwsurf->cairo, CAIRO_ANTIALIAS_NONE);
drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
pango_layout_set_auto_dir(drwsurf->layout, false);
cairo_save(drwsurf->cairo);
return 0;
}

35
drw.h
View File

@ -7,35 +7,22 @@
struct drw {
struct wl_shm *shm;
};
struct drwbuf {
uint32_t size;
struct wl_buffer *buf;
cairo_surface_t *cairo_surf;
cairo_t *cairo;
PangoLayout *layout;
unsigned char *pool_data;
};
struct drwsurf {
uint32_t width, height;
uint32_t width, height, size;
double scale;
struct drw *ctx;
struct wl_surface *surf;
struct wl_buffer *buf;
struct wl_shm *shm;
struct wl_callback *frame_cb;
unsigned char *pool_data;
cairo_region_t *damage, *backport_damage;
bool attached;
bool released;
struct drwbuf *back_buffer;
struct drwbuf *display_buffer;
cairo_t *cairo;
PangoLayout *layout;
};
struct kbd;
void drwsurf_damage(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, double s);
void drwsurf_attach(struct drwsurf *ds);
void drwsurf_flip(struct drwsurf *ds);
typedef union {
@ -43,19 +30,19 @@ typedef union {
uint32_t color;
} Color;
void drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y,
void drw_do_clear(struct drwsurf *d, uint32_t x, uint32_t y,
uint32_t w, uint32_t h);
void drw_do_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
void drw_do_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, bool fill, int rounding);
void drw_fill_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
void drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding);
void drw_over_rectangle(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
void drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, int rounding);
void drw_draw_text(struct drwsurf *ds, Color color, uint32_t x, uint32_t y,
void drw_draw_text(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t w, uint32_t h, uint32_t b, const char *label,
PangoFontDescription *font_description);
uint32_t setup_buffer(struct drwsurf *ds, struct drwbuf *db);
uint32_t setup_buffer(struct drwsurf *drwsurf);
#endif

View File

@ -337,7 +337,10 @@ kbd_release_key(struct kbd *kb, uint32_t time)
kb->last_swipe = NULL;
}
drwsurf_flip(kb->surf);
kbd_clear_last_popup(kb);
drwsurf_flip(kb->popup_surf);
}
void
@ -363,7 +366,10 @@ kbd_motion_key(struct kbd *kb, uint32_t time, uint32_t x, uint32_t y)
kbd_unpress_key(kb, time);
}
drwsurf_flip(kb->surf);
kbd_clear_last_popup(kb);
drwsurf_flip(kb->popup_surf);
}
void
@ -495,6 +501,9 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time)
default:
break;
}
drwsurf_flip(kb->surf);
drwsurf_flip(kb->popup_surf);
}
void
@ -544,13 +553,8 @@ kbd_clear_last_popup(struct kbd *kb)
if (kb->last_popup_w && kb->last_popup_h) {
drw_do_clear(kb->popup_surf, kb->last_popup_x, kb->last_popup_y,
kb->last_popup_w, kb->last_popup_h);
drwsurf_damage(
kb->popup_surf,
kb->last_popup_x,
kb->last_popup_y,
kb->last_popup_w,
kb->last_popup_h
);
wl_surface_damage(kb->popup_surf->surf, kb->last_popup_x,
kb->last_popup_y, kb->last_popup_w, kb->last_popup_h);
kb->last_popup_w = kb->last_popup_h = 0;
}
@ -584,7 +588,7 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
drw_draw_text(kb->surf, scheme->text, k->x, k->y, k->w, k->h,
KBD_KEY_BORDER, label, scheme->font_description);
drwsurf_damage(kb->surf, k->x, k->y, k->w, k->h);
wl_surface_damage(kb->surf->surf, k->x, k->y, k->w, k->h);
if (type == Press || type == Unpress) {
kbd_clear_last_popup(kb);
@ -601,7 +605,8 @@ kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type)
drw_draw_text(kb->popup_surf, scheme->text, k->x, kb->last_popup_y,
k->w, k->h, KBD_KEY_BORDER, label,
scheme->font_description);
drwsurf_damage(kb->popup_surf, k->x, kb->last_popup_y, k->w, k->h);
wl_surface_damage(kb->popup_surf->surf, k->x, kb->last_popup_y, k->w,
k->h);
}
}
@ -628,7 +633,7 @@ kbd_draw_layout(struct kbd *kb)
}
next_key++;
}
drwsurf_damage(d, 0, 0, kb->w, kb->h);
wl_surface_damage(d->surf, 0, 0, kb->w, kb->h);
}
void

10
main.c
View File

@ -62,7 +62,6 @@ static int wl_outputs_size;
/* drawing */
static struct drw draw_ctx;
static struct drwbuf draw_surf_back_buffer, draw_surf_display_buffer, popup_draw_surf_back_buffer, popup_draw_surf_display_buffer;
static struct drwsurf draw_surf, popup_draw_surf;
/* layer surface parameters */
@ -333,6 +332,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time,
}
kbd_next_layer(&keyboard, NULL, (value >= 0));
drwsurf_flip(keyboard.surf);
}
void
@ -517,7 +517,7 @@ xdg_popup_surface_configure(void *data, struct xdg_surface *xdg_surface,
{
xdg_surface_ack_configure(xdg_surface, serial);
popup_xdg_surface_configured = true;
drwsurf_attach(&popup_draw_surf);
drwsurf_flip(&popup_draw_surf);
}
static const struct xdg_surface_listener xdg_popup_surface_listener = {
@ -664,7 +664,7 @@ layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
zwlr_layer_surface_v1_ack_configure(surface, serial);
kbd_resize(&keyboard, layouts, NumLayouts);
drwsurf_attach(&draw_surf);
drwsurf_flip(&draw_surf);
} else {
zwlr_layer_surface_v1_ack_configure(surface, serial);
}
@ -1018,11 +1018,7 @@ main(int argc, char **argv)
}
draw_surf.ctx = &draw_ctx;
draw_surf.back_buffer = &draw_surf_back_buffer;
draw_surf.display_buffer = &draw_surf_display_buffer;
popup_draw_surf.ctx = &draw_ctx;
popup_draw_surf.back_buffer = &popup_draw_surf_back_buffer;
popup_draw_surf.display_buffer = &popup_draw_surf_display_buffer;
keyboard.surf = &draw_surf;
keyboard.popup_surf = &popup_draw_surf;