bitshifter
Joined: 04 Dec 2007
Posts: 810
Location: Massachusetts, USA
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Xlib Window Example for x86_64 Linux ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format ELF64 executable 3
entry main
;;;;;;;;;;;;;;;;;;;;
;; import section ;;
;;;;;;;;;;;;;;;;;;;;
include 'import64.inc'
interpreter '/lib64/ld-linux-x86-64.so.2'
needed 'libX11.so.6'
import XOpenDisplay,\
XDefaultRootWindow,\
XCreateSimpleWindow,\
XSelectInput,\
XStoreName,\
XMapWindow,\
XInternAtom,\
XSetWMProtocols,\
XNextEvent,\
XDestroyWindow,\
XCloseDisplay
;;;;;;;;;;;;;;;;;;;;;
;; equates section ;;
;;;;;;;;;;;;;;;;;;;;;
; Xlib Constants
KeyPressMask = 1
KeyPress = 2
ClientMessage = 33
;;;;;;;;;;;;;;;;;;
;; code section ;;
;;;;;;;;;;;;;;;;;;
segment readable executable
main:
; note: rsp should be already aligned for 0-stack-arg calls
; Open connection to X server
xor rdi, rdi ; char *display_name (NULL)
call [XOpenDisplay]
test rax, rax
jz exit_main
mov [display_handle], rax
; Get default root window
mov rdi, rax ; Display *display
call [XDefaultRootWindow]
mov rsi, rax ; Window root
; Create simple window (9 parameters)
add rsp, 8 ; Remove 0-stack-arg padding to prepare for ODD manual pushes
mov rdi, [display_handle]
; rsi contains the root window handle from above ^^^
mov rdx, 0 ; 3rd: x
mov rcx, 0 ; 4th: y
mov r8, 320 ; 5th: width
mov r9, 240 ; 6th: height
push 0x00FFFFFF ; 9th: background color (white)
push 0x00000000 ; 8th: border color (black)
push 2 ; 7th: border width
call [XCreateSimpleWindow]
mov [window_handle], rax ; Save handle to global memory variable immediately
add rsp, 24 ; Clean up the 3 pushes
sub rsp, 8 ; Re-engage safety padding for 0-stack-arg calls
; Select Input Types
mov rdi, [display_handle] ; Display *display
mov rsi, [window_handle] ; Window w
mov rdx, KeyPressMask ; long event_mask
call [XSelectInput]
; Set window name
mov rdi, [display_handle] ; Display *display
mov rsi, [window_handle] ; Window w
mov rdx, window_name_str ; char *window_name
call [XStoreName]
; Map window to screen
mov rdi, [display_handle] ; Display *display
mov rsi, [window_handle] ; Window w
call [XMapWindow]
; Call Close Button Handler Sub-function
call register_wm_close
; Enter the event message loop
event_loop:
mov rdi, [display_handle] ; Display *display
mov rsi, event_buffer ; XEvent *event_return
call [XNextEvent]
mov eax, dword [event_buffer]
cmp eax, KeyPress
je event_loop_end
; TODO: handle other generic events here...
cmp eax, ClientMessage
jne event_loop
mov rax, qword [event_buffer + 56] ; data.l[0]
cmp rax, [wm_delete_window]
je event_loop_end
; TODO: handle other ClientMessage events here...
jmp event_loop
event_loop_end:
mov qword [exit_code], 0 ; exit status (success)
;exit_cleanup:
; Destroy Window instance
mov rdi, [display_handle] ; Display *display
mov rsi, [window_handle] ; Window w
call [XDestroyWindow]
; Close display connection
mov rdi, [display_handle] ; Display *display
call [XCloseDisplay]
exit_main:
mov rdi, [exit_code] ; exit status
mov rax, 60 ; exit syscall
syscall
; =============================================================================
register_wm_close:
sub rsp, 8
; Create 'WM_PROTOCOLS' Atom
mov rdi, [display_handle] ; Display *display
mov rsi, wm_protocols_str ; char *atom_name
xor rdx, rdx ; Bool only_if_exists
call [XInternAtom]
mov [wm_protocols], rax
; Create 'WM_DELETE_WINDOW' Atom
mov rdi, [display_handle] ; Display *display
mov rsi, wm_delete_window_str ; char *atom_name
xor rdx, rdx ; Bool only_if_exists
call [XInternAtom]
mov [wm_delete_window], rax
; Register protocols with window manager
mov rdi, [display_handle] ; Display *display
mov rsi, [window_handle] ; Window w
lea rdx, [wm_delete_window] ; Atom *protocols
mov rcx, 1 ; int count
call [XSetWMProtocols]
add rsp, 8
ret
; =============================================================================
;;;;;;;;;;;;;;;;;;
;; data section ;;
;;;;;;;;;;;;;;;;;;
segment readable writeable
align 8
exit_code dq 1 ; assume failure
display_handle dq 0
window_handle dq 0
; Explicitly align atoms to 8-byte (64-bit) boundaries
align 8
wm_protocols dq 0
wm_delete_window dq 0
wm_protocols_str db 'WM_PROTOCOLS', 0
wm_delete_window_str db 'WM_DELETE_WINDOW', 0
window_name_str db 'Hello Xlib Linux World!', 0
align 8
event_buffer rb 192
_________________ Coding a 3D game engine with fasm is like trying to eat an elephant,
you just have to keep focused and take it one 'byte' at a time.
|