i3
src/fake_outputs.c
Go to the documentation of this file.
00001 /*
00002  * vim:ts=4:sw=4:expandtab
00003  *
00004  * i3 - an improved dynamic tiling window manager
00005  * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
00006  *
00007  * Faking outputs is useful in pathological situations (like network X servers
00008  * which don’t support multi-monitor in a useful way) and for our testsuite.
00009  *
00010  */
00011 #include "all.h"
00012 
00013 static int num_screens;
00014 
00015 /*
00016  * Looks in outputs for the Output whose start coordinates are x, y
00017  *
00018  */
00019 static Output *get_screen_at(int x, int y) {
00020     Output *output;
00021     TAILQ_FOREACH(output, &outputs, outputs)
00022         if (output->rect.x == x && output->rect.y == y)
00023             return output;
00024 
00025     return NULL;
00026 }
00027 
00028 /*
00029  * Creates outputs according to the given specification.
00030  * The specification must be in the format wxh+x+y, for example 1024x768+0+0,
00031  * with multiple outputs separated by commas:
00032  *   1900x1200+0+0,1280x1024+1900+0
00033  *
00034  */
00035 void fake_outputs_init(const char *output_spec) {
00036     char useless_buffer[1024];
00037     const char *walk = output_spec;
00038     unsigned int x, y, width, height;
00039     while (sscanf(walk, "%ux%u+%u+%u", &width, &height, &x, &y) == 4) {
00040         DLOG("Parsed output as width = %u, height = %u at (%u, %u)\n",
00041              width, height, x, y);
00042         Output *new_output = get_screen_at(x, y);
00043         if (new_output != NULL) {
00044             DLOG("Re-used old output %p\n", new_output);
00045             /* This screen already exists. We use the littlest screen so that the user
00046                can always see the complete workspace */
00047             new_output->rect.width = min(new_output->rect.width, width);
00048             new_output->rect.height = min(new_output->rect.height, height);
00049         } else {
00050             new_output = scalloc(sizeof(Output));
00051             sasprintf(&(new_output->name), "fake-%d", num_screens);
00052             DLOG("Created new fake output %s (%p)\n", new_output->name, new_output);
00053             new_output->active = true;
00054             new_output->rect.x = x;
00055             new_output->rect.y = y;
00056             new_output->rect.width = width;
00057             new_output->rect.height = height;
00058             /* We always treat the screen at 0x0 as the primary screen */
00059             if (new_output->rect.x == 0 && new_output->rect.y == 0)
00060                 TAILQ_INSERT_HEAD(&outputs, new_output, outputs);
00061             else TAILQ_INSERT_TAIL(&outputs, new_output, outputs);
00062             output_init_con(new_output);
00063             init_ws_for_output(new_output, output_get_content(new_output->con));
00064             num_screens++;
00065         }
00066 
00067         /* Figure out how long the input was to skip it */
00068         walk += sprintf(useless_buffer, "%ux%u+%u+%u", width, height, x, y) + 1;
00069     }
00070 
00071     if (num_screens == 0) {
00072         ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
00073         exit(0);
00074     }
00075 }