Загрузка данных


format ELF64

extrn XOpenDisplay
extrn XDefaultRootWindow
extrn XCreateSimpleWindow
extrn XSelectInput
extrn XMapWindow
extrn XNextEvent
extrn XInternAtom
extrn XSetWMProtocols
extrn XFlush
extrn XCreateGC

public main

section '.text' executable

main:
    push rbp
    mov rbp, rsp
    sub rsp, 32         ; Выравниваем стек и выделяем место под параметры

    ; Открыть дисплей
    xor rdi, rdi
    call XOpenDisplay
    cmp rax, 0
    je exit_error
    mov [x_display], rax

    ; Получить корневое окно
    mov rdi, [x_display]
    call XDefaultRootWindow
    mov [root_window], rax

    ; Создать окно 400x300 с фоном 0x1A1A1A
    ; Передаем 7, 8 и 9 параметры через стек согласно ABI
    mov qword [rsp + 16], 0x1A1A1A ; 9-й параметр: фоновый цвет окна (теперь задан жестко)
    mov qword [rsp + 8], 0         ; 8-й параметр: цвет рамки (border)
    mov qword [rsp], 0             ; 7-й параметр: ширина рамки (border_width)

    mov rdi, [x_display]     ; 1-й параметр: Display
    mov rsi, [root_window]   ; 2-й параметр: Parent
    mov rdx, 100              ; 3-й параметр: x
    mov rcx, 100              ; 4-й параметр: y
    mov r8, 400               ; 5-й параметр: width
    mov r9, 300               ; 6-й параметр: height
    call XCreateSimpleWindow
    mov [window], rax

    ; Получить WM_DELETE_WINDOW атом для корректного закрытия
    mov rdi, [x_display]
    lea rsi, [delete_str]
    xor rdx, rdx
    call XInternAtom
    mov [wm_delete], rax

    ; Установить WM_PROTOCOLS
    mov rdi, [x_display]
    mov rsi, [window]
    lea rdx, [wm_delete]
    mov rcx, 1
    call XSetWMProtocols

    ; Подписаться на события (ExposureMask = 0x8000, StructureNotifyMask = 0x20000)
    mov rdi, [x_display]
    mov rsi, [window]
    mov rdx, 0x28000
    call XSelectInput

    ; Показать окно
    mov rdi, [x_display]
    mov rsi, [window]
    call XMapWindow

    ; Создать GC (графический контекст) для будущей отрисовки объектов
    mov rdi, [x_display]
    mov rsi, [window]
    xor rdx, rdx
    xor rcx, rcx
    call XCreateGC
    mov [gc], rax

    ; Сбросить буфер X11, чтобы окно отобразилось сразу
    mov rdi, [x_display]
    call XFlush

event_loop:
    mov rdi, [x_display]
    lea rsi, [event_buffer]
    call XNextEvent

    movzx eax, byte [event_buffer] ; Первый байт структуры XEvent — это тип события

    cmp al, 2   ; KeyPress (любая клавиша закрывает приложение)
    je exit_ok

    cmp al, 33  ; ClientMessage (нажатие на крестик окна)
    je check_delete

    ; Событие Expose (al = 12) убрано, так как фон теперь перерисовывается сервером X11 автоматически

    jmp event_loop

check_delete:
    ; Проверяем, что пришло именно событие WM_DELETE_WINDOW
    mov rax, [event_buffer + 56]
    cmp rax, [wm_delete]
    je exit_ok
    jmp event_loop

exit_ok:
    add rsp, 32
    mov rsp, rbp
    pop rbp
    xor rax, rax
    ret

exit_error:
    add rsp, 32
    mov rsp, rbp
    pop rbp
    mov rax, 1
    ret

section '.data' writeable
    delete_str db 'WM_DELETE_WINDOW', 0

section '.bss' writeable
    x_display:    rq 1
    root_window:  rq 1
    window:       rq 1
    wm_delete:    rq 1
    gc:           rq 1
    event_buffer: rb 192