@@ 63,6 63,7 @@ struct client_state {
struct wl_shm *wl_shm;
struct wl_compositor *wl_compositor;
struct xdg_wm_base *xdg_wm_base;
+ struct wl_output *wl_output;
// Objects
struct wl_surface *wl_surface;
@@ 70,6 71,9 @@ struct client_state {
struct xdg_toplevel *xdg_toplevel;
// State
+ int scale;
+ int width;
+ int height;
float offset;
uint32_t last_frame;
};
@@ 84,7 88,18 @@ static const struct wl_buffer_listener wl_buffer_listener = {
};
static struct wl_buffer *draw_frame(struct client_state *state) {
- const int width = 100, height = 100;
+ const int base_width = 100, base_height = 100;
+ if (state->scale < 1) {
+ state->scale=1;
+ }
+ if (state->width < 1) {
+ state->width=base_width;
+ }
+ if (state->height < 1) {
+ state->height=base_height;
+ }
+ int width = state->scale*state->width;
+ int height = state->scale*state->height;
int stride = width * 4;
int size = stride * height;
@@ 159,6 174,9 @@ static void registry_handle_global(
if (strncmp(interface, xdg_wm_base_interface.name, strlen(xdg_wm_base_interface.name)) == 0) {
state->xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
}
+ if (strncmp(interface, wl_output_interface.name, strlen(wl_output_interface.name)) == 0) {
+ state->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 2);
+ }
}
static void registry_handle_global_remove(
@@ 174,6 192,7 @@ static const struct wl_registry_listener registry_listener = {
.global_remove = registry_handle_global_remove,
};
+// Declare the existence of this value so we can refer to it.
static const struct wl_callback_listener wl_surface_frame_listener;
static void wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) {
@@ 194,16 213,106 @@ static void wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t t
// Submit a frame for this event
struct wl_buffer *buffer = draw_frame(state);
wl_surface_attach(state->wl_surface, buffer, 0, 0);
+ wl_surface_set_buffer_scale(state->wl_surface, state->scale);
wl_surface_damage_buffer(state->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_commit(state->wl_surface);
state->last_frame=time;
}
+// Populate the callback listener.
static const struct wl_callback_listener wl_surface_frame_listener = {
.done = wl_surface_frame_done,
};
+static void wl_output_geometry(
+ void *data,
+ struct wl_output *wl_output,
+ int32_t x, int32_t y, int32_t phys_width, int32_t phys_height,
+ int32_t pixels,
+ const char *make, const char* model,
+ int32_t transform
+) {
+}
+
+static void wl_output_mode(
+ void *data,
+ struct wl_output *wl_output,
+ uint32_t flags,
+ int32_t width,
+ int32_t height,
+ int32_t refresh
+) {
+}
+
+static void wl_output_name(
+ void *data,
+ struct wl_output *wl_output,
+ const char *name
+) {
+}
+
+static void wl_output_scale(
+ void *data,
+ struct wl_output *wl_output,
+ int32_t factor
+) {
+ struct client_state *state = data;
+ state->scale=factor;
+}
+
+static void wl_output_description(
+ void *data,
+ struct wl_output *wl_output,
+ const char *description
+) {
+}
+
+static void wl_output_done(
+ void *data,
+ struct wl_output *wl_output
+) {
+}
+
+static const struct wl_output_listener wl_output_listener = {
+ .geometry=wl_output_geometry,
+ .mode=wl_output_mode,
+ .name=wl_output_name,
+ .scale=wl_output_scale,
+ .description=wl_output_description,
+ .done=wl_output_done,
+};
+
+static void xdg_toplevel_configure(
+ void *data,
+ struct xdg_toplevel *xdg_toplevel,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states
+) {
+ struct client_state *state = data;
+ state->width=width;
+ state->height=height;
+};
+static void xdg_toplevel_close(
+ void *data,
+ struct xdg_toplevel *xdg_toplevel
+) {
+};
+static void xdg_toplevel_configure_bounds(
+ void *data,
+ struct xdg_toplevel *xdg_toplevel,
+ int32_t width,
+ int32_t height
+) {
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+ .configure = xdg_toplevel_configure,
+ .close = xdg_toplevel_close,
+ .configure_bounds = xdg_toplevel_configure_bounds,
+};
+
int main(int argc, char *argv[]) {
struct client_state state = { 0 };
state.wl_display = wl_display_connect(NULL);
@@ 215,11 324,15 @@ int main(int argc, char *argv[]) {
wl_registry_add_listener(state.wl_registry, ®istry_listener, &state);
wl_display_roundtrip(state.wl_display);
+ wl_output_add_listener(state.wl_output, &wl_output_listener, &state);
+
state.wl_surface = wl_compositor_create_surface(state.wl_compositor);
state.xdg_surface = xdg_wm_base_get_xdg_surface(state.xdg_wm_base, state.wl_surface);
xdg_surface_add_listener(state.xdg_surface, &xdg_surface_listener, &state);
state.xdg_toplevel = xdg_surface_get_toplevel(state.xdg_surface);
+ xdg_toplevel_add_listener(state.xdg_toplevel,&xdg_toplevel_listener, &state);
xdg_toplevel_set_title(state.xdg_toplevel, "Example Client");
+ xdg_toplevel_set_min_size(state.xdg_toplevel, 500, 500);
wl_surface_commit(state.wl_surface);
struct wl_callback *cb = wl_surface_frame(state.wl_surface);