From 4193e81fa85180daa9818bdca69b56bd520577e8 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 18 Sep 2008 16:03:05 +0200 Subject: [PATCH] screen: merge with xscreen, remove screens_info Signed-off-by: Julien Danjou --- CMakeLists.txt | 1 - awesome.c | 11 +---- client.c | 6 +-- event.c | 16 +++---- ewmh.c | 2 +- layout.c | 2 +- luaa.c | 4 +- luaa.h | 2 +- mouse.c | 4 +- screen.c | 111 +++++++++++++++++++++++++++++++++++++++--- screen.h | 1 + statusbar.c | 4 +- structs.h | 7 +-- systray.c | 2 +- widget.c | 2 +- xscreen.c | 127 ------------------------------------------------- xscreen.h | 37 -------------- 17 files changed, 133 insertions(+), 206 deletions(-) delete mode 100644 xscreen.c delete mode 100644 xscreen.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d9c0858a..9aa9d410 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,6 @@ set(AWE_SRCS ${SOURCE_DIR}/image.c ${SOURCE_DIR}/draw.c ${SOURCE_DIR}/swindow.c - ${SOURCE_DIR}/xscreen.c ${SOURCE_DIR}/common/buffer.c ${SOURCE_DIR}/common/atoms.c ${SOURCE_DIR}/common/markup.c diff --git a/awesome.c b/awesome.c index 73962bfe..2ed9bbd2 100644 --- a/awesome.c +++ b/awesome.c @@ -426,15 +426,8 @@ main(int argc, char **argv) /* init atom cache */ atoms_init(globalconf.connection); - /* init screens struct */ - globalconf.screens_info = screensinfo_new(); - globalconf.screen_focus = globalconf.screens = p_new(screen_t, globalconf.screens_info->nscreen); - /* \todo stop duplicating this */ - for(screen_nbr = 0; screen_nbr < globalconf.screens_info->nscreen; screen_nbr++) - { - globalconf.screens[screen_nbr].index = screen_nbr; - globalconf.screens[screen_nbr].geometry = globalconf.screens_info->geometry[screen_nbr]; - } + /* init screens information */ + screen_scan(); /* init default font and colors */ colors_reqs[0] = xcolor_init_unchecked(&globalconf.colors.fg, diff --git a/client.c b/client.c index cb4e9749..dc1706ee 100644 --- a/client.c +++ b/client.c @@ -332,7 +332,7 @@ client_stack(void) config_win_vals[0] = client_stack_below(node->client, config_win_vals[0]); /* then stack statusbar window */ - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next) if(sb->sw) { @@ -836,7 +836,7 @@ client_unmanage(client_t *c) if(client_hasstrut(c)) /* All the statusbars (may) need to be repositioned */ - for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(int screen = 0; screen < globalconf.nscreen; screen++) for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) statusbar_position_update(s); @@ -1220,7 +1220,7 @@ luaA_client_newindex(lua_State *L) widget_invalidate_cache((*c)->screen, WIDGET_CACHE_CLIENTS); break; case A_TK_SCREEN: - if(globalconf.screens_info->xinerama_is_active) + if(globalconf.xinerama_is_active) { i = luaL_checknumber(L, 3) - 1; luaA_checkscreen(i); diff --git a/event.c b/event.c index 2733c050..d105b5cb 100644 --- a/event.c +++ b/event.c @@ -138,7 +138,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e * drop them */ ev->state &= 0x00ff; - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) if(statusbar->sw && (statusbar->sw->window == ev->event || statusbar->sw->window == ev->child)) @@ -220,7 +220,7 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), titlebar_draw(c); if(client_hasstrut(c)) /* All the statusbars (may) need to be repositioned */ - for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(int screen = 0; screen < globalconf.nscreen; screen++) for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) statusbar_position_update(s); } @@ -329,7 +329,7 @@ event_handle_destroynotify(void *data __attribute__ ((unused)), else if((emwin = xembed_getbywin(globalconf.embedded, ev->event))) { xembed_window_list_detach(&globalconf.embedded, emwin); - for(i = 0; i < globalconf.screens_info->nscreen; i++) + for(i = 0; i < globalconf.nscreen; i++) widget_invalidate_cache(i, WIDGET_CACHE_EMBEDDED); } @@ -494,7 +494,7 @@ event_handle_expose(void *data __attribute__ ((unused)), if(!ev->count) { - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) if(statusbar->sw && statusbar->sw->window == ev->window) @@ -591,14 +591,14 @@ event_handle_maprequest(void *data __attribute__ ((unused)), { geom_c = xcb_get_geometry_unchecked(connection, ev->window); - if(globalconf.screens_info->xinerama_is_active) + if(globalconf.xinerama_is_active) qp_c = xcb_query_pointer_unchecked(connection, xutil_screen_get(globalconf.connection, globalconf.default_screen)->root); if(!(geom_r = xcb_get_geometry_reply(connection, geom_c, NULL))) { - if(globalconf.screens_info->xinerama_is_active) + if(globalconf.xinerama_is_active) qp_r = xcb_query_pointer_reply(connection, qp_c, NULL); ret = -1; goto bailout; @@ -608,7 +608,7 @@ event_handle_maprequest(void *data __attribute__ ((unused)), for(iter = xcb_setup_roots_iterator(xcb_get_setup(connection)), phys_screen = 0; iter.rem && iter.data->root != geom_r->root; xcb_screen_next(&iter), ++phys_screen); - if(globalconf.screens_info->xinerama_is_active + if(globalconf.xinerama_is_active && (qp_r = xcb_query_pointer_reply(connection, qp_c, NULL))) screen = screen_getbycoord(screen, qp_r->root_x, qp_r->root_y); else @@ -647,7 +647,7 @@ event_handle_unmapnotify(void *data __attribute__ ((unused)), else if((em = xembed_getbywin(globalconf.embedded, ev->window))) { xembed_window_list_detach(&globalconf.embedded, em); - for(i = 0; i < globalconf.screens_info->nscreen; i++) + for(i = 0; i < globalconf.nscreen; i++) widget_invalidate_cache(i, WIDGET_CACHE_EMBEDDED); } diff --git a/ewmh.c b/ewmh.c index 51fb6d16..ca6f15e0 100644 --- a/ewmh.c +++ b/ewmh.c @@ -533,7 +533,7 @@ ewmh_client_strut_update(client_t *c, xcb_get_property_reply_t *strut_r) client_need_arrange(c); /* All the statusbars (may) need to be repositioned */ - for(int screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(int screen = 0; screen < globalconf.nscreen; screen++) for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) statusbar_position_update(s); } diff --git a/layout.c b/layout.c index 3037ffa5..20661afd 100644 --- a/layout.c +++ b/layout.c @@ -84,7 +84,7 @@ layout_refresh(void) { int screen; - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) if(globalconf.screens[screen].need_arrange) arrange(screen); } diff --git a/luaa.c b/luaa.c index e8c3392e..308e5923 100644 --- a/luaa.c +++ b/luaa.c @@ -551,7 +551,7 @@ luaA_spawn(lua_State *L) cmd = luaL_checkstring(L, 1); - if(!globalconf.screens_info->xinerama_is_active) + if(!globalconf.xinerama_is_active) { xcb_parse_display(NULL, &host, &displayp, &screenp); snprintf(newdisplay, sizeof(newdisplay), "%s:%d.%d", host, displayp, screen); @@ -777,7 +777,7 @@ luaA_parserc(const char *confpatharg) bailout: /* Assure there's at least one tag */ - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) if(!globalconf.screens[screen].tags.len) tag_append_to_screen(tag_new("default", sizeof("default")-1, layout_tile, 0.5, 1, 0), &globalconf.screens[screen]); diff --git a/luaa.h b/luaa.h index 2d689895..2d926455 100644 --- a/luaa.h +++ b/luaa.h @@ -95,7 +95,7 @@ typedef int luaA_ref; #define luaA_checkscreen(screen) \ do { \ - if(screen < 0 || screen >= globalconf.screens_info->nscreen) \ + if(screen < 0 || screen >= globalconf.nscreen) \ luaL_error(L, "invalid screen number: %d", screen + 1); \ } while(0) diff --git a/mouse.c b/mouse.c index 6c7c4fc6..639f7b6d 100644 --- a/mouse.c +++ b/mouse.c @@ -1224,8 +1224,8 @@ luaA_mouse_newindex(lua_State *L) phys_screen = screen_virttophys(screen); root = xutil_screen_get(globalconf.connection, phys_screen)->root; - x = globalconf.screens_info->geometry[screen].x; - y = globalconf.screens_info->geometry[screen].y; + x = globalconf.screens[screen].geometry.x; + y = globalconf.screens[screen].geometry.y; mouse_warp_pointer(root, x, y); break; diff --git a/screen.c b/screen.c index 80abe587..7f7b7a6f 100644 --- a/screen.c +++ b/screen.c @@ -22,6 +22,7 @@ #include #include +#include #include "screen.h" #include "ewmh.h" @@ -33,6 +34,100 @@ extern awesome_t globalconf; +static inline area_t +screen_xsitoarea(xcb_xinerama_screen_info_t si) +{ + area_t a = + { + .x = si.x_org, + .y = si.y_org, + .width = si.width, + .height = si.height + }; + return a; +} + +/** Get screens informations and fill global configuration. + */ +void +screen_scan(void) +{ + /* Check for extension before checking for Xinerama */ + if(xcb_get_extension_data(globalconf.connection, &xcb_xinerama_id)->present) + { + xcb_xinerama_is_active_reply_t *xia; + xia = xcb_xinerama_is_active_reply(globalconf.connection, xcb_xinerama_is_active(globalconf.connection), NULL); + globalconf.xinerama_is_active = xia->state; + p_delete(&xia); + } + + if(globalconf.xinerama_is_active) + { + xcb_xinerama_query_screens_reply_t *xsq; + xcb_xinerama_screen_info_t *xsi; + int xinerama_screen_number; + + xsq = xcb_xinerama_query_screens_reply(globalconf.connection, + xcb_xinerama_query_screens_unchecked(globalconf.connection), + NULL); + + xsi = xcb_xinerama_query_screens_screen_info(xsq); + xinerama_screen_number = xcb_xinerama_query_screens_screen_info_length(xsq); + + globalconf.screens = p_new(screen_t, xinerama_screen_number); + + /* now check if screens overlaps (same x,y): if so, we take only the biggest one */ + for(int screen = 0; screen < xinerama_screen_number; screen++) + { + bool drop = false; + for(int screen_to_test = 0; screen_to_test < globalconf.nscreen; screen_to_test++) + if(xsi[screen].x_org == globalconf.screens[screen_to_test].geometry.x + && xsi[screen].y_org == globalconf.screens[screen_to_test].geometry.y) + { + /* we already have a screen for this area, just check if + * it's not bigger and drop it */ + drop = true; + globalconf.screens[screen_to_test].geometry.width = + MAX(xsi[screen].width, xsi[screen_to_test].width); + globalconf.screens[screen_to_test].geometry.height = + MAX(xsi[screen].height, xsi[screen_to_test].height); + } + if(!drop) + { + globalconf.screens[globalconf.nscreen].index = screen; + globalconf.screens[globalconf.nscreen++].geometry = screen_xsitoarea(xsi[screen]); + } + } + + /* realloc smaller if xinerama_screen_number != screen registered */ + if(xinerama_screen_number != globalconf.nscreen) + { + screen_t *new = p_new(screen_t, globalconf.nscreen); + memcpy(new, globalconf.screens, globalconf.nscreen * sizeof(screen_t)); + p_delete(&globalconf.screens); + globalconf.screens = new; + } + + p_delete(&xsq); + } + else + { + globalconf.nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); + globalconf.screens = p_new(screen_t, globalconf.nscreen); + for(int screen = 0; screen < globalconf.nscreen; screen++) + { + xcb_screen_t *s = xutil_screen_get(globalconf.connection, screen); + globalconf.screens[screen].index = screen; + globalconf.screens[screen].geometry.x = 0; + globalconf.screens[screen].geometry.y = 0; + globalconf.screens[screen].geometry.width = s->width_in_pixels; + globalconf.screens[screen].geometry.height = s->height_in_pixels; + } + } + + globalconf.screen_focus = globalconf.screens; +} + /** Return the Xinerama screen number where the coordinates belongs to. * \param screen The logical screen number. * \param x X coordinate @@ -43,16 +138,18 @@ int screen_getbycoord(int screen, int x, int y) { int i; - screens_info_t *si = globalconf.screens_info; /* don't waste our time */ - if(!si->xinerama_is_active) + if(!globalconf.xinerama_is_active) return screen; - for(i = 0; i < si->nscreen; i++) - if((x < 0 || (x >= si->geometry[i].x && x < si->geometry[i].x + si->geometry[i].width)) - && (y < 0 || (y >= si->geometry[i].y && y < si->geometry[i].y + si->geometry[i].height))) + for(i = 0; i < globalconf.nscreen; i++) + { + screen_t *s = &globalconf.screens[i]; + if((x < 0 || (x >= s->geometry.x && x < s->geometry.x + s->geometry.width)) + && (y < 0 || (y >= s->geometry.y && y < s->geometry.y + s->geometry.height))) return i; + } return screen; } @@ -187,7 +284,7 @@ display_area_get(int phys_screen, statusbar_t *statusbar, padding_t *padding) int screen_virttophys(int screen) { - if(globalconf.screens_info->xinerama_is_active) + if(globalconf.xinerama_is_active) return globalconf.default_screen; return screen; } @@ -490,7 +587,7 @@ luaA_screen_padding(lua_State *L) static int luaA_screen_count(lua_State *L) { - lua_pushnumber(L, globalconf.screens_info->nscreen); + lua_pushnumber(L, globalconf.nscreen); return 1; } diff --git a/screen.h b/screen.h index 35558f54..39154e24 100644 --- a/screen.h +++ b/screen.h @@ -26,6 +26,7 @@ #define SCREEN_UNDEF (-1) +void screen_scan(void); int screen_getbycoord(int, int, int); area_t screen_area_get(int, statusbar_t *, padding_t *, bool); area_t display_area_get(int, statusbar_t *, padding_t *); diff --git a/statusbar.c b/statusbar.c index 0a4935f7..da4946f2 100644 --- a/statusbar.c +++ b/statusbar.c @@ -236,7 +236,7 @@ statusbar_t * statusbar_getbywin(xcb_window_t w) { statusbar_t *s; - for(int i = 0; i < globalconf.screens_info->nscreen; i++) + for(int i = 0; i < globalconf.nscreen; i++) for(s = globalconf.screens[i].statusbar; s; s = s->next) if(s->sw->window == w) return s; @@ -251,7 +251,7 @@ statusbar_refresh(void) int screen; statusbar_t *statusbar; - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) if(statusbar->need_update) statusbar_draw(statusbar); diff --git a/structs.h b/structs.h index be573b4f..8337fc30 100644 --- a/structs.h +++ b/structs.h @@ -30,7 +30,6 @@ #include "luaa.h" #include "layout.h" #include "swindow.h" -#include "xscreen.h" #include "image.h" #include "common/xutil.h" #include "common/xembed.h" @@ -436,8 +435,10 @@ struct awesome_t xcb_key_symbols_t *keysyms; /** Logical screens */ screen_t *screens; - /** Screens info */ - screens_info_t *screens_info; + /** Number of screens */ + int nscreen; + /** True if xinerama is active */ + bool xinerama_is_active; /** Mouse bindings list */ button_array_t buttons; /** Numlock mask */ diff --git a/systray.c b/systray.c index 8bc3c48e..52d65d07 100644 --- a/systray.c +++ b/systray.c @@ -172,7 +172,7 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i globalconf.screens[phys_screen].systray.window, MIN(XEMBED_VERSION, em->info.version)); - for(i = 0; i < globalconf.screens_info->nscreen; i++) + for(i = 0; i < globalconf.nscreen; i++) widget_invalidate_cache(i, WIDGET_CACHE_EMBEDDED); return 0; diff --git a/widget.c b/widget.c index 83a9d9db..4b1ab872 100644 --- a/widget.c +++ b/widget.c @@ -236,7 +236,7 @@ widget_invalidate_bywidget(widget_t *widget) widget_node_t *witer; client_t *c; - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) + for(screen = 0; screen < globalconf.nscreen; screen++) for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) diff --git a/xscreen.c b/xscreen.c deleted file mode 100644 index f51c71e6..00000000 --- a/xscreen.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * xscreen.c - common X screen management - * - * Copyright © 2007-2008 Julien Danjou - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include - -#include "xscreen.h" -#include "structs.h" - -extern awesome_t globalconf; - -static inline area_t -screen_xsitoarea(xcb_xinerama_screen_info_t si) -{ - area_t a; - - a.x = si.x_org; - a.y = si.y_org; - a.width = si.width; - a.height = si.height; - - return a; -} - -/** Get screens informations. - * \return A pointer to complete screens_info_t structure. - */ -screens_info_t * -screensinfo_new(void) -{ - screens_info_t *si; - xcb_xinerama_query_screens_reply_t *xsq; - xcb_xinerama_screen_info_t *xsi; - int xinerama_screen_number, screen, screen_to_test; - xcb_screen_t *s; - bool drop; - xcb_xinerama_is_active_reply_t *xia = NULL; - - si = p_new(screens_info_t, 1); - - /* Check for extension before checking for Xinerama */ - if(xcb_get_extension_data(globalconf.connection, &xcb_xinerama_id)->present) - { - xia = xcb_xinerama_is_active_reply(globalconf.connection, xcb_xinerama_is_active(globalconf.connection), NULL); - si->xinerama_is_active = xia->state; - p_delete(&xia); - } - - if(si->xinerama_is_active) - { - xsq = xcb_xinerama_query_screens_reply(globalconf.connection, - xcb_xinerama_query_screens_unchecked(globalconf.connection), - NULL); - - xsi = xcb_xinerama_query_screens_screen_info(xsq); - xinerama_screen_number = xcb_xinerama_query_screens_screen_info_length(xsq); - - si->geometry = p_new(area_t, xinerama_screen_number); - si->nscreen = 0; - - /* now check if screens overlaps (same x,y): if so, we take only the biggest one */ - for(screen = 0; screen < xinerama_screen_number; screen++) - { - drop = false; - for(screen_to_test = 0; screen_to_test < si->nscreen; screen_to_test++) - if(xsi[screen].x_org == si->geometry[screen_to_test].x - && xsi[screen].y_org == si->geometry[screen_to_test].y) - { - /* we already have a screen for this area, just check if - * it's not bigger and drop it */ - drop = true; - si->geometry[screen_to_test].width = - MAX(xsi[screen].width, xsi[screen_to_test].width); - si->geometry[screen_to_test].height = - MAX(xsi[screen].height, xsi[screen_to_test].height); - } - if(!drop) - si->geometry[si->nscreen++] = screen_xsitoarea(xsi[screen]); - } - - /* realloc smaller if xinerama_screen_number != screen registered */ - if(xinerama_screen_number != si->nscreen) - { - area_t *newgeometry = p_new(area_t, si->nscreen); - memcpy(newgeometry, si->geometry, si->nscreen * sizeof(area_t)); - p_delete(&si->geometry); - si->geometry = newgeometry; - } - - p_delete(&xsq); - } - else - { - si->nscreen = xcb_setup_roots_length(xcb_get_setup(globalconf.connection)); - si->geometry = p_new(area_t, si->nscreen); - for(screen = 0; screen < si->nscreen; screen++) - { - s = xutil_screen_get(globalconf.connection, screen); - si->geometry[screen].x = 0; - si->geometry[screen].y = 0; - si->geometry[screen].width = s->width_in_pixels; - si->geometry[screen].height = s->height_in_pixels; - } - } - - return si; -} - -// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/xscreen.h b/xscreen.h deleted file mode 100644 index 418830cf..00000000 --- a/xscreen.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * commeon/xscreen.h - commeon X screen management header - * - * Copyright © 2007-2008 Julien Danjou - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef AWESOME_COMMON_XSCREEN_H -#define AWESOME_COMMON_XSCREEN_H - -#include "draw.h" - -typedef struct -{ - int nscreen; - bool xinerama_is_active; - area_t *geometry; -} screens_info_t; - -screens_info_t * screensinfo_new(void); - -#endif -// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80