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  *                      2004, 2005, 2006, 2007, 2008
8  *                      2009, 2010, 2011  Henrik Sandklef
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 3
13  * of the License, or any later version.
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Boston,
24  * MA  02110-1301, USA.
25  ****/
26 
27 
28 #include "libxnee/xnee.h"
29 #include "libxnee/print.h"
30 #include "libxnee/xnee_record.h"
31 #include "libxnee/xnee_replay.h"
32 #include "libxnee/xnee_sem.h"
33 #include "libxnee/xnee_resolution.h"
34 #include "libxnee/xnee_fake.h"
35 #include "libxnee/xnee_km.h"
36 #include "libxnee/xnee_setget.h"
37 #include "libxnee/xnee_resource.h"
38 #include "libxnee/xnee_time.h"
39 #include "libxnee/xnee_buffer.h"
40 #include "libxnee/xnee_threshold.h"
41 #include "libxnee/xnee_expr.h"
42 #include "libxnee/xnee_error.h"
43 #include "libxnee/xnee_session.h"
44 #include "libxnee/xnee_utils.h"
45 #include "libxnee/xnee_window.h"
46 #include "libxnee/xnee_range.h"
47 #include "libxnee/xnee_xinput.h"
48 
49 static int time_out_counter = 0;
50 static int diff_counter     = 0;
51 
52 static int last_diff;
53 static int last_logread=1;
54 
55 
56 /*
57  *  internal use only
58  */
59 Time
xnee_delta_time(xnee_intercept_data * xindata)60 xnee_delta_time ( xnee_intercept_data * xindata)
61 {
62   if ( xindata->newtime > xindata->oldtime )
63     {
64       return ( xindata->newtime - xindata->oldtime);
65     }
66   else
67     {
68       return 0 ;
69     }
70 }
71 
72 
73 
74 
75 
76 /**************************************************************
77  *                                                            *
78  * xnee_replay_synchronize                                    *
79  *                                                            *
80  *                                                            *
81  **************************************************************/
82 int
xnee_replay_synchronize(xnee_data * xd)83 xnee_replay_synchronize (xnee_data* xd)
84 {
85   int diff;
86 
87   xnee_verbose((xd,"---> xnee_replay_synchronize sync=%d   FALSE=%d \n",
88 		xd->sync, XNEE_FALSE));
89   if ( xd->sync == XNEE_FALSE )
90     {
91       xnee_verbose((xd, "Xnee in NO SYNC mode\n"));
92       return XNEE_OK;
93     }
94 
95   /*****
96    * Check to see if we are in sync
97    */
98   xnee_verbose ((xd, "   synchronize: entering sync test loop\n"));
99 
100   while ( (0==0) )
101     {
102       /*
103        * Handle all pending data from Xserver/RECORD
104        */
105       diff = xnee_process_replies(xd);
106 
107       /*
108        * make sure that the cached values are valid
109        */
110       diff = xnee_update_buffer_cache(xd);
111 
112       /*
113        * check the buffer limits ....
114        */
115       diff = xnee_check_buffer_limits(xd);
116 
117       /*
118        * handle diff in the buffers .....
119        */
120       if (diff!=0)
121 	{
122 	  if ( (xd->meta_data.cached_min > xnee_get_min_threshold(xd))
123 	       &&
124 	       (xd->meta_data.cached_max < xnee_get_max_threshold(xd)))
125 	    break;
126 
127 	  diff_counter++;
128 	  if (diff_counter >= xnee_get_tot_threshold(xd))
129 	    {
130 	      time_out_counter++;
131 
132 	      /*
133 	       */
134 	      diff_counter=0;
135 
136 	      /*
137 		hmmm don't about that know ..... yet!
138 	       */
139 	      if (time_out_counter > MAX_SKIPPED_UNSYNC)
140 		{
141 		  if (xnee_is_force_replay(xd) != 0 )
142                   {
143                      break;
144                   }
145 		  (void)fprintf (stderr,
146                                  "Can't synchronize anymore .... have to leave!  %d %d \n",
147 				 time_out_counter , MAX_SKIPPED_UNSYNC);
148 		  return XNEE_SYNCH_FAULT;
149 		}
150 	      else
151 		{
152 		  last_diff = diff;
153 		  break;
154 		}
155 	    }
156 	  xnee_verbose ((xd, " ...diff => sleeping %d microsecs\n",
157 			 XNEE_MISSING_DATA_DELAY ));
158           /*@ ignore @*/
159 	  usleep (XNEE_MISSING_DATA_DELAY );
160           /*@ end @*/
161 	  last_diff = diff;
162 
163 	}
164       else
165 	{
166 	  /* Thanks, Valia */
167 /* 	  if (diff_counter!=0) */
168 /* 	    { */
169 /* 	      xd->buf_verbose=True; */
170 /* 	      xnee_replay_printbuffer(xd);  */
171 /* 	      return XNEE_SYNCH_FAULT; */
172 /* 	    } */
173 	  diff_counter=0;
174 	  time_out_counter=0;
175 	  break;
176 	}
177     }
178 
179   xnee_replay_printbuffer(xd);
180   xnee_verbose((xd,"<--- xnee_replay_synchronize \n"));
181   return XNEE_OK;
182 }
183 
184 
185 static void
xnee_replay_update_dev_ctr(xnee_data * xd,int type)186 xnee_replay_update_dev_ctr(xnee_data *xd, int type)
187 {
188   if ( type == ButtonPress )
189     {
190       xd->button_pressed++;
191     }
192   else if ( type == ButtonRelease )
193     {
194       xd->button_pressed--;
195     }
196   else if ( type == KeyPress )
197     {
198       xd->key_pressed++;
199     }
200   else if ( type == KeyRelease )
201     {
202       xd->key_pressed--;
203     }
204   return ;
205 }
206 
207 /**************************************************************
208  *                                                            *
209  * xnee_replay_main_loop                                      *
210  *                                                            *
211  *                                                            *
212  **************************************************************/
213 int
xnee_replay_main_loop(xnee_data * xd,int read_mode)214 xnee_replay_main_loop(xnee_data *xd, int read_mode)
215 {
216   static char tmp[256] ;
217 
218 /*@reldef@*/
219   xnee_intercept_data xindata ;
220 
221   int      logread = -1 ;
222   int      replayable ;
223   long int last_elapsed = 0;
224   int      ret = XNEE_OK ;
225   char    *ret_str;
226   Display *context_display;
227 
228   xindata.oldtime = 0 ;
229   xindata.newtime = 0 ;
230 
231   xnee_reset_elapsed_time(xd);
232   xnee_reset_fake(xd);
233 
234   context_display = xnee_get_display_for_recordcontext(xd);
235 
236 
237 
238 
239   if ( xd->data_file == NULL)
240     {
241       xnee_verbose((xd, "Using stdin as file\n"));
242       xd->data_file=stdin;
243     }
244 
245   if ( (read_mode==XNEE_REPLAY_READ_META_DATA) ||
246        (read_mode==XNEE_REPLAY_READ_ALL_DATA)
247        )
248     {
249        while ( (logread != 0)  && ( xd->cont != 0 ) )
250 	{
251 	  ret_str = fgets(tmp, 256, xd->data_file);
252 
253 	  if ( ret_str == NULL)
254           {
255              ret = -1;
256           }
257 	  else
258           {
259              ret = (int)strlen (ret_str);
260           }
261 
262 	  if ( ret == -1 )
263 	    {
264 	      return XNEE_OK;
265 	    }
266 	  else if ( ret == 0 )
267 	    {
268 	      xnee_verbose((xd, "Empty line in data file\n"));
269 	    }
270 	  else
271 	    {
272 	      ret = xnee_expression_handle_project(xd, ret_str);
273 /* 	      ret = xnee_expression_handle_session(xd, ret_str, &xindata); */
274 
275 
276 
277 	      if ( (ret == XNEE_REPLAY_DATA) ||
278 		   (ret == XNEE_PRIMITIVE_DATA) ||
279 		   (ret == XNEE_SYNTAX_ERROR) )
280 		{
281 		  xnee_verbose((xd,
282 				"We are finished reading settings"
283 				" etc from data file\n"));
284 
285 		  /* since NULL arg printing is done when in verbose mode */
286 		  xnee_record_print_record_range (xd, NULL);
287 		  xnee_print_xnee_settings       (xd, NULL);
288 
289 		  xnee_verbose((xd, "REPLAY DATA coming up .... (%d) %s \n",
290 				ret, ret_str));
291 
292 		  /* Make sure SYNTAX ERRROR is not forgotten */
293 		  if (ret==XNEE_SYNTAX_ERROR)
294 		    {
295 		      return ret;
296 		      XNEE_RETURN_IF_ERR (ret);
297 		    }
298 		  break ;
299 		}
300 	    }
301 	}
302 /*        ret = xnee_set_ranges(xd); */
303     }
304 
305 /*   xnee_print_ranges(xd,stdout); */
306 
307   if (
308       (read_mode==XNEE_REPLAY_READ_REPLAY_DATA) ||
309       (read_mode==XNEE_REPLAY_READ_ALL_DATA))
310     {
311       ret = xnee_set_ranges(xd);
312       XNEE_RETURN_IF_ERR (ret);
313 
314 
315       /* REMOVE ME... after testing.
316 	 rep_prepare is done in xnee_prepare */
317       /*    ret = xnee_rep_prepare(xd); */
318       /*    if (ret!=XNEE_OK) */
319       /*      { */
320       /*        xnee_verbose((xd, "xnee_prepare failed (%d)....checking\n", ret)); */
321       /*        xnee_verbose((xd, "xnee_prepare failed.... failure\n")); */
322       /*        return ret; */
323       /*      } */
324 
325       if ( xd->sync != 0 )
326 	{
327            ret = xnee_setup_rep_recording(xd);
328            XNEE_RETURN_IF_ERR(ret);
329 	}
330 
331       if ( xnee_is_verbose(xd) != 0)
332 	{
333            ret = xnee_print_sys_info(xd , xd->out_file);
334            XNEE_RETURN_IF_ERR(ret);
335 	}
336 
337 /*       xnee_print_ranges(xd,stdout); */
338 
339       ret = xnee_expression_handle_session(xd, tmp, &xindata);
340 
341 
342 /*       if ( ret == XNEE_PRIMITIVE_DATA ) { printf ("return XNEE_OK\n"); ret = XNEE_OK; } */
343 
344 /* 	  printf ("  ===== starting \n"); */
345 /* 	  xnee_print_list(); */
346       /**
347        * all META DATA setting up our sessions is read ...
348        * go on replaying
349        *
350        *
351        *       Think of this as the main loop
352        */
353       while  ( (ret!=XNEE_SYNTAX_ERROR) && ( xd->cont != 0 ) )
354 	{
355 	  if (last_logread != 0)
356 	    {
357 	      /*
358 	       * set value for hcoming time calculations
359 	       * Now replay starts off
360 	       */
361 	      xnee_verbose((xd, " -->  xnee_get_elapsed_time\n"));
362 	      last_elapsed = xnee_get_elapsed_time(xd, XNEE_FROM_LAST_READ );
363 	      xnee_verbose((xd, " <--  xnee_get_elapsed_time\n"));
364 	    }
365 
366 	  if ( ret == XNEE_META_DATA )
367 	    {
368 	      xnee_verbose((xd, "META DATA read ... should be "
369 			    "handled in the future... eg script ????\n"));
370 	    }
371 	  else if (ret!=0)
372 	    {
373 
374 
375 /* 	      printf (" CC : "); */
376 	      if (xd->first_read_time==0)
377               {
378                  /*@ ignore @*/
379                  xd->first_read_time = xindata.newtime;
380                  /*@ end @*/
381               }
382 
383 
384 	      /* Interrupt variable set? */
385 	      if (xnee_get_interrupt_action(xd))
386 		{
387 		  xnee_verbose((xd, "interrupt (replay) variable was set (%d)\n",
388 				xnee_get_interrupt_action(xd)));
389 		  xnee_unset_interrupt_action(xd);
390 		  xnee_verbose((xd, "leaving loop  (%d)\n",
391 				xnee_get_interrupt_action(xd)));
392 		  return XNEE_OK;
393 		}
394 
395 /* 	      printf (" DD "); */
396 
397 	      /*
398 	       *
399 	       * Do we have any grabbed key that have been pressed?
400 	       *
401 	       */
402 	      if (xnee_check_key (xd)==XNEE_GRAB_DATA)
403 		{
404 		  ret = xnee_handle_rep_key(xd) ;
405 		  if (ret == XNEE_GRAB_STOP)
406 		    {
407 		      xnee_verbose  ((xd," breaking async loop since STOP \n"));
408 		      return XNEE_OK;
409 		    }
410 		  else if (ret == XNEE_GRAB_RESUME)
411 		    {
412                        if  ( (xd == NULL)
413                              ||
414                              (xd->control ==NULL)
415                              ||
416                              (xd->record_setup ==NULL))
417                        {
418                           return XNEE_RECORD_FAILURE;
419                        }
420 
421 
422 		      xnee_verbose  ((xd," starting async loop since RESUME \n"));
423 		      ret = XRecordEnableContextAsync(context_display,
424                                                       xd->record_setup->rContext,
425                                                       xd->rec_callback,
426                                                       (XPointer) (xd) );
427                       XNEE_RETURN_IF_ERR(ret);
428 		    }
429 		}
430 
431  	      /* printf (" EE   %d\n", xindata.type);  */
432 
433 	      /*
434 	       *
435 	       * OK, all grabbed stuffed is handled, let's fake some events
436 	       *
437 	       */
438 
439 	      switch (xindata.type)
440 		{
441 		case XNEE_PROTO_EVENT:
442 
443 		  /* if type == 0, break .... BTW, why is it 0?? */
444 		  if ( xindata.u.event.type == 0 ) { break ; }
445 
446 		  /* is it a device event ? */
447                    if ( ( xindata.u.event.type >= KeyPress )
448 		       && (xindata.u.event.type <= MotionNotify) )
449 		    {
450 
451 		      xnee_replay_update_dev_ctr(xd, xindata.u.event.type);
452 
453 		      ret = xnee_replay_synchronize (xd);
454 		      if (ret != XNEE_OK)
455 			{
456 			  xnee_verbose((xd, "xnee_replay_main_loop return %d\n",
457 					ret));
458 			  return ret;
459 			}
460 		      /*		  */
461 		      /*		    }*/
462 		      xnee_verbose((xd," replay MAIN  new %lu   old %lu\n",xindata.newtime , xindata.oldtime ));
463 		      replayable =
464 			xnee_replay_event_handler(xd,
465 						  &xindata,
466 						  last_elapsed);
467 		      xnee_verbose((xd," replayable :%d\n",replayable ));
468 
469 		    }
470 		  else
471 		    {
472 		      XNEE_SYNC_DEBUG ( (stderr,
473 					 "SYNC     EVENT   %d\n",
474 					 xindata.u.event.type ) );
475 
476 		      xnee_replay_buffer_handler (
477 						  xd,
478 						  XNEE_EVENT,
479 						  xindata.u.event.type,
480 						  XNEE_REPLAYED);
481 		    }
482 		  break;
483 		case XNEE_PROTO_REQUEST:
484 		  xnee_verbose((xd, "READ A REQUEST\n"));
485 		  xnee_replay_buffer_handler ( xd,
486 					       XNEE_REQUEST,
487 					       xindata.u.request.type,
488 					       XNEE_REPLAYED);
489                   break;
490 		case XNEE_PROTO_REPLY:
491 		  xnee_verbose((xd, "READ A REPLY\n"));
492 		  xnee_replay_buffer_handler (
493 					      xd,
494 					      XNEE_REPLY,
495 					      xindata.u.reply.type,
496 					      XNEE_REPLAYED);
497 		  break;
498 
499 		case XNEE_PROTO_XINPUT_EVENT_MASTER:
500 		  xnee_verbose((xd, "READ A XINPUT EVENT MASTER\n"));
501 /* 		  break; */
502 		case XNEE_PROTO_XINPUT_EVENT_SLAVE:
503 		  xnee_verbose((xd, "READ A XINPUT EVENT SLAVE\n"));
504 
505 		  xnee_replay_update_dev_ctr(xd, xindata.u.xievent.type);
506 
507 		  ret = xnee_replay_synchronize (xd);
508 		  if (ret != XNEE_OK)
509 		    {
510 		      xnee_verbose((xd, "xnee_replay_main_loop return %d\n",
511 				    ret));
512 		      return ret;
513 		    }
514 
515 		  replayable =
516 		    xnee_replay_event_handler(xd,
517 					      &xindata,
518 					      last_elapsed);
519 		  xnee_verbose((xd," replayable :%d\n",replayable ));
520 
521 		  break;
522 
523 		default:
524 		  xnee_verbose((xd,
525 				"xnee_replay_MainReplayLoop: Unknown type \n"));
526 		  break;
527 		}
528 	    }
529 	  else
530 	    {
531 	      xnee_verbose((xd, "Corrupt line ... skipped \n"));
532 	      break;
533 	    }
534 
535 
536 /* 	  (void)XSync(xd->control, False); */
537 	  xnee_verbose((xd, "Flushing after handled event\n"));
538 	  (void)XFlush(xd->control);
539 	  xnee_verbose((xd, "  <-- Flushed after handled event\n"));
540 
541 	  ret_str = fgets(tmp, 256, xd->data_file);
542 	  if (ret_str == NULL)
543 	    {
544  	      break;
545 	    }
546 	  ret = xnee_expression_handle_session(xd, tmp, &xindata);
547 /* 	  printf ("  and again  (%d, %s)\n", ret, xnee_get_err_description(ret)); */
548 	  last_logread = 0;
549 
550 	}
551     }
552 
553   xd->cont     = 1;
554   last_logread = 1;
555   time_out_counter = 0;
556   diff_counter     = 0;
557 
558 
559   return XNEE_OK;
560 }
561 
562 
563 
564 
565 
566 /**************************************************************
567  *                                                            *
568  * xnee_setup_rep_recording                                   *
569  *                                                            *
570  *                                                            *
571  **************************************************************/
572 int
xnee_setup_rep_recording(xnee_data * xd)573 xnee_setup_rep_recording(xnee_data *xd)
574 {
575   int nr_of_ranges=0;
576   int ret;
577   xnee_recordext_setup  *xrs       = xd->record_setup;
578   Display *context_display;
579 
580 
581 
582   if  ( (xd == NULL)
583         ||
584         (xd->control ==NULL)
585         ||
586         (xd->record_setup ==NULL))
587   {
588      return XNEE_RECORD_FAILURE;
589   }
590 
591   xnee_verbose((xd, "--->xnee_setup_rep_recording :)\n"));
592   nr_of_ranges=xnee_get_max_range(xd);
593 
594   if (xd->all_clients != 0)
595     {
596       xrs->xids[0] = XRecordAllClients;
597     }
598   else
599     {
600       xrs->xids[0] = XRecordFutureClients;
601     }
602   xnee_verbose((xd, "\t  CreateContext   nr_of_ranges=%d\n", nr_of_ranges));
603 
604   context_display = xnee_get_display_for_recordcontext(xd);
605 
606   xnee_verbose ((xd, "creating context .... on control = %p\n", (void*)context_display));
607 
608 
609   xrs->rContext = XRecordCreateContext(context_display,
610 				       xrs->data_flags,
611 				       xrs->xids, 1,
612 				       xrs->range_array,nr_of_ranges );
613 
614   xnee_verbose((xd, "--- xnee_setup_rep_recording  freeing state \n"));
615 
616   XRecordFreeState(xrs->rState);
617 
618   xnee_verbose((xd, "--- xnee_setup_rep_recording  setting rstate \n"));
619   xd->record_setup->rState=NULL;
620 
621 
622   xnee_verbose((xd, "XSync()\n"));
623   XSync  (xd->control, False);
624   xnee_verbose((xd, "XFlush()\n"));
625   XFlush (xd->control);
626   XSynchronize(xd->data, True);
627 
628 
629 
630   xnee_verbose((xd, "--- xnee_setup_rep_recording enabling async \n"));
631 
632   /* Enable context for async interception */
633   ret = XRecordEnableContextAsync (context_display,
634                                    xrs->rContext,
635                                    xnee_replay_dispatch,
636                                    (XPointer) (xd) /* closure passed to Dispatch */);
637   if (ret==0)
638     {
639       xnee_verbose ((xd, "Could not start recording\n"));
640       return XNEE_RECORD_FAILURE;
641     }
642 
643 
644   xnee_verbose((xd, "finished setting up record for replaying\n"));
645   xnee_verbose((xd, "<---xnee_setup_rep_recording\n"));
646 
647   return (XNEE_OK);
648 }
649 
650 
651 
652 
653 
654 
655 /**************************************************************
656  *                                                            *
657  * xnee_replay_dispatch                                       *
658  *                                                            *
659  *                                                            *
660  **************************************************************/
661 void
xnee_replay_dispatch(XPointer type_ref,XRecordInterceptData * data)662 xnee_replay_dispatch (XPointer type_ref, XRecordInterceptData *data)
663 {
664   static unsigned int last_record_window_pos_win = 0;
665   static unsigned int last_record_window_pos_par = 0;
666 
667   XRecordDatum *xrec_data;
668   int           type;
669   xnee_data    *xd;
670   int rec_window_pos = 0;
671   XWindowAttributes window_attributes_return;
672   int ret;
673 
674   if (data->data==NULL)
675     {
676       return;
677     }
678 
679 
680 
681 
682   xrec_data  = (XRecordDatum *) (data->data) ;
683   type       = (int) xrec_data->type ;
684   xd         = (xnee_data*) (type_ref);
685 
686   switch(data->category)
687     {
688     case XRecordFromClient:
689       XNEE_SYNC_DEBUG ( (stderr, "DISPATCH REQUEST %d \n",type  ) );
690       xnee_verbose((xd, "GOT A REQUEST:         %d \n ", type));
691 /*       xnee_replay_buffer_handle (xd, XNEE_REQUEST, type, XNEE_RECEIVED); */
692       xnee_replay_buffer_handler (xd, XNEE_REQUEST, type, XNEE_RECEIVED);
693 /*       printf ("dispatch: %d (%d/%d)\n", XNEE_RECEIVED, XNEE_REQUEST,type); */
694 
695       break;
696     case XRecordFromServer:
697       if(type >  X_Reply )
698 	{
699 	  XNEE_SYNC_DEBUG ( (stderr, "DISPATCH EVENT   %d \n",type  ) );
700 	  xnee_verbose((xd, "GOT A EVENT:       %d \n", type));
701 
702 	  if ( type == ReparentNotify )
703 	    {
704 	      rec_window_pos = xnee_get_recall_window_pos(xd);
705 	      /* rec_window_pos interpretation:
706 	       *   0  used to sync
707 	       *   1  used to adjust window pos
708 	       *   2 both of the above
709 		 *   * error
710 		 */
711 	      if ( rec_window_pos == 0 )
712 		{
713 		  /* only sync */
714 		  xnee_replay_buffer_handler (xd, XNEE_EVENT, type, XNEE_RECEIVED);
715 		}
716 	      else if ( ( rec_window_pos == 1 ) || ( rec_window_pos == 2 ) )
717 		{
718 		  XGetWindowAttributes(xd->grab,
719 				       xrec_data->event.u.reparent.window,
720 				       &window_attributes_return);
721 
722 		  /*
723 		   * Prevent the same window pos to be used more than once
724 		   */
725 		  if ( (last_record_window_pos_win !=
726 			xrec_data->event.u.reparent.window) ||
727 		       (last_record_window_pos_par !=
728 			xrec_data->event.u.reparent.parent) )
729 		    {
730 		      xnee_verbose((xd, "   xnee_replay adding window 0x%X\n",
731 				    (unsigned int)xrec_data->event.u.reparent.window));
732 
733 		      xnee_window_add_attribute_received(xd,
734 							 &window_attributes_return,
735 							 xrec_data->event.u.reparent.window,
736 							 xrec_data->event.u.reparent.parent);
737 
738 		      ret = xnee_window_try_move(xd);
739 		      XNEE_RETURN_VOID_IF_ERR(ret);
740 
741 		      last_record_window_pos_win =
742 			xrec_data->event.u.reparent.window;
743 		      last_record_window_pos_par =
744 			xrec_data->event.u.reparent.parent;
745 		    }
746 		}
747 
748 	      if ( rec_window_pos == 2 )
749 		{
750 		  xnee_replay_buffer_handler (xd, XNEE_EVENT, type, XNEE_RECEIVED);
751 		}
752 	    }
753 	  else
754 	    {
755 	      xnee_replay_buffer_handler (xd, XNEE_EVENT, type, XNEE_RECEIVED);
756 	    }
757 	}
758       else
759 	{
760 	  XNEE_SYNC_DEBUG ( (stderr, "DISPATCH type=%d  REPLY \n",type  ) );
761 	  xnee_verbose((xd, "GOT A REPLY:       %d \n", type));
762 /* 	  xnee_replay_buffer_handle (xd, XNEE_REPLY, type, XNEE_RECEIVED); */
763  	  xnee_replay_buffer_handler (xd, XNEE_REPLY, type, XNEE_RECEIVED);
764 	}
765       break;
766     case XRecordClientStarted:
767       xnee_verbose((xd,  "ClientStarted \n"));
768       break;
769     case XRecordClientDied:
770       xnee_verbose((xd,  "ClientDied \n"));
771       break;
772     case XRecordEndOfData:
773       xnee_verbose((xd,  "EndOfData \n"));
774       break;
775     default:
776       xnee_print_error( "Case: Default reached in Dispatch (...) \n");
777       break;
778     }
779   XRecordFreeData(data);
780 }
781 
782 
783 
784 
785 
786 
787 
788 
789 
790 /**************************************************************
791  *                                                            *
792  * xnee_has_xtest_extension                                   *
793  *                                                            *
794  *                                                            *
795  **************************************************************/
796 int
xnee_has_xtest_extension(xnee_data * xd)797 xnee_has_xtest_extension (xnee_data *xd)
798 {
799   int ok=1;
800   xnee_testext_setup* xrs;
801 
802   if  ( (xd == NULL)
803         ||
804         (xd->control ==NULL)
805         ||
806         (xd->replay_setup ==NULL))
807   {
808      return XNEE_RECORD_FAILURE;
809   }
810 
811 
812 
813   xrs=xd->replay_setup;
814   if( XTestQueryExtension(xd->control,
815                           &xrs->xtest_event_basep,
816                           &xrs->xtest_error_basep,
817                           &xrs->xtest_version_major,
818                           &xrs->xtest_version_minor) == 0 )
819     {
820       xnee_print_error ("XTest extension missing\n");
821       ok=0;
822     }
823   xnee_verbose ((xd, "\t  XTest-\n\t  Release         %d.%d\n",
824 		xrs->xtest_version_major,
825 		xrs->xtest_version_minor));
826   return (ok);
827 
828 }
829 
830 
831 
832 
833 
834 
835 /**************************************************************
836  *                                                            *
837  * xnee_replay_init                                           *
838  *                                                            *
839  *                                                            *
840  **************************************************************/
841 void
xnee_replay_init(xnee_data * xd)842 xnee_replay_init          (xnee_data* xd)
843 {
844   int i, j;
845   xd->first_replayed_event=XNEE_TRUE;
846 
847   xnee_verbose((xd, "---> xnee_replay_init\n"));
848   for ( i=0 ; i<4 ; i++)
849     {
850       for ( j=0 ; j<XNEE_REPLAY_BUFFER_SIZE ; j++)
851 	{
852 	  xd->data_buffer[i][j]=0;
853 	  /*
854 		 xnee_verbose((
855 		 xd,
856 		 "xnee_replay_init %d x %d  =%d\n",
857 		 i , j, xd->data_buffer[i][j]));
858 	   */
859 	}
860       xd->meta_data.cached_max=0;
861       xd->meta_data.cached_min=0;
862     }
863   xd->meta_data.total_diff=0;
864   xd->meta_data.sum_max=0;
865   xd->meta_data.sum_min=0;
866 
867   xd->first_read_time = 0;
868 
869 
870   if ( xnee_no_rep_resolution(xd) == 0 )
871   {
872      int ret ;
873 
874      ret = xnee_set_default_rep_resolution (xd);
875      XNEE_RETURN_VOID_IF_ERR(ret);
876   }
877 
878   xnee_init_xinput_devices(xd);
879   xnee_verbose((xd, "<--- xnee_replay_init\n"));
880 }
881 
882