wmfs/src/screen.c
2012-01-31 21:05:24 +01:00

170 lines
3.1 KiB
C

/*
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
* For license, see COPYING.
*/
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif /* HAVE_XINERAMA */
#include "screen.h"
#include "util.h"
#include "tag.h"
#include "infobar.h"
#include "client.h"
static struct screen*
screen_new(struct geo *g, int id)
{
struct screen *s = (struct screen*)xcalloc(1, sizeof(struct screen));
s->geo = s->ugeo = *g;
s->seltag = NULL;
s->id = id;
TAILQ_INIT(&s->tags);
SLIST_INIT(&s->infobars);
SLIST_INSERT_HEAD(&W->h.screen, s, next);
/* Set as selected screen */
W->screen = s;
return s;
}
void
screen_init(void)
{
struct geo g;
SLIST_INIT(&W->h.screen);
#ifdef HAVE_XINERAMA
XineramaScreenInfo *xsi;
int i, n = 0;
if(XineramaIsActive(W->dpy))
{
xsi = XineramaQueryScreens(W->dpy, &n);
for(i = 0; i < n; ++i)
{
g.x = xsi[i].x_org;
g.y = xsi[i].y_org;
g.w = xsi[i].width;
g.h = xsi[i].height;
screen_new(&g, i);
}
W->nscreen = n;
XFree(xsi);
}
else
#endif /* HAVE_XINERAMA */
{
g.x = g.y = 0;
g.w = DisplayWidth(W->dpy, W->xscreen);
g.h = DisplayHeight(W->dpy, W->xscreen);
screen_new(&g, 0);
W->nscreen = 1;
}
}
/*
* Update selected screen with mouse location
*/
struct screen*
screen_update_sel(void)
{
#ifdef HAVE_XINERAMA
if(XineramaIsActive(W->dpy))
return (W->screen = screen_gb_mouse());
#endif /* HAVE_XINERAMA */
return W->screen;
}
static void
screen_select(struct screen *s)
{
XWarpPointer(W->dpy, None, W->root, 0, 0, 0, 0,
s->ugeo.x + (s->ugeo.w >> 1),
s->ugeo.y + (s->ugeo.h >> 1));
W->screen = s;
}
void
uicb_screen_next(Uicb cmd)
{
struct screen *s;
(void)cmd;
if(!(s = SLIST_NEXT(W->screen, next)))
s = SLIST_FIRST(&W->h.screen);
screen_select(s);
}
void
uicb_screen_prev(Uicb cmd)
{
struct screen *s;
(void)cmd;
SLIST_FOREACH(s, &W->h.screen, next)
if(SLIST_NEXT(W->screen, next) == s)
{
screen_select(s);
return;
}
screen_select(SLIST_FIRST(&W->h.screen));
}
void
uicb_screen_move_client_next(Uicb cmd)
{
struct screen *s = SLIST_NEXT(W->screen, next);;
(void)cmd;
if(!s)
s = SLIST_FIRST(&W->h.screen);
if(W->client)
tag_client(s->seltag, W->client);
}
void
uicb_screen_move_client_prev(Uicb cmd)
{
struct screen *s = SLIST_FIRST(&W->h.screen);
(void)cmd;
while(SLIST_NEXT(s, next) && SLIST_NEXT(s, next) != s)
s = SLIST_NEXT(s, next);
if(W->client)
tag_client(s->seltag, W->client);
}
void
screen_free(void)
{
struct screen *s;
while(!SLIST_EMPTY(&W->h.screen))
{
s = SLIST_FIRST(&W->h.screen);
SLIST_REMOVE_HEAD(&W->h.screen, next);
infobar_free(s);
tag_free(s);
free(s);
}
}