// File: /workspace/github_c_makefile_star2_O2/cglindkamp[P]dfm/src/commandline.c
// Function: commandline_handlekey
int commandline_handlekey(struct commandline *commandline, wint_t key, bool iskeycode)
{
	size_t length = wcslen(commandline->buffer);
	size_t cursorpos = commandline->cursor_pos;

	if(iskeycode) {
		switch(key) {
		case KEY_BACKSPACE:
			if(commandline_copy_history_buffer(commandline) != 0)
				return ENOMEM;
			commandline_delete_character_before_cursor(commandline);
			break;
		case KEY_DC:
			if(commandline_copy_history_buffer(commandline) != 0)
				return ENOMEM;
			if(commandline->cursor_pos < length) {
				size_t distance = 0;
				do {
					distance++;
				} while(commandline->cursor_pos + distance < length && wcwidth(commandline->buffer[commandline->cursor_pos + distance]) < 1);
				wmemmove(commandline->buffer + cursorpos, commandline->buffer + cursorpos + distance, length - cursorpos - distance + 1);
			}
			break;
		case KEY_LEFT:
			if(commandline->cursor_pos > 0) {
				int width;
				do {
					width = wcwidth(commandline->buffer[commandline->cursor_pos - 1]);
					commandline->cursor_pos--;
				} while(commandline->cursor_pos > 0 && width < 1);
			}
			break;
		case KEY_RIGHT:
			if(commandline->cursor_pos < length) {
				do {
					commandline->cursor_pos++;
				} while(commandline->cursor_pos < length && wcwidth(commandline->buffer[commandline->cursor_pos]) < 1);
			}
			break;
		case KEY_HOME:
			commandline->cursor_pos = 0;
			break;
		case KEY_END:
			commandline->cursor_pos = length;
			break;
		case KEY_UP:
			if(commandline->history_position < list_length(commandline->history)) {
				if(commandline->history_position == 0)
					commandline->backup_buffer = commandline->buffer;
				commandline->history_position++;
				commandline->buffer = list_get_item(commandline->history, list_length(commandline->history) - commandline->history_position);
			}
			commandline->cursor_pos = wcslen(commandline->buffer);
			break;
		case KEY_DOWN:
			if(commandline->history_position > 0) {
				commandline->history_position--;
				if(commandline->history_position == 0) {
					commandline->buffer = commandline->backup_buffer;
					commandline->backup_buffer = NULL;
				} else
					commandline->buffer = list_get_item(commandline->history, list_length(commandline->history) - commandline->history_position);
			}
			commandline->cursor_pos = wcslen(commandline->buffer);
			break;
		}
	} else {
		if(key == 23) { /* Ctrl-W */
			if(commandline_copy_history_buffer(commandline) != 0)
				return ENOMEM;

			while(commandline->cursor_pos > 0 && commandline->buffer[commandline->cursor_pos - 1] == L' ') {
				commandline_delete_character_before_cursor(commandline);
			}
			while(commandline->cursor_pos > 0 && commandline->buffer[commandline->cursor_pos - 1] != L' ') {
				commandline_delete_character_before_cursor(commandline);
			}

			commandline_updateview(commandline);
			return 0;
		}

		if(key == 0 || wcwidth(key) < 0)
			return EINVAL;

		if(commandline->cursor_pos == 0 && wcwidth(key) == 0)
			return EINVAL;

		if(commandline_copy_history_buffer(commandline) != 0)
			return ENOMEM;

		if(length == commandline->allocated_size - 1)
			if(commandline_makeroom(commandline) != 0)
				return ENOMEM;

		wmemmove(commandline->buffer + cursorpos + 1, commandline->buffer + cursorpos, length - cursorpos);
		commandline->buffer[cursorpos] = key;
		commandline->buffer[length + 1] = L'\0';
		commandline->cursor_pos++;
	}

	commandline_updateview(commandline);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebp
movl %esi, %r15d
movq %rdi, %rbx
movq 0x18(%rdi), %r12
movq %r12, %rdi
callq 0x3280
movq %rax, %r14
movq 0x38(%rbx), %r13
testl %ebp, %ebp
je 0x5821
leal -0x102(%r15), %eax
cmpl $0x5, %eax
ja 0x5888
leaq 0x3a3d(%rip), %rcx      # 0x9214
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%rbx), %rax
testq %rax, %rax
je 0x5a95
decq %rax
movq %rax, 0x10(%rbx)
je 0x5a88
movq 0x8(%rbx), %r14
movq %r14, %rdi
callq 0x7515
subq 0x10(%rbx), %rax
movq %r14, %rdi
movq %rax, %rsi
callq 0x76e4
movq %rax, %r12
movq %rax, 0x18(%rbx)
jmp 0x5a95
pushq $0x16
popq %rbp
testl %r15d, %r15d
je 0x5aab
cmpl $0x17, %r15d
jne 0x58ab
movq %rbx, %rdi
callq 0x5abc
testl %eax, %eax
jne 0x5a73
jmp 0x584d
movq %rbx, %rdi
callq 0x5b24
movq 0x38(%rbx), %rax
testq %rax, %rax
je 0x587e
movq 0x18(%rbx), %rcx
cmpl $0x20, -0x4(%rcx,%rax,4)
je 0x5845
jmp 0x587e
movq 0x18(%rbx), %rcx
cmpl $0x20, -0x4(%rcx,%rax,4)
je 0x5aa1
movq %rbx, %rdi
callq 0x5b24
movq 0x38(%rbx), %rax
testq %rax, %rax
jne 0x5863
jmp 0x5aa1
cmpl $0x14a, %r15d           # imm = 0x14A
je 0x5933
cmpl $0x168, %r15d           # imm = 0x168
jne 0x5aa1
movq %r14, 0x38(%rbx)
jmp 0x5aa1
movl %r15d, %edi
callq 0x3480
testl %eax, %eax
js 0x5aab
cmpq $0x0, 0x38(%rbx)
jne 0x58d2
movl %r15d, %edi
callq 0x3480
testl %eax, %eax
je 0x5aab
movq %rbx, %rdi
callq 0x5abc
pushq $0xc
popq %rbp
testl %eax, %eax
jne 0x5aab
movq 0x28(%rbx), %rax
decq %rax
cmpq %rax, %r14
jne 0x5901
movq %rbx, %rdi
callq 0x5b9d
testl %eax, %eax
jne 0x5aab
movq 0x18(%rbx), %rax
leaq (%rax,%r13,4), %rsi
leaq (%rax,%r13,4), %rdi
addq $0x4, %rdi
movq %r14, %rdx
subq %r13, %rdx
callq 0x35d0
movq 0x18(%rbx), %rax
movl %r15d, (%rax,%r13,4)
andl $0x0, 0x4(%rax,%r14,4)
incq 0x38(%rbx)
jmp 0x5aa1
movq %rbx, %rdi
callq 0x5abc
testl %eax, %eax
jne 0x5a73
cmpq %r14, 0x38(%rbx)
jae 0x5aa1
movq %r13, %rcx
notq %rcx
shlq $0x2, %rcx
xorl %edx, %edx
movq %rdx, %r15
movq %rcx, %r12
movq 0x38(%rbx), %rax
leaq (%rdx,%rax), %rcx
incq %rcx
cmpq %r14, %rcx
jae 0x598c
addq %r15, %rax
movq 0x18(%rbx), %rcx
movl 0x4(%rcx,%rax,4), %edi
callq 0x3480
leaq -0x4(%r12), %rcx
leaq 0x1(%r15), %rdx
testl %eax, %eax
jle 0x5959
movq 0x18(%rbx), %rsi
leaq (%rsi,%r13,4), %rdi
subq %r12, %rsi
subq %r13, %r14
subq %r15, %r14
movq %r14, %rdx
callq 0x35d0
jmp 0x5aa1
andq $0x0, 0x38(%rbx)
jmp 0x5aa1
testq %r13, %r13
je 0x5aa1
movq 0x18(%rbx), %rax
movl -0x4(%rax,%r13,4), %edi
callq 0x3480
movq 0x38(%rbx), %r13
decq %r13
movq %r13, 0x38(%rbx)
je 0x5aa1
testl %eax, %eax
jle 0x59bd
jmp 0x5aa1
cmpq %r13, %r14
jbe 0x5aa1
movq 0x38(%rbx), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x38(%rbx)
cmpq %r14, %rcx
jae 0x5aa1
movq 0x18(%rbx), %rcx
movl 0x4(%rcx,%rax,4), %edi
callq 0x3480
testl %eax, %eax
jle 0x59ee
jmp 0x5aa1
movq 0x8(%rbx), %rdi
movq 0x10(%rbx), %r14
callq 0x7515
cmpq %rax, %r14
jae 0x5a78
movq 0x10(%rbx), %rax
testq %rax, %rax
jne 0x5a3c
movq 0x18(%rbx), %rcx
movq %rcx, 0x20(%rbx)
incq %rax
movq %rax, 0x10(%rbx)
movq 0x8(%rbx), %r14
movq %r14, %rdi
callq 0x7515
subq 0x10(%rbx), %rax
movq %r14, %rdi
movq %rax, %rsi
callq 0x76e4
movq %rax, %rdi
movq %rax, 0x18(%rbx)
jmp 0x5a98
movq %rbx, %rdi
callq 0x5abc
testl %eax, %eax
je 0x5a7e
pushq $0xc
popq %rbp
jmp 0x5aab
movq 0x18(%rbx), %rdi
jmp 0x5a98
movq %rbx, %rdi
callq 0x5b24
jmp 0x5aa1
movq 0x20(%rbx), %r12
movq %r12, 0x18(%rbx)
andq $0x0, 0x20(%rbx)
movq %r12, %rdi
callq 0x3280
movq %rax, 0x38(%rbx)
movq %rbx, %rdi
callq 0x55c8
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq