image: add new image type
[awesome.git] / xscreen.c
blob8d02f40596487dc06df3b19b133622bc3ce9acc6
1 /*
2 * xscreen.c - common X screen management
4 * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <xcb/xcb.h>
23 #include <xcb/xinerama.h>
25 #include "xscreen.h"
26 #include "structs.h"
28 extern awesome_t globalconf;
30 static inline area_t
31 screen_xsitoarea(xcb_xinerama_screen_info_t si)
33 area_t a;
35 a.x = si.x_org;
36 a.y = si.y_org;
37 a.width = si.width;
38 a.height = si.height;
40 return a;
43 void
44 screensinfo_delete(screens_info_t **si)
46 p_delete(&(*si)->geometry);
47 p_delete(si);
50 /** Get screens informations.
51 * \return A pointer to complete screens_info_t structure.
53 screens_info_t *
54 screensinfo_new(void)
56 screens_info_t *si;
57 xcb_xinerama_query_screens_reply_t *xsq;
58 xcb_xinerama_screen_info_t *xsi;
59 int xinerama_screen_number, screen, screen_to_test;
60 xcb_screen_t *s;
61 bool drop;
62 xcb_xinerama_is_active_reply_t *xia = NULL;
64 si = p_new(screens_info_t, 1);
66 /* Check for extension before checking for Xinerama */
67 if(xcb_get_extension_data(globalconf.connection, &xcb_xinerama_id)->present)
69 xia = xcb_xinerama_is_active_reply(globalconf.connection, xcb_xinerama_is_active(globalconf.connection), NULL);
70 si->xinerama_is_active = xia->state;
71 p_delete(&xia);
74 if(si->xinerama_is_active)
76 xsq = xcb_xinerama_query_screens_reply(globalconf.connection,
77 xcb_xinerama_query_screens_unchecked(globalconf.connection),
78 NULL);
80 xsi = xcb_xinerama_query_screens_screen_info(xsq);
81 xinerama_screen_number = xcb_xinerama_query_screens_screen_info_length(xsq);
83 si->geometry = p_new(area_t, xinerama_screen_number);
84 si->nscreen = 0;
86 /* now check if screens overlaps (same x,y): if so, we take only the biggest one */
87 for(screen = 0; screen < xinerama_screen_number; screen++)
89 drop = false;
90 for(screen_to_test = 0; screen_to_test < si->nscreen; screen_to_test++)
91 if(xsi[screen].x_org == si->geometry[screen_to_test].x
92 && xsi[screen].y_org == si->geometry[screen_to_test].y)
94 /* we already have a screen for this area, just check if
95 * it's not bigger and drop it */
96 drop = true;
97 si->geometry[screen_to_test].width =
98 MAX(xsi[screen].width, xsi[screen_to_test].width);
99 si->geometry[screen_to_test].height =
100 MAX(xsi[screen].height, xsi[screen_to_test].height);
102 if(!drop)
103 si->geometry[si->nscreen++] = screen_xsitoarea(xsi[screen]);
106 /* realloc smaller if xinerama_screen_number != screen registered */
107 if(xinerama_screen_number != si->nscreen)
109 area_t *newgeometry = p_new(area_t, si->nscreen);
110 memcpy(newgeometry, si->geometry, si->nscreen * sizeof(area_t));
111 p_delete(&si->geometry);
112 si->geometry = newgeometry;
115 p_delete(&xsq);
117 else
119 si->nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
120 si->geometry = p_new(area_t, si->nscreen);
121 for(screen = 0; screen < si->nscreen; screen++)
123 s = xutil_screen_get(globalconf.connection, screen);
124 si->geometry[screen].x = 0;
125 si->geometry[screen].y = 0;
126 si->geometry[screen].width = s->width_in_pixels;
127 si->geometry[screen].height = s->height_in_pixels;
131 return si;
134 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80