i3
fake_outputs.c
Go to the documentation of this file.
1 #undef I3__FILE__
2 #define I3__FILE__ "fake_outputs.c"
3 /*
4  * vim:ts=4:sw=4:expandtab
5  *
6  * i3 - an improved dynamic tiling window manager
7  * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
8  *
9  * Faking outputs is useful in pathological situations (like network X servers
10  * which don’t support multi-monitor in a useful way) and for our testsuite.
11  *
12  */
13 #include "all.h"
14 
15 static int num_screens;
16 
17 /*
18  * Looks in outputs for the Output whose start coordinates are x, y
19  *
20  */
21 static Output *get_screen_at(int x, int y) {
22  Output *output;
23  TAILQ_FOREACH(output, &outputs, outputs)
24  if (output->rect.x == x && output->rect.y == y)
25  return output;
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  * with multiple outputs separated by commas:
34  * 1900x1200+0+0,1280x1024+1900+0
35  *
36  */
37 void fake_outputs_init(const char *output_spec) {
38  char useless_buffer[1024];
39  const char *walk = output_spec;
40  unsigned int x, y, width, height;
41  while (sscanf(walk, "%ux%u+%u+%u", &width, &height, &x, &y) == 4) {
42  DLOG("Parsed output as width = %u, height = %u at (%u, %u)\n",
43  width, height, x, y);
44  Output *new_output = get_screen_at(x, y);
45  if (new_output != NULL) {
46  DLOG("Re-used old output %p\n", new_output);
47  /* This screen already exists. We use the littlest screen so that the user
48  can always see the complete workspace */
49  new_output->rect.width = min(new_output->rect.width, width);
50  new_output->rect.height = min(new_output->rect.height, height);
51  } else {
52  new_output = scalloc(sizeof(Output));
53  sasprintf(&(new_output->name), "fake-%d", num_screens);
54  DLOG("Created new fake output %s (%p)\n", new_output->name, new_output);
55  new_output->active = true;
56  new_output->rect.x = x;
57  new_output->rect.y = y;
58  new_output->rect.width = width;
59  new_output->rect.height = height;
60  /* We always treat the screen at 0x0 as the primary screen */
61  if (new_output->rect.x == 0 && new_output->rect.y == 0)
62  TAILQ_INSERT_HEAD(&outputs, new_output, outputs);
63  else TAILQ_INSERT_TAIL(&outputs, new_output, outputs);
64  output_init_con(new_output);
65  init_ws_for_output(new_output, output_get_content(new_output->con));
66  num_screens++;
67  }
68 
69  /* Figure out how long the input was to skip it */
70  walk += sprintf(useless_buffer, "%ux%u+%u+%u", width, height, x, y) + 1;
71  }
72 
73  if (num_screens == 0) {
74  ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
75  exit(0);
76  }
77 }
char * name
Name of the output.
Definition: data.h:297
#define DLOG(fmt,...)
Definition: log.h:28
static Output * get_screen_at(int x, int y)
Definition: fake_outputs.c:21
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:363
void fake_outputs_init(const char *output_spec)
Creates outputs according to the given specification.
Definition: fake_outputs.c:37
uint32_t y
Definition: data.h:109
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:252
uint32_t height
Definition: data.h:33
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:353
void * scalloc(size_t size)
Safe-wrapper around calloc which exits if malloc returns NULL (meaning that there is no more memory a...
uint32_t width
Definition: data.h:32
struct outputs_head outputs
Definition: randr.c:28
Rect rect
x, y, width, height
Definition: data.h:303
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...
uint32_t x
Definition: data.h:30
static int num_screens
Definition: fake_outputs.c:15
bool active
Whether the output is currently active (has a CRTC attached with a valid mode)
Definition: data.h:288
An Output is a physical output on your graphics driver.
Definition: data.h:282
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:335
uint32_t y
Definition: data.h:31
int min(int a, int b)
Definition: util.c:28
Con * output_get_content(Con *output)
Returns the output container below the given output container.
Definition: output.c:18
uint32_t x
Definition: data.h:108
void init_ws_for_output(Output *output, Con *content)
Initializes at least one workspace for this output, trying the following steps until there is at leas...
Definition: randr.c:356
Con * con
Pointer to the Con which represents this output.
Definition: data.h:300
uint32_t height
Definition: data.h:111
#define ELOG(fmt,...)
Definition: libi3.h:80
uint32_t width
Definition: data.h:110