]> git.sur5r.net Git - i3/i3/blob - src/fake_outputs.c
explicitly set filenames to $(basename __FILE__)
[i3/i3] / src / fake_outputs.c
1 #line 2 "fake_outputs.c"
2 /*
3  * vim:ts=4:sw=4:expandtab
4  *
5  * i3 - an improved dynamic tiling window manager
6  * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
7  *
8  * Faking outputs is useful in pathological situations (like network X servers
9  * which don’t support multi-monitor in a useful way) and for our testsuite.
10  *
11  */
12 #include "all.h"
13
14 static int num_screens;
15
16 /*
17  * Looks in outputs for the Output whose start coordinates are x, y
18  *
19  */
20 static Output *get_screen_at(int x, int y) {
21     Output *output;
22     TAILQ_FOREACH(output, &outputs, outputs)
23         if (output->rect.x == x && output->rect.y == y)
24             return output;
25
26     return NULL;
27 }
28
29 /*
30  * Creates outputs according to the given specification.
31  * The specification must be in the format wxh+x+y, for example 1024x768+0+0,
32  * with multiple outputs separated by commas:
33  *   1900x1200+0+0,1280x1024+1900+0
34  *
35  */
36 void fake_outputs_init(const char *output_spec) {
37     char useless_buffer[1024];
38     const char *walk = output_spec;
39     unsigned int x, y, width, height;
40     while (sscanf(walk, "%ux%u+%u+%u", &width, &height, &x, &y) == 4) {
41         DLOG("Parsed output as width = %u, height = %u at (%u, %u)\n",
42              width, height, x, y);
43         Output *new_output = get_screen_at(x, y);
44         if (new_output != NULL) {
45             DLOG("Re-used old output %p\n", new_output);
46             /* This screen already exists. We use the littlest screen so that the user
47                can always see the complete workspace */
48             new_output->rect.width = min(new_output->rect.width, width);
49             new_output->rect.height = min(new_output->rect.height, height);
50         } else {
51             new_output = scalloc(sizeof(Output));
52             sasprintf(&(new_output->name), "fake-%d", num_screens);
53             DLOG("Created new fake output %s (%p)\n", new_output->name, new_output);
54             new_output->active = true;
55             new_output->rect.x = x;
56             new_output->rect.y = y;
57             new_output->rect.width = width;
58             new_output->rect.height = height;
59             /* We always treat the screen at 0x0 as the primary screen */
60             if (new_output->rect.x == 0 && new_output->rect.y == 0)
61                 TAILQ_INSERT_HEAD(&outputs, new_output, outputs);
62             else TAILQ_INSERT_TAIL(&outputs, new_output, outputs);
63             output_init_con(new_output);
64             init_ws_for_output(new_output, output_get_content(new_output->con));
65             num_screens++;
66         }
67
68         /* Figure out how long the input was to skip it */
69         walk += sprintf(useless_buffer, "%ux%u+%u+%u", width, height, x, y) + 1;
70     }
71
72     if (num_screens == 0) {
73         ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
74         exit(0);
75     }
76 }