static void process_report(int usb_number, struct usb_state * state, struct libusb_transfer * transfer) { int i; for(i = 0; i < controller[state->type].endpoints.in.reports.nb; ++i) { unsigned char report_id = controller[state->type].endpoints.in.reports.elements[i].report_id; unsigned char report_length = controller[state->type].endpoints.in.reports.elements[i].report_length; if(transfer->buffer[0] == report_id) { if(transfer->actual_length == report_length) { if(state->type == C_TYPE_XONE_PAD && !adapter_get(usb_number)->status) { break; } s_report* current = (s_report*) transfer->buffer; s_report* previous = &state->reports[i].report.value; report2event(state->type, usb_number, (s_report*)current, (s_report*)previous, state->joystick_id); if(state->type == C_TYPE_DS4 || state->type == C_TYPE_T300RS_PS4 || state->type == C_TYPE_G29_PS4) { memcpy(&previous->ds4, ¤t->ds4, report_length); //s_report_ds4 is larger than report_length bytes! } else if(state->type == C_TYPE_360_PAD) { previous->x360 = current->x360; } else if(state->type == C_TYPE_XONE_PAD) { if(report_id == XONE_USB_HID_IN_REPORT_ID) { previous->xone.input = current->xone.input; } else if(report_id == XONE_USB_HID_IN_GUIDE_REPORT_ID) { previous->xone.guide = current->xone.guide; } } } else { fprintf(stderr, "incorrect report length on interrupt endpoint: received %d bytes, expected %d bytes\n", transfer->actual_length, report_length); } break; } } if(i == controller[state->type].endpoints.in.reports.nb) { if(state->type == C_TYPE_XONE_PAD && !adapter_get(usb_number)->status) { if(adapter_forward_interrupt_in(usb_number, transfer->buffer, transfer->actual_length) < 0) { fprintf(stderr, "can't forward interrupt data to the adapter\n"); } } } }
int usb_init(int usb_number, e_controller_type type) { int ret = -1; int dev_i; struct usb_state* state = usb_states+usb_number; if(!controller[type].vendor || !controller[type].product) { gprintf(_("no pass-through device is needed\n")); return 0; } usb_state_indexes[usb_number] = usb_number; memset(state, 0x00, sizeof(*state)); state->joystick_id = -1; state->type = type; state->ack = 1; if(!ctx) { ret = libusb_init(&ctx); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_init: %s.\n", libusb_strerror(ret)); return -1; } } if(!devs) { cnt = libusb_get_device_list(ctx, &devs); if(cnt < 0) { fprintf(stderr, "libusb_get_device_list: %s.\n", libusb_strerror(cnt)); return -1; } } for(dev_i=0; dev_i<cnt; ++dev_i) { struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(devs[dev_i], &desc); if(!ret) { if(desc.idVendor == controller[type].vendor && desc.idProduct == controller[type].product) { libusb_device_handle* devh; ret = libusb_open(devs[dev_i], &devh); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_open: %s.\n", libusb_strerror(ret)); return -1; } else { ret = libusb_reset_device(devh); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_reset_device: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } #if defined(LIBUSB_API_VERSION) || defined(LIBUSBX_API_VERSION) libusb_set_auto_detach_kernel_driver(devh, 1); #else #ifndef WIN32 ret = libusb_kernel_driver_active(devh, 0); if(ret == 1) { ret = libusb_detach_kernel_driver(devh, 0); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_detach_kernel_driver: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } } else if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_kernel_driver_active: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } #endif #endif int config; ret = libusb_get_configuration(devh, &config); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_get_configuration: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } if(config != controller[state->type].configuration) { ret = libusb_set_configuration(devh, controller[state->type].configuration); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_set_configuration: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } } ret = libusb_claim_interface(devh, controller[state->type].interface); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_claim_interface: %s.\n", libusb_strerror(ret)); libusb_close(devh); } else { state->devh = devh; ++nb_opened; #ifndef WIN32 const struct libusb_pollfd** pfd_usb = libusb_get_pollfds(ctx); int poll_i; for (poll_i=0; pfd_usb[poll_i] != NULL; ++poll_i) { GE_AddSource(pfd_usb[poll_i]->fd, usb_number, usb_handle_events, usb_handle_events, usb_close); } free(pfd_usb); #endif if(state->type == C_TYPE_XONE_PAD && adapter_get(usb_number)->status) { //if the authentication was already performed, activate the controller //warning: make sure not to make any libusb async io before this! unsigned char activate[] = { 0x05, 0x20, 0x00, 0x01, 0x00 }; usb_send_interrupt_out_sync(usb_number, activate, sizeof(activate)); unsigned char activate_rumble[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }; usb_send_interrupt_out_sync(usb_number, activate_rumble, sizeof(activate_rumble)); } // register joystick state->joystick_id = GE_RegisterJoystick(controller[state->type].name, NULL); int i; for(i = 0; i < controller[state->type].endpoints.in.reports.nb; ++i) { usb_states[usb_number].reports[i].report_id = controller[state->type].endpoints.in.reports.elements[i].report_id; } return 0; } } } } } return -1; }
void display_run(e_controller_type type, int axis[]) { int i; int d; char label[BUTTON_LENGTH]; char rate[COLS]; int tdiff; cpt++; #ifndef WIN32 gettimeofday(&t1, NULL); tdiff = (t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec); #else QueryPerformanceCounter(&t1); tdiff = (t1.QuadPart - t0.QuadPart) * 1000000 / freq.QuadPart; #endif if(tdiff > RATE_PERIOD) { cpt_total += cpt; sprintf(rate, _("Processing time: current=%dus average=%dus worst=%dus"), proc_time/cpt, proc_time_total/cpt_total, proc_time_worst); mvaddstr(LINES-2, 1, rate); clrtoeol(); sprintf(rate, _("Refresh rate: %3dHz "), cpt*1000000/RATE_PERIOD); mvaddstr(LINES-1, 1, rate); t0 = t1; cpt = 0; proc_time = 0; } d = 0; for(i=rel_axis_rstick_y+1; i<AXIS_MAX; ++i) { if(axis[i]) { snprintf(label, sizeof(label), "%8s: %4d", control_get_name(type, i), axis[i]); mvwaddstr(wbuttons, 1 + d, 1, label); d++; if(d == BUTTON_Y_L - 3) { break; } } } memset(label, ' ', sizeof(label)); label[sizeof(label)-1] = '\0'; for(i=d; i<last_button_nb; ++i) { mvwaddstr(wbuttons, 1 + i, 1, label); } last_button_nb = d; wnoutrefresh(wbuttons); mvwaddch(lstick, cross[0][1], cross[0][0], ' '); cross[0][0] = STICK_X_L / 2 + (double)axis[rel_axis_lstick_x] / controller_get_max_signed(adapter_get(0)->type, rel_axis_lstick_x) * (STICK_X_L / 2 - 1); cross[0][1] = STICK_Y_L / 2 + (double)axis[rel_axis_lstick_y] / controller_get_max_signed(adapter_get(0)->type, rel_axis_lstick_y) * (STICK_Y_L / 2 - 1); if(cross[0][0] <= 0 || cross[0][0] >= STICK_X_L-1 || cross[0][1] <= 0 || cross[0][1] >= STICK_Y_L-1) { mvwaddch(lstick, cross[0][1], cross[0][0], CROSS_CHAR | COLOR_PAIR(3)); } else { mvwaddch(lstick, cross[0][1], cross[0][0], CROSS_CHAR); } wnoutrefresh(lstick); mvwaddch(rstick, cross[1][1], cross[1][0], ' '); cross[1][0] = STICK_X_L / 2 + (double)axis[rel_axis_rstick_x] / controller_get_max_signed(adapter_get(0)->type, rel_axis_rstick_x) * (STICK_X_L / 2 - 1); cross[1][1] = STICK_Y_L / 2 + (double)axis[rel_axis_rstick_y] / controller_get_max_signed(adapter_get(0)->type, rel_axis_rstick_y) * (STICK_Y_L / 2 - 1); if(cross[1][0] <= 0 || cross[1][0] >= STICK_X_L-1 || cross[1][1] <= 0 || cross[1][1] >= STICK_Y_L-1) { mvwaddch(rstick, cross[1][1], cross[1][0], CROSS_CHAR | COLOR_PAIR(3)); } else { mvwaddch(rstick, cross[1][1], cross[1][0], CROSS_CHAR); } wnoutrefresh(rstick); move(LINES-1, COLS-1); wnoutrefresh(stdscr); doupdate(); }
void display_run(e_controller_type type, int axis[]) { int i; int d; char label[BUTTON_LENGTH]; char rate[COLS]; int freq = stats_get_frequency(0); if(freq >= 0) { sprintf(rate, _("Refresh rate: %4dHz "), freq); mvaddstr(LINES-1, 1, rate); } d = 0; for(i=rel_axis_rstick_y+1; i<AXIS_MAX; ++i) { if(axis[i]) { snprintf(label, sizeof(label), "%8s: %4d", controller_get_axis_name(type, i), axis[i]); mvwaddstr(wbuttons, 1 + d, 1, label); d++; if(d == BUTTON_Y_L - 3) { break; } } } memset(label, ' ', sizeof(label)); label[sizeof(label)-1] = '\0'; for(i=d; i<last_button_nb; ++i) { mvwaddstr(wbuttons, 1 + i, 1, label); } last_button_nb = d; wnoutrefresh(wbuttons); mvwaddch(lstick, cross[0][1], cross[0][0], ' '); cross[0][0] = STICK_X_L / 2 + (double)axis[rel_axis_lstick_x] / controller_get_max_signed(adapter_get(0)->ctype, rel_axis_lstick_x) * (STICK_X_L / 2 - 1); cross[0][1] = STICK_Y_L / 2 + (double)axis[rel_axis_lstick_y] / controller_get_max_signed(adapter_get(0)->ctype, rel_axis_lstick_y) * (STICK_Y_L / 2 - 1); if(cross[0][0] <= 0 || cross[0][0] >= STICK_X_L-1 || cross[0][1] <= 0 || cross[0][1] >= STICK_Y_L-1) { mvwaddch(lstick, cross[0][1], cross[0][0], CROSS_CHAR | COLOR_PAIR(3)); } else { mvwaddch(lstick, cross[0][1], cross[0][0], CROSS_CHAR); } wnoutrefresh(lstick); mvwaddch(rstick, cross[1][1], cross[1][0], ' '); cross[1][0] = STICK_X_L / 2 + (double)axis[rel_axis_rstick_x] / controller_get_max_signed(adapter_get(0)->ctype, rel_axis_rstick_x) * (STICK_X_L / 2 - 1); cross[1][1] = STICK_Y_L / 2 + (double)axis[rel_axis_rstick_y] / controller_get_max_signed(adapter_get(0)->ctype, rel_axis_rstick_y) * (STICK_Y_L / 2 - 1); if(cross[1][0] <= 0 || cross[1][0] >= STICK_X_L-1 || cross[1][1] <= 0 || cross[1][1] >= STICK_Y_L-1) { mvwaddch(rstick, cross[1][1], cross[1][0], CROSS_CHAR | COLOR_PAIR(3)); } else { mvwaddch(rstick, cross[1][1], cross[1][0], CROSS_CHAR); } wnoutrefresh(rstick); move(LINES-1, COLS-1); wnoutrefresh(stdscr); doupdate(); }
static void translation_test() { int dpi; int dz; double mul; double exp; GE_Event mouse_evt = { }; s_mouse_cal* mc = cal_get_mouse(current_mouse, current_conf); if(!mc->dzx || !mc->mx || !mc->ex) { return; } dpi = mc->dpi; dz = *mc->dzx; mul = *mc->mx; exp = *mc->ex; if (dpi <= 0) { return; } e_controller_type ctype = adapter_get(cal_get_controller(current_mouse))->ctype; if(ctype == C_TYPE_NONE) { return; } if (dots <= 0) { dots = distance * dpi; } if(delay > 0) { delay--; return; } mouse_evt.motion.xrel = direction * step; mouse_evt.motion.which = current_mouse; mouse_evt.type = GE_MOUSEMOTION; process_event(&mouse_evt); dots -= step; if (dots <= 0) { delay = DURATION / gimx_params.refresh_period; step *= 2; direction *= -1; if (direction > 0) { if ((dz - mul + mul * pow(step * 2 * gimx_params.frequency_scale, exp)) * controller_get_axis_scale(ctype, rel_axis_2) > controller_get_mean_unsigned(ctype, rel_axis_2)) { step = 1; distance = 0.1; } else { distance = distance * 3; } } } }
/* * Use the mouse wheel to calibrate the mouse. */ void cal_button(int which, int button) { double ratio; s_mouse_control* mc = cfg_get_mouse_control(current_mouse); s_mouse_cal* mcal = cal_get_mouse(current_mouse, current_conf); e_controller_type ctype = adapter_get(cal_get_controller(current_mouse))->ctype; if(ctype == C_TYPE_NONE) { return; } switch (button) { case GE_BTN_WHEELUP: switch (current_cal) { case MC: current_mouse += 1; if (!GE_MouseName(current_mouse)) { current_mouse -= 1; } break; case CC: current_conf += 1; if (current_conf > MAX_CONFIGURATIONS - 1) { current_conf = MAX_CONFIGURATIONS - 1; } break; case MX: if (mcal->mx && mcal->my) { ratio = *mcal->my / *mcal->mx; *mcal->mx += DEFAULT_MULTIPLIER_STEP; *mcal->my = *mcal->mx * ratio; } break; case MY: if (mcal->mx && mcal->my) { ratio = *mcal->my / *mcal->mx; ratio += DEFAULT_MULTIPLIER_STEP; *mcal->my = *mcal->mx * ratio; } break; case DZX: if (mcal->dzx) { *mcal->dzx += 1; if (*mcal->dzx > controller_get_mean_unsigned(ctype, rel_axis_rstick_x) / controller_get_axis_scale(ctype, rel_axis_rstick_x)) { *mcal->dzx = controller_get_mean_unsigned(ctype, rel_axis_rstick_x) / controller_get_axis_scale(ctype, rel_axis_rstick_x); } mc->merge_x[mc->index] = 1; mc->merge_y[mc->index] = 0; mc->change = 1; } break; case DZY: if (mcal->dzy) { *mcal->dzy += 1; if (*mcal->dzy > controller_get_mean_unsigned(ctype, rel_axis_rstick_x) / controller_get_axis_scale(ctype, rel_axis_rstick_x)) { *mcal->dzy = controller_get_mean_unsigned(ctype, rel_axis_rstick_x) / controller_get_axis_scale(ctype, rel_axis_rstick_x); } mc->merge_x[mc->index] = 0; mc->merge_y[mc->index] = 1; mc->change = 1; } break; case DZS: if (mcal->dzs) { if (*mcal->dzs == E_SHAPE_CIRCLE) { *mcal->dzs = E_SHAPE_RECTANGLE; } else { *mcal->dzs = E_SHAPE_CIRCLE; } mc->merge_x[mc->index] = 1; mc->merge_y[mc->index] = 1; mc->change = 1; } break; case RD: mcal->rd += 1; break; case VEL: mcal->vel += 1; break; case EX: if (mcal->ex) { *mcal->ex += EXPONENT_STEP; } break; case EY: if (mcal->ey) { *mcal->ey += EXPONENT_STEP; } break; case TEST: test_time += 10; break; case NONE: break; } if(current_cal != NONE) { if(gimx_params.curses) { display_calibration(); } else { cal_display(); } } break; case GE_BTN_WHEELDOWN: switch (current_cal) { case MC: if (current_mouse > 0) { current_mouse -= 1; } break; case CC: if (current_conf > 0) { current_conf -= 1; } break; case MX: if (mcal->mx && mcal->my) { ratio = *mcal->my / *mcal->mx; *mcal->mx -= DEFAULT_MULTIPLIER_STEP; *mcal->my = *mcal->mx * ratio; } break; case MY: if (mcal->mx && mcal->my) { ratio = *mcal->my / *mcal->mx; ratio -= DEFAULT_MULTIPLIER_STEP; *mcal->my = *mcal->mx * ratio; } break; case DZX: if (mcal->dzx && *mcal->dzx > 0) { *mcal->dzx -= 1; mc->merge_x[mc->index] = -1; mc->merge_y[mc->index] = 0; mc->change = 1; } break; case DZY: if (mcal->dzy && *mcal->dzy > 0) { *mcal->dzy -= 1; mc->merge_x[mc->index] = 0; mc->merge_y[mc->index] = -1; mc->change = 1; } break; case DZS: if (mcal->dzs) { if (*mcal->dzs == E_SHAPE_CIRCLE) { *mcal->dzs = E_SHAPE_RECTANGLE; } else { *mcal->dzs = E_SHAPE_CIRCLE; } mc->merge_x[mc->index] = -1; mc->merge_y[mc->index] = -1; mc->change = 1; } break; case RD: mcal->rd -= 1; if(mcal->rd < 1) { mcal->rd = 1; } break; case VEL: mcal->vel -= 1; if(mcal->vel < 1) { mcal->vel = 1; } break; case EX: if (mcal->ex) { *mcal->ex -= EXPONENT_STEP; } break; case EY: if (mcal->ey) { *mcal->ey -= EXPONENT_STEP; } break; case TEST: test_time -= 10; break; case NONE: break; } if(current_cal != NONE) { if(gimx_params.curses) { display_calibration(); } else { cal_display(); } } break; default: break; } }
int args_read(int argc, char *argv[], s_gimx_params* params) { int ret = 0; int c; unsigned char controller = 0; unsigned char input = 0; struct option long_options[] = { /* These options set a flag. */ {"nograb", no_argument, ¶ms->grab, 0}, {"status", no_argument, ¶ms->status, 1}, {"subpos", no_argument, ¶ms->subpositions, 1}, {"force-updates", no_argument, ¶ms->force_updates, 1}, {"curses", no_argument, ¶ms->curses, 1}, {"window-events", no_argument, ¶ms->window_events, 1}, {"btstack", no_argument, ¶ms->btstack, 1}, /* These options don't set a flag. We distinguish them by their indices. */ {"bdaddr", required_argument, 0, 'b'}, {"config", required_argument, 0, 'c'}, {"dst", required_argument, 0, 'd'}, {"event", required_argument, 0, 'e'}, {"hci", required_argument, 0, 'h'}, {"help", no_argument, 0, 'm'}, {"keygen", required_argument, 0, 'k'}, {"log", required_argument, 0, 'l'}, {"port", required_argument, 0, 'p'}, {"refresh", required_argument, 0, 'r'}, {"src", required_argument, 0, 's'}, {"type", required_argument, 0, 't'}, {"version", no_argument, 0, 'v'}, {0, 0, 0, 0} }; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "b:c:d:e:h:k:l:p:r:s:t:vm", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; if(controller == MAX_CONTROLLERS) { printf(_("ignoring: -%c %s (max controllers reached)\n"), c, optarg); continue; } switch (c) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf(_("option %s"), long_options[option_index].name); if (optarg) printf(_(" with arg %s"), optarg); printf("\n"); break; case 'b': adapter_get(controller)->atype = E_ADAPTER_TYPE_BLUETOOTH; adapter_get(controller)->bdaddr_dst = optarg; if(adapter_get(controller)->ctype == C_TYPE_NONE) { adapter_get(controller)->ctype = C_TYPE_SIXAXIS; } printf(_("controller #%d: option -b with value `%s'\n"), controller + 1, optarg); ++controller; printf(_("now reading arguments for controller #%d\n"), controller + 1); break; case 'c': params->config_file = optarg; printf(_("global option -c with value `%s'\n"), optarg); input = 1; break; case 'e': { char label[AXIS_NAME_MAX_SIZE]; int axis; int value; if(sscanf(optarg, "%"STR(AXIS_NAME_MAX_SIZE)"[^(](%d)", label, &value) != 2) { fprintf(stderr, _("Bad event format: %s\n"), optarg); ret = -1; } else { // strip trailing spaces char * end; for (end = label + strlen(label) - 1; end > label && *end == ' '; --end) {} *(end + 1) = '\0'; if((axis = controller_get_axis_index(label)) != -1) { printf(_("controller #%d: option -e with value `%s(%d)'\n"), controller + 1, label, value); adapter_set_axis(controller, axis, value); adapter_get(controller)->event = 1; input = 1; } else { fprintf(stderr, _("Bad axis name for event: %s\n"), optarg); ret = -1; } } } break; case 'h': adapter_get(controller)->dongle_index = atoi(optarg); printf(_("controller #%d: option -h with value `%d'\n"), controller + 1, adapter_get(controller)->dongle_index); break; case 'd': if(read_ip(optarg, &adapter_get(controller)->dst_ip, &adapter_get(controller)->dst_port) < 0) { printf(_("Bad format for argument -d: '%s'\n"), optarg); ret = -1; } else { adapter_get(controller)->atype = E_ADAPTER_TYPE_REMOTE_GIMX; printf(_("controller #%d: option -d with value `%s'\n"), controller + 1, optarg); ++controller; printf(_("now reading arguments for controller #%d\n"), controller + 1); } break; case 'm': usage(); exit(0); break; case 's': if(read_ip(optarg, &adapter_get(controller)->src_ip, &adapter_get(controller)->src_port) < 0) { printf(_("Bad format for argument -s: '%s'\n"), optarg); ret = -1; } else { printf(_("controller #%d: option -s with value `%s'\n"), controller + 1, optarg); input = 1; params->network_input = 1; } break; case 'k': params->keygen = optarg; printf(_("controller #%d: option -k with value `%s'\n"), controller + 1, optarg); break; case 'l': if(params->logfilename == NULL) { if(!params->curses) { params->logfilename = optarg; if(params->logfilename && strlen(params->logfilename)) { char file_path[PATH_MAX]; snprintf(file_path, sizeof(file_path), "%s%s%s%s", params->homedir, GIMX_DIR, LOG_DIR, params->logfilename); params->logfile = fopen(file_path, "w"); if(params->logfile != NULL) { dup2(fileno(params->logfile), fileno(stdout)); dup2(fileno(params->logfile), fileno(stderr)); } else { printf(_("can't open log file (%s)\n"), file_path); ret = -1; } } printf(_("global option -l with value `%s'\n"), optarg); } else { printf(_("log file can't be used with curses\n")); ret = -1; } } else { printf(_("only one log file can be specified\n")); ret = -1; } break; case 'p': if(adapter_get(controller)->atype == E_ADAPTER_TYPE_NONE) { // no adapter type specified => try to guess it from the port if(strstr(optarg, DEV_HIDRAW) || !strstr(optarg, DEV_SERIAL)) { adapter_get(controller)->atype = E_ADAPTER_TYPE_GPP; } else { adapter_get(controller)->atype = E_ADAPTER_TYPE_DIY_USB; } } if(adapter_set_port(controller, optarg) < 0) { printf(_("port already used: `%s'\n"), optarg); ret = -1; } else { printf(_("controller #%d: option -p with value `%s'\n"), controller + 1, optarg); ++controller; printf(_("now reading arguments for controller #%d\n"), controller + 1); } break; case 'r': params->refresh_period = atof(optarg) * 1000; if(params->refresh_period) { params->postpone_count = 3 * DEFAULT_REFRESH_PERIOD / params->refresh_period; printf(_("global option -r with value `%s'\n"), optarg); } else { fprintf(stderr, "Bad refresh period: %s\n", optarg); ret = -1; } break; case 't': printf(_("controller #%d: option -t with value `%s'\n"), controller + 1, optarg); if (!strcmp(optarg, "GPP")) { adapter_get(controller)->atype = E_ADAPTER_TYPE_GPP; } else { adapter_get(controller)->ctype = controller_get_type(optarg); if (adapter_get(controller)->ctype == C_TYPE_NONE) { fprintf(stderr, "Bad controller type: %s\n", optarg); ret = -1; } } break; case 'v': printf("GIMX %s %s\n", INFO_VERSION, INFO_ARCH); exit(0); break; case '?': usage(); exit(-1); break; default: printf(_("unrecognized option: %c\n"), c); ret = -1; break; } } if(params->status || params->logfilename) params->curses = 0; if(!params->grab) printf(_("grab flag is unset\n")); if(params->status) printf(_("status flag is set\n")); if(params->subpositions) printf(_("subpos flag is set\n")); if(params->force_updates) printf(_("force_updates flag is set\n")); if(params->curses) printf(_("curses flag is set\n")); if(params->window_events) printf(_("window_events flag is set\n")); if(params->btstack) printf(_("btstack flag is set\n")); if(!input) { fprintf(stderr, "At least a config file, an event, or a source IP:port should be specified as argument.\n"); ret = -1; } if(params->logfile) { log_info(); } return ret; }