]> git.decadent.org.uk Git - ion3.git/blob - ioncore/fullscreen.c
[svn-inject] Installing original source of ion3
[ion3.git] / ioncore / fullscreen.c
1 /*
2  * ion/ioncore/fullscreen.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <libtu/setparam.h>
13 #include "common.h"
14 #include "global.h"
15 #include "sizehint.h"
16 #include "clientwin.h"
17 #include "attach.h"
18 #include "screen.h"
19 #include "manage.h"
20 #include "fullscreen.h"
21 #include "mwmhints.h"
22 #include "focus.h"
23 #include "group-cw.h"
24
25
26 bool clientwin_fullscreen_may_switchto(WClientWin *cwin)
27 {
28     return (region_may_control_focus((WRegion*)cwin)
29             || !REGION_IS_ACTIVE(region_screen_of((WRegion*)cwin)));
30 }
31
32
33 bool clientwin_check_fullscreen_request(WClientWin *cwin, int w, int h,
34                                         bool sw)
35 {
36     WScreen *scr;
37     WMwmHints *mwm;
38     WRectangle *rwgeom;
39     
40     mwm=xwindow_get_mwmhints(cwin->win);
41     if(mwm==NULL || !(mwm->flags&MWM_HINTS_DECORATIONS) ||
42        mwm->decorations!=0)
43         return FALSE;
44     
45     FOR_ALL_SCREENS(scr){
46         if(!region_same_rootwin((WRegion*)scr, (WRegion*)cwin))
47             continue;
48         /* TODO: if there are multiple possible rootwins, use the one with
49          * requested position, if any.
50          */
51         if(REGION_GEOM(scr).w==w && REGION_GEOM(scr).h==h){
52             cwin->flags|=CLIENTWIN_FS_RQ;
53             if(!clientwin_fullscreen_scr(cwin, (WScreen*)scr, sw)){
54                 cwin->flags&=~CLIENTWIN_FS_RQ;
55                 return FALSE;
56             }
57             return TRUE;
58         }
59     }
60     
61     rwgeom=&REGION_GEOM(region_rootwin_of((WRegion*)cwin));
62                         
63     /* Catch Xinerama-unaware apps here */
64     if(rwgeom->w==w && rwgeom->h==h){
65         cwin->flags|=CLIENTWIN_FS_RQ;
66         if(clientwin_enter_fullscreen(cwin, sw))
67             return TRUE;
68         cwin->flags&=~CLIENTWIN_FS_RQ;
69     }
70
71     return FALSE;
72 }
73
74
75 static void destroy_pholder(WPHolder **fs_pholder)
76 {
77     WPHolder *ph=*fs_pholder;
78     *fs_pholder=NULL;
79     destroy_obj((Obj*)ph);
80 }
81
82
83 static bool do_fullscreen_scr(WRegion *reg, WPHolder **fs_pholder,
84                               WScreen *scr, bool switchto)
85 {
86     int rootx, rooty;
87     bool wasfs=TRUE;
88     int swf=(switchto ? MPLEX_ATTACH_SWITCHTO : 0);
89     WRegion *mgr=REGION_MANAGER(reg);
90     
91     if(*fs_pholder!=NULL)
92         destroy_pholder(fs_pholder);
93         
94     if(*fs_pholder==NULL && mgr!=NULL)
95         *fs_pholder=region_managed_get_pholder(mgr, reg);
96     
97     if(!mplex_attach_simple((WMPlex*)scr, reg, swf)){
98         warn(TR("Failed to enter full screen mode."));
99         if(*fs_pholder!=NULL)
100             destroy_pholder(fs_pholder);
101         return FALSE;
102     }
103
104     return TRUE;
105 }
106
107
108 static bool do_leave_fullscreen(WRegion *reg, WPHolder **fs_pholder, 
109                                 bool switchto)
110 {    
111     bool cf;
112     int swf=(switchto ? PHOLDER_ATTACH_SWITCHTO : 0);
113     
114     if(*fs_pholder==NULL)
115         return FALSE;
116     
117     cf=region_may_control_focus(reg);
118     
119     if(!pholder_attach(*fs_pholder, swf, reg)){
120         warn(TR("Failed to return from full screen mode; remaining manager "
121                 "or parent from previous location refused to manage us."));
122         return FALSE;
123     }
124     
125     if(*fs_pholder!=NULL)
126         destroy_pholder(fs_pholder);
127         
128     if(cf)
129         region_goto(reg);
130     
131     return TRUE;
132 }
133
134
135 static WRegion *get_group(WClientWin *cwin)
136 {
137     WGroupCW *cwg=OBJ_CAST(REGION_MANAGER(cwin), WGroupCW);
138     
139     return ((cwg!=NULL && group_bottom(&cwg->grp)==(WRegion*)cwin)
140             ? (WRegion*)cwg
141             : (WRegion*)cwin);
142 }
143
144
145 bool clientwin_fullscreen_scr(WClientWin *cwin, WScreen *scr, bool switchto)
146 {
147     WRegion *reg=get_group(cwin);
148     return do_fullscreen_scr(reg, &cwin->fs_pholder, scr, switchto);
149 }
150
151
152 bool clientwin_enter_fullscreen(WClientWin *cwin, bool switchto)
153 {
154     WScreen *scr=region_screen_of((WRegion*)cwin);
155     
156     if(scr==NULL){
157         scr=rootwin_current_scr(region_rootwin_of((WRegion*)cwin));
158         if(scr==NULL)
159             return FALSE;
160     }
161     
162     return clientwin_fullscreen_scr(cwin, scr, switchto);
163 }
164
165 bool clientwin_leave_fullscreen(WClientWin *cwin, bool switchto)
166 {
167     WRegion *reg=get_group(cwin);
168     return do_leave_fullscreen(reg, &cwin->fs_pholder, switchto);
169 }
170
171
172 bool clientwin_set_fullscreen(WClientWin *cwin, int sp)
173 {
174     bool set=REGION_IS_FULLSCREEN(cwin);
175     bool nset=libtu_do_setparam(sp, set);
176     
177     if(!XOR(nset, set))
178         return set;
179
180     if(nset)
181         clientwin_enter_fullscreen(cwin, TRUE);
182     else
183         clientwin_leave_fullscreen(cwin, TRUE);
184     
185     return REGION_IS_FULLSCREEN(cwin);
186 }
187
188
189 /*EXTL_DOC
190  * Set client window \var{cwin} full screen state according to the 
191  * parameter \var{how} (set/unset/toggle). Resulting state is returned,
192  * which may not be what was requested.
193  */
194 EXTL_EXPORT_AS(WClientWin, set_fullscreen)
195 bool clientwin_set_fullscreen_extl(WClientWin *cwin, const char *how)
196 {
197     return clientwin_set_fullscreen(cwin, libtu_string_to_setparam(how));
198 }
199
200
201 /*EXTL_DOC
202  * Is \var{cwin} in full screen mode?
203  */
204 EXTL_SAFE
205 EXTL_EXPORT_MEMBER
206 bool clientwin_is_fullscreen(WClientWin *cwin)
207 {
208     return REGION_IS_FULLSCREEN(cwin);
209 }
210
211
212