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 * 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
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_time.h"
34 #include "libxnee/xnee_buffer.h"
35 #include "libxnee/xnee_resolution.h"
36 #include "libxnee/xnee_dl.h"
37
38
39
40
41 /**************************************************************
42 * *
43 * xnee_get_elapsed_time *
44 * *
45 * *
46 **************************************************************/
47 static unsigned long last_read_msecec = 0;
48 static unsigned long last_read_sec = 0;
49 static unsigned long first_read_msecec = 0;
50 static unsigned long first_read_sec = 0;
51
52
53 int
xnee_reset_elapsed_time(xnee_data * xd)54 xnee_reset_elapsed_time(xnee_data *xd)
55 {
56
57 xnee_verbose ((xd, " --- xnee_reset_elapsed_time \n"));
58
59 last_read_msecec = 0;
60 last_read_sec = 0;
61 first_read_msecec = 0;
62 first_read_sec = 0;
63 return XNEE_OK;
64 }
65
66
67 long
xnee_get_elapsed_time(xnee_data * xd,char type)68 xnee_get_elapsed_time(xnee_data *xd, char type )
69 {
70 long last_sec;
71 long last_msec;
72 long diff_sec;
73 long diff_msec;
74 long time_offset_msec = 0;
75
76 struct timeval cur_time;
77 struct timezone zoneData;
78
79 xnee_verbose ((xd, " --- xnee_get_elapsed_time\n"));
80
81
82 /* determine what value to get difference from */
83 if ( type == XNEE_FROM_LAST_READ )
84 {
85 last_sec = last_read_sec;
86 last_msec = last_read_msecec;
87 }
88 else
89 {
90 last_sec = first_read_sec;
91 last_msec = first_read_msecec;
92 }
93
94 /* get current time */
95 if( gettimeofday( &cur_time, &zoneData) == 0 )
96 {
97
98 /* get difference between now and last */
99 diff_sec = cur_time.tv_sec - last_sec;
100 diff_msec = (cur_time.tv_usec/1000) - last_msec;
101
102 /* convert diff to msec */
103 time_offset_msec = (diff_sec * XNEE_MSEC_PER_SEC) + diff_msec;
104
105
106 /* if first time through - save values and return XNEE_OK */
107 if ( last_sec == 0 )
108 {
109 last_read_msecec = cur_time.tv_usec/1000;
110 last_read_sec = cur_time.tv_sec;
111 first_read_msecec = cur_time.tv_usec/1000;
112 first_read_sec = cur_time.tv_sec;
113 /* xnee_verbose ((xd, "1st elapsed time:%c _sec _msec: %d %d timeoffeset = 0\n", */
114 /* type, cur_time.tv_sec, cur_time.tv_usec )); */
115 return XNEE_OK;
116 }
117
118 /* update last_read values with the new time */
119 if ( type == XNEE_FROM_LAST_READ )
120 {
121 last_read_msecec = cur_time.tv_usec/1000;
122 last_read_sec = cur_time.tv_sec;
123 }
124 /* xnee_verbose ((xd, "elapsed time type:%c current time _sec _msec: %d %d time_offset_msec: %d\n", */
125 /* type, cur_time.tv_sec, cur_time.tv_usec, time_offset_msec )); */
126 return time_offset_msec;
127 }
128
129
130
131 /* Shouldn't reach this point.... silent the compiler */
132 return 0;
133 }
134
135
136
137
138
139 /**************************************************************
140 * *
141 * xnee_calc_sleep_amount *
142 * *
143 * *
144 **************************************************************/
145 long
xnee_calc_sleep_amount(xnee_data * xd,unsigned long last_diff,unsigned long first_diff,unsigned long record_last_diff,unsigned long recordFirst_diff)146 xnee_calc_sleep_amount(xnee_data *xd,
147 unsigned long last_diff,
148 unsigned long first_diff,
149 unsigned long record_last_diff,
150 unsigned long recordFirst_diff )
151 {
152 /* Time sleep_amt; */
153 unsigned long out_of_wack_amt = 0;
154 int out_of_wack = 0;
155 float tmp;
156 float start_diff_percent ;
157 float compensation_factor ;
158 float sleep_amt ;
159 static unsigned long stored_recordFirst_diff;
160
161 xnee_verbose ((xd, "xnee_calc_sleep_amount last_diff: %lu first_diff: %lu record_last_diff:"
162 "%lu recordFirst_diff: %lu\n",
163 last_diff, first_diff, record_last_diff, recordFirst_diff ));
164
165 if ( stored_recordFirst_diff != 0 )
166 {
167 start_diff_percent = ((double)stored_recordFirst_diff / (double) first_diff);
168 if ( start_diff_percent < 0.99 )
169 {
170 if ( start_diff_percent < 0.70 )
171 {
172 compensation_factor=0.5;
173 }
174 else if ( start_diff_percent < 0.80 )
175 {
176 compensation_factor=0.8;
177 }
178 else
179 {
180 compensation_factor=0.9;
181 }
182 }
183 else if ( start_diff_percent > 1.01 )
184 {
185 if ( start_diff_percent > 1.3 )
186 {
187 compensation_factor=1.5;
188 }
189 else if ( start_diff_percent > 1.2 )
190 {
191 compensation_factor=1.2;
192 }
193 else
194 {
195 compensation_factor=1.1;
196 }
197 }
198 else
199 {
200 compensation_factor=1.0;
201 }
202 }
203 else
204 {
205 compensation_factor=1.0;
206 }
207 /* compensation_factor=1.0; */
208
209 sleep_amt= (record_last_diff*compensation_factor);
210
211 if (sleep_amt > 5.0)
212 {
213 sleep_amt = sleep_amt - 1.0;
214 }
215
216 stored_recordFirst_diff = recordFirst_diff;
217 return ( sleep_amt );
218
219 /* printf ("\n\t%d compensation: %f \n\n", record_last_diff, compensation_factor); */
220 return record_last_diff*compensation_factor;
221
222 /* determine where we are from first read
223 * either too fast or too slow */
224 if (recordFirst_diff > first_diff)
225 {
226 out_of_wack=1;
227 }
228 else if (recordFirst_diff < first_diff)
229 {
230 out_of_wack=-1;
231 }
232 /* else we keep =0 */
233
234
235
236 if ( out_of_wack==1 )
237 {
238
239 xnee_verbose (( xd, "xnee_calc_sleep_amount: too fast\n" ));
240 /* too fast - we should slow down a bit */
241 if ( record_last_diff > last_diff )
242 {
243 xnee_verbose (( xd, "xnee_calc_sleep_amount: too fast 1\n" ));
244 /* recorded wait more than we have waited so far */
245
246 /* find amount that we are too fast or too slow */
247 out_of_wack_amt = recordFirst_diff - first_diff;
248
249 /* if the amount we are out of wack is more than the recorded wait */
250 /* then sleep the full recorded difference */
251 if ( out_of_wack_amt > record_last_diff )
252 {
253 xnee_verbose (( xd, "xnee_calc_sleep_amount: 1.1\n" ));
254 // sleep_amt = record_last_diff;
255 sleep_amt = out_of_wack_amt ;
256 }
257 else
258 {
259 xnee_verbose (( xd, "xnee_calc_sleep_amount: 1.2\n" ));
260 /* otherwise sleep the amount out of wack */
261 sleep_amt = out_of_wack_amt;
262 }
263 }
264 else
265 {
266 xnee_verbose (( xd, "xnee_calc_sleep_amount: too fast 2 \n" ));
267 /* we have already waited the recorded amount of time */
268 /* but since we are still too fast -
269 sleep a percentage of recorded wait time */
270 tmp = (float)record_last_diff * XNEE_TOO_FAST_ADJ_PERCENTAGE/100;
271 sleep_amt = ( long ) tmp;
272 }
273 }
274 else if ( out_of_wack == -1 )
275 {
276 xnee_verbose (( xd, "xnee_calc_sleep_amount: too slown" ));
277 if ( record_last_diff > last_diff )
278 {
279 /* recorded wait more than we have waited so far */
280 /* amount of wait left */
281 sleep_amt = (record_last_diff - last_diff) / 8 ;
282 }
283 else
284 {
285 /* we have already waited the recorded amount of time */
286 sleep_amt = 0;
287 }
288 }
289 else
290 {
291 xnee_verbose (( xd, "xnee_calc_sleep_amount: on time\n" ));
292 sleep_amt=2;
293 }
294
295 xnee_verbose (( xd, "xnee_calc_sleep_amount: %d\n", (int)sleep_amt ));
296 return ( sleep_amt );
297 }
298
299
300
301
302 /**************************************************************
303 * *
304 * xnee_calc_sleep_amount *
305 * *
306 * *
307 **************************************************************/
308 long
xnee_calc_sleep_amount_slow(xnee_data * xd,unsigned long last_diff,unsigned long first_diff,unsigned long record_last_diff,unsigned long recordFirst_diff)309 xnee_calc_sleep_amount_slow(xnee_data *xd,
310 unsigned long last_diff,
311 unsigned long first_diff,
312 unsigned long record_last_diff,
313 unsigned long recordFirst_diff )
314 {
315 Time sleep_amt;
316 unsigned long out_of_wack_amt = 0;
317 int out_of_wack = 0;
318 float tmp;
319
320
321 recordFirst_diff =
322 recordFirst_diff * xnee_get_speed(xd) / 100;
323 record_last_diff =
324 record_last_diff * xnee_get_speed(xd) / 100;
325
326 xnee_verbose ((xd, "xnee_calc_sleep_amount_slow last_diff: %lu first_diff: %lu record_last_diff: %lu recordFirst_diff: %lu\n",
327 last_diff, first_diff, record_last_diff, recordFirst_diff ));
328 /* printf ("xnee_calc_sleep_amount last_diff: %lu first_diff: %lu record_last_diff: %lu recordFirst_diff: %lu\t", */
329 /* last_diff, first_diff, record_last_diff, recordFirst_diff ); */
330
331
332 /* determine where we are from first read
333 * either too fast or too slow */
334 if (recordFirst_diff > first_diff)
335 {
336 out_of_wack=1;
337 }
338 else if (recordFirst_diff < first_diff)
339 {
340 out_of_wack=-1;
341 }
342 /* else we keep =0 */
343
344
345
346 if ( out_of_wack==1 )
347 {
348 /* too fast - we should slow down a bit */
349 if ( record_last_diff > last_diff )
350 {
351 /* recorded wait more than we have waited so far */
352
353 /* find amount that we are too fast or too slow */
354 out_of_wack_amt = recordFirst_diff - first_diff;
355
356 /* if the amount we are out of wack is more than the recorded wait */
357 /* then sleep the full recorded difference */
358 if ( out_of_wack_amt > record_last_diff )
359 {
360 sleep_amt = record_last_diff;
361 }
362 else
363 {
364 /* otherwise sleep the amount out of wack */
365 sleep_amt = out_of_wack_amt;
366 }
367 }
368 else
369 {
370 /* we have already waited the recorded amount of time */
371 /* but since we are still too fast -
372 sleep a percentage of recorded wait time */
373 tmp = (float)record_last_diff * XNEE_TOO_FAST_ADJ_PERCENTAGE/100;
374 sleep_amt = ( long ) tmp;
375 }
376 }
377 else if ( out_of_wack == -1 )
378 {
379 if ( record_last_diff > last_diff )
380 {
381 /* recorded wait more than we have waited so far */
382 /* amount of wait left */
383 sleep_amt = (record_last_diff - last_diff) / 8 ;
384 }
385 else
386 {
387 /* we have already waited the recorded amount of time */
388 sleep_amt = 0;
389 }
390 }
391 else
392 {
393 sleep_amt=0;
394 }
395
396 /* printf ("xnee_calc_sleep_amount: %d\n", (int)sleep_amt); */
397 xnee_verbose (( xd, "xnee_calc_sleep_amount: %d\n", (int)sleep_amt ));
398
399 return ( sleep_amt );
400
401 }
402
403
404
405
406
407 /**************************************************************
408 * *
409 * xnee_calc_sleep_amount *
410 * *
411 * *
412 **************************************************************/
413 long
xnee_calc_sleep_amount_fast(xnee_data * xd,unsigned long last_diff,unsigned long first_diff,unsigned long record_last_diff,unsigned long recordFirst_diff)414 xnee_calc_sleep_amount_fast(xnee_data *xd,
415 unsigned long last_diff,
416 unsigned long first_diff,
417 unsigned long record_last_diff,
418 unsigned long recordFirst_diff )
419 {
420 Time sleep_amt;
421 unsigned long out_of_wack_amt = 0;
422 int out_of_wack = 0;
423
424 recordFirst_diff =
425 recordFirst_diff * xnee_get_speed(xd) / 100;
426 record_last_diff =
427 record_last_diff * xnee_get_speed(xd) / 100;
428
429
430 /* determine where we are from first read
431 * either too fast or too slow */
432 if (recordFirst_diff > first_diff)
433 {
434 out_of_wack=1;
435 }
436 else if (recordFirst_diff < first_diff)
437 {
438 out_of_wack=-1;
439 }
440 /* else we keep =0 */
441
442
443
444 if ( out_of_wack==1 )
445 {
446 /* too fast - we should slow down a bit */
447 if ( record_last_diff > last_diff )
448 {
449 /* recorded wait more than we have waited so far */
450
451 /* find amount that we are too fast or too slow */
452 out_of_wack_amt = recordFirst_diff - first_diff;
453
454 /* if the amount we are out of wack is more than the
455 * recorded wait then sleep the full recorded difference */
456 if ( out_of_wack_amt > record_last_diff )
457 {
458 sleep_amt = record_last_diff ;
459 }
460 else
461 {
462 /* otherwise sleep the amount out of wack */
463 sleep_amt = out_of_wack_amt;
464 }
465 }
466 else
467 {
468 /* we have already waited the recorded amount of time */
469 /* but since we are still too fast -
470 sleep a percentage of recorded wait time */
471 sleep_amt = record_last_diff ;
472 }
473 }
474 else if ( out_of_wack == -1 )
475 {
476
477
478 /* we have already waited the recorded amount of time */
479 sleep_amt = 10;
480 }
481 else
482 {
483 /* right on time */
484 sleep_amt=0;
485 }
486 xnee_verbose (( xd, "xnee_calc_sleep_amount: %d\n", (int)sleep_amt ));
487
488 return ( sleep_amt );
489 }
490
491
492
493
494