Rattling skeletons of X



Okay, this isn't the "Xkeleton" Wannabee requested. Merely the shadow of a ghost of a skeleton. I'll post it anyway, just to see if we're on the same wavelength as to what's wanted. This is pretty much cribbed from Beth's "Xample"... much the same as Numit_or's example... much the same as Mammon's (Gas) example...

All it does is throw up a window - resizeable and moveable and that good *** - but with no "content". Any key (or the X up in the corner - depending on window manager) quits. Big deal. Much to do...

Later,
Frank

; nasm -f elf x0.asm
; add the "-g" switch for debugging info - good luck!
;
; sorry 'bout this one...
; ld -s -o x0 x0.o -I/lib/ld-linux.so.2 -L/usr/X11R6/lib -lX11
;
; if you want it small:
; strip -R .comment x0
;
; after all that, we still have to tell ld where the fun begins:

global _start

; inform Nasm that ld knows where to find this stuff (we hope!)

extern XOpenDisplay
extern XDefaultRootWindow
extern XCreateSimpleWindow
extern XNextEvent
extern XDestroyWindow
extern XCloseDisplay
extern XMapRaised
extern XSelectInput

; we'll be needing lots more of these...

%define KeyPress 2     ; the "type" of event (offset 0 in "glob of bytes")
%define KeyPressMask 1 ; mask for XSelectInput

event_size equ 20h    ; ??? max size of several different structs
                      ; oops, I mean "globs of bytes" :), in dwords
		      ; I *think* the biggest one is 15 dwords(???)


; a rudimentary "RosAsm compatibility" macro. ; we need a space after this for it to work! ; Note that this depends on undocumented Nasm syntax!!!

%define D$ dword &

section .data
    StringOpenFailed db "Can't Open X display!", 10
    StringOpenFailed_len equ $ - StringOpenFailed

section .bss

; these are "handles".
    Display resd 1
    Window resd 1

; this is a place for XNextEvent to put a "glob of bytes".
    event resd event_size


section .text

_start:    ; let the ritual begin.

;    nop   ; parking place for gdb

; open a connection to the server.
; pushing 0 uses the "DISPLAY" environment variable
; or defaults to local machine.

    push byte 0
    call XOpenDisplay
    add esp, byte 4

    or eax, eax
    je near OpenFailed

    mov D$ Display, eax

    push D$ Display
    call XDefaultRootWindow
    add esp, byte 4
    ; error?

    push byte 0              ; background colour
    push byte 0              ; border colour
    push byte 0              ; border width
    push 300                 ; height
    push 400                 ; width
    push byte 50             ; top co-ord
    push byte 50             ; left co-ord
    push eax                 ; XDefaultRootWindow, from above
    push D$ Display          ; display handle
    call XCreateSimpleWindow ; create window
    add esp, byte 36         ; C clean-up parameters stuff

    or eax, eax
    je CreateFailed

    mov D$ 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.

    push KeyPressMask      ; "or" this with other events to recv!
                           ; don't forget to handle 'em!
    push D$ Window
    push D$ Display
    call XSelectInput
    add esp, byte 12
    ; error?

; make our window visible.

    push D$ Window
    push D$ Display
    call XMapRaised
    add esp, byte 8
    ; error?

; world's simplest messageloop, for any "real" program,
; we'll have to handle a *lot* more than just "exit on keypress"!

MessageLoop:
    push event
    push D$ Display
    call XNextEvent
    add esp, byte 8
    ; error?

    cmp D$ event, KeyPress
    jne MessageLoop

; exit gracefully

    push D$ Window
    push D$ Display
    call XDestroyWindow
    add esp, byte 8

CreateFailed:
    push D$ Display
    call XCloseDisplay
    add esp, byte 4
    jmp Terminate

OpenFailed:
    mov eax, 4                      ; __NR_write
    mov ebx, 2                      ; stderr
    mov ecx, StringOpenFailed       ; buffer
    mov edx, StringOpenFailed_len   ; count
    int 80h

Terminate:
    mov eax, 1     ; function (sys_exit)
    xor ebx, ebx   ; exit code
    int 80h        ; make Linux system call
;-------------------------------------------
.