mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
This function "scrolls" the buffer by the specified number of (pixel) rows. The idea is move the image offset by re-sizing the underlying memfd object. I.e. to scroll forward, increase the size of the memfd file, and move the pixman image offset forward (and the Wayland SHM buffer as well). Only increasing the file size would, obviously, cause the memfd file to grow indefinitely. To deal with this, we "punch" a whole from the beginning of the file to the new offset. This frees the associated memory. Thus, while we have a memfd file whose size is (as seen by e.g. fstat()) is ever growing, the actual file size is always the original buffer size. Some notes: * FALLOC_FL_PUNCH_HOLE can be quite slow when the number of used pages to drop is large. * all normal fallocate() usages have been replaced with ftruncate(), as this is *much* faster. fallocate() guarantees subsequent writes wont fail. I.e. it actually reserves (disk) space. While it doesn't allocate on-disk blocks for on-disk files, it *does* zero-initialize the in-memory blocks. And this is slow. ftruncate() doesn't do this. TODO: implement reverse scrolling (i.e. a negative row count).
42 lines
1.3 KiB
C
42 lines
1.3 KiB
C
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
#include <pixman.h>
|
|
#include <wayland-client.h>
|
|
|
|
struct buffer {
|
|
unsigned long cookie;
|
|
|
|
int width;
|
|
int height;
|
|
int stride;
|
|
|
|
bool busy;
|
|
size_t size; /* Buffer size */
|
|
void *mmapped; /* Raw data */
|
|
|
|
struct wl_buffer *wl_buf;
|
|
pixman_image_t *pix;
|
|
|
|
/* Internal */
|
|
int fd; /* memfd */
|
|
void *real_mmapped; /* Address returned from mmap */
|
|
size_t mmap_size; /* Size of mmap (>= size) */
|
|
size_t offset; /* Offset into memfd where data begins */
|
|
bool purge; /* True if this buffer should be destroyed */
|
|
};
|
|
|
|
struct buffer *shm_get_buffer(
|
|
struct wl_shm *shm, int width, int height, unsigned long cookie);
|
|
void shm_fini(void);
|
|
|
|
bool shm_scroll(struct wl_shm *shm, struct buffer *buf, int rows);
|
|
|
|
void shm_purge(struct wl_shm *shm, unsigned long cookie);
|
|
|
|
struct terminal;
|
|
static inline unsigned long shm_cookie_grid(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 0); }
|
|
static inline unsigned long shm_cookie_search(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 1); }
|
|
static inline unsigned long shm_cookie_csd(const struct terminal *term, int n) { return (unsigned long)((uintptr_t)term + 2 + (n)); }
|