Handle output scaling

This commit is contained in:
Stacy Harper 2021-08-24 20:13:37 +02:00 committed by John Sullivan
parent c806023fd5
commit fb82daea9c
4 changed files with 64 additions and 39 deletions

30
drw.c
View File

@ -6,8 +6,7 @@
#include "shm_open.h" #include "shm_open.h"
void void
drw_init(struct drw *d, const char *fc_pattern, struct wl_display *dpy, drw_init(struct drw *d, const char *fc_pattern, void *shm) {
void *shm) {
d->shm = shm; d->shm = shm;
d->font_description = pango_font_description_from_string(fc_pattern); d->font_description = pango_font_description_from_string(fc_pattern);
} }
@ -19,15 +18,16 @@ drwsurf_init(struct drw *d, struct drwsurf *ds, struct wl_surface *surf) {
} }
void void
drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h) { drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, uint32_t s) {
if (ds->buf) { if (ds->buf) {
munmap(ds->pool_data, ds->s); munmap(ds->pool_data, ds->size);
wl_buffer_destroy(ds->buf); wl_buffer_destroy(ds->buf);
ds->buf = NULL; ds->buf = NULL;
} }
ds->w = w; ds->scale = s;
ds->h = h; ds->width = w * s;
ds->height = h * s;
setup_buffer(ds); setup_buffer(ds);
} }
@ -45,11 +45,12 @@ drwsurf_flip(struct drwsurf *ds) {
wl_callback_add_listener(ds->cb, &frame_listener, (void *)ds); wl_callback_add_listener(ds->cb, &frame_listener, (void *)ds);
if (ds->dirty) { if (ds->dirty) {
wl_surface_damage(ds->surf, 0, 0, ds->w, ds->h); wl_surface_damage(ds->surf, 0, 0, ds->width, ds->height);
ds->dirty = false; ds->dirty = false;
} }
wl_surface_attach(ds->surf, ds->buf, 0, 0); wl_surface_attach(ds->surf, ds->buf, 0, 0);
wl_surface_set_buffer_scale(ds->surf, ds->scale);
wl_surface_commit(ds->surf); wl_surface_commit(ds->surf);
} }
@ -112,32 +113,33 @@ drw_fill_rectangle(struct drwsurf *d, Color color, uint32_t x, uint32_t y,
uint32_t uint32_t
setup_buffer(struct drwsurf *drwsurf) setup_buffer(struct drwsurf *drwsurf)
{ {
int stride = drwsurf->w * 4; int stride = drwsurf->width * 4;
drwsurf->s = stride * drwsurf->h; drwsurf->size = stride * drwsurf->height;
int fd = allocate_shm_file(drwsurf->s); int fd = allocate_shm_file(drwsurf->size);
if (fd == -1) { if (fd == -1) {
return 1; return 1;
} }
drwsurf->pool_data = mmap(NULL, drwsurf->s, drwsurf->pool_data = mmap(NULL, drwsurf->size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (drwsurf->pool_data == MAP_FAILED) { if (drwsurf->pool_data == MAP_FAILED) {
close(fd); close(fd);
return 1; return 1;
} }
struct wl_shm_pool *pool = wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->s); struct wl_shm_pool *pool = wl_shm_create_pool(drwsurf->ctx->shm, fd, drwsurf->size);
drwsurf->buf = wl_shm_pool_create_buffer(pool, 0, drwsurf->buf = wl_shm_pool_create_buffer(pool, 0,
drwsurf->w, drwsurf->h, stride, WL_SHM_FORMAT_ARGB8888); drwsurf->width, drwsurf->height, stride, WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool); wl_shm_pool_destroy(pool);
close(fd); close(fd);
cairo_surface_t *s = cairo_image_surface_create_for_data(drwsurf->pool_data, cairo_surface_t *s = cairo_image_surface_create_for_data(drwsurf->pool_data,
CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_ARGB32,
drwsurf->w, drwsurf->h, stride); drwsurf->width, drwsurf->height, stride);
drwsurf->cairo = cairo_create(s); drwsurf->cairo = cairo_create(s);
cairo_scale(drwsurf->cairo, drwsurf->scale, drwsurf->scale);
drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo); drwsurf->layout = pango_cairo_create_layout(drwsurf->cairo);
pango_layout_set_font_description(drwsurf->layout, drwsurf->ctx->font_description); pango_layout_set_font_description(drwsurf->layout, drwsurf->ctx->font_description);
cairo_save(drwsurf->cairo); cairo_save(drwsurf->cairo);

7
drw.h
View File

@ -8,10 +8,9 @@ struct drw;
struct drwsurf; struct drwsurf;
struct kbd; struct kbd;
void drw_init(struct drw *d, const char *fc_pattern, struct wl_display *dpy, void drw_init(struct drw *d, const char *fc_pattern, void *iface);
void *iface);
void drwsurf_init(struct drw *d, struct drwsurf *ds, struct wl_surface *surf); void drwsurf_init(struct drw *d, struct drwsurf *ds, struct wl_surface *surf);
void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h); void drwsurf_resize(struct drwsurf *ds, uint32_t w, uint32_t h, uint32_t s);
void drwsurf_flip(struct drwsurf *ds); void drwsurf_flip(struct drwsurf *ds);
typedef union { typedef union {
@ -38,7 +37,7 @@ struct drw {
}; };
struct drwsurf { struct drwsurf {
uint32_t w, h, s; uint32_t width, height, scale, size;
bool dirty; bool dirty;
struct drw *ctx; struct drw *ctx;

View File

@ -76,7 +76,7 @@ struct kbd {
struct clr_scheme scheme1; struct clr_scheme scheme1;
bool print; bool print;
uint32_t w, h; uint32_t w, h, s;
uint8_t mods; uint8_t mods;
struct key *last_press; struct key *last_press;
struct layout *prevlayout; struct layout *prevlayout;
@ -101,8 +101,7 @@ static void kbd_press_key(struct kbd *kb, struct key *k, uint32_t time);
static void kbd_print_key_stdout(struct kbd *kb, struct key *k); static void kbd_print_key_stdout(struct kbd *kb, struct key *k);
static void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed); static void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed);
static void kbd_draw_layout(struct kbd *kb); static void kbd_draw_layout(struct kbd *kb);
static void kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, static void kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount);
struct layout *layouts, uint8_t layoutcount);
static uint8_t kbd_get_rows(struct layout *l); static uint8_t kbd_get_rows(struct layout *l);
static double kbd_get_row_length(struct key *k); static double kbd_get_row_length(struct key *k);
static void kbd_switch_layout(struct kbd *kb, struct layout *l); static void kbd_switch_layout(struct kbd *kb, struct layout *l);
@ -431,18 +430,14 @@ kbd_draw_layout(struct kbd *kb) {
} }
void void
kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, struct layout *layouts, kbd_resize(struct kbd *kb, struct layout *layouts, uint8_t layoutcount) {
uint8_t layoutcount) {
struct drwsurf *d = kb->surf; struct drwsurf *d = kb->surf;
kb->w = w; fprintf(stderr, "Resize %dx%d %d, %d layouts\n", kb->w, kb->h, kb->s, layoutcount);
kb->h = h;
fprintf(stderr, "Resize %dx%d, %d layouts\n", w, h, layoutcount); drwsurf_resize(d, kb->w, kb->h, kb->s);
drwsurf_resize(d, w, h);
for (int i = 0; i < layoutcount; i++) { for (int i = 0; i < layoutcount; i++) {
kbd_init_layout(&layouts[i], w, h); kbd_init_layout(&layouts[i], kb->w, kb->h);
} }
kbd_draw_layout(kb); kbd_draw_layout(kb);
d->dirty = true; d->dirty = true;

49
main.c
View File

@ -29,7 +29,6 @@ static struct wl_surface *wl_surface;
static struct zwlr_layer_shell_v1 *layer_shell; static struct zwlr_layer_shell_v1 *layer_shell;
static struct zwlr_layer_surface_v1 *layer_surface; static struct zwlr_layer_surface_v1 *layer_surface;
static struct zwp_virtual_keyboard_manager_v1 *vkbd_mgr; static struct zwp_virtual_keyboard_manager_v1 *vkbd_mgr;
static uint32_t output = UINT32_MAX;
/* drawing */ /* drawing */
static struct drw draw_ctx; static struct drw draw_ctx;
@ -244,20 +243,47 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
void void
seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) {} seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) {}
static void
display_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, int physical_width, int physical_height, int subpixel, const char *make, const char *model, int transform)
{
}
static void
display_handle_done(void *data, struct wl_output *wl_output)
{
}
static void
display_handle_scale(void *data, struct wl_output *wl_output, int32_t scale)
{
keyboard.s = scale;
}
static void
display_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, int width, int height, int refresh)
{
}
static const struct wl_output_listener output_listener = {
.geometry = display_handle_geometry,
.mode = display_handle_mode,
.done = display_handle_done,
.scale = display_handle_scale
};
void void
handle_global(void *data, struct wl_registry *registry, uint32_t name, handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) { const char *interface, uint32_t version) {
if (strcmp(interface, wl_compositor_interface.name) == 0) { if (strcmp(interface, wl_compositor_interface.name) == 0) {
compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 3);
} else if (strcmp(interface, wl_shm_interface.name) == 0) { } else if (strcmp(interface, wl_shm_interface.name) == 0) {
shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) { } else if (strcmp(interface, "wl_output") == 0) {
if (output != UINT32_MAX) { if (!wl_output) {
if (!wl_output) { wl_output = wl_registry_bind(registry, name, &wl_output_interface, 2);
wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1); keyboard.s = 1;
} else { wl_output_add_listener(wl_output, &output_listener, NULL);
output--;
}
} }
} else if (strcmp(interface, wl_seat_interface.name) == 0) { } else if (strcmp(interface, wl_seat_interface.name) == 0) {
seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
@ -278,7 +304,10 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {}
void void
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
uint32_t serial, uint32_t w, uint32_t h) { uint32_t serial, uint32_t w, uint32_t h) {
kbd_resize(&keyboard, w + KBD_PIXEL_OVERSCAN_WIDTH, h, layouts, NumLayouts); keyboard.w = w + KBD_PIXEL_OVERSCAN_WIDTH;
keyboard.h = h;
kbd_resize(&keyboard, layouts, NumLayouts);
zwlr_layer_surface_v1_ack_configure(surface, serial); zwlr_layer_surface_v1_ack_configure(surface, serial);
} }
@ -402,7 +431,7 @@ main(int argc, char **argv) {
/* create surface */ /* create surface */
wl_surface = wl_compositor_create_surface(compositor); wl_surface = wl_compositor_create_surface(compositor);
drw_init(&draw_ctx, fc_font_pattern, display, shm); drw_init(&draw_ctx, fc_font_pattern, shm);
drwsurf_init(&draw_ctx, &draw_surf, wl_surface); drwsurf_init(&draw_ctx, &draw_surf, wl_surface);
layer_surface = zwlr_layer_shell_v1_get_layer_surface( layer_surface = zwlr_layer_shell_v1_get_layer_surface(