; rudimentary "hello world" for Xwindows
; translated from a nasm sample supplied by Frank Kotler.
; LD is used as linker, since WLINK doesn't know how to use shared objects.
;
; 1. assemble: jwasm -elf -Fo=Linux3.o Linux3.asm
; 2. link with LD: ld -s -o Linux3 Linux3.o -I/lib/ld-linux.so.2 -L/usr/X11R6/lib -lX11
.386
.model flat
public _start
;--- The X functions don't have a underscore prefix.
;--- Therefore SYSCALL is used in the prototypes.
;--- If C is to be used instead, the -zcw cmdline parameter is needed.
XOpenDisplay proto syscall :DWORD
XDefaultRootWindow proto syscall :DWORD
XCreateSimpleWindow proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
XSelectInput proto syscall :DWORD, :DWORD, :DWORD
XStoreName proto syscall :DWORD, :DWORD, :DWORD
XMapRaised proto syscall :DWORD, :DWORD
XCreateGC proto syscall :DWORD, :DWORD, :DWORD, :DWORD
XSetForeground proto syscall :DWORD, :DWORD, :DWORD
XSetBackground proto syscall :DWORD, :DWORD, :DWORD
XNextEvent proto syscall :DWORD, :DWORD
XFreeGC proto syscall :DWORD, :DWORD
XDestroyWindow proto syscall :DWORD, :DWORD
XCloseDisplay proto syscall :DWORD
XDrawImageString proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
KeyPressMask equ 1 ; mask for XSelectInput
KeyPress equ 2 ; the "type" of event (offset 0 in "glob of bytes")
ExposeMask equ 1 shl 15
ExposeEvent equ 12
event_size equ 20h ; ??? max size of several different structs
;------------------------------------------
.data
StringOpenFailed db "Can't Open X display!", 10
caption db 'A Window', 0
string db ' Greetings from X, Earthling! '
;-----------------------------------------
.data?
Display dd ?
Window dd ?
GC dd ?
event dd event_size dup (?)
;-------------------------------------
.code
_start: ; let the ritual begin.
; open a connection to the server.
; param 0 uses the "DISPLAY" environment variable
; or defaults to local machine.
invoke XOpenDisplay, 0
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset StringOpenFailed; buffer
mov edx, sizeof StringOpenFailed; count
int 80h
jmp Terminate
.endif
mov [Display], eax
invoke XDefaultRootWindow, [Display]
; error?
;--- params: display handle, defaultrootwindow, left, top, width, height
;--- border width, border colour, background colour
invoke XCreateSimpleWindow, [Display], eax, 50, 50, 400, 300, 0, 0, 0
.if (eax == 0)
invoke XCloseDisplay, [Display]
jmp Terminate
.endif
mov [Window], eax
; this is one Windows doesn't do. if we don't specify
; what events (messages) we want to receive, we don't get any.
; "or" this with other events to recv!
; don't forget to handle 'em!
invoke XSelectInput, [Display], [Window], KeyPressMask or ExposeMask
; error?
; give the baby a name
invoke XStoreName, [Display], [Window], offset caption
; error?
invoke XMapRaised, [Display], [Window] ; make our window visible.
; error?
invoke XCreateGC, [Display], [Window], 0, 0
; error?
mov [GC], eax
; Mmmm, looks like 16-bit color, 5-6-5, on my machine.
; Bet we can't count on it!
; 1111100000000000b = red
invoke XSetForeground, [Display], [GC], 1111100000000000b
; error?
; 0000011111100000b = green
invoke XSetBackground, [Display], [GC], 0000011111100000b
; error?
.while (1)
invoke XNextEvent, [Display], offset event
; error?
.if (dword ptr [event+0] == ExposeEvent)
invoke XDrawImageString, [Display], [Window], [GC], 155, 140, offset string, sizeof string
.elseif (dword ptr [event+0] == KeyPress)
.break ; exit gracefully if key pressed
.endif
.endw
invoke XFreeGC, [Display], [GC]
invoke XDestroyWindow, [Display], [Window]
invoke XCloseDisplay, [Display]
Terminate:
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
end _start
|