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