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