1 /*****
2 * Xnee's Not an Event Emulator
3 *
4 * Xnee enables recording and replaying of X protocol data
5 *
6 * Copyright (C) 1999, 2000, 2001, 2002, 2003,
7 * 2010, 2011 Henrik Sandklef
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 3
12 * of the License, or any later version.
13 *
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Boston,
23 * MA 02110-1301, USA.
24 ****/
25
26
27 #include "libxnee/xnee.h"
28 #include "libxnee/print.h"
29 #include "libxnee/xnee_record.h"
30 #include "libxnee/xnee_replay.h"
31 #include "libxnee/xnee_sem.h"
32 #include "libxnee/xnee_buffer.h"
33 #include "libxnee/xnee_threshold.h"
34 #include "libxnee/xnee_setget.h"
35 #include "libxnee/xnee_resolution.h"
36 #include "libxnee/xnee_xinput.h"
37
38
39
40 /**************************************************************
41 * *
42 * xnee_replay_buffer_status *
43 * *
44 * *
45 **************************************************************/
46 int
xnee_replay_buffer_status(xnee_data * xd,int data_type,int nr)47 xnee_replay_buffer_status (xnee_data* xd, int data_type, int nr)
48 {
49 return xd->data_buffer[data_type][nr];
50 }
51
52
53
54 /**************************************************************
55 * *
56 * xnee_replay_buffer_max_diff *
57 * *
58 * *
59 **************************************************************/
60 int
xnee_replay_buffer_max_diff(xnee_data * xd,int type)61 xnee_replay_buffer_max_diff (xnee_data* xd, int type)
62 {
63 int max_val=0;
64 int i ;
65
66 for (i=0;i<XNEE_REPLAY_BUFFER_SIZE;i++)
67 {
68 max_val = XNEE_MAX ( xd->data_buffer[type][i], max_val);
69 }
70 return max_val;
71 }
72
73
74 /**************************************************************
75 * *
76 * xnee_replay_buffer_min_diff *
77 * *
78 * *
79 **************************************************************/
80 int
xnee_replay_buffer_min_diff(xnee_data * xd,int type)81 xnee_replay_buffer_min_diff (xnee_data* xd, int type)
82 {
83 int min_val=0;
84 int i ;
85
86 for (i=0;i<XNEE_REPLAY_BUFFER_SIZE;i++)
87 {
88 min_val = XNEE_MIN ( xd->data_buffer[type][i], min_val);
89 }
90 return min_val;
91 }
92
93
94 /**************************************************************
95 * *
96 * xnee_replay_buffer_tot_diff *
97 * *
98 * *
99 **************************************************************/
100 int
xnee_replay_buffer_tot_diff(xnee_data * xd,int type)101 xnee_replay_buffer_tot_diff (xnee_data* xd, int type)
102 {
103 int i;
104 int tot_val=0;
105
106 for (i=0;i<XNEE_REPLAY_BUFFER_SIZE;i++)
107 {
108 tot_val += XNEE_ABS(xd->data_buffer[type][i]);
109 }
110 return tot_val;
111 }
112
113
114
115
116
117
118 /**************************************************************
119 * *
120 * OBSOLETE ..... all is done is synchron... function *
121 * *
122 * *
123 * xnee_replay_buffer_handle *
124 * *
125 * *
126 **************************************************************/
127 int
xnee_replay_buffer_handle(xnee_data * xd,int data_type,int nr,Bool rec_or_rep)128 xnee_replay_buffer_handle (xnee_data* xd, int data_type, int nr, Bool rec_or_rep)
129 {
130
131
132 /*
133 * int i,j;
134 */
135 int nr_of_data=0;
136
137
138 /*
139 * protect the buffer by waiting for the buffer semaphore
140 */
141 xnee_sem_wait(xd, xd->buf_sem);
142
143 /*
144 * From where did we get the data?
145 *
146 * If rec_or_rep equals XNEE_RECEIVED from the Xserver .... decrement
147 * If not (thats is if XNEE_REPLAYED ) from file ..... increment
148 *
149 */
150 if (rec_or_rep==XNEE_RECEIVED)
151 {
152 if (! (
153 ( data_type==XNEE_EVENT ) &&
154 ( nr <= ButtonRelease ) ))
155 {
156 xd->data_buffer[data_type][nr]--;
157 xnee_verbose ((xd,
158 "xnee_replay_buffer_handle decremented %d %d to %d\n",
159 data_type,nr,xd->data_buffer[data_type][nr] ));
160 }
161 }
162 else
163 {
164 if (! (
165 ( data_type==XNEE_EVENT ) &&
166 ( nr <= ButtonRelease) ))
167 {
168 xd->data_buffer[data_type][nr]++;
169 xnee_verbose ((xd,
170 "xnee_replay_buffer_handle incremented %d %d to %d\n",
171 data_type, nr, xd->data_buffer[data_type][nr] ));
172 }
173 }
174
175
176 /*
177 * release the protecting semaphore the buffer
178 */
179 xnee_sem_post (xd, xd->buf_sem);
180 return nr_of_data;
181 }
182
183
184
185
186
187 /**************************************************************
188 * *
189 * xnee_replay_buffer_handler *
190 * *
191 * *
192 **************************************************************/
193 void
xnee_replay_buffer_handler(xnee_data * xd,int data_type,int data_nr,Bool rec_or_rep)194 xnee_replay_buffer_handler (xnee_data* xd,
195 int data_type,
196 int data_nr,
197 Bool rec_or_rep)
198 {
199
200 /*
201 * We don't use device event while synching
202 *
203 if ( (data_type==XNEE_EVENT) &&
204 ( (data_nr>=KeyPress) || (data_nr<=MotionNotify)) )
205 {
206 return;
207 }
208 */
209
210 xnee_verbose((xd,"---> xnee_replay_buffer_handler "));
211 if (rec_or_rep==XNEE_RECEIVED)
212 {
213 xnee_verbose((xd," XNEE_RECEIVED \n"));
214 }
215 else
216 {
217 xnee_verbose((xd," XNEE_REPLAYED \n"));
218 }
219
220 /*
221 * protect the buffer by waiting for the buffer semaphore
222 */
223 xnee_sem_wait(xd, xd->buf_sem);
224
225
226 /*
227 * From where did we get the data?
228 *
229 * If rec_or_rep equals:
230 * XNEE_RECEIVED from the Xserver .... decrement
231 * XNEE_REPLAYED from file ..... increment
232 *
233 */
234 if (rec_or_rep==XNEE_RECEIVED)
235 {
236 if (!(
237 ( data_type == XNEE_EVENT ) &&
238 ( data_nr <= ButtonRelease ) ))
239 {
240 #ifdef XNEE_XINPUT_SUPPORT
241 if (xnee_get_xinput_event_base(xd->fake) > 0)
242 {
243 if (( (data_nr - xnee_get_xinput_event_base(xd->fake)) >= 0 ) &&
244 ( (data_nr - xnee_get_xinput_event_base(xd->fake)) <= MotionNotify ) &&
245 xnee_is_replayer(xd))
246 {
247 return;
248 }
249 }
250 #endif /* XNEE_XINPUT_SUPPORT */
251 if ( ( data_nr >= KeyPress )
252 &&
253 ( data_nr <= MotionNotify )
254 &&
255 xnee_is_replayer(xd))
256 {
257 xnee_verbose((xd,"--- xnee_replay_buffer_handler : ignonring recorded data "));
258
259 /*
260 * release the protecting semaphore the buffer
261 */
262 xnee_sem_post (xd, xd->buf_sem);
263 return;
264
265 }
266 if (data_nr==161)
267 {
268 fprintf (stderr,
269 "161 received:This is workaround for a bug in Xnee\n");
270
271 /*
272 * release the protecting semaphore the buffer
273 */
274 xnee_sem_post (xd, xd->buf_sem);
275 return;
276 }
277
278 /*
279 * If we get a data such that its amount of
280 * unsynced data (xd->data_buffer[data_type][data_nr])
281 * is the same as the cached maximum value for
282 * the buffer we can't assure that the cached
283 * maximum value is valid, since we are going to
284 * decrement the value. Set the cache to -1
285 */
286 if (xd->meta_data.cached_max ==
287 xd->data_buffer[data_type][data_nr])
288 {
289 /* don't get it?
290 .... please read the above read again */
291 xd->meta_data.cached_max=-1;
292 }
293
294
295
296 /*
297 * decrement the data buffer
298 * decrement the total buffer
299 */
300 xd->data_buffer[data_type][data_nr]--;
301 xd->meta_data.total_diff--;
302 xd->meta_data.sum_min--;
303 xd->meta_data.sum_max--;
304
305 /*
306 * If the value for this data is smaller than the cached
307 * minimum value. Set this value in the cache
308 */
309 if ( xd->data_buffer[data_type][data_nr] <
310 xd->meta_data.cached_min)
311 {
312 xd->meta_data.cached_min =
313 xd->data_buffer[data_type][data_nr] ;
314 }
315
316
317 XNEE_SYNC_DEBUG ( (stdout, "-------- [%d][%d] %d \n",
318 data_type, nr, nr_of_data)) ;
319 xnee_verbose ((xd, " buffer_handler %d %d to %d\n" ,
320 data_type,data_nr, xd->data_buffer[data_type][data_nr]));
321 }
322 }
323 else
324 {
325
326 /*
327 * If we get a data such that its amount of unsynced data
328 * (xd->data_buffer[data_type][data_nr]) is the same as the
329 * cached minimum value for the buffer we can't assure that the cached
330 * minimum value is valid, sice we are going to decrement the value.
331 * Set the cache to +1
332 */
333 if (xd->meta_data.cached_min ==
334 xd->data_buffer[data_type][data_nr])
335 {
336 xd->meta_data.cached_min=+1;
337 }
338
339 /*
340 * increment the data buffer
341 * increment the total buffer
342 */
343 xd->data_buffer[data_type][data_nr]++;
344 xd->meta_data.total_diff++;
345
346 xd->meta_data.sum_max++;
347 xd->meta_data.sum_min++;
348
349 /*
350 * If the value for this data is bigger than the cached maximum value.
351 * Set this value in the cache
352 */
353 if ( xd->data_buffer[data_type][data_nr] >
354 xd->meta_data.cached_max)
355 {
356 xd->meta_data.cached_max =
357 xd->data_buffer[data_type][data_nr] ;
358 }
359
360 xnee_verbose ((xd, " buffer_handler incremented %d %d to %d \n",
361 data_type, data_nr,
362 xd->data_buffer[data_type][data_nr] ));
363 }
364
365 /*
366 * release the protecting semaphore the buffer
367 */
368 xnee_sem_post (xd, xd->buf_sem);
369
370 xnee_replay_printbuffer(xd);
371 xnee_verbose((xd,"<--- xnee_replay_buffer_handler \n"));;
372 }
373
374
375
376 int
xnee_update_buffer_cache(xnee_data * xd)377 xnee_update_buffer_cache(xnee_data *xd)
378 {
379 int type ;
380 int counter ;
381
382
383 /*
384 * protect the buffer by waiting for the buffer semaphore
385 */
386 xnee_sem_wait(xd, xd->buf_sem);
387
388 for (counter=0 ; counter < MAX_UNSYNC_LOOPS; counter++)
389 {
390 for ( type=0 ; type< 2 ; type++)
391 {
392 int real_min=0;
393 int real_max=0;
394
395 real_min=xd->meta_data.cached_min;
396 real_max=xd->meta_data.cached_max;
397
398
399 /* The cached values might be invalid.
400 * If so, get fresh value and replace them */
401 if (real_min==1)
402 {
403 xnee_replay_buffer_min_diff (xd,type);
404 real_min = xnee_replay_buffer_min_diff (xd,type);
405 xnee_verbose ((xd,
406 " cached min value invalid. refreshing to %d old: %d\n",
407 real_min,
408 xd->meta_data.cached_min));
409 xd->meta_data.cached_min=real_min;
410 }
411
412
413 if (real_max==-1)
414 {
415 xnee_replay_buffer_max_diff (xd,type);
416 real_max = xnee_replay_buffer_max_diff (xd,type);
417 xnee_verbose ((xd, " cached max value invalid. refreshing to %d old: %d\n",
418 real_max,
419 xd->meta_data.cached_max));
420 xd->meta_data.cached_max=real_max;
421 }
422 }
423 }
424 /*
425 * release the protecting semaphore the buffer
426 */
427 xnee_sem_post (xd, xd->buf_sem);
428
429 return XNEE_OK;
430 }
431
432
433
434
435 int
xnee_hard_update_buffer_cache(xnee_data * xd)436 xnee_hard_update_buffer_cache(xnee_data *xd)
437 {
438 int type ;
439 int counter ;
440 int real_min=0;
441 int real_max=0;
442
443
444 /*
445 * protect the buffer by waiting for the buffer semaphore
446 */
447 xnee_sem_wait(xd, xd->buf_sem);
448
449 for (counter=0 ; counter < MAX_UNSYNC_LOOPS; counter++)
450 {
451 for ( type=0 ; type< 2 ; type++)
452 {
453
454 real_min = xnee_replay_buffer_min_diff (xd,type);
455 if (real_min<xd->meta_data.cached_min)
456 {
457 xd->meta_data.cached_min=real_min;
458 }
459
460 real_max = xnee_replay_buffer_max_diff (xd,type);
461 if (real_max>xd->meta_data.cached_max)
462 {
463 xd->meta_data.cached_max=real_max;
464 }
465 }
466 }
467 /*
468 * release the protecting semaphore the buffer
469 */
470 xnee_sem_post (xd, xd->buf_sem);
471
472 return XNEE_OK;
473 }
474
475
476
477
478 int
xnee_check_buffer_limits(xnee_data * xd)479 xnee_check_buffer_limits (xnee_data *xd)
480 {
481 int cached_min = 0 ;
482 int cached_max = 0 ;
483 int sum_max = 0 ;
484 int sum_min = 0 ;
485 int tot_diff = 0 ;
486 int diff = 0 ;
487 static int upd_ctr = -1 ;
488
489 if ( ( upd_ctr == -1 ) || ( upd_ctr > 10 ) )
490 {
491 xnee_verbose ((xd, " xnee_hard_update_buffer_cache\n"));
492 xnee_hard_update_buffer_cache (xd);
493 upd_ctr=0;
494 }
495 else
496 {
497 xnee_verbose ((xd, " xnee_update_buffer_cache\n"));
498 xnee_update_buffer_cache (xd);
499 }
500 upd_ctr++;
501
502 cached_max = xd->meta_data.cached_max;
503 cached_min = xd->meta_data.cached_min;
504 sum_max = xd->meta_data.sum_max;
505 sum_min = xd->meta_data.sum_min;
506 tot_diff = xd->meta_data.total_diff;
507
508 xnee_verbose ((xd, "---> xnee_check_buffer_limits button %d key %d\n",
509 xd->button_pressed,
510 xd->key_pressed
511 ));
512
513 xnee_verbose ((xd, "--- cached: %02d/%02d sum_max=%02d sum_min=%02d sum_tot=%02d \n",
514 cached_max ,
515 cached_min ,
516 sum_max ,
517 sum_min ,
518 tot_diff ));
519
520 if ( cached_max > xnee_get_max_threshold(xd))
521 {
522 xnee_verbose ((xd, "cached_max %d > xnee_get_max_threshold(xd) %d\n",
523 cached_max , xnee_get_max_threshold(xd)));
524 xnee_replay_printbuffer(xd);
525 diff=cached_max;
526 }
527 else if ( cached_min < xnee_get_min_threshold(xd))
528 {
529 xnee_verbose ((xd, "cached_min %d < xnee_get_min_threshold(xd) %d\n",
530 cached_min , xnee_get_min_threshold(xd)));
531 xnee_replay_printbuffer(xd);
532 diff=cached_min;
533 }
534 /*
535 else if ( sum_max > XNEE_BUFFER_SUM_MAX )
536 {
537 xnee_verbose ((xd, "sum_max %d > XNEE_BUFFER_SUM_MAX %d\n",
538 sum_max , XNEE_BUFFER_SUM_MAX));
539 xnee_replay_printbuffer(xd);
540 diff=sum_max;
541 }
542 else if ( sum_min < XNEE_BUFFER_SUM_MIN )
543 {
544 xnee_verbose ((xd, "sum_min %d < XNEE_BUFFER_SUM_MIN %d\n",
545 sum_min , XNEE_BUFFER_SUM_MIN));
546 xnee_replay_printbuffer(xd);
547 diff=sum_min;
548 }
549 */
550 else if ( tot_diff > xnee_get_tot_threshold(xd) )
551 {
552 xnee_verbose ((xd, "tot_diff %d > xnee_get_tot_threshold(xd) %d\n",
553 tot_diff , xnee_get_tot_threshold(xd)));
554 xnee_replay_printbuffer(xd);
555 diff=tot_diff;
556 }
557 else
558 {
559 xnee_verbose ((xd, "no diff %d %d\n",
560 tot_diff , xnee_get_tot_threshold(xd)));
561 xnee_replay_printbuffer(xd);
562 diff=0;
563 }
564
565 xnee_verbose ((xd, "<--- xnee_check_buffer_limits diff=%d\n", diff));
566 return diff;
567 }
568
569
570