📄 xtest1dd.c
字号:
static voidparse_motion_fake(fmotion)XTestMotionInfo *fmotion;{ int dx; int dy; dx = (XTestUnpackXMotionValue(fmotion->motion_data)); dy = (XTestUnpackYMotionValue(fmotion->motion_data)); if (((fmotion->header) & XTestX_SIGN_BIT_MASK) == XTestX_NEGATIVE) { pmousex -= dx; } else { pmousex += dx; } if (((fmotion->header) & XTestY_SIGN_BIT_MASK) == XTestY_NEGATIVE) { pmousey -= dy; } else { pmousey += dy; } action_array[write_index].type = XTestJUMP_ACTION; action_array[write_index].device = XTestUnpackDeviceID(fmotion->header); action_array[write_index].x = pmousex; action_array[write_index].y = pmousey; action_array[write_index].delay_time = fmotion->delay_time; write_index++;}/****************************************************************************** * * parse_jump_fake * * Called from parse_fake_input. * * Copy the fake jump input action from its packed form into the array of * pending input events. */static voidparse_jump_fake(fjump)XTestJumpInfo *fjump;{ pmousex = fjump->jumpx; pmousey = fjump->jumpy; action_array[write_index].type = XTestJUMP_ACTION; action_array[write_index].device = XTestUnpackDeviceID(fjump->header); action_array[write_index].x = pmousex; action_array[write_index].y = pmousey; action_array[write_index].delay_time = fjump->delay_time; write_index++;}/****************************************************************************** * * parse_delay_fake * * Called from parse_fake_input. * * Copy the fake delay input action from its packed form into the array of * pending input events. */static voidparse_delay_fake(tevent)XTestDelayInfo *tevent;{ action_array[write_index].type = XTestDELAY_ACTION; action_array[write_index].delay_time = tevent->delay_time; write_index++;}/****************************************************************************** * * XTestComputeWaitTime * * Compute the amount of time the server should wait before sending the * next monitor event in playback mode. */voidXTestComputeWaitTime(waittime)struct timeval *waittime;{ /* * The playback_on flag is set to 1 in parse_fake_input. It is set to * 0 in XTestProcessInputAction if the server has replayed all input * actions. */ if (playback_on) { if (!play_clock) { /* * if the playback clock has never been set, * then do it now */ start_play_clock(); } /* * We need to save the waittime the first time through. This * is a value the server uses, and we have to restore it when * all of the input actions are processed by the server. */ if (!time_saved) { saved_sec = waittime->tv_sec; saved_usec = waittime->tv_usec; time_saved = 1; } if (go_for_next) { /* * if we just processed an input action, figure out * how long to wait for the next input action */ compute_action_time(&rtime); } else { /* * else just find out how much more time to wait * on the current input action */ (void)find_residual_time(&rtime); } waittime->tv_sec = rtime.tv_sec; waittime->tv_usec = rtime.tv_usec; }}/****************************************************************************** * * XTestProcessInputAction * * If there are any input actions in the input action array, * then take one out and process it. * */intXTestProcessInputAction(readable, waittime)/* * This is the value that a 'select' function returned just before this * routine was called. If the select timed out, this value will be 0. * * This extension modifies the select call's timeout value to cause the * select to time out when the next input action is ready to given to * the server. This routine is called immediately after the select, to * give it a chance to process an input action. If we have an input action * to process and the only reason that the select returned was because it * timed out, then we change the select value to 1 and return 1 instead of 0. */int readable;/* * this is the timeout value that the select was called with */struct timeval *waittime;{ int mousex, mousey; /* * if playback_on is 0, then the input action array is empty */ if (playback_on) { restorewait = waittime; /* * figure out if we need to wait for the next input action */ if (find_residual_time(&rtime) > 0) { /* * still have to wait before processing the current * input action */ go_for_next = 0; } else { /* * don't have to wait any longer before processing * the current input action */ go_for_next = 1; } /* * if we have an input action to process and the only reason * that the select returned was because it timed out, then we * change the select value to 1 and return 1 instead of 0 */ if (readable == 0) { readable++; } /* * if we don't need to wait, then get an input action from * the input action array and process it */ if (go_for_next) { /* * There are three possible types of input actions in * the input action array (motion input actions are * converted to jump input actions before being put * into the input action array). Delay input actions * are processed by the compute_action_time function * which is called from XTestComputeWaitTime. The * other two types of input actions are processed here. */ if (action_array[read_index].type == XTestJUMP_ACTION) { XTestJumpPointer( action_array[read_index].x, action_array[read_index].y, action_array[read_index].device); mx = action_array[read_index].x; my = action_array[read_index].y; } if (action_array[read_index].type == XTestKEY_ACTION) { GetSpritePosition(&mousex, &mousey); XTestGenerateEvent( action_array[read_index].device, action_array[read_index].keycode, action_array[read_index].keystate, mousex, mousey); } read_index++; /* * if all input actions are processed, then restore * the server state */ if (read_index >= write_index) { waittime->tv_sec = saved_sec; waittime->tv_usec = saved_usec; time_saved = 0; playback_on = 0; if (acknowledge) { /* * if the playback client is waiting * for an xTestFakeAck event, send * it to him */ send_ack(playback_client); acknowledge = 0; } write_index = 0; read_index = 0; playback_client = (ClientPtr) NULL; play_clock = 0; } } } return(readable);}/****************************************************************************** * * send_ack * * send an xTestFakeAck event to the client */static voidsend_ack(client)ClientPtr client;{ xTestFakeAckEvent rep; /* * set the serial number of the xTestFakeAck event */ rep.sequenceNumber = client->sequence; rep.type = XTestFakeAckType; WriteEventsToClient(client, 1, (xEvent *) &rep); } /****************************************************************************** * * start_play_clock * * start the clock for play back. */static voidstart_play_clock(){ X_GETTIMEOFDAY(&play_time); /* * flag that play_time is valid */ play_clock = 1;}/****************************************************************************** * * compute_action_time * * Set the play clock to the time when the next input action should be put * into the server's input queue. Fill the rtime structure with values * for the delta until the time for the next input action. */static voidcompute_action_time(rtime)struct timeval *rtime;{ /* * holds the delay time in milliseconds */ unsigned long dtime; /* * holds the number of microseconds in the sum of the dtime value * and the play_time value */ unsigned long tot_usec; /* * holds the number of seconds and microseconds in the * dtime value */ unsigned long sec; unsigned long usec; /* * holds the current time */ struct timeval btime; /* * Put the time from the current input action in dtime */ dtime = action_array[read_index].delay_time; /* * If the current input action is a delay input action, * add in the time from the following input action. */ if ((action_array[read_index].type == XTestDELAY_ACTION) && ((read_index + 1) < write_index)) { read_index++; dtime = dtime + action_array[read_index].delay_time; } /* * compute the number of seconds and microseconds in the * dtime value */ sec = dtime / 1000; usec = (dtime % 1000) * 1000; /* * get the current time in btime */ X_GETTIMEOFDAY(&btime); /* * compute the number of microseconds in the sum of the dtime value * and the current usec value */ tot_usec = btime.tv_usec + usec; /* * if it is greater than one second's worth, adjust the seconds */ if (tot_usec >= 1000000) { tot_usec -= 1000000; sec++; } play_time.tv_usec = tot_usec; play_time.tv_sec = btime.tv_sec + sec; /* * put the time until the next input action in rtime */ rtime->tv_sec = sec; rtime->tv_usec = usec;}/****************************************************************************** * * find_residual_time * * Find the time interval from the current time to the value in play_time. * This is the time to wait till putting the next input action into the * server's input queue. If the time is already up, reset play_time to * the current time. */static intfind_residual_time(the_residual)struct timeval *the_residual;{ /* * if > 0, there is time to wait. If < 0, then don't wait */ int wait = 1; /* * holds the current time */ struct timeval btime; /* * holds the current time in seconds and microseconds */ unsigned long bsec; unsigned long busec; /* * holds the playback time in seconds and microseconds */ unsigned long psec; unsigned long pusec; /* * get the current time in btime */ X_GETTIMEOFDAY(&btime); /* * get the current time in seconds and microseconds */ bsec = btime.tv_sec; busec = btime.tv_usec; /* * get the playback time in seconds and microseconds */ psec = play_time.tv_sec; pusec = play_time.tv_usec; /* * if the current time is already later than the playback time, * we don't need to wait */ if (bsec > psec) { wait = -1; } else { if (bsec == psec) { /* * if the current and playback times have the same * second value, then compare the microsecond values */ if ( busec >= pusec) { /* * if the current time is already later than * the playback time, we don't need to wait */ wait = -1; } else { the_residual->tv_usec = pusec - busec; the_residual->tv_sec = 0; } } else { if (busec > pusec) { /* * 'borrow' a second's worth of microseconds * from the seconds left to wait */ the_residual->tv_usec = 1000000 - busec + pusec; psec--; the_residual->tv_sec = psec - bsec; } else { the_residual->tv_sec = psec - bsec; the_residual->tv_usec = pusec - busec; } } } if (wait < 0) { /* * if don't need to wait, set the playback time * to the current time */ X_GETTIMEOFDAY(&play_time); /* * set the time to wait to 0 */ the_residual->tv_sec = 0; the_residual->tv_usec = 0; } return(wait);} /****************************************************************************** * * abort_play_back */voidabort_play_back(){ /* * If we were playing back input actions at the time of the abort, * restore the original wait time for the select in the main wait * loop of the server */ if (playback_on) { restorewait->tv_sec = saved_sec; restorewait->tv_usec = saved_usec; } /* * make the input action array empty */ read_index = 0; write_index = 0; /* * we are no longer playing back anything */ playback_on = 0; play_clock = 0; go_for_next = 1; /* * there is no valid wait time saved any more */ time_saved = 0; /* * there are no valid clients using this extension */ playback_client = (ClientPtr) NULL; current_xtest_client = (ClientPtr) NULL;}/****************************************************************************** * * return_input_array_size * * Return the number of input actions in the input action array. */voidreturn_input_array_size(client)/* * which client to send the reply to */ClientPtr client;{ xTestQueryInputSizeReply rep; rep.type = X_Reply; /* * set the serial number of the reply */ rep.sequenceNumber = client->sequence; rep.length = 0; rep.size_return = ACTION_ARRAY_SIZE; WriteReplyToClient(client, sizeof(xTestQueryInputSizeReply), (pointer) &rep); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -