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