1 2; rudimentary "hello world" for Xwindows 3; translated from a nasm sample supplied by Frank Kotler. 4; LD is used as linker, since WLINK doesn't know how to use shared objects. 5; 6; 1. assemble: jwasm -elf -Fo=Linux3.o Linux3.asm 7; 2. link with LD: ld -s -o Linux3 Linux3.o -I/lib/ld-linux.so.2 -L/usr/X11R6/lib -lX11 8 9 .386 10 .model flat 11 12 public _start 13 14;--- The X functions don't have a underscore prefix. 15;--- Therefore SYSCALL is used in the prototypes. 16;--- If C is to be used instead, the -zcw cmdline parameter is needed. 17 18XOpenDisplay proto syscall :DWORD 19XDefaultRootWindow proto syscall :DWORD 20XCreateSimpleWindow proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD 21XSelectInput proto syscall :DWORD, :DWORD, :DWORD 22XStoreName proto syscall :DWORD, :DWORD, :DWORD 23XMapRaised proto syscall :DWORD, :DWORD 24XCreateGC proto syscall :DWORD, :DWORD, :DWORD, :DWORD 25XSetForeground proto syscall :DWORD, :DWORD, :DWORD 26XSetBackground proto syscall :DWORD, :DWORD, :DWORD 27XNextEvent proto syscall :DWORD, :DWORD 28XFreeGC proto syscall :DWORD, :DWORD 29XDestroyWindow proto syscall :DWORD, :DWORD 30XCloseDisplay proto syscall :DWORD 31XDrawImageString proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD 32 33KeyPressMask equ 1 ; mask for XSelectInput 34KeyPress equ 2 ; the "type" of event (offset 0 in "glob of bytes") 35 36ExposeMask equ 1 shl 15 37ExposeEvent equ 12 38 39event_size equ 20h ; ??? max size of several different structs 40 41;------------------------------------------ 42 .data 43 StringOpenFailed db "Can't Open X display!", 10 44 caption db 'A Window', 0 45 string db ' Greetings from X, Earthling! ' 46 47;----------------------------------------- 48 .data? 49 50Display dd ? 51Window dd ? 52GC dd ? 53 54event dd event_size dup (?) 55 56;------------------------------------- 57 58 .code 59 60_start: ; let the ritual begin. 61; open a connection to the server. 62; param 0 uses the "DISPLAY" environment variable 63; or defaults to local machine. 64 invoke XOpenDisplay, 0 65 .if (eax == 0) 66 mov eax, 4 ; __NR_write 67 mov ebx, 2 ; stderr 68 mov ecx, offset StringOpenFailed; buffer 69 mov edx, sizeof StringOpenFailed; count 70 int 80h 71 jmp Terminate 72 .endif 73 mov [Display], eax 74 75 invoke XDefaultRootWindow, [Display] 76 ; error? 77;--- params: display handle, defaultrootwindow, left, top, width, height 78;--- border width, border colour, background colour 79 invoke XCreateSimpleWindow, [Display], eax, 50, 50, 400, 300, 0, 0, 0 80 .if (eax == 0) 81 invoke XCloseDisplay, [Display] 82 jmp Terminate 83 .endif 84 mov [Window], eax 85; this is one Windows doesn't do. if we don't specify 86; what events (messages) we want to receive, we don't get any. 87; "or" this with other events to recv! 88; don't forget to handle 'em! 89 invoke XSelectInput, [Display], [Window], KeyPressMask or ExposeMask 90 ; error? 91 ; give the baby a name 92 invoke XStoreName, [Display], [Window], offset caption 93 ; error? 94 invoke XMapRaised, [Display], [Window] ; make our window visible. 95 ; error? 96 invoke XCreateGC, [Display], [Window], 0, 0 97 ; error? 98 mov [GC], eax 99; Mmmm, looks like 16-bit color, 5-6-5, on my machine. 100; Bet we can't count on it! 101; 1111100000000000b = red 102 invoke XSetForeground, [Display], [GC], 1111100000000000b 103 ; error? 104; 0000011111100000b = green 105 invoke XSetBackground, [Display], [GC], 0000011111100000b 106 ; error? 107 108 .while (1) 109 invoke XNextEvent, [Display], offset event 110 ; error? 111 .if (dword ptr [event+0] == ExposeEvent) 112 invoke XDrawImageString, [Display], [Window], [GC], 155, 140, offset string, sizeof string 113 .elseif (dword ptr [event+0] == KeyPress) 114 .break ; exit gracefully if key pressed 115 .endif 116 .endw 117 118 invoke XFreeGC, [Display], [GC] 119 invoke XDestroyWindow, [Display], [Window] 120 invoke XCloseDisplay, [Display] 121 122Terminate: 123 mov eax, 1 ; function (sys_exit) 124 xor ebx, ebx ; exit code 125 int 80h ; make Linux system call 126 127 end _start 128