+ xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
+
+ DLOG("RandR extension unusable, disabling.\n");
+
+ Output *s = scalloc(sizeof(Output));
+
+ s->active = true;
+ s->rect.x = 0;
+ s->rect.y = 0;
+ s->rect.width = root_screen->width_in_pixels;
+ s->rect.height = root_screen->height_in_pixels;
+ s->name = "xroot-0";
+ output_init_con(s);
+
+ TAILQ_INSERT_TAIL(&outputs, s, outputs);
+
+ randr_disabled = true;
+}
+
+/*
+ * Initializes a CT_OUTPUT Con (searches existing ones from inplace restart
+ * before) to use for the given Output.
+ *
+ * XXX: for assignments, we probably need to move workspace creation from here
+ * to after the loop in randr_query_outputs().
+ *
+ */
+void output_init_con(Output *output) {
+ Con *con = NULL, *current;
+ bool reused = false;
+
+ DLOG("init_con for output %s\n", output->name);
+
+ /* Search for a Con with that name directly below the root node. There
+ * might be one from a restored layout. */
+ TAILQ_FOREACH(current, &(croot->nodes_head), nodes) {
+ if (strcmp(current->name, output->name) != 0)
+ continue;
+
+ con = current;
+ reused = true;
+ DLOG("Using existing con %p / %s\n", con, con->name);
+ break;
+ }
+
+ if (con == NULL) {
+ con = con_new(croot);
+ FREE(con->name);
+ con->name = sstrdup(output->name);
+ con->type = CT_OUTPUT;
+ con->layout = L_OUTPUT;
+ }
+ con->rect = output->rect;
+ output->con = con;
+
+ char *name;
+ asprintf(&name, "[i3 con] output %s", con->name);
+ x_set_name(con, name);
+ FREE(name);
+
+ if (reused) {
+ DLOG("Not adding workspace, this was a reused con\n");
+ return;
+ }
+
+ DLOG("Changing layout, adding top/bottom dockarea\n");
+ Con *topdock = con_new(NULL);
+ topdock->type = CT_DOCKAREA;
+ topdock->layout = L_DOCKAREA;
+ topdock->orientation = VERT;
+ /* this container swallows dock clients */
+ Match *match = scalloc(sizeof(Match));
+ match_init(match);
+ match->dock = M_DOCK_TOP;
+ match->insert_where = M_BELOW;
+ TAILQ_INSERT_TAIL(&(topdock->swallow_head), match, matches);
+
+ topdock->name = sstrdup("topdock");
+
+ asprintf(&name, "[i3 con] top dockarea %s", con->name);
+ x_set_name(topdock, name);
+ FREE(name);
+ DLOG("attaching\n");
+ con_attach(topdock, con, false);
+
+ /* content container */
+
+ DLOG("adding main content container\n");
+ Con *content = con_new(NULL);
+ content->type = CT_CON;
+ content->name = sstrdup("content");
+
+ asprintf(&name, "[i3 con] content %s", con->name);
+ x_set_name(content, name);
+ FREE(name);
+ con_attach(content, con, false);
+
+ /* bottom dock container */
+ Con *bottomdock = con_new(NULL);
+ bottomdock->type = CT_DOCKAREA;
+ bottomdock->layout = L_DOCKAREA;
+ bottomdock->orientation = VERT;
+ /* this container swallows dock clients */
+ match = scalloc(sizeof(Match));
+ match_init(match);
+ match->dock = M_DOCK_BOTTOM;
+ match->insert_where = M_BELOW;
+ TAILQ_INSERT_TAIL(&(bottomdock->swallow_head), match, matches);
+
+ bottomdock->name = sstrdup("bottomdock");
+
+ asprintf(&name, "[i3 con] bottom dockarea %s", con->name);
+ x_set_name(bottomdock, name);
+ FREE(name);
+ DLOG("attaching\n");
+ con_attach(bottomdock, con, false);
+
+ DLOG("Now adding a workspace\n");
+
+ /* add a workspace to this output */
+ Con *ws = con_new(NULL);
+ ws->type = CT_WORKSPACE;
+
+ /* get the next unused workspace number */
+ DLOG("Getting next unused workspace\n");
+ int c = 0;
+ bool exists = true;
+ while (exists) {
+ Con *out, *current, *child;
+
+ c++;
+
+ FREE(ws->name);
+ asprintf(&(ws->name), "%d", c);
+
+ exists = false;
+ TAILQ_FOREACH(out, &(croot->nodes_head), nodes) {
+ TAILQ_FOREACH(current, &(out->nodes_head), nodes) {
+ if (current->type != CT_CON)
+ continue;
+
+ TAILQ_FOREACH(child, &(current->nodes_head), nodes) {
+ if (strcasecmp(child->name, ws->name) != 0)
+ continue;