initial commit
This commit is contained in:
BIN
build/main.o
Normal file
BIN
build/main.o
Normal file
Binary file not shown.
414
src/main.asm
Normal file
414
src/main.asm
Normal file
@@ -0,0 +1,414 @@
|
||||
;+------------------------------------------------------------------+
|
||||
;| Create simple window using ASMx86 with Xlib |
|
||||
;| --------------------------------------------- |
|
||||
;| |
|
||||
;| This source code demonstrates on how to create GUI using |
|
||||
;| ASMx86 NASM Language with Xlib. |
|
||||
;| |
|
||||
;| HOW TO COMPILE |
|
||||
;| ---------------- |
|
||||
;| |
|
||||
;| Open Terminal and use these commands: |
|
||||
;| $ nasm src/main.asm -o build/main.o -felf32 -w+all -gstabs |
|
||||
;| $ ld build/main.o -o bin/exe \ |
|
||||
;| -melf_i386 \ |
|
||||
;| -dynamic-linker /lib/ld-linux.so.2 \ |
|
||||
;| /lib/libX11.so.6 |
|
||||
;| |
|
||||
;| @author: Nik Mohamad Aizuddin b. Nik Azmi |
|
||||
;| @email : nickaizuddin93@gmail.com |
|
||||
;+------------------------------------------------------------------+
|
||||
|
||||
; ---- structure definition -----------------------------------------
|
||||
struc xserver
|
||||
.pDisplay: resd 1
|
||||
.pScreen: resd 1
|
||||
.screen_number: resd 1
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc xswa
|
||||
.background_pixmap: resd 1
|
||||
.background_pixel: resd 1
|
||||
.border_pixmap: resd 1
|
||||
.border_pixel: resd 1
|
||||
.bit_gravity: resd 1
|
||||
.win_gravity: resd 1
|
||||
.backing_store: resd 1
|
||||
.backing_planes: resd 1
|
||||
.backing_pixel: resd 1
|
||||
.save_under: resd 1
|
||||
.event_mask: resd 1
|
||||
.do_not_propagate_mask: resd 1
|
||||
.override_redirect: resd 1
|
||||
.colormap: resd 1
|
||||
.cursor: resd 1
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc xwin
|
||||
.rootwindow: resd 1
|
||||
.window: resd 1
|
||||
.x: resd 1
|
||||
.y: resd 1
|
||||
.width: resd 1
|
||||
.height: resd 1
|
||||
.border_width: resd 1
|
||||
.depth: resd 1
|
||||
.class: resd 1
|
||||
.visual: resd 1
|
||||
.valuemask: resd 1
|
||||
.wm_delete_msg: resd 1
|
||||
.atom_name: resd 4
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc xevent
|
||||
.data: resd 24
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
; ---- section read/write data --------------------------------------
|
||||
section .data
|
||||
|
||||
gui_t:
|
||||
istruc xserver
|
||||
at xserver.pDisplay, dd 0 ;+0
|
||||
at xserver.pScreen, dd 0 ;+1
|
||||
at xserver.screen_number, dd 0 ;+2
|
||||
iend
|
||||
|
||||
istruc xswa
|
||||
at xswa.background_pixmap, dd 0 ;+3
|
||||
at xswa.background_pixel, dd 0 ;+4
|
||||
at xswa.border_pixmap, dd 0 ;+5
|
||||
at xswa.border_pixel, dd 0 ;+6
|
||||
at xswa.bit_gravity, dd 0 ;+7
|
||||
at xswa.win_gravity, dd 0 ;+8
|
||||
at xswa.backing_store, dd 0 ;+9
|
||||
at xswa.backing_planes, dd 0 ;+10
|
||||
at xswa.backing_pixel, dd 0 ;+11
|
||||
at xswa.save_under, dd 0 ;+12
|
||||
at xswa.event_mask, dd 0b0000000000000000000000100 ;+13
|
||||
at xswa.do_not_propagate_mask, dd 0 ;+14
|
||||
at xswa.override_redirect, dd 0 ;+15
|
||||
at xswa.colormap, dd 0 ;+16
|
||||
at xswa.cursor, dd 0 ;+17
|
||||
iend
|
||||
|
||||
istruc xwin
|
||||
at xwin.rootwindow, dd 0 ;+18
|
||||
at xwin.window, dd 0 ;+19
|
||||
at xwin.x, dd 100 ;+20
|
||||
at xwin.y, dd 100 ;+21
|
||||
at xwin.width, dd 640 ;+22
|
||||
at xwin.height, dd 480 ;+23
|
||||
at xwin.border_width, dd 4 ;+24
|
||||
at xwin.depth, dd 24 ;+25
|
||||
at xwin.class, dd 1 ;+26
|
||||
at xwin.visual, dd 0 ;+27
|
||||
at xwin.valuemask, dd 0b000100000001010 ;+28
|
||||
at xwin.wm_delete_msg, dd 0 ;+29
|
||||
at xwin.atom_name, dd "WM_D" ;+30
|
||||
dd "ELET" ;+31
|
||||
dd "E_WI" ;+32
|
||||
dd "NDOW" ;+33
|
||||
iend
|
||||
|
||||
istruc xevent
|
||||
at xevent.data, times 24 dd 0
|
||||
iend
|
||||
|
||||
; ---- section instruction code -------------------------------------
|
||||
section .text
|
||||
|
||||
extern XOpenDisplay
|
||||
extern XDisplayName
|
||||
extern XDefaultScreen
|
||||
extern XDefaultScreenOfDisplay
|
||||
extern XRootWindow
|
||||
extern XWhitePixel
|
||||
extern XBlackPixel
|
||||
extern XCreateWindow
|
||||
extern XMapWindow
|
||||
extern XNextEvent
|
||||
extern XCloseDisplay
|
||||
extern XInternAtom
|
||||
extern XSetWMProtocols
|
||||
|
||||
global _start
|
||||
_start:
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; connect to x server by calling:
|
||||
; Display *XOpenDisplay(char *display_name)
|
||||
;
|
||||
; Set display_name=NULL because we want the XOpenDisplay()
|
||||
; to connect to the server specified in the UNIX environment
|
||||
; DISPLAY variable. Use BASH command "echo $DISPLAY" to view
|
||||
; the current contents of the DISPLAY environment variable.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 4 ;reserve 4 bytes
|
||||
mov dword [esp], 0 ;arg1: NULL
|
||||
call XOpenDisplay
|
||||
add esp, 4 ;restore 4 bytes
|
||||
mov [gui_t+xserver.pDisplay], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; get default screen by calling:
|
||||
; int XDefaultScreen(Display *display)
|
||||
;
|
||||
; This function should be used to retrieve the screen number in
|
||||
; applications that will use only a single screen.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 4 ;reserve 4 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov [esp], eax ;arg1: pDisplay
|
||||
call XDefaultScreen
|
||||
add esp, 4 ;restore 4 bytes
|
||||
mov [gui_t+xserver.screen_number], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; get pointer to the default screen:
|
||||
; Screen *XDefaultScreenOfDisplay(Display *display)
|
||||
;
|
||||
; This function returns a pointer to the default screen.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 4 ;reserve 4 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov [esp], eax ;arg1: pDisplay
|
||||
call XDefaultScreenOfDisplay
|
||||
add esp, 4 ;restore 4 bytes
|
||||
mov [gui_t+xserver.pScreen], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; set atom delete window message:
|
||||
; Atom XInternAtom(Display *display,
|
||||
; char *atom_name,
|
||||
; Bool only_if_exists)
|
||||
;
|
||||
; This function returns the atom identifier associated with the
|
||||
; specified atom_name string.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 12 ;reserve 12 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, gui_t
|
||||
add ebx, xserver.size
|
||||
add ebx, xswa.size
|
||||
add ebx, xwin.atom_name
|
||||
xor ecx, ecx
|
||||
mov [esp ], eax ;arg1: pDisplay
|
||||
mov [esp + 4], ebx ;arg2: atom_name
|
||||
mov [esp + 8], ecx ;arg3: FALSE
|
||||
call XInternAtom
|
||||
add esp, 12 ;restore 12 bytes
|
||||
mov [gui_t+xserver.size+xswa.size+xwin.wm_delete_msg], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; get rootwindow by calling:
|
||||
; Window XRootWindow(Display *display, int screen_number)
|
||||
;
|
||||
; Useful function if want a drawable of a particular screen
|
||||
; and for creating top-level windows.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 8 ;reserve 8 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.screen_number]
|
||||
mov [esp ], eax ;arg1: pDisplay
|
||||
mov [esp + 4], ebx ;arg2: screen_number
|
||||
call XRootWindow
|
||||
add esp, 8 ;restore 8 bytes
|
||||
mov [gui_t+xserver.size+xswa.size+\
|
||||
xwin.rootwindow], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; set window attribute background pixel color:
|
||||
; unsigned long XBlackPixel(Display *display, int screen_number)
|
||||
;
|
||||
; This function returns the black pixel value.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 8 ; reserve 8 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.screen_number]
|
||||
mov [esp ], eax ; arg1: pDisplay
|
||||
mov [esp + 4], ebx ; arg2: screen_number
|
||||
call XBlackPixel
|
||||
add esp, 8 ; restore 8 bytes
|
||||
mov [gui_t+xserver.size+\
|
||||
xswa.background_pixel], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; set window attribute border pixel color:
|
||||
; unsigned long XWhitePixel(Display *display, int screen_number)
|
||||
;
|
||||
; This function returns the white pixel value.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 8 ; reserve 8 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.screen_number]
|
||||
mov [esp ], eax ; arg1: pDisplay
|
||||
mov [esp + 4], ebx ; arg2: screen_number
|
||||
call XWhitePixel
|
||||
add esp, 8 ; restore 8 bytes
|
||||
mov [gui_t+xserver.size+\
|
||||
xswa.border_pixel], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; create the window:
|
||||
; Window XCreateWindow(Display display,
|
||||
; Window parent,
|
||||
; int x,
|
||||
; int y,
|
||||
; unsigned int width,
|
||||
; unsigned int height,
|
||||
; unsigned int border_width,
|
||||
; int depth,
|
||||
; unsigned int class,
|
||||
; Visual *visual,
|
||||
; unsigned long valuemask,
|
||||
; XSetWindowAttributes *attributes)
|
||||
;
|
||||
; This function creates an unmapped subwindow for a specified
|
||||
; parent window. It returns the window ID of the created window
|
||||
; and causes X server to generate a CreateNotify event.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 48 ;reserve 48 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+xwin.rootwindow]
|
||||
mov ecx, [gui_t+xserver.size+xswa.size+xwin.x]
|
||||
mov edx, [gui_t+xserver.size+xswa.size+xwin.y]
|
||||
mov [esp ], eax ;arg1
|
||||
mov [esp + 4], ebx ;arg2
|
||||
mov [esp + 8], ecx ;arg3
|
||||
mov [esp + 12], edx ;arg4
|
||||
mov eax, [gui_t+xserver.size+xswa.size+xwin.width]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+xwin.height]
|
||||
mov ecx, [gui_t+xserver.size+xswa.size+xwin.border_width]
|
||||
mov edx, [gui_t+xserver.size+xswa.size+xwin.depth]
|
||||
mov [esp + 16], eax ;arg5
|
||||
mov [esp + 20], ebx ;arg6
|
||||
mov [esp + 24], ecx ;arg7
|
||||
mov [esp + 28], edx ;arg8
|
||||
mov eax, [gui_t+xserver.size+xswa.size+xwin.class]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+xwin.visual]
|
||||
mov ecx, [gui_t+xserver.size+xswa.size+xwin.valuemask]
|
||||
mov edx, gui_t
|
||||
add edx, xserver.size
|
||||
mov [esp + 32], eax ;arg9
|
||||
mov [esp + 36], ebx ;arg10
|
||||
mov [esp + 40], ecx ;arg11
|
||||
mov [esp + 44], edx ;arg12
|
||||
call XCreateWindow
|
||||
add esp, 48 ;restore 48 bytes
|
||||
mov [gui_t+xserver.size+xswa.size+xwin.window], eax
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; overwrite WM_PROTOCOLS property with specified atom:
|
||||
; Status XSetWMProtocols(Display *display,
|
||||
; Window w,
|
||||
; Atom *protocols,
|
||||
; int count)
|
||||
;
|
||||
; If the function failed to intern the WM_PROTOCOLS, the return
|
||||
; status will be zero.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 16 ;reserve 16 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+xwin.window]
|
||||
mov ecx, gui_t
|
||||
add ecx, xserver.size
|
||||
add ecx, xswa.size
|
||||
add ecx, xwin.wm_delete_msg
|
||||
mov edx, 1
|
||||
mov [esp ], eax ;arg1: pDisplay
|
||||
mov [esp + 4], ebx ;arg2: window
|
||||
mov [esp + 8], ecx ;arg3: wm_delete_msg
|
||||
mov [esp + 12], edx ;arg4: 1
|
||||
call XSetWMProtocols
|
||||
add esp, 16 ;restore 16 bytes
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; map the window:
|
||||
; void XMapWindow(Display *display, Window w)
|
||||
;
|
||||
; This function maps the window and all of its subwindows that have
|
||||
; map requests.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 8 ;reserve 8 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+\
|
||||
xwin.window]
|
||||
mov [esp ], eax ;arg1
|
||||
mov [esp + 4], ebx ;arg2
|
||||
call XMapWindow
|
||||
add esp, 8 ;restore 8 bytes
|
||||
|
||||
mainloop:
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; Get event:
|
||||
; XNextEvent(Display *display, XEvent *event_return)
|
||||
;
|
||||
; This function copies the first event from the event queue into the
|
||||
; specified XEvent structure and then removes it from the queue. If
|
||||
; the event queue is empty, XNextEvent flushes the output buffer and
|
||||
; blocks until an event is received.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 8 ;reserve 8 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov ebx, gui_t
|
||||
add ebx, xserver.size
|
||||
add ebx, xswa.size
|
||||
add ebx, xwin.size
|
||||
mov [esp ], eax ;arg1
|
||||
mov [esp + 4], ebx ;arg2
|
||||
call XNextEvent
|
||||
add esp, 8 ;restore 8 bytes
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; exit if type of event is buttonpress
|
||||
; -------------------------------------------------------------------
|
||||
mov eax, [gui_t+xserver.size+xswa.size+\
|
||||
xwin.size+xevent.data+0]
|
||||
cmp eax, 0b0100
|
||||
je exit
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; exit if button "X" is clicked
|
||||
; -------------------------------------------------------------------
|
||||
mov eax, [gui_t+xserver.size+xswa.size+\
|
||||
xwin.size+xevent.data+0]
|
||||
cmp eax, 0b100001
|
||||
jne is_not_msg_delete
|
||||
is_msg_delete:
|
||||
mov eax, [gui_t+xserver.size+xswa.size+\
|
||||
xwin.size+xevent.data+28]
|
||||
mov ebx, [gui_t+xserver.size+xswa.size+\
|
||||
xwin.wm_delete_msg]
|
||||
cmp eax, ebx
|
||||
je exit
|
||||
is_not_msg_delete:
|
||||
|
||||
jmp mainloop
|
||||
|
||||
exit:
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; disconnect from X Server:
|
||||
; void XCloseDisplay(Display *display)
|
||||
;
|
||||
; This function destroys all windows, resource IDs, and other
|
||||
; resources created by the client on this display.
|
||||
; -------------------------------------------------------------------
|
||||
sub esp, 4 ;reserve 4 bytes
|
||||
mov eax, [gui_t+xserver.pDisplay]
|
||||
mov [esp], eax ;arg1
|
||||
call XCloseDisplay
|
||||
add esp, 4 ;restore 4 bytes
|
||||
|
||||
; -------------------------------------------------------------------
|
||||
; system call exit
|
||||
; -------------------------------------------------------------------
|
||||
mov eax, 0x1
|
||||
mov ebx, 0x0
|
||||
int 0x80
|
||||
Reference in New Issue
Block a user