/** * Swap a device from one master to another. */ int change_attachment(Display* dpy, int argc, char** argv, char *name, char* desc) { XIDeviceInfo *sd_info, *md_info; XIAttachSlaveInfo c; int ret; if (argc < 2) { fprintf(stderr, "usage: xinput %s %s\n", name, desc); return EXIT_FAILURE; } sd_info = xi2_find_device_info(dpy, argv[0]); md_info= xi2_find_device_info(dpy, argv[1]); if (!sd_info) { fprintf(stderr, "unable to find device %s\n", argv[0]); return EXIT_FAILURE; } if (!md_info) { fprintf(stderr, "unable to find device %s\n", argv[1]); return EXIT_FAILURE; } c.type = XIAttachSlave; c.deviceid = sd_info->deviceid; c.new_master = md_info->deviceid; ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1); return ret; }
/** * Set a device floating. */ int float_device(Display* dpy, int argc, char** argv, char* name, char* desc) { XIDeviceInfo *info; XIDetachSlaveInfo c; int ret; if (argc < 1) { fprintf(stderr, "usage: xinput %s %s\n", name, desc); return EXIT_FAILURE; } info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[0]); return EXIT_FAILURE; } c.type = XIDetachSlave; c.deviceid = info->deviceid; ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&c, 1); return ret; }
static int list_props_xi2(Display *dpy, int argc, char** argv, char* name, char *desc) { XIDeviceInfo *info; int i; int nprops; Atom *props; if (argc == 0) { fprintf(stderr, "Usage: xinput %s %s\n", name, desc); return EXIT_FAILURE; } for (i = 0; i < argc; i++) { info = xi2_find_device_info(dpy, argv[i]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[i]); continue; } props = XIListProperties(dpy, info->deviceid, &nprops); if (!nprops) { printf("Device '%s' does not report any properties.\n", info->name); continue; } printf("Device '%s':\n", info->name); while(nprops--) { print_property_xi2(dpy, info->deviceid, props[nprops]); } XFree(props); } return EXIT_SUCCESS; }
static int delete_prop_xi2(Display *dpy, int argc, char** argv, char* n, char *desc) { XIDeviceInfo *info; char *name; Atom prop; info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[0]); return EXIT_FAILURE; } name = argv[1]; prop = parse_atom(dpy, name); XIDeleteProperty(dpy, info->deviceid, prop); return EXIT_SUCCESS; }
int map_to_output(Display *dpy, int argc, char *argv[], char *name, char *desc) { char *output_name; XIDeviceInfo *info; XRROutputInfo *output_info; if (argc < 2) { fprintf(stderr, "Usage: xinput %s %s\n", name, desc); return EXIT_FAILURE; } info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device '%s'\n", argv[0]); return EXIT_FAILURE; } output_name = argv[1]; output_info = find_output_xrandr(dpy, output_name); if (!output_info) { /* Output doesn't exist. Is this a (partial) non-RandR setup? */ output_info = find_output_xrandr(dpy, "default"); if (output_info) { XRRFreeOutputInfo(output_info); if (strncmp("HEAD-", output_name, strlen("HEAD-")) == 0) return map_output_xinerama(dpy, info->deviceid, output_name); } } else XRRFreeOutputInfo(output_info); return map_output_xrandr(dpy, info->deviceid, output_name); }
static int do_set_prop_xi2(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc) { XIDeviceInfo *info; Atom prop; Atom old_type; char *name; int i; Atom float_atom; int old_format, nelements = 0; unsigned long act_nitems, bytes_after; char *endptr; union { unsigned char *c; int16_t *s; int32_t *l; } data; if (argc < 3) { fprintf(stderr, "Usage: xinput %s %s\n", n, desc); return EXIT_FAILURE; } info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[0]); return EXIT_FAILURE; } name = argv[1]; prop = parse_atom(dpy, name); if (prop == None) { fprintf(stderr, "invalid property %s\n", name); return EXIT_FAILURE; } float_atom = XInternAtom(dpy, "FLOAT", False); nelements = argc - 2; if (type == None || format == 0) { if (XIGetProperty(dpy, info->deviceid, prop, 0, 0, False, AnyPropertyType, &old_type, &old_format, &act_nitems, &bytes_after, &data.c) != Success) { fprintf(stderr, "failed to get property type and format for %s\n", name); return EXIT_FAILURE; } else { if (type == None) type = old_type; if (format == 0) format = old_format; } XFree(data.c); } if (type == None) { fprintf(stderr, "property %s doesn't exist, you need to specify " "its type and format\n", name); return EXIT_FAILURE; } data.c = calloc(nelements, sizeof(int32_t)); for (i = 0; i < nelements; i++) { if (type == XA_INTEGER) { switch (format) { case 8: data.c[i] = atoi(argv[2 + i]); break; case 16: data.s[i] = atoi(argv[2 + i]); break; case 32: data.l[i] = atoi(argv[2 + i]); break; default: fprintf(stderr, "unexpected size for property %s", name); return EXIT_FAILURE; } } else if (type == float_atom) { if (format != 32) { fprintf(stderr, "unexpected format %d for property %s\n", format, name); return EXIT_FAILURE; } *(float *)(data.l + i) = strtod(argv[2 + i], &endptr); if (endptr == argv[2 + i]) { fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]); return EXIT_FAILURE; } } else if (type == XA_ATOM) { if (format != 32) { fprintf(stderr, "unexpected format %d for property %s\n", format, name); return EXIT_FAILURE; } data.l[i] = parse_atom(dpy, argv[2 + i]); } else { fprintf(stderr, "unexpected type for property %s\n", name); return EXIT_FAILURE; } } XIChangeProperty(dpy, info->deviceid, prop, type, format, PropModeReplace, data.c, nelements); free(data.c); return EXIT_SUCCESS; }
int test_xi2(Display *display, int argc, char *argv[], char *name, char *desc) { XIEventMask mask[2]; XIEventMask *m; Window win; int deviceid = -1; int use_root = 0; int rc; setvbuf(stdout, NULL, _IOLBF, 0); if (argc >= 1 && strcmp(argv[0], "--root") == 0) { use_root = 1; argc--; argv++; } rc = list(display, argc, argv, name, desc); if (rc != EXIT_SUCCESS) return rc; if (use_root) win = DefaultRootWindow(display); else win = create_win(display); if (argc >= 1) { XIDeviceInfo *info; info = xi2_find_device_info(display, argv[0]); deviceid = info->deviceid; } /* Select for motion events */ m = &mask[0]; m->deviceid = (deviceid == -1) ? XIAllDevices : deviceid; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = calloc(m->mask_len, sizeof(char)); XISetMask(m->mask, XI_ButtonPress); XISetMask(m->mask, XI_ButtonRelease); XISetMask(m->mask, XI_KeyPress); XISetMask(m->mask, XI_KeyRelease); XISetMask(m->mask, XI_Motion); XISetMask(m->mask, XI_DeviceChanged); XISetMask(m->mask, XI_Enter); XISetMask(m->mask, XI_Leave); XISetMask(m->mask, XI_FocusIn); XISetMask(m->mask, XI_FocusOut); #ifdef HAVE_XI22 XISetMask(m->mask, XI_TouchBegin); XISetMask(m->mask, XI_TouchUpdate); XISetMask(m->mask, XI_TouchEnd); #endif if (m->deviceid == XIAllDevices) XISetMask(m->mask, XI_HierarchyChanged); XISetMask(m->mask, XI_PropertyEvent); m = &mask[1]; m->deviceid = (deviceid == -1) ? XIAllMasterDevices : deviceid; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = calloc(m->mask_len, sizeof(char)); XISetMask(m->mask, XI_RawKeyPress); XISetMask(m->mask, XI_RawKeyRelease); XISetMask(m->mask, XI_RawButtonPress); XISetMask(m->mask, XI_RawButtonRelease); XISetMask(m->mask, XI_RawMotion); #ifdef HAVE_XI22 XISetMask(m->mask, XI_RawTouchBegin); XISetMask(m->mask, XI_RawTouchUpdate); XISetMask(m->mask, XI_RawTouchEnd); #endif XISelectEvents(display, win, &mask[0], use_root ? 2 : 1); if (!use_root) { XISelectEvents(display, DefaultRootWindow(display), &mask[1], 1); XMapWindow(display, win); } XSync(display, False); free(mask[0].mask); free(mask[1].mask); if (!use_root) { XEvent event; XMaskEvent(display, ExposureMask, &event); XSelectInput(display, win, 0); } /* test_sync_grab(display, win); */ while(1) { XEvent ev; XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; XNextEvent(display, (XEvent*)&ev); if (XGetEventData(display, cookie) && cookie->type == GenericEvent && cookie->extension == xi_opcode) { printf("EVENT type %d (%s)\n", cookie->evtype, type_to_name(cookie->evtype)); switch (cookie->evtype) { case XI_DeviceChanged: print_devicechangedevent(display, cookie->data); break; case XI_HierarchyChanged: print_hierarchychangedevent(cookie->data); break; case XI_RawKeyPress: case XI_RawKeyRelease: case XI_RawButtonPress: case XI_RawButtonRelease: case XI_RawMotion: case XI_RawTouchBegin: case XI_RawTouchUpdate: case XI_RawTouchEnd: print_rawevent(cookie->data); break; case XI_Enter: case XI_Leave: case XI_FocusIn: case XI_FocusOut: print_enterleave(cookie->data); break; case XI_PropertyEvent: print_propertyevent(display, cookie->data); break; default: print_deviceevent(cookie->data); break; } } XFreeEventData(display, cookie); } XDestroyWindow(display, win); return EXIT_SUCCESS; }
/** * Remove a master device. * By default, all attached devices are set to Floating, unless parameters are * given. */ int remove_master(Display* dpy, int argc, char** argv, char *name, char *desc) { XIRemoveMasterInfo r; XIDeviceInfo *info; int ret; if (argc == 0) { fprintf(stderr, "usage: xinput %s %s\n", name, desc); return EXIT_FAILURE; } info = xi2_find_device_info(dpy, argv[0]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[0]); return EXIT_FAILURE; } r.type = XIRemoveMaster; r.deviceid = info->deviceid; if (argc >= 2) { if (!strcmp(argv[1], "Floating")) r.return_mode = XIFloating; else if (!strcmp(argv[1], "AttachToMaster")) r.return_mode = XIAttachToMaster; else Error(BadValue, "Invalid return_mode.\n"); } else r.return_mode = XIFloating; if (r.return_mode == XIAttachToMaster) { r.return_pointer = 0; if (argc >= 3) { info = xi2_find_device_info(dpy, argv[2]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[2]); return EXIT_FAILURE; } r.return_pointer = info->deviceid; } r.return_keyboard = 0; if (argc >= 4) { info = xi2_find_device_info(dpy, argv[3]); if (!info) { fprintf(stderr, "unable to find device %s\n", argv[3]); return EXIT_FAILURE; } r.return_keyboard = info->deviceid; } if (!r.return_pointer || !r.return_keyboard) { int i, ndevices; info = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices); for(i = 0; i < ndevices; i++) { if (info[i].use == XIMasterPointer && !r.return_pointer) r.return_pointer = info[i].deviceid; if (info[i].use == XIMasterKeyboard && !r.return_keyboard) r.return_keyboard = info[i].deviceid; if (r.return_pointer && r.return_keyboard) break; } XIFreeDeviceInfo(info); } } ret = XIChangeHierarchy(dpy, (XIAnyHierarchyChangeInfo*)&r, 1); return ret; }