Я сейчас работаю с linux сборкой nasm и gtk3 drawing_area. Я могу успешно показать окно gtk и визуализировать компоненты (окно отображается с правильным заголовком и размером). Однако я не могу ничего визуализировать в моем gtk drawing_area с помощью cairo. Запустив приведенный ниже код, я получаю следующую ошибку:
GLib-GObject-CRITICAL **: 19:10:00.207: g_boxed_free: assertion 'G_TYPE_IS_BOXED (boxed_type)' failed
Я подозреваю, что ошибка заключается в функциях draw_callback, поскольку я не получаю сообщение об ошибке, если я либо оставлю ее, либо вернусь сразу же при запуске функции. По какой-то странной причине я получаю сообщение об ошибке, если возвращаюсь после установки rdi на r14 и rsi на r15. Функция draw_callback подключается к событию рисования, поскольку я могу выполнить код в функции draw_callback. Я получил те же вызовы logi c и gtk, написанные на COBOL & C, чтобы они работали, так что в этом не должно быть ничего плохого. Скорее всего, проблема заключается в моих навыках сборки (или их отсутствии). Я смог отобразить другие компоненты, такие как флажки, с тем же макетом, поэтому это не должно быть проблемой.
;code.asm
bits 64
%define GTK_WINDOW_TOPLEVEL 0
%define GTK_WIN_POS_CENTER 1
%define FALSE 0
%define TRUE 1
extern gtk_init
extern gtk_window_new
extern gtk_window_set_position
extern gtk_window_set_default_size
extern gtk_window_set_title
extern gtk_box_new
extern gtk_container_add
extern gtk_drawing_area_new
extern cairo_move_to
extern cairo_rectangle
extern gtk_style_context_get_color
extern gtk_widget_get_style_context
extern cairo_show_text
extern cairo_fill
extern gtk_box_pack_start
extern gdk_cairo_set_source_rgba
extern gtk_widget_queue_draw
extern gtk_container_set_border_width
extern gtk_vbox_new
extern exit
extern gtk_box_pack_start
extern g_signal_connect_data
extern gtk_widget_show_all
extern gtk_main
extern gtk_main_quit
extern gtk_widget_show
section .bss
color: resq 1
window: resq 1 ; pointer to the GtkWidget, in this case the window
drawing_area: resq 1
vbox: resq 1
quit: resq 1
section .data
mainwindow:
.title: db "title",0
signal:
.draw: db "draw", 0
.destroy: db "destroy", 0
height dd 1000
width dd 1000
section .text
global _start
_start:
xor rsi, rsi ; argv
xor rdi, rdi ; argc
call gtk_init
mov rdi, GTK_WINDOW_TOPLEVEL
call gtk_window_new
mov qword[window], rax
mov rdi, qword[window]
mov rsi, GTK_WIN_POS_CENTER
call gtk_window_set_position
mov rdi, qword[window]
mov rsi, [height]
mov rdx, [width]
call gtk_window_set_default_size
mov rdi, qword[window]
mov rsi, mainwindow.title
call gtk_window_set_title
mov rdi, qword[window]
mov rsi, 2
call gtk_container_set_border_width
xor r9d, r9d
xor r8d, r8d
xor rcx, rcx
mov rdx, gtk_main_quit
mov rsi, signal.destroy
mov rdi, qword[window]
call g_signal_connect_data
mov rdi, 0
mov rsi, 5
call gtk_vbox_new
mov qword [vbox], rax
mov rdi, qword[window]
mov rsi, qword[vbox]
call gtk_container_add
call gtk_drawing_area_new
mov qword [drawing_area], rax
call connect_draw
mov rdi, qword [vbox]
mov rsi, qword [drawing_area]
mov rdx, 1
mov rcx, 1
mov r8, 0
call gtk_box_pack_start
mov rdi, qword[drawing_area]
call gtk_widget_show
mov rdi, qword[vbox]
call gtk_widget_show
mov rdi, qword[window]
call gtk_widget_show
call gtk_main
xor rdi, rdi
call exit
;The graphics part starts here
connect_draw:
xor r9d, r9d
xor r8d, r8d
xor rcx, rcx
mov rdi, qword[drawing_area]
mov rsi, signal.draw
;A gtk window reference
mov rdx, draw_callback
call g_signal_connect_data
ret
draw_callback: ;GBoolean (GtkWidget *widget, cairo_t *cr, gpointer data)
mov r14, rdi; GtkWidget *widget
mov r15, rsi ; cairo_t *cr
mov rdi, r15
mov rsi, 100
mov rdx, 100
mov rcx, 100
mov r8, 100
call cairo_rectangle ;void cairo_rectangle (cairo_t *cr, double x, double y,double width, double height);
;Nothing happens here
;Next lines attempt to fill the drawn rectangle
mov rdi, r14
call gtk_widget_get_style_context
; GtkStyleContext *
; gtk_widget_get_style_context (GtkWidget *widget);
mov rdi, rax
mov rsi, 0
mov rdx, color
call gtk_style_context_get_color
;void
; gtk_style_context_get_color (GtkStyleContext *context,
; GtkStateFlags state,
; GdkRGBA *color);
mov rdi, r15
mov rsi, color
call gdk_cairo_set_source_rgba
;void
;gdk_cairo_set_source_rgba (cairo_t *cr,
; const GdkRGBA *rgba);
mov rdi, r15
call cairo_fill
;void
; cairo_fill (cairo_t *cr);
;A nice return value
mov rax, FALSE
ret
И, наконец, вот как я компилирую, связываю и запускаю код (на всякий случай)
nasm -felf64 -o code.o -l code.lst code.asm
ld -s -m elf_x86_64 code.o -o code -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2 -lgtk-3 -lpthread -lcairo -lgobject-2.0 -lglib-2.0 -lgdk_pixbuf-2.0 -lgdk-3
./code