bool tiling_do_attach_initial(WTiling *ws, WRegion *reg) { assert(ws->split_tree==NULL); ws->split_tree=(WSplit*)create_splitregion(®ION_GEOM(reg), reg); if(ws->split_tree==NULL) return FALSE; ws->split_tree->ws_if_root=ws; if(!tiling_managed_add(ws, reg)){ destroy_obj((Obj*)ws->split_tree); ws->split_tree=NULL; return FALSE; } return TRUE; }
WSplitRegion *splittree_split_floating(WSplit *node, int dir, int primn, int nmins, WRegionSimpleCreateFn *fn, WTiling *ws) { WSplitFloat *sf; int omins, mins; int sn, so, s, rs; int bn, bo; WRectangle gn, go, gnc, goc; WFitParams fp; WRegion *nreg; WSplitRegion *nnode; WSplitInner *psplit; if(primn!=PRIMN_TL && primn!=PRIMN_BR) primn=PRIMN_BR; split_update_bounds(split_find_root(node), TRUE); sf=create_splitfloat(&node->geom, ws, dir); if(sf==NULL) return NULL; omins=(dir==SPLIT_VERTICAL ? node->min_h : node->min_w); s=split_size(node, dir); if(primn==PRIMN_BR){ bn=BR_BORDER(sf); bo=TL_BORDER(sf); }else{ bn=TL_BORDER(sf); bo=BR_BORDER(sf); } mins=MAXOF(omins+bo, nmins+bn); /* Potentially resize old node. */ splittree_begin_resize(); if(mins>s){ WRectangle ng=node->geom, rg; if(dir==SPLIT_VERTICAL) ng.h=mins; else ng.w=mins; split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, TRUE); rs=(dir==SPLIT_VERTICAL ? rg.h : rg.w); if(rs<mins){ warn(TR("Unable to split: not enough free space.")); destroy_obj((Obj*)sf); return NULL; } split_do_rqgeom_(node, &ng, TRUE, TRUE, &rg, FALSE); s=split_size(node, dir); }else{ splittree_scan_stdisp_rootward(node); } /* Calculate geometries. */ sn=MAXOF(nmins+bn, s/2); so=MAXOF(omins+bo, s-s/2); ((WSplit*)sf)->geom=node->geom; if(primn==PRIMN_TL){ calc_tlg_brg(&(node->geom), sn, so, dir, &gn, &go); splitfloat_update_handles(sf, &gn, &go); gnc=gn; splitfloat_tl_pwin_to_cnt(sf, &gnc); goc=go; splitfloat_br_pwin_to_cnt(sf, &goc); }else{ calc_tlg_brg(&(node->geom), so, sn, dir, &go, &gn); splitfloat_update_handles(sf, &go, &gn); goc=go; splitfloat_tl_pwin_to_cnt(sf, &goc); gnc=gn; splitfloat_br_pwin_to_cnt(sf, &gnc); } /* Create the region. */ fp.mode=REGION_FIT_EXACT; fp.g=gnc; nreg=fn(REGION_PARENT(ws), &fp); if(nreg==NULL){ destroy_obj((Obj*)sf); return NULL; } nnode=create_splitregion(&(fp.g), nreg); if(nnode==NULL){ destroy_obj((Obj*)nreg); destroy_obj((Obj*)sf); return NULL; } /* Now that everything's ok, resize and move original node. */ split_do_resize(node, &goc, (dir==SPLIT_HORIZONTAL ? primn : PRIMN_ANY), (dir==SPLIT_VERTICAL ? primn : PRIMN_ANY), FALSE); /* Set up split structure. */ psplit=node->parent; if(psplit!=NULL) splitinner_replace(psplit, node, (WSplit*)sf); else splittree_changeroot(node, (WSplit*)sf); node->parent=(WSplitInner*)sf; ((WSplit*)nnode)->parent=(WSplitInner*)sf; if(primn==PRIMN_BR){ sf->ssplit.tl=node; sf->ssplit.br=(WSplit*)nnode; }else{ sf->ssplit.tl=(WSplit*)nnode; sf->ssplit.br=node; } /*splittree_end_resize();*/ return nnode; }