1 /******************************************************************************
2 *                            recordMyDesktop                                  *
3 *******************************************************************************
4 *                                                                             *
5 *            Copyright (C) 2006,2007,2008 John Varouhakis                     *
6 *                                                                             *
7 *                                                                             *
8 *   This program is free software; you can redistribute it and/or modify      *
9 *   it under the terms of the GNU General Public License as published by      *
10 *   the Free Software Foundation; either version 2 of the License, or         *
11 *   (at your option) any later version.                                       *
12 *                                                                             *
13 *   This program is distributed in the hope that it will be useful,           *
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
16 *   GNU General Public License for more details.                              *
17 *                                                                             *
18 *   You should have received a copy of the GNU General Public License         *
19 *   along with this program; if not, write to the Free Software               *
20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *
21 *                                                                             *
22 *                                                                             *
23 *                                                                             *
24 *   For further information contact me at johnvarouhakis@gmail.com            *
25 ******************************************************************************/
26 
27 #include "config.h"
28 #include "rmd_setbrwindow.h"
29 
30 #include "rmd_types.h"
31 
32 
33 /**
34 *Align the recording window to a divisible by 2 pixel start and
35 *and a size divisible by 16.
36 *
37 * \param start x or y of the recording window
38 *
39 * \param size  width or height of the recording window
40 *
41 * \param limit  width or height of the Display
42 *
43 * \note This is called separately for width and height.
44 */
SizePack2_8_16(short * start,unsigned short * size,unsigned short limit)45 static void SizePack2_8_16(short *start, unsigned short *size, unsigned short limit) {
46     int octoffset,hexoffset;
47 
48     //align in two
49     //an odd x can always go down and still be in recording area.
50     //Resolutions come in even numbers
51     //so if x is an odd numer, width max is an odd number, too
52     //thus since x will go down one then width can go up one too and still
53     //be inbounds
54     (*size)+=((*size)%2)|((*start)%2);
55     //but if x goes down 1 and width is already even,it becomes odd so:
56     (*size)+=((*size)%2);
57     (*start)-=(*start)%2;
58 
59 
60     //32 bit pack align
61     //we already have disible by two width,so
62     //it's 2, 4 or 6
63     octoffset=((*size)%8);
64     if(octoffset==2){
65         (*size)-=2;
66 
67     }
68     else if(octoffset==6){
69         if((*size)+(*start)+2<=limit)
70             (*size)+=2;
71         else if((*start)>=2){
72             (*start)-=2;
73             (*size)+=2;
74         }
75         else{
76             (*start)+=2;
77             (*size)-=4;
78         }
79     }
80 
81     else if(octoffset==4){
82         if(((*size)+(*start)+2<=limit)&&((*start)>=2)){
83             (*start)-=2;
84             (*size)+=4;
85         }
86         else if((*size)+(*start)+4<=limit){
87             (*size)+=4;
88         }
89         else if((*start)>=4){
90             (*start)-=4;
91             (*size)+=4;
92         }
93         else{
94             (*start)+=2;
95             (*size)-=4;
96         }
97     }
98 
99     //16 divisble width(needed for shared memory only,
100     //but applied anyway since theora wants it, too)
101     //we already have divisibility by 8 so module
102     //by 16 is euther 8 or 0
103     hexoffset=((*size)%16);
104     if(hexoffset){
105         if(((*size)+(*start)+4<=limit)&&((*start)>=4)){
106             (*start)-=4;
107             (*size)+=8;
108         }
109         else if((*size)+(*start)+8<=limit){
110             (*size)+=8;
111         }
112         else if((*start)>=8){
113             (*start)-=8;
114             (*size)+=8;
115         }
116         else{
117             (*start)+=4;
118             (*size)-=8;
119         }
120     }
121 
122 }
123 
124 
125 
SetBRWindow(Display * dpy,BRWindow * brwin,DisplaySpecs * specs,ProgArgs * args)126 boolean SetBRWindow(Display *dpy,
127                     BRWindow *brwin,
128                     DisplaySpecs *specs,
129                     ProgArgs *args) {
130     //before we start recording we have to make sure the ranges are valid
131     if(args->windowid==0){//root window
132         //first set it up
133         brwin->windowid=specs->root;
134         brwin->rect.x=brwin->rect.y=0;
135         brwin->rect.width=specs->width;
136         brwin->rect.height=specs->height;
137         brwin->rrect.x=args->x;
138         brwin->rrect.y=args->y;
139         brwin->rrect.width=((args->width)?
140                             args->width:specs->width-brwin->rrect.x);
141         brwin->rrect.height=((args->height)?
142                              args->height:specs->height-brwin->rrect.y);
143         //and then check validity
144         if((brwin->rrect.x+brwin->rrect.width>specs->width)||
145             (brwin->rrect.y+brwin->rrect.height>specs->height)){
146             fprintf(stderr,"Window size specification out of bounds!"
147                            "(current resolution:%dx%d)\n",
148                            specs->width,specs->height);
149             return FALSE;
150         }
151     }
152     else{
153         Window wchid;
154         int transl_x,transl_y;
155 
156         XWindowAttributes attribs;
157         XGetWindowAttributes(dpy,args->windowid,&attribs);
158         if((attribs.map_state==IsUnviewable)||(attribs.map_state==IsUnmapped)){
159             fprintf(stderr,"Window must be mapped and visible!\n");
160             return FALSE;
161         }
162         XTranslateCoordinates(dpy,
163                               specs->root,
164                               args->windowid,
165                               attribs.x,
166                               attribs.y,
167                               &transl_x,
168                               &transl_y,
169                               &wchid);
170 
171         brwin->rect.x=attribs.x-transl_x;
172         brwin->rect.y=attribs.y-transl_y;
173         brwin->rect.width=attribs.width;
174         brwin->rect.height=attribs.height;
175         if((brwin->rect.x+brwin->rect.width>specs->width)||
176             (brwin->rect.y+brwin->rect.height>specs->height)){
177             fprintf(stderr,"Window must be on visible screen area!\n");
178             return FALSE;
179         }
180 
181         brwin->rrect.x=brwin->rect.x+args->x;
182         brwin->rrect.y=brwin->rect.y+args->y;
183         brwin->rrect.width=((args->width)?
184                             args->width:brwin->rect.width-args->x);
185         brwin->rrect.height=((args->height)?
186                              args->height:brwin->rect.height-args->y);
187         if((args->x+brwin->rrect.width>brwin->rect.width)||
188             (args->y+brwin->rrect.height>brwin->rect.height)){
189             fprintf(stderr,"Specified Area is larger than window!\n");
190             return FALSE;
191         }
192     }
193     fprintf(stderr, "Initial recording window is set to:\n"
194                     "X:%d   Y:%d    Width:%d    Height:%d\n",
195                     brwin->rrect.x,brwin->rrect.y,
196                     brwin->rrect.width,brwin->rrect.height);
197     SizePack2_8_16(&brwin->rrect.x,&brwin->rrect.width,specs->width);
198     SizePack2_8_16(&brwin->rrect.y,&brwin->rrect.height,specs->height);
199 
200     fprintf(stderr, "Adjusted recording window is set to:\n"
201                     "X:%d   Y:%d    Width:%d    Height:%d\n",
202                     brwin->rrect.x,brwin->rrect.y,
203                     brwin->rrect.width,brwin->rrect.height);
204 
205 
206 
207     brwin->nbytes=(((brwin->rrect.width+15)>>4)<<4)*
208                   (((brwin->rrect.height+15)>>4)<<4)*
209                   ((specs->depth==16)?2:4);
210 
211     return TRUE;
212 }
213