i3
|
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 }