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_poll_events.h"
29 
30 #include "rmd_frame.h"
31 #include "rmd_macro.h"
32 #include "rmd_rectinsert.h"
33 #include "rmd_types.h"
34 
35 #include <X11/Xlib.h>
36 #include <X11/Xlibint.h>
37 #include <X11/extensions/Xdamage.h>
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <signal.h>
42 #include <pthread.h>
43 
44 
45 #define CLIP_EVENT_AREA(e,brwin,xrect){\
46     if(((e)->area.x<=(brwin)->rrect.x)&&((e)->area.y<=(brwin)->rrect.y)&&\
47         ((e)->area.width>=(brwin)->rrect.width)&&\
48         ((e)->area.height<(brwin)->rrect.height)){\
49         (xrect)->x=(brwin)->rrect.x;\
50         (xrect)->y=(brwin)->rrect.y;\
51         (xrect)->width=(brwin)->rrect.width;\
52         (xrect)->height=(brwin)->rrect.height;\
53     }\
54     else{\
55         (xrect)->x=((((e)->area.x+(e)->area.width>=(brwin)->rrect.x)&&\
56         ((e)->area.x<=(brwin)->rrect.x+(brwin)->rrect.width))?\
57         (((e)->area.x<=(brwin)->rrect.x)?(brwin)->rrect.x:(e)->area.x):-1);\
58     \
59         (xrect)->y=((((e)->area.y+(e)->area.height>=(brwin)->rrect.y)&&\
60         ((e)->area.y<=(brwin)->rrect.y+(brwin)->rrect.height))?\
61         (((e)->area.y<=(brwin)->rrect.y)?(brwin)->rrect.y:(e)->area.y):-1);\
62     \
63         (xrect)->width=((e)->area.x<=(brwin)->rrect.x)?\
64         (e)->area.width-((brwin)->rrect.x-(e)->area.x):\
65         ((e)->area.x<=(brwin)->rrect.x+(brwin)->rrect.width)?\
66         (((brwin)->rrect.width-(e)->area.x+(brwin)->rrect.x<(e)->area.width)?\
67         (brwin)->rrect.width-(e)->area.x+(brwin)->rrect.x:e->area.width):0;\
68     \
69         (xrect)->height=((e)->area.y<=(brwin)->rrect.y)?\
70         (e)->area.height-((brwin)->rrect.y-(e)->area.y):\
71         ((e)->area.y<=(brwin)->rrect.y+(brwin)->rrect.height)?\
72         (((brwin)->rrect.height-(e)->area.y+\
73          (brwin)->rrect.y<(e)->area.height)?\
74          (brwin)->rrect.height-(e)->area.y+\
75          (brwin)->rrect.y:(e)->area.height):0;\
76     \
77         if((xrect)->width>(brwin)->rrect.width)\
78             (xrect)->width=(brwin)->rrect.width;\
79         if((xrect)->height>(brwin)->rrect.height)\
80             (xrect)->height=(brwin)->rrect.height;\
81     }\
82 }
83 
84 
InitEventsPolling(ProgData * pdata)85 void InitEventsPolling(ProgData *pdata){
86     Window root_return,
87            parent_return,
88            *children;
89     unsigned int i,
90                  nchildren;
91 
92 
93     XSelectInput (pdata->dpy,pdata->specs.root, SubstructureNotifyMask);
94 
95 
96     if(!pdata->args.full_shots){
97         XQueryTree (pdata->dpy,
98                     pdata->specs.root,
99                     &root_return,
100                     &parent_return,
101                     &children,
102                     &nchildren);
103 
104         for (i = 0; i < nchildren; i++){
105             XWindowAttributes attribs;
106             if (XGetWindowAttributes (pdata->dpy,children[i],&attribs)){
107                 if(!attribs.override_redirect &&
108                    attribs.depth==pdata->specs.depth)
109                     XDamageCreate(pdata->dpy,
110                                   children[i],
111                                   XDamageReportRawRectangles);
112             }
113         }
114         XFree(children);
115         XDamageCreate(pdata->dpy,
116                       pdata->specs.root,
117                       XDamageReportRawRectangles);
118     }
119 
120 
121 
122 }
123 
124 
EventLoop(ProgData * pdata)125 void EventLoop(ProgData *pdata){
126     int inserts=0;
127 
128     XEvent event;
129 
130     while(XPending(pdata->dpy)){
131         XNextEvent(pdata->dpy,&event);
132         if(event.type == KeyPress){
133             XKeyEvent *e=(XKeyEvent *)(&event);
134             if(e->keycode == pdata->pause_key.key){
135                 int i=0;
136                 int found=0;
137                 for(i=0;i<pdata->pause_key.modnum;i++){
138                     if(pdata->pause_key.mask[i]==e->state){
139                         found=1;
140                         break;
141                     }
142                 }
143                 if(found){
144                     raise(SIGUSR1);
145                     continue;
146                 }
147             }
148             if(e->keycode == pdata->stop_key.key){
149                 int i=0;
150                 int found=0;
151                 for(i=0;i<pdata->stop_key.modnum;i++){
152                     if(pdata->stop_key.mask[i]==e->state){
153                         found=1;
154                         break;
155                     }
156                 }
157                 if(found){
158                     raise(SIGINT);
159                     continue;
160                 }
161             }
162         }
163         else if(event.type == Expose){
164 
165             if(event.xexpose.count!=0)
166                 continue;
167             else if(!pdata->args.noframe){
168                 rmdDrawFrame(pdata->dpy,
169                              pdata->specs.screen,
170                              pdata->shaped_w,
171                              pdata->brwin.rrect.width,
172                              pdata->brwin.rrect.height);
173 
174             }
175 
176         }
177         else if(!pdata->args.full_shots){
178             if(event.type == MapNotify ){
179                 XWindowAttributes attribs;
180                 if (!((XMapEvent *)(&event))->override_redirect&&
181                     XGetWindowAttributes(pdata->dpy,
182                                          event.xcreatewindow.window,
183                                          &attribs)){
184                     if(!attribs.override_redirect&&
185                        attribs.depth==pdata->specs.depth)
186                         XDamageCreate(pdata->dpy,
187                                       event.xcreatewindow.window,
188                                       XDamageReportRawRectangles);
189                 }
190             }
191             else if(event.type == pdata->damage_event + XDamageNotify ){
192                 XDamageNotifyEvent *e =(XDamageNotifyEvent *)( &event );
193                 XRectangle xrect;
194                 CLIP_EVENT_AREA(e,&(pdata->brwin),&xrect);
195                 if((xrect.x>=0)&&(xrect.y>=0)&&
196                    (xrect.width>0)&&(xrect.height>0)){
197 
198                     inserts+=RectInsert(&pdata->rect_root,&xrect);
199 
200                 }
201             }
202         }
203 
204     }
205 
206 
207 }
208 
209 
210