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_setget.h"
33 #include "libxnee/xnee_resolution.h"
34 #include "libxnee/xnee_time.h"
35 #include "libxnee/xnee_fake.h"
36 #include "libxnee/xnee_keysym.h"
37 #include "libxnee/xnee_display.h"
38 #include "libxnee/xnee_xinput.h"
39 #include "libxnee/xnee_utils.h"
40 
41 
42 static int loop_nr = 0;
43 
44 #ifdef XNEE_XINPUT_SUPPORT
45 static int xnee_xi_last_know_pointer_pos[]={0,0};
46 #endif /* XNEE_XINPUT_SUPPORT */
47 
48 int
xnee_reset_fake(xnee_data * xd)49 xnee_reset_fake( xnee_data *xd)
50 {
51     xnee_verbose((xd, "reset fake\n"));
52     loop_nr = 0 ;
53     return XNEE_OK;
54 }
55 
56 static void
xnee_fake_sleep(unsigned long period)57 xnee_fake_sleep(unsigned long period)
58 {
59   static unsigned long collected_time=0;
60 
61 #define SLEEP_THRESH 4
62   if (period>SLEEP_THRESH)
63     {
64       usleep ((period+collected_time)*1000);
65       collected_time=0;
66     }
67   else
68     {
69       collected_time+=period;
70       if (collected_time>SLEEP_THRESH)
71 	{
72 	  usleep(collected_time*1000);
73 	  collected_time=0;
74 	}
75     }
76 }
77 
78 
79 
80 
81 static unsigned long
xnee_replay_event_handler_sleep_amt(xnee_data * xd,xnee_intercept_data * xindata,long int last_elapsed,int only_update_time)82 xnee_replay_event_handler_sleep_amt(xnee_data* xd,
83 				    xnee_intercept_data* xindata,
84 				    long int last_elapsed,
85 				    int      only_update_time)
86 {
87   unsigned long last_diff = 0;
88   unsigned long first_diff = 0 ;
89   unsigned long record_last_diff = 0 ;
90   unsigned long sleep_amt = 0;
91   unsigned long record_first_diff =0 ;
92   int speed ;
93   Time saved_time = 0 ; /* used to restore time of last replayable event */
94 
95 
96   /* Get the recorded time difference.
97      Should be from previous read
98      X server time recorded in file*/
99   saved_time = xindata->oldtime ;
100 
101   if ( only_update_time )
102     {
103       xindata->oldtime = saved_time;
104       return 0;
105     }
106 
107 
108 
109   /* Synchronise the time */
110   xnee_verbose((xd,"ev handler  new %lu   old %lu\n",xindata->newtime , xindata->oldtime ));
111   record_last_diff = xnee_delta_time(xindata) ;
112 
113   record_first_diff = ( xindata->newtime - xd->first_read_time ) ;
114 
115 
116   /* get the actual difference from last read -
117      we may have had to wait/sleep */
118   last_diff = xnee_get_elapsed_time(xd, XNEE_FROM_LAST_READ );
119 
120   /* get the actual elapsed time from the start of the read */
121   first_diff = xnee_get_elapsed_time(xd, XNEE_FROM_FIRST_READ );
122 
123 
124 
125   if (loop_nr==0)
126     {
127       record_last_diff = 0 ;
128       record_first_diff = 0 ;
129       loop_nr=1;
130     }
131   else if (loop_nr==1)
132     {
133       record_last_diff = 0 ;
134       record_first_diff = 0 ;
135       loop_nr=2;
136     }
137 
138   /* if the first event is also the 1st entry from recorded file
139      - reset time - should seldom happen */
140   if ( (xd->first_replayed_event==XNEE_TRUE) && (last_elapsed == 0 ))
141     {
142       xd->first_replayed_event=XNEE_FALSE;
143       xnee_verbose ((xd,
144 		     "\txd->first_replayed_event==%d  ----> dtime1=10 ; \n", XNEE_TRUE
145 		     ));
146       record_last_diff = 10 ;
147     }
148   speed = xnee_get_replay_speed(xd);
149 
150   if (speed==100)
151     {
152       sleep_amt =
153 	xnee_calc_sleep_amount( xd,
154 				last_diff,
155 				first_diff,
156 				record_last_diff,
157 				record_first_diff ) ;
158     }
159   else  if (speed>100)
160     {
161       sleep_amt =
162 	xnee_calc_sleep_amount_fast( xd,
163 				     last_diff,
164 				     first_diff,
165 				     record_last_diff,
166 				     record_first_diff ) ;
167     }
168   else
169     {
170       sleep_amt =
171 	xnee_calc_sleep_amount_slow( xd,
172 				     last_diff,
173 				     first_diff,
174 				     record_last_diff,
175 				     record_first_diff ) ;
176     }
177 
178   /*
179     printf ("xnee_calc_sleep_amount : %lu : (%lu) : %lu :  %lu ===>  %d\n",
180 	    last_diff,
181 	    first_diff,
182 	    record_last_diff,
183 	    record_first_diff,
184 	    sleep_amt);
185     fflush(stdout);
186   */
187 
188   return sleep_amt;
189 }
190 
191 
192 /**************************************************************
193  *                                                            *
194  * xnee_replay_event_handler                                  *
195  *                                                            *
196  *                                                            *
197  **************************************************************/
198 int
xnee_replay_event_handler(xnee_data * xd,xnee_intercept_data * xindata,long int last_elapsed)199 xnee_replay_event_handler( xnee_data* xd,
200 			   xnee_intercept_data* xindata,
201 			   long int last_elapsed)
202 {
203   int           return_value=0;
204   unsigned long sleep_amt = 0;
205 
206   int screen;
207   int x ;
208   int y ;
209 
210   xnee_verbose((xd, "---  xnee_replay_event_handler fake=%p\n ", (void*)xd->fake));
211   XTestGrabControl (xd->fake, True);
212   xnee_verbose((xd, "---  xnee_replay_event_handler 0\n "));
213   XFlush(xd->fake);
214 
215   xnee_verbose((xd, "---  xnee_replay_event_handler 1\n "));
216 
217   xnee_verbose((xd, "---  xnee_replay_event_handler switch on %d  (assuming %d or %d )\n ",
218 		xindata->u.event.type,
219 		KeyPress,
220 		KeyRelease));
221 
222 #ifdef XNEE_XINPUT_SUPPORT
223   if ( xnee_is_forced_core_device_events(xd))
224    {
225 
226       if ( xindata->type == XNEE_PROTO_XINPUT_EVENT_MASTER )
227 	{
228 	  xnee_verbose ((xd, "ignore master event %d\n", xindata->type));
229 	}
230       else
231 	{
232 #endif /* XNEE_XINPUT_SUPPORT*/
233 
234 	  /* If we use the last args to the XTestFakexxx functions
235 	   * it is harder to synchronize ....
236 	   * XNEE_FAKE_SLEEP is a macro for usleep
237 	   */
238 	  switch (xindata->u.event.type)
239 	    {
240 	    case KeyPress:
241 	      sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
242 							      xindata,
243 							      last_elapsed,
244 							      0);
245 	      xnee_inc_events_replayed(xd);
246 	      xnee_fake_key_event (xd, xindata->u.event.keycode, XNEE_PRESS, sleep_amt );
247 	      break;
248 	    case KeyRelease:
249 	      sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
250 							      xindata,
251 							      last_elapsed,
252 							      0);
253 	      xnee_inc_events_replayed(xd);
254 	      xnee_fake_key_event (xd, xindata->u.event.keycode, XNEE_RELEASE, sleep_amt);
255 	      break;
256 	    case ButtonPress:
257 	      sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
258 							      xindata,
259 							      last_elapsed,
260 							      0);
261 	      xnee_inc_events_replayed(xd);
262 	      xnee_fake_button_event(xd, xindata->u.event.button, XNEE_PRESS, sleep_amt);
263 	      break;
264 	    case ButtonRelease:
265 	      sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
266 							      xindata,
267 							      last_elapsed,
268 							      0);
269 	      xnee_inc_events_replayed(xd);
270 	      xnee_fake_button_event(xd, xindata->u.event.button, XNEE_RELEASE, sleep_amt);
271 	      break;
272 	    case MotionNotify:
273 	      xnee_inc_events_replayed(xd);
274 	      screen = xindata->u.event.screen_nr ;
275 	      x      = (int) xindata->u.event.x ;
276 	      y      = (int) xindata->u.event.y ;
277 
278 
279 	      if (xnee_is_screen_ok(xd, screen))
280 		{
281 		  /* xnee_set_verbose(xd); */
282 		  sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
283 								  xindata,
284 								  last_elapsed,
285 								  0);
286 		  /*xnee_unset_verbose(xd); */
287 		  xnee_fake_motion_event (xd,
288 					  screen,
289 					  x,
290 					  y,
291 					  sleep_amt);
292 		}
293 	      else
294 		{
295 		  ;
296 		}
297 	      break;
298 
299 	    default:                  /*  Do nothing  */
300 	      xnee_verbose((xd, " Did NOT replay %d  returning XNEE_NOT_REPLAYABLE \n", xindata->u.event.type));
301 	      /* restore time of last replayable event */
302 	      xnee_replay_event_handler_sleep_amt(xd,
303 						  xindata,
304 						  last_elapsed,
305 						  1);
306 	      return_value= XNEE_NOT_REPLAYABLE;
307 	      break;
308 	    }
309 #ifdef XNEE_XINPUT_SUPPORT
310 	}
311     }
312   else
313     {
314       if ( xindata->type == XNEE_PROTO_XINPUT_EVENT_SLAVE )
315 	{
316 	  sleep_amt = xnee_replay_event_handler_sleep_amt(xd,
317 							  xindata,
318 							  last_elapsed,
319 							  0);
320 
321 	  if ( ( xindata->u.xievent.type >= KeyPress )
322 	       && (xindata->u.xievent.type <= MotionNotify) )
323 	    {
324 	      int screen = xindata->u.event.screen_nr ;
325 	      int x      = (int) xindata->u.xievent.x ;
326 	      int y      = (int) xindata->u.xievent.y ;
327 	      int devid  = (int) xindata->u.xievent.deviceid ;
328 
329 	      if ( xindata->u.xievent.type == MotionNotify)
330 		{
331 		  xnee_fake_xi_motion_event (xd,
332 					     screen,
333 					     x,
334 					     y,
335 					     sleep_amt,
336 					     devid);
337 		}
338 	      else if (xindata->u.xievent.type == ButtonPress)
339 		{
340 		  xnee_inc_events_replayed(xd);
341 		  xnee_fake_xi_button_event(xd, xindata->u.event.button,
342 					    XNEE_PRESS, sleep_amt, devid);
343 		}
344 	      else if (xindata->u.xievent.type == ButtonRelease)
345 		{
346 		  xnee_inc_events_replayed(xd);
347 		  xnee_fake_xi_button_event(xd, xindata->u.event.button,
348 					    XNEE_RELEASE, sleep_amt, devid);
349 		}
350 	      else if (xindata->u.xievent.type == KeyPress)
351 		{
352 		  xnee_inc_events_replayed(xd);
353 		  xnee_fake_xi_key_event (xd, xindata->u.xievent.keycode, XNEE_PRESS, sleep_amt, devid);
354 		}
355 	      else if (xindata->u.xievent.type == KeyRelease)
356 		{
357 		  xnee_inc_events_replayed(xd);
358 		  xnee_fake_xi_key_event (xd, xindata->u.xievent.keycode, XNEE_RELEASE, sleep_amt, devid);
359 		}
360 	    }
361 	}
362       else
363 	{
364 	  xnee_verbose((xd,
365 			"Not replaying master device events\n"));
366 	}
367     }
368 #endif /* XNEE_XINPUT_SUPPORT*/
369 
370   if (return_value==0)
371     {
372       ;
373     }
374   xnee_verbose((xd, "<--- xnee_replay_event_handler returning after handling of %d \n",
375 		xindata->u.event.type ));
376 
377 
378 
379   return return_value ;
380 }
381 
382 
383 
384 
385 
386 /**************************************************************
387  *                                                            *
388  * xnee_fake_key_event_impl                                   *
389  *                                                            *
390  *                                                            *
391  **************************************************************/
392 int
xnee_fake_key_event_impl(xnee_data * xd,int keycode,Bool bo,int dtime,int deviceid)393 xnee_fake_key_event_impl  (xnee_data* xd, int keycode, Bool bo, int dtime, int deviceid)
394 {
395   int i=0;
396 
397   int size= xd->distr_list_size;
398 #ifdef XNEE_XINPUT_SUPPORT
399   XDevice *xdevice;
400 #endif /* XNEE_XINPUT_SUPPORT*/
401 
402   if (!xnee_is_recorder (xd))
403     {
404       if (xnee_is_swinput_playback(xd))
405 	{
406 	  fprintf (stdout, "fake swinput\n");
407 	  fprintf (stderr, "fake swinput\n");
408 	}
409       else if (deviceid != 0 )
410 	{
411 #ifdef XNEE_XINPUT_SUPPORT
412 
413 	  xdevice = xnee_get_xinput_device(xd, deviceid);
414 
415 	  xnee_fake_sleep (dtime);
416 
417 
418 	  XTestFakeDeviceKeyEvent(xd->fake,
419 				  xdevice,
420 				  keycode,
421 				  bo,
422 				  NULL,
423 				  0,
424 				  1);
425 
426 #endif /* XNEE_XINPUT_SUPPORT*/
427 	}
428       else
429 	{
430 	  xnee_fake_sleep (dtime);
431 	  xnee_verbose((xd, "XTestFakeKeyEvent (%p, %d, %d, %d ))\n",
432 			(void*) xd->fake,
433 			(int) keycode,
434 			(int) bo,
435 			(int) dtime));
436 	  XTestFakeKeyEvent (xd->fake, keycode, bo, CurrentTime);
437 	  XFlush(xd->fake);
438 
439 	  for (i=0; i<size ; i++)
440 	    {
441 	      XTestGrabControl (xd->distr_list[i].dpy, True);
442 	      xnee_verbose((xd, "XTestFakeKeyEvent (%p, %d, %d, %d )) **\n",
443 			    (void*) xd->distr_list[i].dpy,
444 			    (int) keycode,
445 			    (int) bo,
446 			    (int) dtime));
447 	      XTestFakeKeyEvent (xd->distr_list[i].dpy, keycode, bo, dtime);
448 	      XFlush (xd->distr_list[i].dpy);
449 	    }
450 	}
451     }
452   xnee_verbose((xd,"\n\n\n"));
453   return (XNEE_OK);
454 }
455 
456 
457 
458 /**************************************************************
459  *                                                            *
460  * xnee_fake_key_mod_event                                        *
461  *                                                            *
462  *                                                            *
463  **************************************************************/
464 int
xnee_fake_key_mod_event(xnee_data * xd,xnee_script_s * xss,Bool bo,int dtime)465 xnee_fake_key_mod_event (xnee_data* xd, xnee_script_s *xss, Bool bo, int dtime)
466 {
467   int i=0;
468   int size= xd->distr_list_size;
469   int mods=0;
470 
471 
472   if (!xnee_is_recorder (xd))
473     {
474 
475       for (mods=0;(mods<8)&&(xss->kc.mod_keycodes[mods]!=0);mods++)
476 	{
477 	  xnee_fake_sleep (dtime);
478 
479 	  xnee_fake_key_event (xd,
480 			       xss->kc.mod_keycodes[mods],
481 			       bo,
482 			       0);
483 	}
484       xnee_fake_sleep (dtime);
485       xnee_verbose((xd, "XTestFakeKeyEvent (%p, %d, %d, %d ))\n",
486 		    (void*) xd->fake,
487 		    (int) xss->kc.kc,
488 		    (int) bo,
489 		    (int) dtime));
490       XTestFakeKeyEvent (xd->fake, xss->kc.kc, bo, CurrentTime);
491       XFlush(xd->fake);
492     }
493 
494   for (i=0; i<size ; i++)
495     {
496       XTestGrabControl (xd->distr_list[i].dpy, True);
497       for (mods=0;(mods<8)&&(xss->kc.mod_keycodes[mods]!=0);mods++)
498 	{
499 	  xnee_verbose((xd, "XTestFakeKeyEvent modifier \n"));
500 	  xnee_fake_key_event (xd,
501 			       xss->kc.mod_keycodes[mods],
502 			       True,
503 			       0);
504 	}
505       xnee_verbose((xd, "XTestFakeKeyEvent (%p, %d, %d, %d )) **\n",
506 		    (void*) xd->distr_list[i].dpy,
507 		    (int) xss->kc.kc,
508 		    (int) bo,
509 		    (int) dtime));
510       XTestFakeKeyEvent (xd->distr_list[i].dpy, xss->kc.kc, bo, dtime);
511       XFlush (xd->distr_list[i].dpy);
512     }
513 
514   xnee_verbose((xd,"\n\n\n"));
515   return (XNEE_OK);
516 }
517 
518 
519 
520 
521 
522 /**************************************************************
523  *                                                            *
524  * xnee_fake_button_event                                     *
525  *                                                            *
526  *                                                            *
527  **************************************************************/
528 int
xnee_fake_button_event_impl(xnee_data * xd,int button,Bool bo,int dtime,int deviceid)529 xnee_fake_button_event_impl (xnee_data* xd,
530 			     int button,
531 			     Bool bo ,
532 			     int dtime,
533 			     int deviceid)
534 {
535   int i=0;
536   int size= xd->distr_list_size;
537 
538 #ifdef XNEE_XINPUT_SUPPORT
539   XDevice *xdevice;
540 #endif /* XNEE_XINPUT_SUPPORT*/
541 
542   if (!xnee_is_recorder (xd))
543     {
544       if (xnee_is_swinput_playback(xd))
545 	{
546 	  fprintf (stdout, "fake swinput\n");
547 	  fprintf (stderr, "fake swinput\n");
548 	}
549       else if (deviceid != 0 )
550 	{
551 #ifdef XNEE_XINPUT_SUPPORT
552 	  xdevice = xnee_get_xinput_device(xd, deviceid);
553 
554 	  xnee_fake_sleep (dtime);
555 	  XTestFakeDeviceButtonEvent(xd->fake,
556 				     xdevice,
557 				     button,
558 				     bo,
559 				     xnee_xi_last_know_pointer_pos,
560 				     2,
561 				     1);
562 #endif /* XNEE_XINPUT_SUPPORT*/
563 	}
564       else
565 	{
566 	  xnee_fake_sleep (dtime);
567 	  xnee_verbose((xd, "XTestFakeButtonEvent (%p, %d, %d, %d)) \n",
568 			(void*) xd->fake,
569 			(int) button,
570 			(int) bo,
571 			(int) dtime));
572 	  XTestFakeButtonEvent (xd->fake, button, bo, 0);
573 	}
574 
575       for (i=0; i<size ; i++)
576 	{
577 	  XTestGrabControl (xd->distr_list[i].dpy, True);
578 	  xnee_verbose((xd, "XTestFakeButtonEvent (%p, %d, %d, %d))  **\n",
579 			(void*) xd->distr_list[i].dpy,
580 			(int) button,
581 			(int) bo,
582 			(int) dtime));
583 	  XTestFakeButtonEvent (xd->distr_list[i].dpy, button, bo, dtime);
584 	  XFlush (xd->distr_list[i].dpy);
585 	}
586       XFlush(xd->fake);
587 
588     }
589   return (XNEE_OK);
590 }
591 
592 
593 
594 
595 /**************************************************************
596  *                                                            *
597  * xnee_fake_motion_event                                     *
598  *                                                            *
599  *                                                            *
600  **************************************************************/
601 int
xnee_fake_motion_event_impl(xnee_data * xd,int screen,int x,int y,unsigned long dtime,int deviceid)602 xnee_fake_motion_event_impl (xnee_data* xd,
603 			     int screen,
604 			     int x,
605 			     int y,
606 			     unsigned long dtime,
607 			     int deviceid)
608 {
609   int i=0;
610   int size= xd->distr_list_size;
611   int new_x;
612   int new_y;
613 #ifdef XNEE_XINPUT_SUPPORT
614   int axes[3];
615   XDevice *xdevice;
616 #endif /* XNEE_XINPUT_SUPPORT*/
617 
618   xnee_verbose((xd, "---> xnee_fake_motion_event\n"));
619   xnee_verbose((xd, "---  delay = %d\n", (int)dtime));
620 
621   if (!xnee_is_recorder (xd))
622     {
623 
624       /* printf ("    res: %dx%d\n", x, y); */
625       /* printf ("    res: %dx%d\n", new_x, new_y); */
626 
627 
628       new_x = xnee_resolution_newx(xd,x) + xd->res_info.x_offset;
629       new_y = xnee_resolution_newy(xd,y) + xd->res_info.y_offset;
630 
631       if (xnee_is_swinput_playback(xd))
632 	{
633 	  fprintf (stdout, "fake swinput\n");
634 	  fprintf (stderr, "fake swinput\n");
635 	}
636       else if (deviceid == 0 )
637 	{
638 	  xnee_fake_sleep (dtime);
639 	  xnee_verbose((xd, "XTestFakeMotionEvent (%p, %d, %d, %d, %d))\n",
640 			(void*) xd->fake,
641 			(int) screen,
642 			(int) new_x,
643 			(int) new_y,
644 			0));
645 	  XTestFakeMotionEvent(xd->fake,
646 			       screen,
647 			       new_x,
648 			       new_y,
649 			       0);
650 	}
651       else
652 	{
653 
654 #ifdef XNEE_XINPUT_SUPPORT
655 	  axes[0] = new_x;
656 	  axes[1] = new_y;
657 	  xnee_verbose((xd, "---  xi find device\n"));
658 
659 	  xdevice = xnee_get_xinput_device(xd, deviceid);
660 
661 	  xnee_verbose((xd, "---  xi devices found? \n"));
662 
663 	  if (xdevice==NULL)
664 	    {
665 	      fprintf(stderr,
666 		      "Couldn't find device for device id: %d\n",
667 		      deviceid);
668 	      return XNEE_XINPUT_EXTENSION_FAILURE;
669 	    }
670 
671 	  xnee_fake_sleep (dtime);
672 
673 
674 	  xnee_verbose((xd, "XTestFakeDeviceMotionEvent (%d, %d, %d, {%d, %d}, %d, %d))\n",
675 			(int) xd->fake,
676 			(int) xdevice,
677 			(int) False,
678 			(int) new_x,
679 			(int) new_y,
680 			2,0));
681 
682 
683 	  xnee_xi_last_know_pointer_pos[0]=axes[0];
684 	  xnee_xi_last_know_pointer_pos[1]=axes[1];
685 
686 	  XTestFakeDeviceMotionEvent(xd->fake,
687 				     xdevice,
688 				     False,
689 				     0,
690 				     axes,
691 				     2,
692 				     0);
693 
694 
695 #endif /* XNEE_XINPUT_SUPPORT*/
696 	}
697 
698       for (i=0; i<size ; i++)
699 	{
700 	  /*       XTestGrabControl (xd->distr_list[i].dpy, True);  */
701 
702 	  xnee_verbose((xd, "XTestFakeMotionEvent (%p, %d, %d, %d, %d))  **\n",
703 			(void*) xd->distr_list[i].dpy,
704 			(int) 0,
705 			(int) x,
706 			(int) y,
707 			10));
708 	  XTestFakeMotionEvent(xd->distr_list[i].dpy,
709 			       0,
710 			       x,
711 			       y,
712 			       CurrentTime);
713 	  XFlush (xd->distr_list[i].dpy);
714 
715 	}
716 
717 
718       XFlush(xd->fake);
719     }
720 
721 
722 
723   xnee_verbose((xd, " <------- xnee_fake_motion_event\n"));
724   return (XNEE_OK);
725 }
726 
727 /**************************************************************
728  *                                                            *
729  * xnee_fake_relative_motion_event                            *
730  *                                                            *
731  *                                                            *
732  **************************************************************/
733 int
xnee_fake_relative_motion_event(xnee_data * xd,int x,int y,unsigned long dtime)734 xnee_fake_relative_motion_event (xnee_data* xd,
735 				 int x,
736 				 int y,
737 				 unsigned long dtime)
738 {
739   int i=0;
740   int size= xd->distr_list_size;
741 
742   xnee_verbose((xd, "---> xnee_fake_relative_motion_event\n"));
743   if (!xnee_is_recorder (xd))
744     {
745       xnee_fake_sleep (dtime);
746       xnee_verbose((xd, "XTestFakeRelativeMotionEvent (%p, %d, %d, %d))\n",
747 		    (void*) xd->fake,
748 		    (int) x,
749 		    (int) y,
750 		    0));
751       XTestFakeRelativeMotionEvent(xd->fake,
752 			   x,
753 			   y,
754 			   0);
755       XFlush(xd->fake);
756     }
757 
758   for (i=0; i<size ; i++)
759     {
760       XTestGrabControl (xd->distr_list[i].dpy, True);
761 
762       xnee_verbose((xd, "XTestFakeRelativeMotionEvent (%p, %d, %d, %d))  **\n",
763 		   (void*) xd->distr_list[i].dpy,
764 		   (int) x,
765 		   (int) y,
766 		    10));
767 
768       XTestFakeRelativeMotionEvent(xd->distr_list[i].dpy,
769 			   x,
770 			   y,
771 			   CurrentTime);
772       XFlush (xd->distr_list[i].dpy);
773 
774     }
775   xnee_verbose((xd, " <------- xnee_fake_relative_motion_event\n"));
776   return (XNEE_OK);
777 }
778 
779 int
xnee_type_file(xnee_data * xd)780 xnee_type_file(xnee_data *xd)
781 {
782   char tmp[256]="" ;
783   int i;
784   int mode=123;
785 
786   xnee_script_s xss;
787 
788   xnee_verbose ((xd,"---> xnee_type_file\n"));
789 
790   xnee_setup_display (xd);
791   xnee_replay_init (xd);
792 
793   xnee_verbose ((xd,"--- xnee_type_file\n"));
794 
795   if (!xnee_has_xtest_extension(xd))
796     {
797       return(XNEE_NO_TEST_EXT);
798     }
799 
800   xnee_verbose ((xd,"--- xnee_type_file\n"));
801 
802   while (fgets(tmp, 256, xd->rt_file)!=NULL)
803     {
804       xnee_verbose ((xd,"  xnee_type_file loop read size=" SIZE_T_PRINTF_FMT " \"%s\"\n",
805 	     strlen(tmp),tmp));
806 
807       for ( i=0 ; (size_t)i<strlen(tmp) ;  )
808 	{
809 	  if (xnee_check_key (xd)==XNEE_GRAB_DATA)
810 	    {
811 	      mode = xnee_handle_rec_key(xd);
812 	    }
813 
814 	  if (mode == XNEE_GRAB_RESUME )
815 	    {
816 	      mode = -1;
817 	      ;
818 	    }
819 	  else if (mode == XNEE_GRAB_PAUSE )
820 	    {
821 	      usleep(1000*200);
822 	    }
823 	  else if (mode == XNEE_GRAB_STOP )
824 	    {
825 	      return 0;
826 	    }
827 	  else
828 	    {
829 
830 
831 	      xnee_char2keycode(xd, tmp[i], &xss.kc);
832 
833 
834 	      xnee_verbose ((xd, "retyping key %c keycode %d\n",
835 			     tmp[i],xss.kc.kc));
836 
837 	      xnee_fake_key_mod_event (xd, &xss, XNEE_PRESS, 0);
838 
839 	      usleep ( 1000 * xnee_get_retype_press_delay(xd));
840 
841 	      xnee_fake_key_mod_event (xd, &xss, XNEE_RELEASE, 0);
842 	      usleep ( 1000 * xnee_get_retype_release_delay(xd));
843 
844 	      i++;
845 	    }
846 	}
847     }
848 
849   xnee_verbose ((xd,"<--- xnee_type_file\n"));
850   return (XNEE_OK);
851 }
852