模拟鼠标,按键代码

/* * * Copyright (c) 2002 Steve Slaven, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * */


#include <stdio.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#include "debug.h"

#define IS_CMD( x, y ) strncmp( x, y, strlen( y ) ) == 0

#include "kbd.h"

[comment]
/* Generates an X event, like keypress/mouseclick/move/etc like a little man in your computer. :) */


KeyCode thing_to_keycode( Display *d, char *thing )

{
  KeyCode kc;
  KeySym ks;
  
  ks = XStringToKeysym( thing );
  if( ks == NoSymbol ){
    fprintf( stderr, "Unable to resolve keysym for '%s'/n", thing );
    return( thing_to_keycode( d, "space" ) );
  }

  kc = XKeysymToKeycode( d, ks );
  dmsg( 1, "String '%s' maps to keysym '%d'/n", thing, ks );
  dmsg( 1, "String '%s' maps to keycode '%d'/n", thing, kc );

  return( kc );
}



void send_key( Display *d, char *thing )

{
  int probidx;
  char *wrap_key = NULL;

  dmsg( 1, "Sending key '%s'/n", thing );

  /* Catch some common problem characters (thanks Martin Pirker) */
  probidx = 0;
  while( problems[ probidx ] != NULL ) {
    if( strcmp( thing, problems[ probidx ] ) == 0 ) {
      wrap_key = problems[ probidx + 1 ];
      thing = problems[ probidx + 2 ];
    }
    probidx += 3;
  }

  if( wrap_key != NULL )
       XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), True, CurrentTime );
  XTestFakeKeyEvent( d, thing_to_keycode( d, thing ), True, CurrentTime );
  XTestFakeKeyEvent( d, thing_to_keycode( d, thing ), False, CurrentTime );
  if( wrap_key != NULL )
       XTestFakeKeyEvent( d, thing_to_keycode( d, wrap_key ), False, CurrentTime );
}



void mouse_click( Display *d, int button )

{
  dmsg( 1, "Clicking mouse button %d/n", button );
  XTestFakeButtonEvent( d, button, True, CurrentTime );
  XTestFakeButtonEvent( d, button, False, CurrentTime );
}



void mouse_move( Display *d, int x, int y )

{
  dmsg( 1, "Moving mouse to %d,%d/n", x, y );
  XTestFakeMotionEvent( d, -1, x, y, CurrentTime );
}



void mouse_rel_move( Display *d, int x, int y )

{
  dmsg( 1, "Moving mouse relatively by %d,%d/n", x, y );
  /* This does not match my docs... hrm... */
  XTestFakeRelativeMotionEvent( d, x, y, CurrentTime );
  /* Should include screen? XTestFakeRelativeMotionEvent( d, -1, x, y, CurrentTime ); */
}



void process_command( Display *d, const char *cmd )

{
  /* Process a command */
  int tmpx,tmpy;
  char str[ 128 ];

  bzero( str, 128 );
  if( IS_CMD( cmd, "mouseclick " ) ) {
    sscanf( cmd, "mouseclick %d", &tmpx );
    mouse_click( d, tmpx );
  }else if( IS_CMD( cmd, "key " ) ) {
    strncpy( str, &cmd[ 4 ], 128 );
    send_key( d, str );
  }else if( IS_CMD( cmd, "keydown " ) ) {
    strncpy( str, &cmd[ 8 ], 128 );
    XTestFakeKeyEvent( d, thing_to_keycode( d, str ), True, CurrentTime );
  }else if( IS_CMD( cmd, "keyup " ) ) {
    strncpy( str, &cmd[ 6 ], 128 );
    XTestFakeKeyEvent( d, thing_to_keycode( d, str ), False, CurrentTime );
  }else if( IS_CMD( cmd, "mousemove " ) ) {
    sscanf( cmd, "mousemove %d %d", &tmpx, &tmpy );
    mouse_move( d, tmpx, tmpy );
  }else if( IS_CMD( cmd, "mousermove " ) ) {
    sscanf( cmd, "mousermove %d %d", &tmpx, &tmpy );
    mouse_rel_move( d, tmpx, tmpy );
  }else if( IS_CMD( cmd, "sleep " ) ) {
    sscanf( cmd, "sleep %d", &tmpx );
    dmsg( 1, "sleep %d/n", tmpx );
    sleep( tmpx );
  }else if( IS_CMD( cmd, "usleep " ) ) {
    sscanf( cmd, "usleep %d", &tmpx );
    dmsg( 1, "usleep %d/n", tmpx );
    usleep( tmpx );
  }else if( IS_CMD( cmd, "mousedown " ) ) {
    sscanf( cmd, "mousedown %d", &tmpx );
    XTestFakeButtonEvent( d, tmpx, True, CurrentTime );
  }else if( IS_CMD( cmd, "mouseup " ) ) {
    sscanf( cmd, "mouseup %d", &tmpx );
    XTestFakeButtonEvent( d, tmpx, False, CurrentTime );
  }else if( IS_CMD( cmd, "str " ) ) {
    cmd += 4;
    while( cmd[ 0 ] != 0 ) {
      str[ 0 ] = cmd[ 0 ];
      send_key( d, str );
      cmd++;
    }
  }else{
    fprintf( stderr, "Unknown command '%s'/n", cmd );
  }

  XFlush( d );
}



int main( int argc, char *argv[] )

{
  Display *dpy = NULL;
  int cnt, tmp_i;
  char *buf, *display = NULL;
  int opt;
 
  while( ( opt = getopt( argc, argv, "hd:x:" ) ) != EOF ) {
    switch( opt ) {
    case 'h':
      printf( "xte v" VERSION "/n"
	      "Generates fake input using the XTest extension, more reliable than xse/n"
	      "Author: Steve Slaven - http://hoopajoo.net/n"
	      "Current keyboard map: " KBDMAP "/n"
	      "/n"
	      "usage: %s [-h] [-x display] [arg ..]/n"
	      "/n"
	      " -h this help/n"
	      " -x send commands to remote X server. Note that some commands/n"
	      " may not work correctly unless the display is on the console,/n"
	      " e.g. the display is currently controlled by the keyboard and/n"
	      " mouse and not in the background. This seems to be a limitation/n"
	      " of the XTest extension./n"
	      " arg args instructing the little man on what to do (see below)/n"
	      " if no args are passed, commands are read from stdin separated/n"
	      " by newlines, to allow a batch mode/n"
	      "/n"
	      " Commands:/n"
	      " key k Press and release key k/n"
	      " keydown k Press key k down/n"
	      " keyup k Release key k/n"
	      " str string Do a bunch of key X events for each char in string/n"
	      " mouseclick i Click mouse button i/n"
	      " mousemove x y Move mouse to screen position x,y/n"
	      " mousermove x y Move mouse relative from current location by x,y/n"
	      " mousedown i Press mouse button i down/n"
	      " mouseup i Release mouse button i/n"
	      " sleep x Sleep x seconds/n"
	      " usleep x uSleep x microseconds/n"
	      "/n"
	      "Some useful keys (case sensitive)/n"
	      " Home/n"
	      " Left/n"
	      " Up/n"
	      " Right/n"
	      " Down/n"
	      " Page_Up/n"
	      " Page_Down/n"
	      " End/n"
	      " Return/n"
	      " Backspace/n"
	      " Tab/n"
	      " Escape/n"
	      " Delete/n"
	      " Shift_L/n"
	      " Shift_R/n"
	      " Control_L/n"
	      " Control_R/n"
	      " Meta_L/n"
	      " Meta_R/n"
	      " Alt_L/n"
	      " Alt_R/n"
	      "/n"
	      "Sample, drag from 100,100 to 200,200 using mouse1:/n"
	      " xte 'mousemove 100 100' 'mousedown 1' 'mousemove 200 200' 'mouseup 1'/n"
	      "/n"
	      , argv[ 0 ] );
      exit( 0 );
      break;
      
    case 'd':
      sscanf( optarg, "%d", &tmp_i );
      dmsg( 2, "Debug set to %d/n", tmp_i );
      debug_level( tmp_i );
      break;
  
    case 'x':
      display = optarg;
      break;

    case '?':
      fprintf( stderr, "Unknown option '%c'/n", optopt );
      break;
      
    default:
      fprintf( stderr, "Unhandled option '%c'/n", opt );
      break;
    }
  }
  
  dpy = XOpenDisplay( display );
  if( dpy == NULL ) {
    fprintf( stderr, "Unable to open display '%s'/n", display == NULL ? "default" : display );
    exit( 1 );
  }

  if( argc - optind >= 1 ) {
    /* Arg mode */
    for( cnt = optind; cnt < argc; cnt++ ) {
      process_command( dpy, argv[ cnt ] );
    }
  }else{
    /* STDIN mode */
    buf = (char *)malloc( 128 );
    while( fgets( buf, 128, stdin ) ) {
      buf[ strlen( buf ) - 1 ] = 0; /* Chop /n */
      process_command( dpy, buf );
    }
  }
  
  XCloseDisplay( dpy );
  exit( 0 );
}

你可能感兴趣的:(代码)