i3
fake_outputs.c
Go to the documentation of this file.
1/*
2 * vim:ts=4:sw=4:expandtab
3 *
4 * i3 - an improved tiling window manager
5 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6 *
7 * Faking outputs is useful in pathological situations (like network X servers
8 * which don’t support multi-monitor in a useful way) and for our testsuite.
9 *
10 */
11#include "all.h"
12
13static int num_screens;
14
15/*
16 * Looks in outputs for the Output whose start coordinates are x, y
17 *
18 */
19static Output *get_screen_at(unsigned int x, unsigned int y) {
20 Output *output;
21 TAILQ_FOREACH (output, &outputs, outputs) {
22 if (output->rect.x == x && output->rect.y == y) {
23 return output;
24 }
25 }
26
27 return NULL;
28}
29
30/*
31 * Creates outputs according to the given specification.
32 * The specification must be in the format wxh+x+y, for example 1024x768+0+0,
33 * optionally followed by 'P' to indicate a primary output,
34 * with multiple outputs separated by commas:
35 * 1900x1200+0+0P,1280x1024+1900+0
36 *
37 */
38void fake_outputs_init(const char *output_spec) {
39 const char *walk = output_spec;
40 unsigned int x, y, width, height;
41 int chars_consumed;
42 while (sscanf(walk, "%ux%u+%u+%u%n", &width, &height, &x, &y, &chars_consumed) == 4) {
43 walk += chars_consumed;
44 bool primary = false;
45 if (*walk == 'P') {
46 primary = true;
47 walk++;
48 }
49 if (*walk == ',') {
50 walk++; /* Skip delimiter */
51 }
52 DLOG("Parsed output as width = %u, height = %u at (%u, %u)%s\n",
53 width, height, x, y, primary ? " (primary)" : "");
54
55 Output *new_output = get_screen_at(x, y);
56 if (new_output != NULL) {
57 DLOG("Re-used old output %p\n", new_output);
58 /* This screen already exists. We use the littlest screen so that the user
59 can always see the complete workspace */
60 new_output->rect.width = min(new_output->rect.width, width);
61 new_output->rect.height = min(new_output->rect.height, height);
62 } else {
63 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
64 new_output = scalloc(1, sizeof(Output));
65 sasprintf(&(output_name->name), "fake-%d", num_screens);
66 SLIST_INIT(&(new_output->names_head));
67 SLIST_INSERT_HEAD(&(new_output->names_head), output_name, names);
68 DLOG("Created new fake output %s (%p)\n", output_primary_name(new_output), new_output);
69 new_output->active = true;
70 new_output->rect.x = x;
71 new_output->rect.y = y;
72 new_output->rect.width = width;
73 new_output->rect.height = height;
74 /* We always treat the screen at 0x0 as the primary screen */
75 if (new_output->rect.x == 0 && new_output->rect.y == 0) {
76 TAILQ_INSERT_HEAD(&outputs, new_output, outputs);
77 } else {
78 TAILQ_INSERT_TAIL(&outputs, new_output, outputs);
79 }
80 output_init_con(new_output);
81 init_ws_for_output(new_output);
83 }
84 new_output->primary = primary;
85 }
86
87 if (num_screens == 0) {
88 ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
89 exit(EXIT_FAILURE);
90 }
91}
#define y(x,...)
Definition commands.c:18
static Output * get_screen_at(unsigned int x, unsigned int y)
void fake_outputs_init(const char *output_spec)
Creates outputs according to the given specification.
static int num_screens
char * output_primary_name(Output *output)
Retrieves the primary name of an output.
Definition output.c:53
void init_ws_for_output(Output *output)
Initializes at least one workspace for this output, trying the following steps until there is at leas...
Definition randr.c:455
void output_init_con(Output *output)
Initializes a CT_OUTPUT Con (searches existing ones from inplace restart before) to use for the given...
Definition randr.c:346
struct outputs_head outputs
Definition randr.c:22
xcb_randr_get_output_primary_reply_t * primary
Definition randr.c:19
int min(int a, int b)
Definition util.c:24
#define DLOG(fmt,...)
Definition libi3.h:105
#define ELOG(fmt,...)
Definition libi3.h:100
void * scalloc(size_t num, size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
int sasprintf(char **strp, const char *fmt,...)
Safe-wrapper around asprintf which exits if it returns -1 (meaning that there is no more memory avail...
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:347
#define SLIST_INIT(head)
Definition queue.h:127
#define SLIST_INSERT_HEAD(head, elm, field)
Definition queue.h:138
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:376
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition queue.h:366
uint32_t height
Definition data.h:189
uint32_t x
Definition data.h:186
uint32_t y
Definition data.h:187
uint32_t width
Definition data.h:188
char * name
Definition data.h:380
An Output is a physical output on your graphics driver.
Definition data.h:391
bool active
Whether the output is currently active (has a CRTC attached with a valid mode)
Definition data.h:397
bool primary
Definition data.h:403
Rect rect
x, y, width, height
Definition data.h:414