; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Window management OS interface functions.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



body _CreateWindow

.attr XSetWindowAttributes
.vis  XVisualInfo

.prop dd ?

begin
        pushad
        mov     esi, [.pWindow]

        cinvoke XDefaultScreen, [hApplicationDisplay]
        mov     edx, eax
        lea     eax, [.vis]
        cinvoke XMatchVisualInfo, [hApplicationDisplay], edx, $20, TrueColor, eax

        cinvoke XCreateColormap, [hApplicationDisplay], [hRootWindow], [.vis.Visual], AllocNone
        mov     [.attr.colormap], eax

; border

        mov     ecx, [esi+TWindow._border]
        test    ecx, ecx                        ; borderNone = 0
        setz    al
        movzx   eax, al
        mov     [.attr.override_redirect], eax

        and     ecx, $3
        mov     eax, [.types+4*ecx]
        mov     [.prop], eax

        xor     eax, eax
        mov     [.attr.backing_store], eax              ; NotUseful
        mov     [.attr.background_pixmap], eax          ; None
        mov     [.attr.border_pixel], eax               ; 0
        mov     [.attr.event_mask], ExposureMask or FocusChangeMask or       \
                                    KeyPressMask or KeyReleaseMask or        \
                                    ButtonPressMask or ButtonReleaseMask or  \
                                    EnterWindowMask or LeaveWindowMask or    \
                                    PointerMotionMask or StructureNotifyMask

        lea     eax, [.attr]
        cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow],                                            \
                               [esi+TWindow._x], [esi+TWindow._y], [esi+TWindow._width], [esi+TWindow._height], \
                               0, $20, InputOutput, [.vis.Visual],                                              \
                               CWBackingStore or CWOverrideRedirect or                                          \
                               CWBorderPixel or CWColormap or                                                   \
                               CWEventMask or CWBackPixmap, eax

        mov     edi, eax
        test    eax, eax
        jz      .exit           ; Error processing???

        cinvoke XChangeProperty, [hApplicationDisplay], edi, [atomWindowType], XA_ATOM, 32, PropModeReplace, [.prop], 1
        cinvoke XSetWMProtocols, [hApplicationDisplay], edi, atomWMDelete, 1
        cinvoke XSaveContext,    [hApplicationDisplay], edi, win_structure_context, esi

; the caption
        mov     eax, [esi+TWindow._caption]
        test    eax, eax
        jz      .show

        stdcall StrPtr, eax
        cinvoke XStoreName, [hApplicationDisplay], edi, eax

.show:
        cinvoke XMapWindow, [hApplicationDisplay], edi
.exit:
        mov     [esp+4*regEAX], edi
        popad
        return


.types  dd  atomWindowTypeMenu, atomWindowTypeNormal, atomWindowTypeDialog, atomWindowTypeUtility


endp


;_________________________________________________________________________________________



body _DestroyWindow
begin
        push    eax ecx edx
        cinvoke XSaveContext,   [hApplicationDisplay], [.hwnd], win_structure_context, 0
        cinvoke XDestroyWindow, [hApplicationDisplay], [.hwnd]
        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________



proc _GetParent, .hwnd
.root dd ?
.parent dd ?
.children dd ?
.count    dd ?
begin
        push    ecx edx esi

        lea     esi, [.count]
        lea     edx, [.children]
        lea     ecx, [.parent]
        lea     eax, [.root]
        cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, esi
        test    eax, eax
        jz      .exit   ; function failed

        cinvoke XFree, [.children]

        mov     eax, [.parent]

.exit:
        pop     esi edx ecx
        return
endp



;_________________________________________________________________________________________


body _ClientToScreen
.attr XWindowAttributes
begin
        push    eax

.loop:
        lea     ecx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ecx

        mov     ecx, [.attr.x]
        mov     edx, [.attr.y]
        add     [.x], ecx
        add     [.y], edx

        stdcall _GetParent, [.hwnd]
        mov     [.hwnd], eax
        test    eax, eax
        jnz     .loop

        mov     ecx, [.x]
        mov     edx, [.y]

        pop     eax
        return
endp


;_________________________________________________________________________________________


body _ShowWindow
begin
        push    eax ecx edx

        mov     ecx, XUnmapWindow
        cmp     [.flag], 0
        je      @f
        mov     ecx, XMapWindow
@@:
        push    [.hwnd] [hApplicationDisplay]
        call    dword [ecx]
        add     esp, 8

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


body _RefreshWindowRect
begin
        push    eax ecx edx
        cinvoke XClearArea, [hApplicationDisplay], [.hwnd], [.x], [.y], [.width], [.height], TRUE
        cinvoke XFlush, [hApplicationDisplay]
        pop     edx ecx eax
        return
endp


;body _RefreshWindowRect
;begin
;        push    eax ecx edx
;
;        stdcall _GetWindowStruct, [.hwnd]
;        mov     ecx, eax
;
;        mov     eax, [ecx+TWindow._screen]
;        test    eax, eax
;        jnz     .draw
;
;        mov     eax, [ecx+TWindow._canvas]
;        test    eax, eax
;        jz      .exit
;
;.draw:
;        stdcall DrawImageRect, [.hwnd], eax, [.x], [.y], [.x], [.y], [.width], [.height]
;
;.exit:
;        pop     edx ecx eax
;        return
;endp


;_________________________________________________________________________________________


body _SetWindowTextUtf8
begin
        push    eax ecx edx
        cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


body _SetModalTowards
begin
        push    eax ecx edx


        cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]

; The following is not working for every window manager!!! It is not a problem of the below code. (probably... :)

        cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateAbove, 1
        cinvoke XChangeProperty, [hApplicationDisplay], [.hwnd], [atomState], XA_ATOM, 32, PropModeAppend, atomStateModal, 1

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________



body _FinalizeModal
  .flushevent XEvent
begin
        push    eax ecx edx

; dirty hack, but the button receives LeaveNotify after DestroyNotify
        cinvoke XSync, [hApplicationDisplay], FALSE

.loop_flush:
        lea     eax, [.flushevent]
        cinvoke XCheckMaskEvent, [hApplicationDisplay], LeaveWindowMask, eax
        test    eax, eax
        jnz     .loop_flush

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


win_structure_context = 1


body _GetWindowStruct
  .user_data dd ?
begin
        push    ecx edx
        lea     eax, [.user_data]
        cinvoke XFindContext, [hApplicationDisplay], [.hwin], win_structure_context, eax

        test    eax, eax
        jnz     .error

        mov     eax, [.user_data]
        clc
        pop     edx ecx
        return

.error:
        OutputValue "FreshLib: Error window context. Call from $", [ebp+4], 16, 8

        stc
        pop      edx ecx
        return
endp




;_________________________________________________________________________________________



body _SetWindowStruct
begin
        push    eax ecx edx
        cinvoke XSaveContext, [hApplicationDisplay], [.hwin], win_structure_context, [.value]
        pop     edx ecx eax
        return
endp






