Esempio n. 1
0
int cmd_mousemove_relative(context_t *context) {
  int x, y;
  int ret = 0;
  char *cmd = *context->argv;
  int polar_coordinates = 0;
  int clear_modifiers = 0;
  int opsync = 0;
  int origin_x = -1, origin_y = -1;

  xdo_active_mods_t *active_mods = NULL;
  int c;
  typedef enum {
    opt_unused, opt_help, opt_sync, opt_clearmodifiers, opt_polar
  } optlist_t;
  static struct option longopts[] = {
    { "help", no_argument, NULL, opt_help },
    { "sync", no_argument, NULL, opt_sync },
    { "polar", no_argument, NULL, opt_polar },
    { "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
    { 0, 0, 0, 0 },
  };
  static const char *usage =
      "Usage: %s [options] <x> <y>\n"
      "-c, --clearmodifiers      - reset active modifiers (alt, etc) while typing\n"
      "-p, --polar               - Use polar coordinates. X as an angle, Y as distance\n"
      "--sync                    - only exit once the mouse has moved\n"
      "\n"
      "Using polar coordinate mode makes 'x' the angle (in degrees) and\n"
      "'y' the distance.\n"
      "\n"
      "If you want to use negative numbers for a coordinate, you'll need to\n"
      "invoke it this way (with the '--'):\n"
      "   %s -- -20 -15\n"
      "otherwise, normal usage looks like this:\n"
      "   %s 100 140\n";
  int option_index;

  while ((c = getopt_long_only(context->argc, context->argv, "+cph",
                               longopts, &option_index)) != -1) {
    switch (c) {
      case 'h':
      case opt_help:
        printf(usage, cmd, cmd, cmd);
        consume_args(context, context->argc);
        return EXIT_SUCCESS;
        break;
      case 'p':
      case opt_polar:
        polar_coordinates = 1;
        break;
      case opt_sync:
        opsync = 1;
        break;
      case 'c':
      case opt_clearmodifiers:
        clear_modifiers = 1;
        break;
      default:
        fprintf(stderr, usage, cmd, cmd, cmd);
        return EXIT_FAILURE;
    }
  }

  consume_args(context, optind);

  if (context->argc < 2) {
    fprintf(stderr, usage, cmd, cmd, cmd);
    fprintf(stderr, "You specified the wrong number of args (expected 2).\n");
    return EXIT_FAILURE;
  }

  x = atoi(context->argv[0]);
  y = atoi(context->argv[1]);
  consume_args(context, 2);

  /* Quit early if we don't have to move. */
  if (x == 0 && y == 0) {
    return EXIT_SUCCESS;
  }

  if (polar_coordinates) {
    /* The original request for polar support was that '0' degrees is up
     * and that rotation was clockwise, so 0 is up, 90 right, 180 down, 270
     * left. This conversion can be done with (360 - degrees) + 90 */
    double radians = ((360 - x) + 90) * (M_PI / 180);
    double distance = y;
    x = (cos(radians) * distance);

    /* Negative sin, since screen Y coordinates are descending, where cartesian
     * is ascending */
    y = (-sin(radians) * distance);
  }
 
  if (clear_modifiers) {
    active_mods = xdo_get_active_modifiers(context->xdo);
    xdo_clear_active_modifiers(context->xdo, CURRENTWINDOW, active_mods);
  }

  if (opsync) {
    xdo_mouselocation(context->xdo, &origin_x, &origin_y, NULL);
  }

  ret = xdo_mousemove_relative(context->xdo, x, y);

  if (ret) {
    fprintf(stderr, "xdo_mousemove_relative reported an error\n");
  } else {
    if (opsync) {
      /* Wait until the mouse moves away from its current position */
      xdo_mouse_wait_for_move_from(context->xdo, origin_x, origin_y);
    }
  }

  if (clear_modifiers) {
    xdo_set_active_modifiers(context->xdo, CURRENTWINDOW, active_mods);
    xdo_free_active_modifiers(active_mods);
  }

  return ret;
}
Esempio n. 2
0
int cmd_key(context_t *context) {
  int ret = 0;
  int i, j;
  int c;
  char *cmd = *context->argv;
  charcodemap_t *active_mods = NULL;
  int active_mods_n;
  useconds_t key_delay = 12000;
  useconds_t repeat_delay = 0;
  int repeat = 1;
  const char *window_arg = NULL;
  int free_arg = 0;

  /* Options */
  int clear_modifiers = 0;

  static struct option longopts[] = {
    { "clearmodifiers", no_argument, NULL, 'c' },
    { "delay", required_argument, NULL, 'd' },
    { "repeat-delay", required_argument, NULL, 'R' },
    { "help", no_argument, NULL, 'h' },
    { "window", required_argument, NULL, 'w' },
    { "repeat", required_argument, NULL, 'r' },
    { 0, 0, 0, 0 },
  };

  static const char *usage = 
     "Usage: %s [options] <keysequence> [keysequence ...]\n"
     "--clearmodifiers     - clear active keyboard modifiers during keystrokes\n"
     "--delay DELAY        - Use DELAY milliseconds between keystrokes\n"
     "--repeat TIMES       - How many times to repeat the key sequence\n"
     "--repeat-delay DELAY - DELAY milliseconds between repetitions\n"
     "--window WINDOW      - send keystrokes to a specific window\n"
     "Each keysequence can be any number of modifiers and keys, separated by plus (+)\n"
     "  For example: alt+r\n"
     "\n"
     "Any letter or key symbol such as Shift_L, Return, Dollar, a, space are valid,\n"
     "including those not currently available on your keyboard.\n"
     "\n"
     "If no window is given, and there are windows in the stack, %1 is used. Otherwise\n"
     "the currently-focused window is used\n"
     HELP_CHAINING_ENDS;
  int option_index;

  while ((c = getopt_long_only(context->argc, context->argv, "+d:hcw:",
                               longopts, &option_index)) != -1) {
    switch (c) {
      case 'w':
        window_arg = strdup(optarg);
        free_arg = 1;
        break;
      case 'c':
        clear_modifiers = 1;
        break;
      case 'h':
        printf(usage, cmd);
        consume_args(context, context->argc);
        return EXIT_SUCCESS;
        break;
      case 'd':
        /* Argument is in milliseconds, keysequence delay is in microseconds. */
        key_delay = strtoul(optarg, NULL, 0) * 1000;
        break;
      case 'r':
        repeat = atoi(optarg);
        if (repeat < 1) {
          fprintf(stderr, "Invalid '--repeat' value given: %s\n", optarg);
          return EXIT_FAILURE;
        }
        break;
      case 'R': // --repeat-delay
        /* Argument is in milliseconds, keysequence delay is in microseconds. */
        repeat_delay = strtoul(optarg, NULL, 0) * 1000;
        break;
      default:
        fprintf(stderr, usage, cmd);
        return EXIT_FAILURE;
    }
  }

  consume_args(context, optind);

  if (context->argc == 0) {
    fprintf(stderr, "You specified the wrong number of args.\n");
    fprintf(stderr, usage, cmd);
    return 1;
  }

  /* use %1 if there is a window stack */
  if (window_arg == NULL && context->nwindows > 0) {
    window_arg = "%1";
  }

  int (*keyfunc)(const xdo_t *, Window, const char *, useconds_t) = NULL;

  if (!strcmp(cmd, "key")) {
    keyfunc = xdo_send_keysequence_window;
  } else if (!strcmp(cmd, "keyup")) {
    keyfunc = xdo_send_keysequence_window_up;
  } else if (!strcmp(cmd, "keydown")) {
    keyfunc = xdo_send_keysequence_window_down;
  } else {
    fprintf(stderr, "Unknown command '%s'\n", cmd);
    return 1;
  }

  int max_arg = context->argc;
  window_each(context, window_arg, {
    if (clear_modifiers) {
      xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
      xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
    }

    for (j = 0; j < repeat; j++) {
      for (i = 0; i < context->argc; i++) {
        if (is_command(context->argv[i])) {
          max_arg = i;
          break;
        }
        int tmp = keyfunc(context->xdo, window, context->argv[i], key_delay);
        if (tmp != 0) {
          fprintf(stderr,
                  "xdo_send_keysequence_window reported an error for string '%s'\n",
                  context->argv[i]);
        }
        ret += tmp;
      } /* each keysequence */

      /* Sleep if --repeat-delay given and not on the last repetition */
      if (repeat_delay > 0 && j < (repeat-1))  {
        usleep(repeat_delay);
      }
    } /* repeat */

    if (clear_modifiers) {
      xdo_set_active_modifiers(context->xdo, window, active_mods, active_mods_n);
      free(active_mods);
    }
  }); /* window_each(...) */
Esempio n. 3
0
int cmd_type(int argc, char **args) {
  int ret = 0;
  int i;
  int c;
  char *cmd = *args;
  xdo_active_mods_t *active_mods = NULL;

  /* Options */
  int clear_modifiers = 0;
  Window window = 0;
  useconds_t delay = 12000; /* 12ms between keystrokes default */

  struct option longopts[] = {
    { "clearmodifiers", no_argument, NULL, 'c' },
    { "delay", required_argument, NULL, 'd' },
    { "help", no_argument, NULL, 'h' },
    { "window", required_argument, NULL, 'w' },
    { 0, 0, 0, 0 },
  };

  static const char *usage =
            "Usage: %s [--window windowid] [--delay milliseconds] "
            "<things to type>\n"
            "--window <windowid>    - specify a window to send keys to\n"
            "--delay <milliseconds> - delay between keystrokes\n"
            "--clearmodifiers       - reset active modifiers (alt, etc) while typing\n"
            "-h, --help             - show this help output\n";
  int option_index;

  while ((c = getopt_long_only(argc, args, "w:d:ch", longopts, &option_index)) != -1) {
    switch (c) {
      case 'w':
        window = strtoul(optarg, NULL, 0);
        break;
      case 'd':
        /* --delay is in milliseconds, convert to microseconds */
        delay = strtoul(optarg, NULL, 0) * 1000;
        break;
      case 'c':
        clear_modifiers = 1;
        break;
      case 'h':
        printf(usage, cmd);
        return EXIT_SUCCESS;
        break;
      default:
        fprintf(stderr, usage, cmd);
        return EXIT_FAILURE;
    }
  }

  args += optind;
  argc -= optind;

  if (argc == 0) {
    fprintf(stderr, "You specified the wrong number of args.\n");
    fprintf(stderr, usage, cmd);
    return 1;
  }

  if (clear_modifiers) {
    active_mods = xdo_get_active_modifiers(xdo);
    xdo_clear_active_modifiers(xdo, window, active_mods);
  }

  for (i = 0; i < argc; i++) {
    int tmp = xdo_type(xdo, window, args[i], delay);

    if (tmp) {
      fprintf(stderr, "xdo_type reported an error\n");
    }

    ret += tmp;
  }

  if (clear_modifiers) {
    xdo_set_active_modifiers(xdo, window, active_mods);
    xdo_free_active_modifiers(active_mods);
  }

  return ret > 0;
}
Esempio n. 4
0
int cmd_type(context_t *context) {
  int ret = 0;
  int i;
  int c;
  char *cmd = *context->argv;
  char *window_arg = NULL;
  int arity = -1;
  char *terminator = NULL;
  char *file = NULL;

  FILE *input = NULL;
  char *buffer = NULL;
  char *marker = NULL;
  size_t bytes_read = 0;

  char **data = NULL; /* stuff to type */
  int data_count = 0;
  int args_count = 0;
  charcodemap_t *active_mods = NULL;
  int active_mods_n;

  /* Options */
  int clear_modifiers = 0;
  useconds_t delay = 12000; /* 12ms between keystrokes default */

  typedef enum {
    opt_unused, opt_clearmodifiers, opt_delay, opt_help, opt_window, opt_args,
    opt_terminator, opt_file
  } optlist_t;

  struct option longopts[] = {
    { "clearmodifiers", no_argument, NULL, opt_clearmodifiers },
    { "delay", required_argument, NULL, opt_delay },
    { "help", no_argument, NULL, opt_help },
    { "window", required_argument, NULL, opt_window },
    { "args", required_argument, NULL, opt_args },
    { "terminator", required_argument, NULL, opt_terminator },
    { "file", required_argument, NULL, opt_file },
    { 0, 0, 0, 0 },
  };

  static const char *usage =
    "Usage: %s [--window windowid] [--delay milliseconds] "
    "<things to type>\n"
    "--window <windowid>    - specify a window to send keys to\n"
    "--delay <milliseconds> - delay between keystrokes\n"
    "--clearmodifiers       - reset active modifiers (alt, etc) while typing\n"
    "--args N  - how many arguments to expect in the exec command. This is\n"
    "            useful for ending an exec and continuing with more xdotool\n"
    "            commands\n"
    "--terminator TERM - similar to --args, specifies a terminator that\n"
    "                    marks the end of 'exec' arguments. This is useful\n"
    "                    for continuing with more xdotool commands.\n"
    "--file <filepath> - specify a file, the contents of which will be\n"
    "                    be typed as if passed as an argument. The filepath\n"
    "                    may also be '-' to read from stdin.\n"
            "-h, --help             - show this help output\n";
  int option_index;

  while ((c = getopt_long_only(context->argc, context->argv, "+w:d:ch",
                               longopts, &option_index)) != -1) {
    switch (c) {
      case opt_window:
        window_arg = strdup(optarg);
        break;
      case opt_delay:
        /* --delay is in milliseconds, convert to microseconds */
        delay = strtoul(optarg, NULL, 0) * 1000;
        break;
      case opt_clearmodifiers:
        clear_modifiers = 1;
        break;
      case opt_help:
        printf(usage, cmd);
        consume_args(context, context->argc);
        return EXIT_SUCCESS;
        break;
      case opt_args:
        arity = atoi(optarg);
        break;
      case opt_terminator:
        terminator = strdup(optarg);
        break;
      case opt_file:
	file = strdup(optarg);
	break;
      default:
        fprintf(stderr, usage, cmd);
        return EXIT_FAILURE;
    }
  }

  consume_args(context, optind);

  if (context->argc == 0 && file == NULL) {
    fprintf(stderr, "You specified the wrong number of args.\n");
    fprintf(stderr, usage, cmd);
    return 1;
  }

  if (arity > 0 && terminator != NULL) {
    fprintf(stderr, "Don't use both --terminator and --args.\n");
    return EXIT_FAILURE;
  }

  if (context->argc < arity) {
    fprintf(stderr, "You said '--args %d' but only gave %d arguments.\n",
            arity, context->argc);
    return EXIT_FAILURE;
  }

  if (file != NULL) {
    data = calloc(1 + context->argc, sizeof(char *));

    /* determine whether reading from a file or from stdin */
    if (!strcmp(file, "-")) {
      input = fdopen(0, "r");
    } else {
      input = fopen(file, "r");
      if (input == NULL) {
        fprintf(stderr, "Failure opening '%s': %s\n", file, strerror(errno));
        return EXIT_FAILURE;
      }
    }

    while (feof(input) == 0) {
      marker = realloc(buffer, bytes_read + 4096);
      if (marker == NULL) {
        fprintf(stderr, "Failure allocating for '%s': %s\n", file, strerror(errno));
        return EXIT_FAILURE;
      }

      buffer = marker;
      marker = buffer + bytes_read;
      if (fgets(marker, 4096, input) != NULL) {
        bytes_read = (marker - buffer) + strlen(marker);
      }

      if (ferror(input) != 0) {
        fprintf(stderr, "Failure reading '%s': %s\n", file, strerror(errno));
        return EXIT_FAILURE;
      }
    }

    data[0] = buffer;
    data_count++;

    fclose(input);
  }
  else {
    data = calloc(context->argc, sizeof(char *));
  }

  /* Apply any --arity or --terminator */
  for (i=0; i < context->argc; i++) {
    if (arity > 0 && i == arity) {
      data[data_count] = NULL;
      break;
    }

    /* if we have a terminator and the current argument matches it... */
    if (terminator != NULL && strcmp(terminator, context->argv[i]) == 0) {
      data[data_count] = NULL;
      args_count++; /* Consume the terminator, too */
      break;
    }

    data[data_count] = strdup(context->argv[i]);
    xdotool_debug(context, "Exec arg[%d]: %s", i, data[data_count]);
    data_count++;
    args_count++;
  }

  window_each(context, window_arg, {
    if (clear_modifiers) {
      xdo_get_active_modifiers(context->xdo, &active_mods, &active_mods_n);
      xdo_clear_active_modifiers(context->xdo, window, active_mods, active_mods_n);
    }

    for (i = 0; i < data_count; i++) {
      //printf("Typing: '%s'\n", context->argv[i]);
      int tmp = xdo_enter_text_window(context->xdo, window, data[i], delay);

      if (tmp) {
        fprintf(stderr, "xdo_enter_text_window reported an error\n");
      }

      ret += tmp;
    }

    if (clear_modifiers) {
      xdo_set_active_modifiers(context->xdo, window, active_mods, active_mods_n);
      free(active_mods);
    }
  }); /* window_each(...) */