The NASM code below creates a blank X11 window. No effort was made to make sure that the 'X' close button works properly.
Compile and link with:
nasm -f elf64 main.asm -o main.o
ld -melf_x86_64 -o main main.o -lX11 --dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc
The code:
global _start
extern XOpenDisplay
extern XNextEvent
extern XPending
extern XCreateSimpleWindow
extern XMapRaised
extern XSetStandardProperties
extern XCreateGC
extern XSetBackground
extern XSetForeground
extern XClearWindow
section .bss
dis: resq 1
screen: resd 1
win: resq 1
gc: resq 1
black_pixel: resq 1
root_window: resq 1
struc XDisplay
.trash_1: resb 224
.default_screen: resd 1
.nscreens: resd 1
.screens: resd 1
endstruc
struc XScreen
.trash_1: resb 16
.root: resq 1
.trash_2: resb 64
.white_pixel: resq 1
.black_pixel: resq 1
.trash_3: resb 24
.SIZE: resb 0
endstruc
section .text
init_x:
sub rsp, 8
xor rdi, rdi
call XOpenDisplay
mov qword [dis], rax
add rsp, 8
mov rax, qword [dis]
add rax, XDisplay.default_screen
mov eax, dword [rax]
mov dword [screen], eax
; black=BlackPixel(dis, screen)
; black = ((_XPrivDisplay)(dis))->screens[screen].black_pixel
mov rax, qword [dis]
mov rax, qword [rax + XDisplay.screens]
mov edx, dword [screen]
imul edx, XScreen.SIZE
add rax, rdx
mov rax, [rax + XScreen.black_pixel]
mov qword [black_pixel], rax
; root_window = DefaultRootWindow(dis)
; root_window = ((_XPrivDisplay)(dis))->screens[screen].root
mov rax, qword [dis]
mov rax, qword [rax + XDisplay.screens]
mov edx, dword [screen]
imul edx, XScreen.SIZE
add rax, rdx
mov rax, qword [rax + XScreen.root]
mov qword [root_window], rax
; Set up window and related
mov rax, [black_pixel]
push rax
push rax
push qword 0 ; I guess supposed to be 0?
mov rdi, [dis]
mov rsi, [root_window]
mov rdx, 0
mov rcx, 0
mov r8, 600
mov r9, 300
call XCreateSimpleWindow
mov [win], rax
pop rax
pop rax
pop rax
; Give the window a title
sub rsp, 8
push qword 0
push qword 0
mov rdi, [dis]
mov rsi, [win]
mov rdx, window_title
mov rcx, icon_name
mov r8, 0
mov r9, 0
call XSetStandardProperties
pop rax
pop rax
add rsp, 8
; Set background and show window
sub rsp, 8
mov rdi, [dis]
mov rsi, [win]
mov rdx, 0
call XCreateGC
mov qword [gc], rax
add rsp, 8
sub rsp, 8
mov rdi, [dis]
mov rsi, [gc]
mov rdx, [black_pixel]
call XSetBackground
add rsp, 8
sub rsp, 8
mov rdi, [dis]
mov rsi, [gc]
mov rdx, [black_pixel]
call XSetForeground
add rsp, 8
sub rsp, 8
mov rdi, [dis]
mov rsi, [win]
call XClearWindow
add rsp, 8
sub rsp, 8
mov rdi, [dis]
mov rsi, [win]
call XMapRaised
add rsp, 8
ret
_start:
; _start has no return address, so no need to align stack before init_x call.
call init_x
; event: rsp+0
sub rsp, 0xc0
.main_loop:
mov rdi, [dis]
lea rsi, [rsp+0]
call XNextEvent
mov rdi, [dis]
mov rsi, [win]
call XClearWindow
jmp .main_loop
mov rax, 60
syscall
section .data
window_title: db "window title", 0
icon_name: db "", 0 ; icon name? Not sure what this does. But it's part of XSetStandardProperties so...