]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/rootwin.c
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / ioncore / rootwin.c
index 5fc4891aff5c60fb1958b85772f413d2a3f4063d..6e75ee3b5de1ed3a33000a7b3fe7bbe8da6dd1ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * ion/ioncore/rootwin.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2006
+ * Copyright (c) Tuomo Valkonen 1999-2007
  *
  * 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
 #include <stdio.h>
 #include <X11/Xlib.h>
 #include <X11/Xproto.h>
-/*#include <X11/Xmu/Error.h>*/
-#ifdef CF_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#elif defined(CF_SUN_XINERAMA)
-#include <X11/extensions/xinerama.h>
-#endif
 
 #include <libtu/objp.h>
 #include "common.h"
@@ -201,13 +195,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 +210,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 +232,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,208 +249,9 @@ 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;
-
-
-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
-
-    scr=create_screen(rw, id, &fp, useroot);
-    
-    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<nxi; i++){
-        for(j=0; j<nxi; j++){
-            if(i!=j &&
-               (xi[j].x_org>=xi[i].x_org && xi[j].x_org<xi[i].x_org+xi[i].width) &&
-               (xi[j].y_org>=xi[i].y_org && xi[j].y_org<xi[i].y_org+xi[i].height)){
-                warn(TR("Xinerama sanity check failed; overlapping "
-                        "screens detected."));
-                return FALSE;
-            }
-        }
-        
-        if(xi[i].width<=0 || xi[i].height<=0){
-            warn(TR("Xinerama sanity check failed; zero size detected."));
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-#elif defined(CF_SUN_XINERAMA)
-static bool xinerama_sanity_check(XRectangle *monitors, int nxi)
-{
-    int i, j;
-
-    for(i=0; i<nxi; i++){
-        for(j=0; j<nxi; j++){
-            if(i!=j &&
-               (monitors[j].x>=monitors[i].x &&
-                monitors[j].x<monitors[i].x+monitors[i].width) &&
-               (monitors[j].y>=monitors[i].y &&
-                monitors[j].y<monitors[i].y+monitors[i].height)){
-                warn(TR("Xinerama sanity check failed; overlapping "
-                        "screens detected."));
-                return FALSE;
-            }
-        }
-        
-        if(monitors[i].width<=0 || monitors[i].height<=0){
-            warn(TR("Xinerama sanity check failed; zero size detected."));
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-#endif
-
-
-WRootWin *ioncore_manage_rootwin(int xscr, bool noxinerama)
-{
-    WRootWin *rootwin;
-    int nxi=0, fail=0;
-#ifdef CF_XINERAMA
-    XineramaScreenInfo *xi=NULL;
-    int i;
-    int event_base, error_base;
-#elif defined(CF_SUN_XINERAMA)
-    XRectangle monitors[MAXFRAMEBUFFERS];
-    int i;
-#endif
-
-    if(!noxinerama){
-#ifdef CF_XINERAMA
-        if(XineramaQueryExtension(ioncore_g.dpy, &event_base, &error_base)){
-            xi=XineramaQueryScreens(ioncore_g.dpy, &nxi);
-
-            if(xi!=NULL && ioncore_g.rootwins!=NULL){
-                warn(TR("Don't know how to get Xinerama information for "
-                        "multiple X root windows."));
-                XFree(xi);
-                xi=NULL;
-                nxi=0;
-            }
-        }
-#elif defined(CF_SUN_XINERAMA)
-        if(XineramaGetState(ioncore_g.dpy, xscr)){
-            unsigned char hints[16];
-            int num;
-
-            if(XineramaGetInfo(ioncore_g.dpy, xscr, monitors, hints,
-                               &nxi)==0){
-                warn(TR("Error retrieving Xinerama information."));
-                nxi=0;
-            }else{
-                if(ioncore_g.rootwins!=NULL){
-                    warn(TR("Don't know how to get Xinerama information for "
-                            "multiple X root windows."));
-                    nxi=0;
-                }
-            }
-        }
-#endif
-    }
-
-    rootwin=preinit_rootwin(xscr);
-
-    if(rootwin==NULL){
-#ifdef CF_XINERAMA
-        if(xi!=NULL)
-            XFree(xi);
-#endif
-        return NULL;
-    }
-
     net_virtual_roots=XInternAtom(ioncore_g.dpy, "_NET_VIRTUAL_ROOTS", False);
-    XDeleteProperty(ioncore_g.dpy, WROOTWIN_ROOT(rootwin), net_virtual_roots);
-
-#ifdef CF_XINERAMA
-    if(xi!=NULL && nxi!=0 && xinerama_sanity_check(xi, nxi)){
-        bool useroot=FALSE;
-        WRectangle geom;
-
-        for(i=0; i<nxi; i++){
-            geom.x=xi[i].x_org;
-            geom.y=xi[i].y_org;
-            geom.w=xi[i].width;
-            geom.h=xi[i].height;
-            /*if(nxi==1)
-                useroot=(geom.x==0 && geom.y==0);*/
-            if(!add_screen(rootwin, i, &geom, useroot)){
-                warn(TR("Unable to setup Xinerama screen %d."), i);
-                fail++;
-            }
-        }
-        XFree(xi);
-    }else
-#elif defined(CF_SUN_XINERAMA)
-    if(nxi!=0 && xinerama_sanity_check(monitors, nxi)){
-        bool useroot=FALSE;
-        WRectangle geom;
-
-        for(i=0; i<nxi; i++){
-            geom.x=monitors[i].x;
-            geom.y=monitors[i].y;
-            geom.w=monitors[i].width;
-            geom.h=monitors[i].height;
-            /*if(nxi==1)
-                useroot=(geom.x==0 && geom.y==0);*/
-            if(!add_screen(rootwin, i, &geom, useroot)){
-                warn(TR("Unable to setup Xinerama screen %d."), i);
-                fail++;
-            }
-        }
-    }else
-#endif
-    {
-        nxi=1;
-        if(!add_screen(rootwin, xscr, &REGION_GEOM(rootwin), TRUE))
-            fail++;
-    }
-    
-    if(fail==nxi){
-        warn(TR("Unable to setup X screen %d."), xscr);
-        destroy_obj((Obj*)rootwin);
-        return NULL;
-    }
-    
+    XDeleteProperty(ioncore_g.dpy, root, net_virtual_roots);
+
     /* */ {
         /* TODO: typed LINK_ITEM */
         WRegion *tmp=(WRegion*)ioncore_g.rootwins;
@@ -473,9 +259,15 @@ WRootWin *ioncore_manage_rootwin(int xscr, bool noxinerama)
         ioncore_g.rootwins=(WRootWin*)tmp;
     }
 
-    xwindow_set_cursor(WROOTWIN_ROOT(rootwin), IONCORE_CURSOR_DEFAULT);
+    xwindow_set_cursor(root, IONCORE_CURSOR_DEFAULT);
     
-    return rootwin;
+    return TRUE;
+}
+
+
+WRootWin *create_rootwin(int xscr)
+{
+    CREATEOBJ_IMPL(WRootWin, rootwin, (p, xscr));
 }
 
 
@@ -498,7 +290,9 @@ void rootwin_deinit(WRootWin *rw)
     
     XFreeGC(ioncore_g.dpy, rw->xor_gc);
     
-    window_deinit((WWindow*)rw);
+    rw->scr.mplex.win.win=None;
+
+    screen_deinit(&rw->scr);
 }
 
 
@@ -508,29 +302,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 +322,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 +335,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 +358,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);
 
     
 /*}}}*/