Reorganize randr/xinerama detection, add monitor_add().

This commit is contained in:
John Vogel 2014-02-10 21:42:14 -05:00
parent 59fb6c5dfe
commit 3f6bf2afc6
1 changed files with 62 additions and 76 deletions

138
bar.c
View File

@ -361,8 +361,10 @@ monitor_new (int x, int y, int width, int height)
monitor_t *ret;
ret = malloc(sizeof(monitor_t));
if (!ret)
return NULL;
if (!ret) {
fprintf(stderr, "Failed to allocate new monitor\n");
exit(EXIT_FAILURE);
}
ret->x = x;
ret->width = width;
@ -383,6 +385,22 @@ monitor_new (int x, int y, int width, int height)
return ret;
}
void
monitor_add (monitor_t *mon)
{
if (!monhead) {
monhead = mon;
} else if (!montail) {
montail = mon;
monhead->next = mon;
mon->prev = monhead;
} else {
mon->prev = montail;
montail->next = mon;
montail = montail->next;
}
}
void
get_randr_outputs(void)
{
@ -409,6 +427,7 @@ get_randr_outputs(void)
fprintf(stderr, "Failed to get current randr outputs\n");
return;
}
xcb_rectangle_t rects[num];
/* get all outputs */
@ -476,24 +495,7 @@ get_randr_outputs(void)
MIN(width, rects[i].width),
rects[i].height);
if (!mon) {
fprintf(stderr, "Failed to allocate new monitor\n");
exit(EXIT_FAILURE);
}
if (!monhead) {
monhead = mon;
}
else if (!montail) {
montail = mon;
monhead->next = mon;
mon->prev = monhead;
}
else {
mon->prev = montail;
montail->next = mon;
montail = montail->next;
}
monitor_add (mon);
width -= rects[i].width;
@ -505,6 +507,41 @@ get_randr_outputs(void)
}
}
void
get_xinerama_screens (void)
{
xcb_xinerama_query_screens_reply_t *xqs_reply;
xcb_xinerama_screen_info_iterator_t iter;
int width = cfg.width;
xqs_reply = xcb_xinerama_query_screens_reply (c,
xcb_xinerama_query_screens_unchecked (c), NULL);
iter = xcb_xinerama_query_screens_screen_info_iterator (xqs_reply);
/* The width is consumed across all the screens */
while (iter.rem) {
monitor_t *mon = monitor_new (
iter.data->x_org,
iter.data->y_org,
MIN(width, iter.data->width),
iter.data->height);
monitor_add (mon);
width -= iter.data->width;
/* No need to check for other monitors */
if (width <= 0)
break;
xcb_xinerama_screen_info_next (&iter);
}
free (xqs_reply);
}
void
init (void)
{
@ -546,11 +583,8 @@ init (void)
qe_reply = xcb_get_extension_data (c, &xcb_randr_id);
if (qe_reply && qe_reply->present) {
get_randr_outputs();
get_randr_outputs ();
} else {
int xia = 0;
qe_reply = xcb_get_extension_data (c, &xcb_xinerama_id);
/* Check if Xinerama extension is present and active */
@ -559,63 +593,15 @@ init (void)
xia_reply = xcb_xinerama_is_active_reply (c, xcb_xinerama_is_active (c), NULL);
if (xia_reply && xia_reply->state)
xia = 1;
get_xinerama_screens ();
free (xia_reply);
}
if (xia) {
xcb_xinerama_query_screens_reply_t *xqs_reply;
xcb_xinerama_screen_info_iterator_t iter;
xqs_reply = xcb_xinerama_query_screens_reply (c,
xcb_xinerama_query_screens_unchecked (c), NULL);
iter = xcb_xinerama_query_screens_screen_info_iterator (xqs_reply);
/* The width is consumed across all the screens */
while (iter.rem) {
monitor_t *mon = monitor_new (
iter.data->x_org,
iter.data->y_org,
MIN(width, iter.data->width),
iter.data->height);
if (!monhead) {
monhead = mon;
}
else if (!montail) {
montail = mon;
monhead->next = mon;
mon->prev = monhead;
}
else {
mon->prev = montail;
montail->next = mon;
montail = montail->next;
}
width -= iter.data->width;
/* No need to check for other monitors */
if (width <= 0)
break;
xcb_xinerama_screen_info_next (&iter);
}
free (xqs_reply);
}
}
if (!monhead) {
fprintf(stderr, "Falling back to using whole screen mode\n");
if (!monhead)
/* If no RandR outputs or Xinerama screens, fall back to using whole screen */
monhead = monitor_new (0, 0, width, scr->height_in_pixels);
}
if (!monhead) {
fprintf(stderr, "Failed to retrieve any usable monitors!\n");
exit(EXIT_FAILURE);
}
/* For WM that support EWMH atoms */
set_ewmh_atoms();