Загрузка данных
format ELF64
; Импорт функций GTK-3 для работы в нативном Wayland
extrn gtk_init
extrn gtk_window_new
extrn gtk_window_set_title
extrn gtk_window_set_default_size
extrn gtk_box_new
extrn gtk_entry_new
extrn gtk_button_new_with_label
extrn gtk_label_new
extrn gtk_container_add
extrn gtk_box_pack_start
extrn gtk_widget_show_all
extrn gtk_main
extrn g_signal_connect_data
public main
section '.text' executable
main:
push rbp
mov rbp, rsp
sub rsp, 32 ; Выравнивание стека по ABI
; 1. Инициализация GTK (передаем NULL в аргументы)
xor rdi, rdi
xor rsi, rsi
call gtk_init
; 2. Создание главного окна (0 = GTK_WINDOW_TOPLEVEL)
mov rdi, 0
call gtk_window_new
mov [window], rax
; Настройка окна: заголовок и размеры (400x300)
mov rdi, [window]
lea rsi, [title_str]
call gtk_window_set_title
mov rdi, [window]
mov rsi, 400
mov rdx, 300
call gtk_window_set_default_size
; Привязка крестика закрытия окна к выходу из GTK
mov rdi, [window]
lea rsi, [signal_destroy]
lea rdx, [gtk_main_quit] ; Используем функцию выхода как коллбек
xor rcx, rcx
xor r8, r8
xor r9, r9
call g_signal_connect_data
; 3. Создание вертикального контейнера (Layout)
; 1 = GTK_ORIENTATION_VERTICAL, 10 = отступ в пикселях между виджетами
mov rdi, 1
mov rsi, 10
call gtk_box_new
mov [vbox], rax
; Добавляем вертикальный контейнер внутрь главного окна
mov rdi, [window]
mov rsi, [vbox]
call gtk_container_add
; 4. Создание 1-го виджета: EditText (GtkEntry)
call gtk_entry_new
mov [edit_text], rax
; Упаковываем EditText в контейнер (сверху вниз)
mov rdi, [vbox]
mov rsi, [edit_text]
xor rdx, rdx ; expand = FALSE
xor rcx, rcx ; fill = FALSE
xor r8, r8 ; padding = 0
call gtk_box_pack_start
; 5. Создание 2-го виджета: Button (GtkButton)
lea rdi, [btn_txt]
call gtk_button_new_with_label
mov [button], rax
; Упаковываем Кнопку
mov rdi, [vbox]
mov rsi, [button]
xor rdx, rdx
xor rcx, rcx
xor r8, r8
call gtk_box_pack_start
; Привязка клика по кнопке к функции show_message_box (наше уведомление)
mov rdi, [button]
lea rsi, [signal_clicked]
lea rdx, [show_message_box]
xor rcx, rcx
xor r8, r8
xor r9, r9
call g_signal_connect_data
; 6. Создание 3-го виджета: Label (GtkLabel)
lea rdi, [label_txt]
call gtk_label_new
mov [label_widget], rax
; Упаковываем Label в самый низ
mov rdi, [vbox]
mov rsi, [label_widget]
xor rdx, rdx
xor rcx, rcx
xor r8, r8
call gtk_box_pack_start
; 7. Отображение всего интерфейса и запуск главного цикла
mov rdi, [window]
call gtk_widget_show_all
call gtk_main
; Выход из программы
add rsp, 32
pop rbp
xor rax, rax
ret
; === ФУНКЦИЯ-ОБРАБОТЧИК НАЖАТИЯ НА КНОПКУ ===
; В GTK уведомления (MessageBox) делаются через запуск утилиты zenity,
; так как это нативный инструмент вызова диалогов GNOME/Wayland.
extrn fork
extrn execve
show_message_box:
push rbp
mov rbp, rsp
call fork
cmp eax, 0
jne .parent_ret
; Код дочернего процесса запускает уведомление zenity
lea rdi, [zenity_path]
lea rsi, [zenity_args]
xor rdx, rdx
call execve
.parent_ret:
pop rbp
ret
; Внешняя функция завершения GTK
extrn gtk_main_quit
section '.data' writeable
title_str db 'Wayland Native App', 0
btn_txt db 'Click Here', 0
label_txt db 'Hello world!', 0
signal_destroy db 'destroy', 0
signal_clicked db 'clicked', 0
; Конфигурация MessageBox уведомления для Wayland
zenity_path db '/usr/bin/zenity', 0
arg0 db 'zenity', 0
arg1 db '--info', 0
arg2 db '--title=Wayland Msg', 0
arg3 db '--text=Кнопка успешно нажата в нативном Wayland!', 0
zenity_args dq arg0, arg1, arg2, arg3, 0
section '.bss' writeable
window rq 1
vbox rq 1
edit_text rq 1
button rq 1
label_widget rq 1