X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Ffullscreen.c;h=56ea52702e54c75f58aa083d0da7f2f755f787db;hp=e11a2d929bafa2ee04c59c961ac09e4015354aa1;hb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d;hpb=8366314611bf30a0f31d25bf5f5023186fa87692 diff --git a/ioncore/fullscreen.c b/ioncore/fullscreen.c index e11a2d9..56ea527 100644 --- a/ioncore/fullscreen.c +++ b/ioncore/fullscreen.c @@ -1,7 +1,7 @@ /* * ion/ioncore/fullscreen.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 @@ -21,192 +21,171 @@ #include "mwmhints.h" #include "focus.h" #include "group-cw.h" +#include "return.h" -bool clientwin_fullscreen_may_switchto(WClientWin *cwin) -{ - return (region_may_control_focus((WRegion*)cwin) - || !REGION_IS_ACTIVE(region_screen_of((WRegion*)cwin))); -} +/*{{{ Generic full screen mode code */ -bool clientwin_check_fullscreen_request(WClientWin *cwin, int w, int h, - bool sw) + +bool region_fullscreen_scr(WRegion *reg, WScreen *scr, bool switchto) { - WScreen *scr; - WMwmHints *mwm; - WRectangle *rwgeom; - - mwm=xwindow_get_mwmhints(cwin->win); - if(mwm==NULL || !(mwm->flags&MWM_HINTS_DECORATIONS) || - mwm->decorations!=0) - return FALSE; + int rootx, rooty; + bool wasfs=TRUE; + int swf=(switchto ? MPLEX_ATTACH_SWITCHTO : 0); + WPHolder *ph=NULL; + bool newph=FALSE, ret; + + ph=region_unset_get_return(reg); - FOR_ALL_SCREENS(scr){ - if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin)) - continue; - /* TODO: if there are multiple possible rootwins, use the one with - * requested position, if any. - */ - if(REGION_GEOM(scr).w==w && REGION_GEOM(scr).h==h){ - cwin->flags|=CLIENTWIN_FS_RQ; - if(!clientwin_fullscreen_scr(cwin, (WScreen*)scr, sw)){ - cwin->flags&=~CLIENTWIN_FS_RQ; - return FALSE; - } - return TRUE; - } + if(ph==NULL){ + ph=region_make_return_pholder(reg); + newph=TRUE; } - rwgeom=®ION_GEOM(region_rootwin_of((WRegion*)cwin)); - - /* Catch Xinerama-unaware apps here */ - if(rwgeom->w==w && rwgeom->h==h){ - cwin->flags|=CLIENTWIN_FS_RQ; - if(clientwin_enter_fullscreen(cwin, sw)) - return TRUE; - cwin->flags&=~CLIENTWIN_FS_RQ; - } - - return FALSE; -} - - -static void destroy_pholder(WPHolder **fs_pholder) -{ - WPHolder *ph=*fs_pholder; - *fs_pholder=NULL; - destroy_obj((Obj*)ph); + ret=(mplex_attach_simple((WMPlex*)scr, reg, swf)!=NULL); + + if(!ret) + warn(TR("Failed to enter full screen mode.")); + + if(!ret && newph) + destroy_obj((Obj*)ph); + else if(!region_do_set_return(reg, ph)) + destroy_obj((Obj*)ph); + + return TRUE; } -static bool do_fullscreen_scr(WRegion *reg, WPHolder **fs_pholder, - WScreen *scr, bool switchto) +bool region_enter_fullscreen(WRegion *reg, bool switchto) { - int rootx, rooty; - bool wasfs=TRUE; - int swf=(switchto ? MPLEX_ATTACH_SWITCHTO : 0); - WRegion *mgr=REGION_MANAGER(reg); - - if(*fs_pholder!=NULL) - destroy_pholder(fs_pholder); - - if(*fs_pholder==NULL && mgr!=NULL) - *fs_pholder=region_managed_get_pholder(mgr, reg); + WScreen *scr=region_screen_of(reg); - if(!mplex_attach_simple((WMPlex*)scr, reg, swf)){ - warn(TR("Failed to enter full screen mode.")); - if(*fs_pholder!=NULL) - destroy_pholder(fs_pholder); - return FALSE; + if(scr==NULL){ + scr=rootwin_current_scr(region_rootwin_of(reg)); + if(scr==NULL) + return FALSE; } - - return TRUE; + + return region_fullscreen_scr(reg, scr, switchto); } -static bool do_leave_fullscreen(WRegion *reg, WPHolder **fs_pholder, - bool switchto) -{ - bool cf; +bool region_leave_fullscreen(WRegion *reg, bool switchto) +{ int swf=(switchto ? PHOLDER_ATTACH_SWITCHTO : 0); + WPHolder *ph=region_unset_get_return(reg); - if(*fs_pholder==NULL) + if(ph==NULL) return FALSE; - cf=region_may_control_focus(reg); - - if(!pholder_attach(*fs_pholder, swf, reg)){ + if(!pholder_attach_mcfgoto(ph, swf, reg)){ warn(TR("Failed to return from full screen mode; remaining manager " "or parent from previous location refused to manage us.")); return FALSE; } - if(*fs_pholder!=NULL) - destroy_pholder(fs_pholder); - - if(cf) - region_goto(reg); + destroy_obj((Obj*)ph); return TRUE; } -static WRegion *get_group(WClientWin *cwin) +/*#undef REGION_IS_FULLSCREEN +#define REGION_IS_FULLSCREEN(REG) (region_get_return((WRegion*)REG)!=NULL)*/ + + +static bool region_set_fullscreen(WRegion *reg, int sp) { - WGroupCW *cwg=OBJ_CAST(REGION_MANAGER(cwin), WGroupCW); + bool set=REGION_IS_FULLSCREEN(reg); + bool nset=libtu_do_setparam(sp, set); - return ((cwg!=NULL && group_bottom(&cwg->grp)==(WRegion*)cwin) - ? (WRegion*)cwg - : (WRegion*)cwin); + if(!XOR(nset, set)) + return set; + + if(nset) + region_enter_fullscreen(reg, TRUE); + else + region_leave_fullscreen(reg, TRUE); + + return REGION_IS_FULLSCREEN(reg); } -bool clientwin_fullscreen_scr(WClientWin *cwin, WScreen *scr, bool switchto) +/*}}}*/ + + +/*{{{ Client window requests */ + + +bool clientwin_fullscreen_may_switchto(WClientWin *cwin) { - WRegion *reg=get_group(cwin); - return do_fullscreen_scr(reg, &cwin->fs_pholder, scr, switchto); + return (region_may_control_focus((WRegion*)cwin) + || !REGION_IS_ACTIVE(region_screen_of((WRegion*)cwin))); } -bool clientwin_enter_fullscreen(WClientWin *cwin, bool switchto) +bool clientwin_check_fullscreen_request(WClientWin *cwin, int w, int h, + bool sw) { - WScreen *scr=region_screen_of((WRegion*)cwin); + WScreen *scr; + WMwmHints *mwm; + WRectangle *rwgeom; - if(scr==NULL){ - scr=rootwin_current_scr(region_rootwin_of((WRegion*)cwin)); - if(scr==NULL) - return FALSE; + mwm=xwindow_get_mwmhints(cwin->win); + if(mwm==NULL || !(mwm->flags&MWM_HINTS_DECORATIONS) || + mwm->decorations!=0) + return FALSE; + + FOR_ALL_SCREENS(scr){ + if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin)) + continue; + /* Only Mplayer supports single Xinerama region FS to my knowledge, + * and doesn't set position, so we also don't check position here, + * and instead take the first screen with matching size. + */ + if(REGION_GEOM(scr).w==w && REGION_GEOM(scr).h==h){ + cwin->flags|=CLIENTWIN_FS_RQ; + if(!region_fullscreen_scr((WRegion*)cwin, (WScreen*)scr, sw)){ + cwin->flags&=~CLIENTWIN_FS_RQ; + return FALSE; + } + return TRUE; + } } - return clientwin_fullscreen_scr(cwin, scr, switchto); + return FALSE; } -bool clientwin_leave_fullscreen(WClientWin *cwin, bool switchto) -{ - WRegion *reg=get_group(cwin); - return do_leave_fullscreen(reg, &cwin->fs_pholder, switchto); -} +/*}}}*/ -bool clientwin_set_fullscreen(WClientWin *cwin, int sp) -{ - bool set=REGION_IS_FULLSCREEN(cwin); - bool nset=libtu_do_setparam(sp, set); - - if(!XOR(nset, set)) - return set; - if(nset) - clientwin_enter_fullscreen(cwin, TRUE); - else - clientwin_leave_fullscreen(cwin, TRUE); - - return REGION_IS_FULLSCREEN(cwin); -} +/*{{{ Group exports */ /*EXTL_DOC - * Set client window \var{cwin} full screen state according to the + * Set client window \var{reg} full screen state according to the * parameter \var{how} (set/unset/toggle). Resulting state is returned, * which may not be what was requested. */ -EXTL_EXPORT_AS(WClientWin, set_fullscreen) -bool clientwin_set_fullscreen_extl(WClientWin *cwin, const char *how) +EXTL_EXPORT_AS(WGroup, set_fullscreen) +bool group_set_fullscreen_extl(WGroup *grp, const char *how) { - return clientwin_set_fullscreen(cwin, libtu_string_to_setparam(how)); + return region_set_fullscreen((WRegion*)grp, libtu_string_to_setparam(how)); } /*EXTL_DOC - * Is \var{cwin} in full screen mode? + * Is \var{reg} in full screen mode? */ EXTL_SAFE EXTL_EXPORT_MEMBER -bool clientwin_is_fullscreen(WClientWin *cwin) +bool group_is_fullscreen(WGroup *grp) { - return REGION_IS_FULLSCREEN(cwin); + return REGION_IS_FULLSCREEN(grp); } +/*}}}*/