summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c142
-rw-r--r--src/surface.c19
-rw-r--r--src/surface.h5
-rw-r--r--src/tofi.h1
4 files changed, 138 insertions, 29 deletions
diff --git a/src/main.c b/src/main.c
index 362fef6..6284cda 100644
--- a/src/main.c
+++ b/src/main.c
@@ -56,9 +56,6 @@ static void zwlr_layer_surface_configure(
tofi->window.surface.width = tofi->window.width;
tofi->window.surface.height = tofi->window.height;
- /* Assume 4 bytes per pixel for WL_SHM_FORMAT_ARGB8888 */
- tofi->window.surface.stride = tofi->window.surface.width * 4;
-
/*
* Need to redraw the background at the new size. This entails
* a wl_surface_commit, so no need to do so explicitly here.
@@ -587,6 +584,62 @@ static const struct wl_surface_listener wl_surface_listener = {
.leave = surface_leave
};
+/*
+ * These "dummy_*" functions are callbacks just for the dummy surface used to
+ * select the default output if there's more than one.
+ */
+static void dummy_layer_surface_configure(
+ void *data,
+ struct zwlr_layer_surface_v1 *zwlr_layer_surface,
+ uint32_t serial,
+ uint32_t width,
+ uint32_t height)
+{
+ zwlr_layer_surface_v1_ack_configure(
+ zwlr_layer_surface,
+ serial);
+}
+
+static void dummy_layer_surface_close(
+ void *data,
+ struct zwlr_layer_surface_v1 *zwlr_layer_surface)
+{
+}
+
+static const struct zwlr_layer_surface_v1_listener dummy_layer_surface_listener = {
+ .configure = dummy_layer_surface_configure,
+ .closed = dummy_layer_surface_close
+};
+
+static void dummy_surface_enter(
+ void *data,
+ struct wl_surface *wl_surface,
+ struct wl_output *wl_output)
+{
+ struct tofi *tofi = data;
+ struct output_list_element *el;
+ wl_list_for_each(el, &tofi->output_list, link) {
+ if (el->wl_output == wl_output) {
+ tofi->default_output = el;
+ break;
+ }
+ }
+}
+
+static void dummy_surface_leave(
+ void *data,
+ struct wl_surface *wl_surface,
+ struct wl_output *wl_output)
+{
+ /* Deliberately left blank */
+}
+
+static const struct wl_surface_listener dummy_surface_listener = {
+ .enter = dummy_surface_enter,
+ .leave = dummy_surface_leave
+};
+
+
static void usage()
{
fprintf(stderr, "%s",
@@ -749,6 +802,9 @@ static void parse_args(struct tofi *tofi, int argc, char *argv[])
int main(int argc, char *argv[])
{
+ /* Call log_debug to initialise the timers we use for perf checking. */
+ log_debug("This is tofi.\n");
+
/*
* Set the locale to the user's default, so we can deal with non-ASCII
* characters.
@@ -834,11 +890,60 @@ int main(int argc, char *argv[])
log_unindent();
log_debug("Second roundtrip done.\n");
- /*
- * Walk through our output list and select the one we want if the
- * user's asked for a specific one, otherwise just get the first one.
- */
- {
+ /* If there's more than one output, we need to select one. */
+ if (wl_list_length(&tofi.output_list) > 1) {
+ /*
+ * Determine the default output
+ *
+ * This seems like an ugly solution, but as far as I know
+ * there's no way to determine the default output other than to
+ * call get_layer_surface with NULL as the output and see which
+ * output our surface turns up on.
+ *
+ * Here we set up a single pixel surface, perform the required
+ * two roundtrips, then tear it down. tofi.default_output
+ * should then contain the output our surface was assigned to.
+ */
+ struct surface surface = {
+ .width = 1,
+ .height = 1
+ };
+ surface.wl_surface =
+ wl_compositor_create_surface(tofi.wl_compositor);
+ wl_surface_add_listener(
+ surface.wl_surface,
+ &dummy_surface_listener,
+ &tofi);
+
+ struct zwlr_layer_surface_v1 *zwlr_layer_surface =
+ zwlr_layer_shell_v1_get_layer_surface(
+ tofi.zwlr_layer_shell,
+ surface.wl_surface,
+ NULL,
+ ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND,
+ "dummy");
+ zwlr_layer_surface_v1_add_listener(
+ zwlr_layer_surface,
+ &dummy_layer_surface_listener,
+ &tofi);
+ zwlr_layer_surface_v1_set_size(
+ zwlr_layer_surface,
+ 1,
+ 1);
+ wl_surface_commit(surface.wl_surface);
+ wl_display_roundtrip(tofi.wl_display);
+ surface_init(&surface, tofi.wl_shm);
+ surface_draw(&surface);
+ wl_display_roundtrip(tofi.wl_display);
+ surface_destroy(&surface);
+ zwlr_layer_surface_v1_destroy(zwlr_layer_surface);
+ wl_surface_destroy(surface.wl_surface);
+
+ /*
+ * Walk through our output list and select the one we want if
+ * the user's asked for a specific one, otherwise just get the
+ * default one.
+ */
bool found_target = false;
struct output_list_element *head;
head = wl_container_of(tofi.output_list.next, head, link);
@@ -847,6 +952,14 @@ int main(int argc, char *argv[])
struct output_list_element *tmp;
if (tofi.target_output_name[0] != 0) {
log_debug("Looking for output %s.\n", tofi.target_output_name);
+ } else if (tofi.default_output != NULL) {
+ snprintf(
+ tofi.target_output_name,
+ N_ELEM(tofi.target_output_name),
+ "%s",
+ tofi.default_output->name);
+ /* We don't need this anymore. */
+ tofi.default_output = NULL;
}
wl_list_for_each_reverse_safe(el, tmp, &tofi.output_list, link) {
if (!strcmp(tofi.target_output_name, el->name)) {
@@ -865,10 +978,13 @@ int main(int argc, char *argv[])
free(el);
}
}
+ }
+ {
/*
* The only output left should either be the one we want, or
* the first that was advertised.
*/
+ struct output_list_element *el;
el = wl_container_of(tofi.output_list.next, el, link);
tofi.output_width = el->width;
tofi.output_height = el->height;
@@ -1013,10 +1129,7 @@ int main(int argc, char *argv[])
log_debug("Renderer initialised.\n");
/* Perform an initial render. */
- surface_draw(
- &tofi.window.surface,
- &tofi.window.entry.background_color,
- &tofi.window.entry.image);
+ surface_draw(&tofi.window.surface);
/*
* entry_init() left the second of the two buffers we use for
@@ -1058,10 +1171,7 @@ int main(int argc, char *argv[])
break;
}
if (tofi.window.surface.redraw) {
- surface_draw(
- &tofi.window.surface,
- &tofi.window.entry.background_color,
- &tofi.window.entry.image);
+ surface_draw(&tofi.window.surface);
tofi.window.surface.redraw = false;
}
if (tofi.submit) {
diff --git a/src/surface.c b/src/surface.c
index e7b2ac1..e640c40 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -13,7 +13,11 @@ void surface_init(
struct wl_shm *wl_shm)
{
const int height = surface->height;
- const int stride = surface->stride;
+ const int width = surface->width;
+
+ /* Assume 4 bytes per pixel for WL_SHM_FORMAT_ARGB8888 */
+ const int stride = width * 4;
+ surface->stride = stride;
/* Double-buffered pool, so allocate space for two windows */
surface->shm_pool_size =
@@ -34,13 +38,13 @@ void surface_init(
surface->shm_pool_size);
for (int i = 0; i < 2; i++) {
- int offset = surface->height * surface->stride * i;
+ int offset = height * stride * i;
surface->buffers[i] = wl_shm_pool_create_buffer(
surface->wl_shm_pool,
offset,
- surface->width,
- surface->height,
- surface->stride,
+ width,
+ height,
+ stride,
WL_SHM_FORMAT_ARGB8888);
}
@@ -58,10 +62,7 @@ void surface_destroy(struct surface *surface)
wl_buffer_destroy(surface->buffers[1]);
}
-void surface_draw(
- struct surface *surface,
- struct color *color,
- struct image *texture)
+void surface_draw(struct surface *surface)
{
wl_surface_attach(surface->wl_surface, surface->buffers[surface->index], 0, 0);
wl_surface_damage_buffer(surface->wl_surface, 0, 0, INT32_MAX, INT32_MAX);
diff --git a/src/surface.h b/src/surface.h
index 68f9a31..e1a5887 100644
--- a/src/surface.h
+++ b/src/surface.h
@@ -26,9 +26,6 @@ void surface_init(
struct surface *surface,
struct wl_shm *wl_shm);
void surface_destroy(struct surface *surface);
-void surface_draw(
- struct surface *surface,
- struct color *color,
- struct image *texture);
+void surface_draw(struct surface *surface);
#endif /* SURFACE_H */
diff --git a/src/tofi.h b/src/tofi.h
index ec3582b..7ad202c 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -29,6 +29,7 @@ struct tofi {
struct wl_shm *wl_shm;
struct zwlr_layer_shell_v1 *zwlr_layer_shell;
struct wl_list output_list;
+ struct output_list_element *default_output;
/* Wayland objects */
struct wl_keyboard *wl_keyboard;