X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=ioncore%2Frootwin.c;h=fd2d2584d054fc68aa0e4b88915599d4488372ed;hb=29aae1975d46f66b97a2b873f1875eded8c6fbc3;hp=5fc4891aff5c60fb1958b85772f413d2a3f4063d;hpb=8366314611bf30a0f31d25bf5f5023186fa87692;p=ion3.git diff --git a/ioncore/rootwin.c b/ioncore/rootwin.c index 5fc4891..fd2d258 100644 --- a/ioncore/rootwin.c +++ b/ioncore/rootwin.c @@ -1,12 +1,9 @@ /* * ion/ioncore/rootwin.c * - * Copyright (c) Tuomo Valkonen 1999-2006. + * Copyright (c) Tuomo Valkonen 1999-2008. * - * Ion is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. + * See the included file LICENSE for details. */ #include @@ -20,12 +17,6 @@ #include #include #include -/*#include */ -#ifdef CF_XINERAMA -#include -#elif defined(CF_SUN_XINERAMA) -#include -#endif #include #include "common.h" @@ -68,9 +59,13 @@ static int my_error_handler(Display *dpy, XErrorEvent *ev) /* Just ignore bad window and similar errors; makes the rest of * the code simpler. + * + * Apparently XGetWindowProperty can return BadMatch on a race + * condition where the server is already reusing the XID for a + * non-window drawable, so let's just ignore BadMatch entirely... */ if((ev->error_code==BadWindow || - (ev->error_code==BadMatch && ev->request_code==X_SetInputFocus) || + (ev->error_code==BadMatch /*&& ev->request_code==X_SetInputFocus*/) || (ev->error_code==BadDrawable && ev->request_code==X_GetGeometry)) && ignore_badwindow) return 0; @@ -201,13 +196,14 @@ static void preinit_gr(WRootWin *rootwin) } -static WRootWin *preinit_rootwin(int xscr) +static Atom net_virtual_roots=None; + + +static bool rootwin_init(WRootWin *rootwin, int xscr) { Display *dpy=ioncore_g.dpy; - WRootWin *rootwin; WFitParams fp; Window root; - int i; /* Try to select input on the root window */ root=RootWindow(dpy, xscr); @@ -215,24 +211,16 @@ static WRootWin *preinit_rootwin(int xscr) redirect_error=FALSE; XSetErrorHandler(my_redirect_error_handler); - XSelectInput(dpy, root, IONCORE_EVENTMASK_ROOT); + XSelectInput(dpy, root, IONCORE_EVENTMASK_ROOT|IONCORE_EVENTMASK_SCREEN); XSync(dpy, 0); XSetErrorHandler(my_error_handler); if(redirect_error){ warn(TR("Unable to redirect root window events for screen %d."), xscr); - return NULL; + return FALSE; } - rootwin=ALLOC(WRootWin); - - if(rootwin==NULL) - return NULL; - - /* Init the struct */ - OBJ_INIT(rootwin, WRootWin); - rootwin->xscr=xscr; rootwin->default_cmap=DefaultColormap(dpy, xscr); rootwin->tmpwins=NULL; @@ -245,14 +233,12 @@ static WRootWin *preinit_rootwin(int xscr) fp.g.w=DisplayWidth(dpy, xscr); fp.g.h=DisplayHeight(dpy, xscr); - if(!window_do_init((WWindow*)rootwin, NULL, root, &fp)){ + if(!screen_init((WScreen*)rootwin, NULL, &fp, xscr, root)){ free(rootwin); - return NULL; + return FALSE; } - /* Note: this mask isn't right if some WScreen auses the same window. */ - ((WWindow*)rootwin)->event_mask=IONCORE_EVENTMASK_ROOT; - + ((WWindow*)rootwin)->event_mask=IONCORE_EVENTMASK_ROOT|IONCORE_EVENTMASK_SCREEN; ((WRegion*)rootwin)->flags|=REGION_BINDINGS_ARE_GRABBED|REGION_PLEASE_WARP; ((WRegion*)rootwin)->rootwin=rootwin; @@ -264,218 +250,20 @@ static WRootWin *preinit_rootwin(int xscr) preinit_gr(rootwin); netwm_init_rootwin(rootwin); - region_add_bindmap((WRegion*)rootwin, ioncore_rootwin_bindmap); - - return rootwin; -} - - -static Atom net_virtual_roots=None; - + net_virtual_roots=XInternAtom(ioncore_g.dpy, "_NET_VIRTUAL_ROOTS", False); + XDeleteProperty(ioncore_g.dpy, root, net_virtual_roots); -static WScreen *add_screen(WRootWin *rw, int id, const WRectangle *geom, - bool useroot) -{ - WScreen *scr; - CARD32 p[1]; - WFitParams fp; - - fp.g=*geom; - fp.mode=REGION_FIT_EXACT; - -#ifdef CF_ALWAYS_VIRTUAL_ROOT - useroot=FALSE; -#endif + LINK_ITEM(*(WRegion**)&ioncore_g.rootwins, (WRegion*)rootwin, p_next, p_prev); - scr=create_screen(rw, id, &fp, useroot); + xwindow_set_cursor(root, IONCORE_CURSOR_DEFAULT); - if(scr==NULL) - return NULL; - - region_set_manager((WRegion*)scr, (WRegion*)rw); - - region_map((WRegion*)scr); - - if(!useroot){ - p[0]=region_xwindow((WRegion*)scr); - XChangeProperty(ioncore_g.dpy, WROOTWIN_ROOT(rw), net_virtual_roots, - XA_WINDOW, 32, PropModeAppend, (uchar*)&(p[0]), 1); - } - - return scr; -} - - -#ifdef CF_XINERAMA -static bool xinerama_sanity_check(XineramaScreenInfo *xi, int nxi) -{ - int i, j; - - for(i=0; i=xi[i].x_org && xi[j].x_org=xi[i].y_org && xi[j].y_org=monitors[i].x && - monitors[j].x=monitors[i].y && - monitors[j].yxor_gc); - window_deinit((WWindow*)rw); + rw->scr.mplex.win.win=None; + + screen_deinit(&rw->scr); } @@ -508,29 +294,6 @@ void rootwin_deinit(WRootWin *rw) /*{{{ region dynfun implementations */ -static void rootwin_do_set_focus(WRootWin *rootwin, bool warp) -{ - WRegion *sub; - - sub=REGION_ACTIVE_SUB(rootwin); - - if(sub==NULL || !REGION_IS_MAPPED(sub)){ - WScreen *scr; - FOR_ALL_SCREENS(scr){ - if(REGION_IS_MAPPED(scr)){ - sub=(WRegion*)scr; - break; - } - } - } - - if(sub!=NULL) - region_do_set_focus(sub, warp); - else - window_do_set_focus((WWindow*)rootwin, warp); -} - - static bool rootwin_fitrep(WRootWin *rootwin, WWindow *par, const WFitParams *fp) { @@ -551,30 +314,12 @@ static void rootwin_unmap(WRootWin *rootwin) } -static void rootwin_managed_remove(WRootWin *rootwin, WRegion *reg) -{ - region_unset_manager(reg, (WRegion*)rootwin); -} - - -static Window rootwin_x_window(WRootWin *rootwin) -{ - return WROOTWIN_ROOT(rootwin); -} - - /*}}}*/ /*{{{ Misc */ -static bool scr_ok(WRegion *r) -{ - return (OBJ_IS(r, WScreen) && REGION_IS_MAPPED(r)); -} - - /*EXTL_DOC * Returns previously active screen on root window \var{rootwin}. */ @@ -582,22 +327,17 @@ EXTL_SAFE EXTL_EXPORT_MEMBER WScreen *rootwin_current_scr(WRootWin *rootwin) { - WRegion *r=REGION_ACTIVE_SUB(rootwin); - WScreen *scr; - - /* There should be no non-WScreen as children or managed by us, but... */ - - if(r!=NULL && scr_ok(r)) - return (WScreen*)r; + WScreen *scr, *fb=NULL; FOR_ALL_SCREENS(scr){ - if(REGION_MANAGER(scr)==(WRegion*)rootwin - && REGION_IS_MAPPED(scr)){ - break; + if(REGION_MANAGER(scr)==(WRegion*)rootwin && REGION_IS_MAPPED(scr)){ + fb=scr; + if(REGION_IS_ACTIVE(scr)) + return scr; } } - return scr; + return (fb ? fb : &rootwin->scr); } @@ -610,16 +350,13 @@ WScreen *rootwin_current_scr(WRootWin *rootwin) static DynFunTab rootwin_dynfuntab[]={ {region_map, rootwin_map}, {region_unmap, rootwin_unmap}, - {region_do_set_focus, rootwin_do_set_focus}, - {(DynFun*)region_xwindow, (DynFun*)rootwin_x_window}, {(DynFun*)region_fitrep, (DynFun*)rootwin_fitrep}, - {region_managed_remove, rootwin_managed_remove}, END_DYNFUNTAB }; EXTL_EXPORT -IMPLCLASS(WRootWin, WWindow, rootwin_deinit, rootwin_dynfuntab); +IMPLCLASS(WRootWin, WScreen, rootwin_deinit, rootwin_dynfuntab); /*}}}*/