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