// File: /workspace/github_c_makefile_star2_O3/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
subq $0x18, %rsp
movq %rdx, %r12
movl %esi, %r13d
movq %rdi, %r14
callq 0x6af7
cmpl $0x9, %r13d
movq %rax, 0x10(%rsp)
jne 0x27291
movzwl 0x20(%rax), %eax
jmp 0x27299
movq %r14, %rdi
callq 0x1e0ae
movw %ax, 0xe(%rsp)
movq 0x28(%r14), %r15
movq $0x0, 0x28(%r14)
movzbl %r13b, %ebp
movq %r14, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq *0x391bc(%rip)          # 0x60478
movl %eax, %ebx
cmpb $0x1, %al
jne 0x27322
cmpb $0x7, %r13b
jne 0x272e5
leaq 0x1895d(%rip), %rsi     # 0x3fc2c
movq %r12, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6c02
movq %r15, 0x28(%r14)
movb $0x1, %bl
testb %r13b, %r13b
je 0x27322
cmpl $0x8, %ebp
jne 0x27333
callq 0x378a
testq %rax, %rax
movq 0x10(%rsp), %r15
je 0x2731d
leaq 0x8(%rsp), %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x3838
movzwl (%r14), %eax
movw %ax, 0x38(%r15)
andb $-0x4, 0x3a(%r15)
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x9, %r13b
jne 0x273bd
callq 0x378a
testq %rax, %rax
movq 0x10(%rsp), %r15
je 0x27382
leaq 0x8(%rsp), %r12
movl $0x0, (%r12)
movq %rax, %rdi
movq %r12, %rsi
callq 0x3838
movswl (%r12), %eax
movswl 0x38(%r15), %ecx
subl %ecx, %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
cmpw $0xb, %cx
jb 0x27382
orb $0x2, 0x3a(%r15)
testb $0x2, 0x3a(%r15)
jne 0x273a4
movq %r14, %rdi
callq 0x94aa
xorl %ecx, %ecx
cmpw $0x32, %ax
movl $0x64, %eax
cmovll %ecx, %eax
movw %ax, 0x20(%r15)
movzwl 0xe(%rsp), %eax
cmpw $0x31, %ax
jg 0x2740e
cmpw $0x32, 0x20(%r15)
jle 0x27322
jmp 0x27424
addl $-0xa, %ebp
cmpl $0x9, %ebp
ja 0x27322
leaq 0x18814(%rip), %rax     # 0x3fbe4
movslq (%rax,%rbp,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %r14, %rdi
callq 0x94aa
cmpw $0x32, %ax
jl 0x274da
movq 0x10(%rsp), %rax
movq 0x30(%rax), %rdx
movq %r14, %rdi
movl $0x2, %esi
callq 0x1dfe8
movq %r14, %rdi
movl $0x64, %esi
jmp 0x274f5
cmpw $0x32, %ax
je 0x27322
cmpw $0x31, 0x20(%r15)
jg 0x27322
orb $0x1, 0x3a(%r15)
jmp 0x27322
movzbl (%r12), %eax
movl %eax, %ecx
andb $-0x3, %cl
cmpb $0x11, %cl
jne 0x2749b
movq %r14, %rdi
movl $0x64, %esi
movl $0x1, %edx
callq 0x920b
leaq 0x8(%rsp), %rdx
movl $0x1, (%rdx)
jmp 0x274c3
movq 0x10(%rsp), %rax
testb $0x1, 0x3a(%rax)
jne 0x27504
movq %r14, %rdi
callq 0x94aa
cmpw $0x32, %ax
jl 0x27516
movq %r14, %rdi
movl $0x1, %esi
callq 0x27637
xorl %ebx, %ebx
jmp 0x27528
movb $0x0, (%r12)
jmp 0x27322
cmpl $0x14, %eax
je 0x274a9
cmpl $0x12, %eax
jne 0x27322
movq %r14, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x920b
leaq 0x8(%rsp), %rdx
movl $0x0, (%rdx)
movq %r14, %rdi
movl $0xe, %esi
callq 0x5018
cmpb $0x1, %al
je 0x27322
jmp 0x2753c
movq 0x10(%rsp), %rax
movq 0x28(%rax), %rdx
movq %r14, %rdi
movl $0x2, %esi
callq 0x1dfe8
movq %r14, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x920b
jmp 0x27322
movq %r14, %rdi
callq 0x1e0ae
cmpw $0x33, %ax
jl 0x2747d
movl $0x1, %ebx
movq %r14, %rdi
movl $0x1, %esi
callq 0x275e3
leaq 0x8(%rsp), %rdx
movl %ebx, (%rdx)
movq %r14, %rdi
movl $0xe, %esi
callq 0x5018
movl %eax, %ebx
jmp 0x27322