/*
* 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
- * 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 <libtu/setparam.h>
#include "fullscreen.h"
#include "mwmhints.h"
#include "focus.h"
-#include "group-cw.h"
+#include "group.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);
+
+ if(!XOR(nset, set))
+ return set;
+
+ if(nset)
+ region_enter_fullscreen(reg, TRUE);
+ else
+ region_leave_fullscreen(reg, TRUE);
- return ((cwg!=NULL && group_bottom(&cwg->grp)==(WRegion*)cwin)
- ? (WRegion*)cwg
- : (WRegion*)cwin);
+ return REGION_IS_FULLSCREEN(reg);
}
-bool clientwin_fullscreen_scr(WClientWin *cwin, WScreen *scr, bool switchto)
-{
- WRegion *reg=get_group(cwin);
- return do_fullscreen_scr(reg, &cwin->fs_pholder, scr, switchto);
-}
+/*}}}*/
-bool clientwin_enter_fullscreen(WClientWin *cwin, bool switchto)
-{
- WScreen *scr=region_screen_of((WRegion*)cwin);
-
- if(scr==NULL){
- scr=rootwin_current_scr(region_rootwin_of((WRegion*)cwin));
- if(scr==NULL)
- return FALSE;
- }
-
- return clientwin_fullscreen_scr(cwin, scr, switchto);
-}
+/*{{{ Client window requests */
+
-bool clientwin_leave_fullscreen(WClientWin *cwin, bool switchto)
+bool clientwin_fullscreen_may_switchto(WClientWin *cwin)
{
- WRegion *reg=get_group(cwin);
- return do_leave_fullscreen(reg, &cwin->fs_pholder, switchto);
+ return (region_may_control_focus((WRegion*)cwin)
+ || !REGION_IS_ACTIVE(region_screen_of((WRegion*)cwin)));
}
-bool clientwin_set_fullscreen(WClientWin *cwin, int sp)
+WScreen *clientwin_fullscreen_chkrq(WClientWin *cwin, int w, int h)
{
- bool set=REGION_IS_FULLSCREEN(cwin);
- bool nset=libtu_do_setparam(sp, set);
+ WScreen *scr;
+ WMwmHints *mwm;
+ WRectangle *rwgeom;
- if(!XOR(nset, set))
- return set;
-
- if(nset)
- clientwin_enter_fullscreen(cwin, TRUE);
- else
- clientwin_leave_fullscreen(cwin, TRUE);
+ mwm=xwindow_get_mwmhints(cwin->win);
+ if(mwm==NULL || !(mwm->flags&MWM_HINTS_DECORATIONS) ||
+ mwm->decorations!=0)
+ return NULL;
- return REGION_IS_FULLSCREEN(cwin);
+ 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)
+ return scr;
+ }
+
+ return NULL;
}
-/*EXTL_DOC
- * Set client window \var{cwin} 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)
-{
- return clientwin_set_fullscreen(cwin, libtu_string_to_setparam(how));
-}
+/*}}}*/
+
+
+/*{{{ Group exports */
/*EXTL_DOC
- * Is \var{cwin} in full screen mode?
+ * Set client window \var{reg} full screen state according to the
+ * parameter \var{how} (one of \codestr{set}, \codestr{unset}, or
+ * \codestr{toggle}). Resulting state is returned, which may not be
+ * what was requested.
*/
-EXTL_SAFE
-EXTL_EXPORT_MEMBER
-bool clientwin_is_fullscreen(WClientWin *cwin)
+EXTL_EXPORT_AS(WGroup, set_fullscreen)
+bool group_set_fullscreen_extl(WGroup *grp, const char *how)
{
- return REGION_IS_FULLSCREEN(cwin);
+ return region_set_fullscreen((WRegion*)grp, libtu_string_to_setparam(how));
}
+/*}}}*/