From 0bde5c9e2936bc96651df8983b8f1fbef457585c Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 13 Mar 2008 09:05:34 +0100 Subject: [PATCH] Move some screen functions from screen.c to new common/xscreen.c --- Makefile.am | 18 +++--- awesome.c | 5 +- client.c | 9 +-- common/xscreen.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++ common/xscreen.h | 38 +++++++++++++ event.c | 7 ++- mouse.c | 3 +- screen.c | 110 ------------------------------------- screen.h | 9 --- 9 files changed, 202 insertions(+), 137 deletions(-) create mode 100644 common/xscreen.c create mode 100644 common/xscreen.h diff --git a/Makefile.am b/Makefile.am index 98f07616a..16f738095 100644 --- a/Makefile.am +++ b/Makefile.am @@ -111,17 +111,23 @@ AM_CPPFLAGS = $(XFT_CFLAGS) $(X_CFLAGS) $(CAIRO_CFLAGS) $(CONFUSE_CFLAGS) $(XRAN bin_PROGRAMS += awesome awesome_SOURCES = \ + common/socket.c common/socket.h \ + common/swindow.c common/swindow.h \ + common/version.c common/version.h \ + common/util.c common/util.h \ + common/xutil.c common/xutil.h \ + common/configopts.h common/configopts.c \ + common/xscreen.h common/xscreen.c \ + common/list.h \ + structs.h \ client.c client.h \ placement.c placement.h \ - common/version.c common/version.h \ focus.c focus.h \ common/draw.c common/draw.h \ event.c event.h \ layout.c layout.h \ awesome.c awesome.h \ tag.c tag.h \ - common/util.c common/util.h \ - common/xutil.c common/xutil.h \ config.c config.h \ screen.c screen.h \ statusbar.c statusbar.h \ @@ -129,12 +135,8 @@ awesome_SOURCES = \ window.c window.h \ rules.c rules.h \ mouse.c mouse.h \ - common/socket.c common/socket.h \ - common/swindow.c common/swindow.h \ widget.c widget.h \ - ewmh.c ewmh.h \ - common/list.h structs.h \ - common/configopts.h common/configopts.c + ewmh.c ewmh.h awesome_SOURCES += $(LAYOUTS) awesome_SOURCES += $(WIDGETS) awesome_LDADD = $(XFT_LIBS) $(X_LIBS) $(CAIRO_LIBS) $(CONFUSE_LIBS) $(XRANDR_LIBS) $(XINERAMA_LIBS) diff --git a/awesome.c b/awesome.c index 50424ce8a..6ec07343d 100644 --- a/awesome.c +++ b/awesome.c @@ -57,6 +57,7 @@ #include "common/util.h" #include "common/version.h" #include "common/configopts.h" +#include "common/xscreen.h" static int (*xerrorxlib) (Display *, XErrorEvent *); static Bool running = True; @@ -86,7 +87,7 @@ scan() continue; if(wa.map_state == IsViewable || window_getstate(wins[i]) == IconicState) { - real_screen = screen_get_bycoord(screen, wa.x, wa.y); + real_screen = screen_get_bycoord(globalconf.display, screen, wa.x, wa.y); client_manage(wins[i], &wa, real_screen); } } @@ -98,7 +99,7 @@ scan() if(XGetTransientForHint(globalconf.display, wins[i], &d1) && (wa.map_state == IsViewable || window_getstate(wins[i]) == IconicState)) { - real_screen = screen_get_bycoord(screen, wa.x, wa.y); + real_screen = screen_get_bycoord(globalconf.display, screen, wa.x, wa.y); client_manage(wins[i], &wa, real_screen); } } diff --git a/client.c b/client.c index 298b08208..bacf9543e 100644 --- a/client.c +++ b/client.c @@ -30,10 +30,11 @@ #include "window.h" #include "focus.h" #include "ewmh.h" -#include "screen.h" #include "widget.h" -#include "common/xutil.h" +#include "screen.h" #include "layouts/floating.h" +#include "common/xutil.h" +#include "common/xscreen.h" extern AwesomeConf globalconf; @@ -262,7 +263,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen) c = p_new(Client, 1); - c->screen = screen_get_bycoord(screen, wa->x, wa->y); + c->screen = screen_get_bycoord(globalconf.display, screen, wa->x, wa->y); screen_geom = screen_get_area(c->screen, globalconf.screens[screen].statusbar, @@ -459,7 +460,7 @@ client_resize(Client *c, Area geometry, Bool sizehints) if(c->geometry.x != geometry.x || c->geometry.y != geometry.y || c->geometry.width != geometry.width || c->geometry.height != geometry.height) { - new_screen = screen_get_bycoord(c->screen, geometry.x, geometry.y); + new_screen = screen_get_bycoord(globalconf.display, c->screen, geometry.x, geometry.y); c->geometry.x = wc.x = geometry.x; c->geometry.y = wc.y = geometry.y; diff --git a/common/xscreen.c b/common/xscreen.c new file mode 100644 index 000000000..6faa5c32b --- /dev/null +++ b/common/xscreen.c @@ -0,0 +1,140 @@ +/* + * common/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 "common/xscreen.h" + +/** Return the Xinerama screen number where the coordinates belongs to + * \param disp Display ref + * \param x x coordinate of the window + * \param y y coordinate of the window + * \return screen number or DefaultScreen of disp on no match + */ +int +screen_get_bycoord(Display *disp, int screen, int x, int y) +{ + int i; + ScreensInfo *si; + + /* don't waste our time */ + if(!XineramaIsActive(disp)) + return screen; + + /* XXX si should be an arg instead of disp */ + si = screensinfo_new(disp); + 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))) + { + screensinfo_delete(&si); + return i; + } + + screensinfo_delete(&si); + return DefaultScreen(disp); +} + +static inline Area +screen_xsi_to_area(XineramaScreenInfo si) +{ + Area a; + + a.x = si.x_org; + a.y = si.y_org; + a.width = si.width; + a.height = si.height; + a.next = NULL; + + return a; +} + +void +screensinfo_delete(ScreensInfo **si) +{ + p_delete(&(*si)->geometry); + p_delete(si); +} + +ScreensInfo * +screensinfo_new(Display *disp) +{ + ScreensInfo *si; + XineramaScreenInfo *xsi; + int xinerama_screen_number, screen, screen_to_test; + Bool drop; + + si = p_new(ScreensInfo, 1); + + if(XineramaIsActive(disp)) + { + xsi = XineramaQueryScreens(disp, &xinerama_screen_number); + si->geometry = p_new(Area, 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_xsi_to_area(xsi[screen]); + } + + /* realloc smaller if xinerama_screen_number != screen registered */ + if(xinerama_screen_number != si->nscreen) + { + Area *newgeometry = p_new(Area, si->nscreen); + memcpy(newgeometry, si->geometry, si->nscreen * sizeof(Area)); + p_delete(&si->geometry); + si->geometry = newgeometry; + } + + XFree(xsi); + } + else + { + si->nscreen = ScreenCount(disp); + si->geometry = p_new(Area, si->nscreen); + for(screen = 0; screen < si->nscreen; screen++) + { + si->geometry[screen].x = 0; + si->geometry[screen].y = 0; + si->geometry[screen].width = DisplayWidth(disp, screen); + si->geometry[screen].height = DisplayHeight(disp, screen); + } + } + + return si; +} + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/common/xscreen.h b/common/xscreen.h new file mode 100644 index 000000000..d6fa47849 --- /dev/null +++ b/common/xscreen.h @@ -0,0 +1,38 @@ +/* + * 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 "common/draw.h" + +typedef struct +{ + int nscreen; + Area *geometry; +} ScreensInfo; + +int screen_get_bycoord(Display *, int, int, int); +void screensinfo_delete(ScreensInfo **); +ScreensInfo *screensinfo_new(Display *); + +#endif +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/event.c b/event.c index 5cbd26ba9..f57bf7561 100644 --- a/event.c +++ b/event.c @@ -38,6 +38,7 @@ #include "rules.h" #include "layouts/tile.h" #include "layouts/floating.h" +#include "common/xscreen.h" extern AwesomeConf globalconf; @@ -144,7 +145,7 @@ event_handle_buttonpress(XEvent *e) &wdummy, &x, &y, &i, &i, &udummy)) { - screen = screen_get_bycoord(screen, x, y); + screen = screen_get_bycoord(globalconf.display, screen, x, y); event_handle_mouse_button_press(screen, ev->button, ev->state, globalconf.buttons.root, NULL); return; @@ -320,7 +321,7 @@ event_handle_keypress(XEvent *e) * only screen in Xinerama, so we can ask for a better screen * number with screen_get_bycoord: we'll get 0 in Zaphod mode * so it's the same, or maybe the real Xinerama screen */ - screen = screen_get_bycoord(screen, x, y); + screen = screen_get_bycoord(globalconf.display, screen, x, y); break; } @@ -383,7 +384,7 @@ event_handle_maprequest(XEvent *e) if(XineramaIsActive(globalconf.display) && XQueryPointer(e->xany.display, RootWindow(e->xany.display, screen), &dummy, &dummy, &x, &y, &d, &d, &m)) - screen = screen_get_bycoord(screen, x, y); + screen = screen_get_bycoord(globalconf.display, screen, x, y); else for(screen = 0; wa.screen != ScreenOfDisplay(e->xany.display, screen); screen++); diff --git a/mouse.c b/mouse.c index b1487f29d..baf8c04f5 100644 --- a/mouse.c +++ b/mouse.c @@ -30,6 +30,7 @@ #include "client.h" #include "layouts/floating.h" #include "layouts/tile.h" +#include "common/xscreen.h" #define MOUSEMASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask) @@ -116,7 +117,7 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) XQueryPointer(globalconf.display, RootWindow(globalconf.display, phys_screen), &dummy, &child, &x, &y, &di, &di, &dui); - if((newscreen = screen_get_bycoord(c->screen, x, y)) != c->screen) + if((newscreen = screen_get_bycoord(globalconf.display, c->screen, x, y)) != c->screen) { move_client_to_screen(c, newscreen, True); globalconf.screens[c->screen].need_arrange = True; diff --git a/screen.c b/screen.c index f1c425ac8..76eb05c94 100644 --- a/screen.c +++ b/screen.c @@ -104,116 +104,6 @@ get_display_area(int screen, Statusbar *statusbar, Padding *padding) return area; } -/** Return the Xinerama screen number where the coordinates belongs to - * \param x x coordinate of the window - * \param y y coordinate of the window - * \return screen number or DefaultScreen of disp on no match - */ -int -screen_get_bycoord(int screen, int x, int y) -{ - int i; - Area area; - - /* don't waste our time */ - if(!XineramaIsActive(globalconf.display)) - return screen; - - for(i = 0; i < globalconf.nscreen; i++) - { - area = screen_get_area(i, NULL, NULL); - if((x < 0 || (x >= area.x && x < area.x + area.width)) - && (y < 0 || (y >= area.y && y < area.y + area.height))) - return i; - } - return DefaultScreen(globalconf.display); -} - - -static inline Area -screen_xsi_to_area(XineramaScreenInfo si) -{ - Area a; - - a.x = si.x_org; - a.y = si.y_org; - a.width = si.width; - a.height = si.height; - a.next = NULL; - - return a; -} - -void -screensinfo_delete(ScreensInfo **si) -{ - p_delete(&(*si)->geometry); - p_delete(si); -} - -ScreensInfo * -screensinfo_new(Display *disp) -{ - ScreensInfo *si; - XineramaScreenInfo *xsi; - int xinerama_screen_number, screen, screen_to_test; - Bool drop; - - si = p_new(ScreensInfo, 1); - - if(XineramaIsActive(disp)) - { - xsi = XineramaQueryScreens(disp, &xinerama_screen_number); - si->geometry = p_new(Area, 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_xsi_to_area(xsi[screen]); - } - - /* realloc smaller if xinerama_screen_number != screen registered */ - if(xinerama_screen_number != si->nscreen) - { - Area *newgeometry = p_new(Area, si->nscreen); - memcpy(newgeometry, si->geometry, si->nscreen * sizeof(Area)); - p_delete(&si->geometry); - si->geometry = newgeometry; - } - - XFree(xsi); - } - else - { - si->nscreen = ScreenCount(disp); - si->geometry = p_new(Area, si->nscreen); - for(screen = 0; screen < si->nscreen; screen++) - { - si->geometry[screen].x = 0; - si->geometry[screen].y = 0; - si->geometry[screen].width = DisplayWidth(disp, screen); - si->geometry[screen].height = DisplayHeight(disp, screen); - } - } - - return si; -} - /** This returns the real X screen number for a logical * screen if Xinerama is active. * \param screen the logical screen diff --git a/screen.h b/screen.h index 7ab48de37..0fbea9842 100644 --- a/screen.h +++ b/screen.h @@ -24,17 +24,8 @@ #include "structs.h" -typedef struct -{ - int nscreen; - Area *geometry; -} ScreensInfo; - Area screen_get_area(int, Statusbar *, Padding *); Area get_display_area(int, Statusbar *, Padding *); -int screen_get_bycoord(int, int, int); -void screensinfo_delete(ScreensInfo **); -ScreensInfo *screensinfo_new(Display *); int get_phys_screen(int); void move_client_to_screen(Client *, int, Bool);