lisgd + wvkbd
This commit is contained in:
parent
adbe4541cb
commit
6d345f43d4
36 changed files with 31637 additions and 0 deletions
285
packages/wvkbd/drw.c
Normal file
285
packages/wvkbd/drw.c
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "drw.h"
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
drw_draw_text(struct drwsurf *ds, 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;
|
||||
drwsurf_damage(ds, x, y, w, h);
|
||||
|
||||
cairo_save(d->cairo);
|
||||
|
||||
pango_layout_set_font_description(d->layout, font_description);
|
||||
|
||||
cairo_set_source_rgba(
|
||||
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
||||
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
|
||||
cairo_move_to(d->cairo, x + w / 2, y + h / 2);
|
||||
|
||||
pango_layout_set_text(d->layout, label, -1);
|
||||
pango_layout_set_width(d->layout, (w - (b * 2)) * PANGO_SCALE);
|
||||
pango_layout_set_height(d->layout, (h - (b * 2)) * PANGO_SCALE);
|
||||
|
||||
int width, height;
|
||||
pango_layout_get_pixel_size(d->layout, &width, &height);
|
||||
|
||||
cairo_rel_move_to(d->cairo, -width / 2, -height / 2);
|
||||
|
||||
pango_cairo_show_layout(d->cairo, d->layout);
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
|
||||
void
|
||||
drw_do_clear(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
drwsurf_flip(ds);
|
||||
struct drwbuf *d = ds->back_buffer;
|
||||
drwsurf_damage(ds, x, y, w, h);
|
||||
|
||||
cairo_save(d->cairo);
|
||||
|
||||
cairo_set_operator(d->cairo, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_rectangle(d->cairo, x, y, w, h);
|
||||
cairo_fill(d->cairo);
|
||||
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
|
||||
void
|
||||
drw_do_rectangle(struct drwsurf *ds, 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;
|
||||
drwsurf_damage(ds, x, y, w, h);
|
||||
|
||||
cairo_save(d->cairo);
|
||||
|
||||
if (over) {
|
||||
cairo_set_operator(d->cairo, CAIRO_OPERATOR_OVER);
|
||||
} else {
|
||||
cairo_set_operator(d->cairo, CAIRO_OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
if (rounding > 0) {
|
||||
double radius = rounding / 1.0;
|
||||
double degrees = M_PI / 180.0;
|
||||
|
||||
cairo_new_sub_path (d->cairo);
|
||||
cairo_arc (d->cairo, x + w - radius, y + radius, radius, -90 * degrees, 0 * degrees);
|
||||
cairo_arc (d->cairo, x + w - radius, y + h - radius, radius, 0 * degrees, 90 * degrees);
|
||||
cairo_arc (d->cairo, x + radius, y + h - radius, radius, 90 * degrees, 180 * degrees);
|
||||
cairo_arc (d->cairo, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
|
||||
cairo_close_path (d->cairo);
|
||||
|
||||
cairo_set_source_rgba(
|
||||
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
||||
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
|
||||
cairo_fill (d->cairo);
|
||||
cairo_set_source_rgba(d->cairo, 0, 0, 0, 0.9);
|
||||
cairo_set_line_width(d->cairo, 1.0);
|
||||
cairo_stroke(d->cairo);
|
||||
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
else {
|
||||
cairo_rectangle(d->cairo, x, y, w, h);
|
||||
cairo_set_source_rgba(
|
||||
d->cairo, color.bgra[2] / (double)255, color.bgra[1] / (double)255,
|
||||
color.bgra[0] / (double)255, color.bgra[3] / (double)255);
|
||||
cairo_fill(d->cairo);
|
||||
|
||||
cairo_restore(d->cairo);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h, int rounding)
|
||||
{
|
||||
drw_do_rectangle(d, color, x, y, w, h, false, rounding);
|
||||
}
|
||||
|
||||
void
|
||||
drw_over_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h, int rounding)
|
||||
{
|
||||
drw_do_rectangle(d, color, x, y, w, h, true, rounding);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
setup_buffer(struct drwsurf *drwsurf, struct drwbuf *drwbuf)
|
||||
{
|
||||
int prev_size = drwbuf->size;
|
||||
int stride = drwsurf->width * 4;
|
||||
drwbuf->size = stride * drwsurf->height;
|
||||
|
||||
int fd = allocate_shm_file(drwbuf->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) {
|
||||
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_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,
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue