// File: /workspace/github_c_makefile_star2_O1/OnionIoT[P]lv_example/lvgl/src/lv_objx/lv_sw.c
// Function: lv_sw_signal
static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param)
{
    lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw);

    /*Save the current (old) value before slider signal modifies it. It will be required in the
     * later calculations*/
    int16_t old_val;
    if(sign == LV_SIGNAL_PRESSING)
        old_val = ext->slider.drag_value;
    else
        old_val = lv_slider_get_value(sw);

    /*Don't let the slider to call the action. Switch handles it differently*/
    lv_event_cb_t event_cb = sw->event_cb;
    sw->event_cb           = NULL;

    lv_res_t res;
    /* Include the ancient signal function */

    res = ancestor_signal(sw, sign, param);
    if(res != LV_RES_OK) return res;
    if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME);

    sw->event_cb = event_cb;

    if(sign == LV_SIGNAL_CLEANUP) {
        /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/
    } else if(sign == LV_SIGNAL_PRESSED) {

        /*Save the x coordinate of the pressed point to see if the switch was slid*/
        lv_indev_t * indev = lv_indev_get_act();
        if(indev) {
            lv_point_t p;
            lv_indev_get_point(indev, &p);
            ext->start_x = p.x;
        }
        ext->slided  = 0;
        ext->changed = 0;
    } else if(sign == LV_SIGNAL_PRESSING) {
        /*See if the switch was slid (moved at least a little)*/
        lv_indev_t * indev = lv_indev_get_act();
        if(indev) {
            lv_point_t p = {0, 0};
            lv_indev_get_point(indev, &p);
            if(LV_MATH_ABS(p.x - ext->start_x) > LV_INDEV_DEF_DRAG_LIMIT) ext->slided = 1;
        }

        /*If didn't slide then revert the min/max value. So click without slide won't move the
         * switch as a slider*/
        if(ext->slided == 0) {
            if(lv_sw_get_state(sw))
                ext->slider.drag_value = LV_SW_MAX_VALUE;
            else
                ext->slider.drag_value = 0;
        }

        /*If explicitly changed (by slide) don't need to be toggled on release*/
        int16_t threshold = LV_SW_MAX_VALUE / 2;
        if((old_val < threshold && ext->slider.drag_value > threshold) ||
           (old_val > threshold && ext->slider.drag_value < threshold)) {
            ext->changed = 1;
        }
    } else if(sign == LV_SIGNAL_PRESS_LOST) {
        if(lv_sw_get_state(sw)) {
            lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on);
            lv_slider_set_value(sw, LV_SW_MAX_VALUE, LV_ANIM_ON);
            if(res != LV_RES_OK) return res;
        } else {
            lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off);
            lv_slider_set_value(sw, 0, LV_ANIM_ON);
            if(res != LV_RES_OK) return res;
        }
    } else if(sign == LV_SIGNAL_RELEASED) {
        /*If not dragged then toggle the switch*/
        if(ext->changed == 0) {
            int32_t state;
            if(lv_sw_get_state(sw)) {
                lv_sw_off(sw, LV_ANIM_ON);
                state = 0;
            } else {
                lv_sw_on(sw, LV_ANIM_ON);
                state = 1;
            }

            res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
            if(res != LV_RES_OK) return res;
        }
        /*If the switch was dragged then calculate the new state based on the current position*/
        else {
            int16_t v = lv_slider_get_value(sw);
            int32_t state;
            if(v > LV_SW_MAX_VALUE / 2) {
                lv_sw_on(sw, LV_ANIM_ON);
                state = 1;
            } else {
                lv_sw_off(sw, LV_ANIM_ON);
                state = 0;
            }
            res = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
            if(res != LV_RES_OK) return res;
        }
    } else if(sign == LV_SIGNAL_CONTROL) {
        char c = *((char *)param);
        uint32_t state;
        if(c == LV_KEY_RIGHT || c == LV_KEY_UP) {
            lv_slider_set_value(sw, LV_SW_MAX_VALUE, true);
            state = 1;
            res   = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
            if(res != LV_RES_OK) return res;
        } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
            lv_slider_set_value(sw, 0, true);
            state = 0;
            res   = lv_event_send(sw, LV_EVENT_VALUE_CHANGED, &state);
            if(res != LV_RES_OK) return res;
        }
    } else if(sign == LV_SIGNAL_GET_EDITABLE) {
        bool * editable = (bool *)param;
        *editable       = false; /*The ancestor slider is editable the switch is not*/
    }

    return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r12
movl %esi, %r13d
movq %rdi, %r14
callq 0x6ad8
movq %rax, %r15
cmpl $0x9, %r13d
jne 0x26bc4
movzwl 0x20(%r15), %eax
jmp 0x26bcc
movq %r14, %rdi
callq 0x1d8aa
movw %ax, 0x6(%rsp)
movq 0x28(%r14), %rbx
movq $0x0, 0x28(%r14)
movzbl %r13b, %ebp
movq %r14, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq *0x39889(%rip)          # 0x60478
cmpb $0x1, %al
jne 0x26c4e
cmpb $0x7, %r13b
jne 0x26c16
leaq 0x18e94(%rip), %rsi     # 0x3fa94
movq %r12, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6bf5
movq %rbx, 0x28(%r14)
testb %r13b, %r13b
je 0x26c4e
cmpl $0x8, %ebp
jne 0x26c5d
movl %eax, %ebx
callq 0x3784
testq %rax, %rax
je 0x26c47
movq %rsp, %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x3832
movzwl (%r14), %eax
movw %ax, 0x38(%r15)
andb $-0x4, 0x3a(%r15)
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x9, %r13b
jne 0x26cfe
movl %eax, %ebx
callq 0x3784
testq %rax, %rax
je 0x26ca7
movq %rsp, %r12
movl $0x0, (%r12)
movq %rax, %rdi
movq %r12, %rsi
callq 0x3832
movswl (%r12), %eax
movswl 0x38(%r15), %ecx
subl %ecx, %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
cmpw $0xb, %cx
jb 0x26ca7
orb $0x2, 0x3a(%r15)
testb $0x2, 0x3a(%r15)
jne 0x26cc9
movq %r14, %rdi
callq 0x9525
xorl %ecx, %ecx
cmpw $0x32, %ax
movl $0x64, %eax
cmovll %ecx, %eax
movw %ax, 0x20(%r15)
movzwl 0x6(%rsp), %ecx
cmpw $0x31, %cx
movl %ebx, %eax
jg 0x26cde
cmpw $0x32, 0x20(%r15)
jg 0x26cf4
cmpw $0x33, %cx
jl 0x26c4e
cmpw $0x31, 0x20(%r15)
jg 0x26c4e
orb $0x1, 0x3a(%r15)
jmp 0x26c4e
addl $-0xa, %ebp
cmpl $0x9, %ebp
ja 0x26c4e
leaq 0x18d3b(%rip), %rdx     # 0x3fa4c
movslq (%rdx,%rbp,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl %eax, %ebx
movq %r14, %rdi
callq 0x9525
cmpw $0x32, %ax
jl 0x26e06
movq 0x30(%r15), %rdx
movq %r14, %rdi
movl $0x2, %esi
callq 0x1d7e4
movq %r14, %rdi
movl $0x64, %esi
jmp 0x26e1c
movzbl (%r12), %edx
movl %edx, %ecx
andb $-0x3, %cl
cmpb $0x11, %cl
jne 0x26dc6
movq %r14, %rdi
movl $0x64, %esi
movl $0x1, %edx
callq 0x928d
movq %rsp, %rdx
movl $0x1, (%rdx)
movq %r14, %rdi
movl $0xe, %esi
callq 0x4fea
cmpb $0x1, %al
je 0x26dfb
xorl %ebp, %ebp
jmp 0x26dfe
testb $0x1, 0x3a(%r15)
jne 0x26e2b
movq %r14, %rdi
callq 0x9525
cmpw $0x32, %ax
jl 0x26e3d
movq %r14, %rdi
movl $0x1, %esi
callq 0x26f5c
xorl %ebx, %ebx
jmp 0x26e4f
movb $0x0, (%r12)
jmp 0x26c4e
cmpl $0x14, %edx
je 0x26dd0
cmpl $0x12, %edx
jne 0x26dfb
xorl %ebp, %ebp
movq %r14, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x928d
movq %rsp, %rdx
movl $0x0, (%rdx)
movq %r14, %rdi
movl $0xe, %esi
callq 0x4fea
cmpb $0x1, %al
jne 0x26dfe
movb $0x1, %bpl
testb %bpl, %bpl
jmp 0x26c4e
movq 0x28(%r15), %rdx
movq %r14, %rdi
movl $0x2, %esi
callq 0x1d7e4
movq %r14, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x928d
jmp 0x26c4c
movq %r14, %rdi
callq 0x1d8aa
cmpw $0x33, %ax
jl 0x26da8
movl $0x1, %ebx
movq %r14, %rdi
movl $0x1, %esi
callq 0x26f08
movq %rsp, %rdx
movl %ebx, (%rdx)
movq %r14, %rdi
movl $0xe, %esi
callq 0x4fea
cmpb $0x1, %al
jmp 0x26c4e