// File: thjaeger[P]bindbutton/bindbutton.cc
// Function: init_xi()
void init_xi() {
	int n;
	XDeviceInfo *devs = XListInputDevices(dpy, &n);
	if (!devs)
		exit(EXIT_FAILURE);

	for (int i = 0; i < n; i++) {
		if (devs[i].use == IsXKeyboard || devs[i].use == IsXPointer)
			continue;

		XiDevice dev;

		dev.num_buttons = 0;
		XAnyClassPtr any = (XAnyClassPtr) (devs[i].inputclassinfo);
		for (int j = 0; j < devs[i].num_classes; j++) {
			if (any->c_class == ButtonClass) {
				XButtonInfo *info = (XButtonInfo *)any;
				dev.num_buttons = info->num_buttons;
			}
			any = (XAnyClassPtr) ((char *) any + any->length);
		}
		if (!dev.num_buttons)
			continue;

		if (device_name && strcasecmp(device_name, devs[i].name))
			continue;

		dev.dev = XOpenDevice(dpy, devs[i].id);
		if (!dev.dev) {
			printf("Opening Device %s failed.\n", devs[i].name);
			continue;
		}

		DeviceButtonPress(dev.dev, dev.press, dev.classes[0]);
		DeviceButtonRelease(dev.dev, dev.release, dev.classes[1]);

		devices.push_back(dev);
	}
	XFreeDeviceList(devs);
	if (devices.size() == 0) {
		printf("Error: No devices found\n");
		exit(EXIT_FAILURE);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq 0x8d5e(%rip), %rdi      # 0xb160
leaq -0x4(%rbp), %rsi
callq 0x21a0
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x2420
movl $0x1, %edi
callq 0x21d0
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x4(%rbp), %eax
jge 0x2728
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, 0x1c(%rax)
je 0x245d
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x1c(%rax)
jne 0x2462
jmp 0x271a
leaq -0x70(%rbp), %rdi
callq 0x3230
movl $0x0, -0x50(%rbp)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rax
movq %rax, -0x78(%rbp)
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
movq -0x10(%rbp), %rcx
movslq -0x14(%rbp), %rdx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x18(%rcx), %eax
jge 0x24e8
movq -0x78(%rbp), %rax
cmpq $0x1, (%rax)
jne 0x24ca
movq -0x78(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movswl 0xc(%rax), %eax
movl %eax, -0x50(%rbp)
movq -0x78(%rbp), %rax
movq -0x78(%rbp), %rcx
movslq 0x8(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x2490
cmpl $0x0, -0x50(%rbp)
jne 0x24fd
movl $0x4, -0x8c(%rbp)
jmp 0x2701
cmpq $0x0, 0x8c6b(%rip)      # 0xb170
je 0x253a
movq 0x8c62(%rip), %rdi      # 0xb170
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rsi
callq 0x2180
cmpl $0x0, %eax
je 0x253a
movl $0x4, -0x8c(%rbp)
jmp 0x2701
movq 0x8c1f(%rip), %rdi      # 0xb160
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,4), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x20e0
movq %rax, -0xc0(%rbp)
jmp 0x255f
movq -0xc0(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jne 0x25c1
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,4), %rcx
movq 0x10(%rax,%rcx,8), %rsi
leaq 0x4a8f(%rip), %rdi      # 0x7018
xorl %eax, %eax
callq 0x2030
jmp 0x2592
movl $0x4, -0x8c(%rbp)
jmp 0x2701
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3290
jmp 0x2764
movl $0x0, -0x58(%rbp)
movq $0x0, -0x68(%rbp)
movl $0x0, -0xa0(%rbp)
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xa8(%rbp)
movl -0xa0(%rbp), %eax
movq -0x70(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x2653
movq -0xa8(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x262e
movq -0xa8(%rbp), %rax
movzbl 0x1(%rax), %eax
addl $0x0, %eax
movl %eax, -0x58(%rbp)
movq -0x70(%rbp), %rax
movq (%rax), %rax
shlq $0x8, %rax
movslq -0x58(%rbp), %rcx
orq %rcx, %rax
movq %rax, -0x68(%rbp)
jmp 0x2630
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
movq -0xa8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xa8(%rbp)
jmp 0x25e9
movl $0x0, -0x54(%rbp)
movq $0x0, -0x60(%rbp)
movl $0x0, -0xac(%rbp)
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb8(%rbp)
movl -0xac(%rbp), %eax
movq -0x70(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x26e5
movq -0xb8(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jne 0x26c0
movq -0xb8(%rbp), %rax
movzbl 0x1(%rax), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movq -0x70(%rbp), %rax
movq (%rax), %rax
shlq $0x8, %rax
movslq -0x54(%rbp), %rcx
orq %rcx, %rax
movq %rax, -0x60(%rbp)
jmp 0x26c2
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
movq -0xb8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xb8(%rbp)
jmp 0x267b
leaq 0x8a8c(%rip), %rdi      # 0xb178
leaq -0x70(%rbp), %rsi
callq 0x3250
jmp 0x26f7
movl $0x0, -0x8c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3290
movl -0x8c(%rbp), %eax
testl %eax, %eax
je 0x2718
jmp 0x2716
jmp 0x271a
jmp 0x271a
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x2427
movq -0x10(%rbp), %rdi
callq 0x2060
leaq 0x8a40(%rip), %rdi      # 0xb178
callq 0x32b0
cmpq $0x0, %rax
jne 0x275b
leaq 0x48e9(%rip), %rdi      # 0x7033
movb $0x0, %al
callq 0x2030
movl $0x1, %edi
callq 0x21d0
addq $0xc0, %rsp
popq %rbp
retq
movq -0x98(%rbp), %rdi
callq 0x2260