~ubuntu-branches/ubuntu/karmic/recordmydesktop/karmic

« back to all changes in this revision

Viewing changes to src/rectinsert.c

  • Committer: Bazaar Package Importer
  • Author(s): José L. Redrejo Rodríguez
  • Date: 2007-04-25 11:54:22 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070425115422-5jvf144ln0c44afr
Tags: 0.3.4-1
* New upstream release
* debian/control: conflicts with previous gtk-recordmydesktop versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*********************************************************************************
2
 
*                             recordMyDesktop                                    *
3
 
**********************************************************************************
4
 
*                                                                                *
5
 
*             Copyright (C) 2006  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
 
**********************************************************************************/
 
1
/******************************************************************************
 
2
*                            recordMyDesktop                                  *
 
3
*******************************************************************************
 
4
*                                                                             *
 
5
*            Copyright (C) 2006,2007 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
26
 
27
27
 
28
28
#include <recordmydesktop.h>
29
 
//return 1 and null if geom1 in geom2 ,2 and null if geom2 in geom1,0 if they don't collide
30
 
//-1 and two geoms if they collide and geom1 is broken.//-2 and one or two geoms if they collide and geom2 is broken.
 
29
//return 1 and null if geom1 in geom2 ,2 and null if geom2 in geom1,
 
30
//0 if they don't collide
 
31
//-1 and two geoms if they collide and geom1 is broken.
 
32
//-2 and one or two geoms if they collide and geom2 is broken.
31
33
//-10 if group and replace is possible
32
 
int CollideRects(WGeometry *wgeom1,WGeometry *wgeom2,WGeometry **wgeom_return,int *ngeoms){
 
34
int CollideRects(WGeometry *wgeom1,
 
35
                 WGeometry *wgeom2,
 
36
                 WGeometry **wgeom_return,
 
37
                 int *ngeoms){
33
38
    //1 fits in 2
34
39
    if((wgeom1->x>=wgeom2->x)&&
35
40
        (wgeom1->x+wgeom1->width<=wgeom2->x+wgeom2->width)&&
59
64
//this happens because libxdamage may generate many events for one change
60
65
//and some of them may be in the the exact same region
61
66
//so identical rects would be considered not colliding
62
 
//in order though to avoid endless recursion on the RectInsert 
 
67
//in order though to avoid endless recursion on the RectInsert
63
68
//function should always start at the next element(which is logical since
64
 
//if any rect makes it to a points none of it's part collides with previous 
 
69
//if any rect makes it to a points none of it's part collides with previous
65
70
//nodes on the list, too)
66
71
        int x1[2]={wgeom1->x,wgeom1->x+wgeom1->width};
67
72
        int y1[2]={wgeom1->y,wgeom1->y+wgeom1->height};
88
93
        tot2=enclosed[1][0]+enclosed[1][1]+enclosed[1][2]+enclosed[1][3];
89
94
        if((tot1==2)&&(tot2==2)){//same width or height, which is the best case
90
95
            //group
91
 
            if((enclosed[1][0]&&enclosed[1][1])&&(wgeom1->width==wgeom2->width)){
 
96
            if((enclosed[1][0]&&enclosed[1][1])&&
 
97
               (wgeom1->width==wgeom2->width)){
92
98
                wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
93
99
                *ngeoms=1;
94
100
                wgeom_return[0]->x=wgeom1->x;
97
103
                wgeom_return[0]->height=wgeom2->height+wgeom2->y-wgeom1->y;
98
104
                return -10;
99
105
            }
100
 
            else if((enclosed[1][0]&&enclosed[1][2])&&(wgeom1->height==wgeom2->height)){
101
 
//                 wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
 
106
            else if((enclosed[1][0]&&enclosed[1][2])&&
 
107
                    (wgeom1->height==wgeom2->height)){
102
108
                *ngeoms=1;
103
109
                wgeom_return[0]->x=wgeom1->x;
104
110
                wgeom_return[0]->y=wgeom1->y;
105
111
                wgeom_return[0]->width=wgeom2->width+wgeom2->x-wgeom1->x;
106
 
                wgeom_return[0]->height=wgeom1->height;    
 
112
                wgeom_return[0]->height=wgeom1->height;
107
113
                return -10;
108
114
            }
109
 
            else if((enclosed[1][3]&&enclosed[1][1])&&(wgeom1->height==wgeom2->height)){
110
 
//                 wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
 
115
            else if((enclosed[1][3]&&enclosed[1][1])&&
 
116
                    (wgeom1->height==wgeom2->height)){
111
117
                *ngeoms=1;
112
118
                wgeom_return[0]->x=wgeom2->x;
113
119
                wgeom_return[0]->y=wgeom2->y;
115
121
                wgeom_return[0]->height=wgeom2->height;
116
122
                return -10;
117
123
            }
118
 
            else if((enclosed[1][3]&&enclosed[1][2])&&(wgeom1->width==wgeom2->width)){
119
 
//                 wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
 
124
            else if((enclosed[1][3]&&enclosed[1][2])&&
 
125
                    (wgeom1->width==wgeom2->width)){
120
126
                *ngeoms=1;
121
127
                wgeom_return[0]->x=wgeom2->x;
122
128
                wgeom_return[0]->y=wgeom2->y;
128
134
        }
129
135
        if(tot2==2){
130
136
            //break geom2
131
 
//             wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
132
137
            wgeom_return[0]->x=wgeom2->x;
133
138
            wgeom_return[0]->y=wgeom2->y;
134
139
            wgeom_return[0]->width=wgeom2->width;
150
155
        }
151
156
        else if(tot1==2){
152
157
            //if the first one breaks(which is already inserted)
153
 
            //then we reenter the part that was left and the one 
 
158
            //then we reenter the part that was left and the one
154
159
            //that was to be inserted
155
 
//             wgeom_return[1]=wgeom2;
156
160
            wgeom_return[1]->x=wgeom2->x;
157
161
            wgeom_return[1]->y=wgeom2->y;
158
162
            wgeom_return[1]->width=wgeom2->width;
159
163
            wgeom_return[1]->height=wgeom2->height;
160
 
//             wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
161
164
            wgeom_return[0]->x=wgeom1->x;
162
165
            wgeom_return[0]->y=wgeom1->y;
163
166
            wgeom_return[0]->width=wgeom1->width;
178
181
            return -1;
179
182
 
180
183
        }
181
 
        else if(tot2==1){//in which case there is also tot1==1 but we rather not break that
182
 
            //break geom2 in two
183
 
//             wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
184
 
//             wgeom_return[1]=(WGeometry *)malloc(sizeof(WGeometry));
 
184
        else if(tot2==1){   //in which case there is also tot1==1
 
185
                            //but we rather not break that
 
186
                            //break geom2 in two
185
187
            *ngeoms=2;
186
188
            if(enclosed[1][0]){
187
189
//first
205
207
                wgeom_return[1]->x=x1[0];
206
208
                wgeom_return[1]->y=y1[1];
207
209
                wgeom_return[1]->width=x2[1]-x1[0];
208
 
                wgeom_return[1]->height=wgeom2->height-y1[1]+y2[0];            
 
210
                wgeom_return[1]->height=wgeom2->height-y1[1]+y2[0];
209
211
            }
210
212
            else if(enclosed[1][2]){
211
213
//first(same as [1][0])
241
243
            //geom2 crossing vertically geom1
242
244
            //and geom2 crossing horizontally geom1
243
245
            //The proper one can be found by simply checking x,y positions
244
 
//             wgeom_return[0]=(WGeometry *)malloc(sizeof(WGeometry));
245
 
//             wgeom_return[1]=(WGeometry *)malloc(sizeof(WGeometry));
246
246
            *ngeoms=2;
247
247
            if(wgeom2->y<wgeom1->y){
248
248
                //common
299
299
 
300
300
        int ngeoms=0,insert_ok=1,i=0;
301
301
        temp=*root;
302
 
        while(insert_ok){//if something is broken list does not procceed(except on -1 collres case)
303
 
            int collres/*=0;//*/=CollideRects(&(temp->geom),wgeom,wgeom_return,&ngeoms);
 
302
        while(insert_ok){   //if something is broken list does not procceed
 
303
                            //(except on -1 collres case)
 
304
            int collres=CollideRects(&(temp->geom),wgeom,wgeom_return,&ngeoms);
304
305
            if((!collres))
305
306
                insert_ok=1;
306
307
            else{
307
308
                for(i=0;i<ngeoms;i++){
308
 
                    wgeom_return[i]->width+=(wgeom_return[i]->width%2)|(wgeom_return[i]->x%2);
309
 
                    wgeom_return[i]->height+=(wgeom_return[i]->height%2)|(wgeom_return[i]->y%2);
 
309
                    wgeom_return[i]->width+=(wgeom_return[i]->width%2)|
 
310
                                            (wgeom_return[i]->x%2);
 
311
                    wgeom_return[i]->height+=(wgeom_return[i]->height%2)|
 
312
                                             (wgeom_return[i]->y%2);
310
313
                    wgeom_return[i]->width+=(wgeom_return[i]->width%2);
311
314
                    wgeom_return[i]->height+=(wgeom_return[i]->height%2);
312
315
                    wgeom_return[i]->x-=wgeom_return[i]->x%2;
353
356
                    case 2://done,area is already covered
354
357
                        free(newnode);
355
358
                        break;
356
 
                    case -1://current node is broken and reinserted(in same pos)
 
359
                    case -1://current node is broken and reinserted
 
360
                            //(in same pos)
357
361
                            //newnode is also reinserted
358
 
                        if((wgeom_return[0]->width>0)&&(wgeom_return[0]->height>0)){
 
362
                        if((wgeom_return[0]->width>0)&&
 
363
                           (wgeom_return[0]->height>0)){
359
364
                            temp->geom.x=wgeom_return[0]->x;
360
365
                            temp->geom.y=wgeom_return[0]->y;
361
366
                            temp->geom.width=wgeom_return[0]->width;
369
374
                                insert_ok=1;
370
375
                            }
371
376
                        }
372
 
                        else{//it might happen that the old and now broken node 
373
 
                            //is of zero width or height(so it isn't reinserted)
374
 
                            /*TODO this may cause lines to be left not updated
375
 
                            so maybe it is needed to increase the size by one
376
 
                            pixel(zero width or height cause BadValue*/
 
377
                        else{//it might happen that the old and now broken node
 
378
                            //is of zero width or height
 
379
                            //(so it isn't reinserted)
377
380
                            if((temp->prev==NULL)&&(temp->next!=NULL)){
378
381
                                *root=(*root)->next;
379
382
                                (*root)->prev=NULL;
388
391
                                total_insertions--;
389
392
                                temp->next->prev=temp->prev;
390
393
                                temp->prev->next=temp->next;
391
 
                                total_insertions+=RectInsert(&temp->next,wgeom);
 
394
                                total_insertions+=RectInsert(&temp->next,
 
395
                                                             wgeom);
392
396
                            }
393
397
                            free(temp);
394
398
                        }
403
407
                            temp->next=newnode;
404
408
                            newnode->prev=temp;
405
409
                            if(ngeoms>1){
406
 
                                RectArea *newnode1=(RectArea *)malloc(sizeof(RectArea));
 
410
                                RectArea *newnode1=
 
411
                                (RectArea *)malloc(sizeof(RectArea));
 
412
 
407
413
                                newnode1->geom.x=wgeom_return[1]->x;
408
414
                                newnode1->geom.y=wgeom_return[1]->y;
409
415
                                newnode1->geom.width=wgeom_return[1]->width;
415
421
                        }
416
422
                        else{
417
423
                            for(i=0;i<ngeoms;i++){
418
 
                                if((wgeom_return[i]->width>0)&&(wgeom_return[i]->height>0))
419
 
                                    total_insertions+=RectInsert(&temp->next,wgeom_return[i]);
 
424
                                if((wgeom_return[i]->width>0)&&
 
425
                                   (wgeom_return[i]->height>0))
 
426
                                    total_insertions+=
 
427
                                    RectInsert(&temp->next,wgeom_return[i]);
420
428
                            }
421
429
                        }
422
430
                        break;
426
434
                                    newnode->geom.x=wgeom_return[0]->x;
427
435
                                    newnode->geom.y=wgeom_return[0]->y;
428
436
                                    newnode->geom.width=wgeom_return[0]->width;
429
 
                                    newnode->geom.height=wgeom_return[0]->height;
 
437
                                    newnode->geom.height=
 
438
                                    wgeom_return[0]->height;
 
439
 
430
440
                                    *root=newnode;
431
441
                                    free(temp);
432
442
                            }
435
445
                                *root=temp->next;
436
446
                                (*root)->prev=NULL;
437
447
                                free(temp);
438
 
                                if((wgeom_return[0]->width>0)&&(wgeom_return[0]->height>0))
439
 
                                    total_insertions+=RectInsert(root,wgeom_return[0]);
 
448
                                if((wgeom_return[0]->width>0)&&
 
449
                                   (wgeom_return[0]->height>0))
 
450
                                    total_insertions+=
 
451
                                    RectInsert(root,wgeom_return[0]);
440
452
                            }
441
453
                        }
442
454
                        else if(temp->next==NULL){//last, enter anyway
454
466
                            temp->prev->next=temp->next;
455
467
                            temp->next->prev=temp->prev;
456
468
                            free(temp);
457
 
                            if((wgeom_return[0]->width>0)&&(wgeom_return[0]->height>0))
458
 
                                total_insertions+=RectInsert(&temp1,wgeom_return[0]);
 
469
                            if((wgeom_return[0]->width>0)&&
 
470
                               (wgeom_return[0]->height>0))
 
471
                                total_insertions+=
 
472
                                RectInsert(&temp1,wgeom_return[0]);
459
473
                        }
460
474
                        break;
461
475
                }
480
494
        free(wgeom_return[1]);
481
495
    }
482
496
    return total_insertions;
483
 
484
 
    
 
497
}
 
498
 
485
499
void ClearList(RectArea **root){
486
500
 
487
501
    RectArea *temp;
490
504
        while(temp->next!=NULL){
491
505
            temp=temp->next;
492
506
            free(temp->prev);
493
 
            
 
507
 
494
508
        }
495
509
        free(temp);
496
510
        *root=NULL;