; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: TApplication object class.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: TApplication by the idea is the base of GUI application, but the implementation
;         somehow need fixing...
;_________________________________________________________________________________________


uglobal
  if used hApplicationDisplay
    var hApplicationDisplay = ?
    var hRootWindow = ?

    var flagSharedMemory = ?

    var hInputMethod = ?
    var hInputContext = ?

    var atomWMDelete = ?

    var atomState = ?
    var atomStateAbove = ?
    var atomStateModal = ?

    var atomAllowedActions = ?
    var atomActionMove = ?
    var atomActionResize = ?
    var atomActionMinimize = ?
    var atomActionShade = ?
    var atomActionStick = ?
    var atomActionMaximizeHorz = ?
    var atomActionMaximizeVert = ?
    var atomActionFullscreen = ?
    var atomActionChangeDesktop = ?
    var atomActionClose = ?

    var atomWindowType = ?
    var atomWindowTypeMenu = ?
    var atomWindowTypeUtility = ?
    var atomWindowTypeDialog = ?
    var atomWindowTypeNormal = ?

    var ShmCompletionEvent = ?
    var FTLibrary = ?
    var FTCManager = ?
    var FTCImageCache = ?
    var FTCCMapCache = ?
  end if
endg



;XNVaNestedList                text "XNVaNestedList"
;XNSeparatorofNestedList       text "separatorofNestedList"
;XNQueryInputStyle             text "queryInputStyle"
;XNClientWindow                text "clientWindow"
;XNInputStyle                  text "inputStyle"
;XNFocusWindow                 text "focusWindow"
;XNResourceName                text "resourceName"
;XNResourceClass               text "resourceClass"
;XNGeometryCallback            text "geometryCallback"
;XNDestroyCallback             text "destroyCallback"
;XNFilterEvents                text "filterEvents"
;XNPreeditStartCallback        text "preeditStartCallback"
;XNPreeditDoneCallback         text "preeditDoneCallback"
;XNPreeditDrawCallback         text "preeditDrawCallback"
;XNPreeditCaretCallback        text "preeditCaretCallback"
;XNPreeditStateNotifyCallback  text "preeditStateNotifyCallback"
;XNPreeditAttributes           text "preeditAttributes"
;XNStatusStartCallback         text "statusStartCallback"
;XNStatusDoneCallback          text "statusDoneCallback"
;XNStatusDrawCallback          text "statusDrawCallback"
;XNStatusAttributes            text "statusAttributes"
;XNArea                        text "area"
;XNAreaNeeded                  text "areaNeeded"
;XNSpotLocation                text "spotLocation"
;XNColormap                    text "colorMap"
;XNStdColormap                 text "stdColorMap"
;XNForeground                  text "foreground"
;XNBackground                  text "background"
;XNBackgroundPixmap            text "backgroundPixmap"
;XNFontSet                     text "fontSet"
;XNLineSpace                   text "lineSpace"
;XNCursor                      text "cursor"
;XNQueryIMValuesList           text "queryIMValuesList"
;XNQueryICValuesList           text "queryICValuesList"
;XNStringConversionCallback    text "stringConversionCallback"
;XNStringConversion            text "stringConversion"
;XNResetState                  text "resetState"
;XNHotKey                      text "hotkey"
;XNHotKeyState                 text "hotkeyState"
;XNPreeditState                text "preeditState"
;XNVisiblePosition             text "visiblePosition"
;XNR6PreeditCallbackBehavior   text "r6PreeditCallback"
;XNRequiredCharSet             text "requiredCharSet"
;XNQueryOrientation            text "queryOrientation"
;XNDirectionalDependentDrawing text "directionalDependentDrawing"
;XNContextualDrawing           text "contextualDrawing"
;XNBaseFontName                text "baseFontName"
;XNMissingCharSet              text "missingCharSet"
;XNDefaultString               text "defaultString"
;XNOrientation                 text "orientation"
;XNFontInfo                    text "fontInfo"
;XNOMAutomatic                 text "omAutomatic"




method TApplication.__create
.ptr dd ?
begin
        cinvoke XInitThreads
        test    eax, eax
        jz      .exit_error

        cinvoke XSetErrorHandler, __FreshXErrorHandler

        mov     ecx, 5

.disp_loop:
        push    ecx
        cinvoke XOpenDisplay, 0
        pop     ecx

        test    eax, eax
        jnz     .continue

        stdcall Sleep, 245      ; wait a little.
        loop    .disp_loop
        jmp     .error_disp

.continue:
        OutputValue "Display opened: ", eax, 16, 0
        mov     [hApplicationDisplay], eax

  if defined options.DebugMode.XSync & options.DebugMode.XSync
        cinvoke XSynchronize, [hApplicationDisplay], TRUE
;        cinvoke XSetAfterFunction, [hApplicationDisplay], XAfterFunction
  end if

        cinvoke XShmGetEventBase, [hApplicationDisplay]
        mov     [ShmCompletionEvent], eax

        cinvoke XDefaultRootWindow, [hApplicationDisplay]
        mov     [hRootWindow], eax

        cinvoke XOpenIM, [hApplicationDisplay], 0, 0, 0
        mov     [hInputMethod], eax

        lea     eax, [.ptr]
        cinvoke XGetIMValues, [hInputMethod], "queryInputStyle", eax, 0

        mov     eax, [.ptr]
        mov     eax, [eax+4]
        cinvoke XCreateIC, [hInputMethod], "inputStyle", [eax], 0
        mov     [hInputContext], eax

        cinvoke XFree, [.ptr]

        stdcall InitMouseCursors

; Creating internal atoms that to be used with Window manager of the application windows...
; Maybe this code should reside somewhere else, not in application. In initialize TWindow???

        cinvoke XInternAtom, [hApplicationDisplay], "WM_DELETE_WINDOW", 1
        mov     [atomWMDelete], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE", 1
        mov     [atomState], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_ABOVE", 1
        mov     [atomStateAbove], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_STATE_MODAL", 1
        mov     [atomStateModal], eax

;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ALLOWED_ACTIONS", 1
;        mov     [atomAllowedActions], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MOVE", 1
;        mov     [atomActionMove], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_RESIZE", 1
;        mov     [atomActionResize], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MINIMIZE", 1
;        mov     [atomActionMinimize], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_SHADE", 1
;        mov     [atomActionShade], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_STICK", 1
;        mov     [atomActionStick], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_HORZ", 1
;        mov     [atomActionMaximizeHorz], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_MAXIMIZE_VERT", 1
;        mov     [atomActionMaximizeVert], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_FULLSCREEN", 1
;        mov     [atomActionFullscreen], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CHANGE_DESKTOP", 1
;        mov     [atomActionChangeDesktop], eax
;        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_ACTION_CLOSE", 1
;        mov     [atomActionClose], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE", 1
        mov     [atomWindowType], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_POPUP_MENU", 1
        mov     [atomWindowTypeMenu], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_UTILITY", 1
        mov     [atomWindowTypeUtility], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_DIALOG", 1
        mov     [atomWindowTypeDialog], eax

        cinvoke XInternAtom, [hApplicationDisplay], "_NET_WM_WINDOW_TYPE_NORMAL", 1
        mov     [atomWindowTypeNormal], eax

; XShm extension check

        cinvoke XShmQueryExtension, [hApplicationDisplay]
        mov     [flagSharedMemory], eax

        OutputValue "XSHM extension available:", eax, 10, -1

        cinvoke FT_Init_FreeType, FTLibrary
        test    eax, eax
        jnz     .error_ft

        cinvoke FTC_Manager_New, [FTLibrary], 0, 0, 0, FTCRequester, 0, FTCManager
        cinvoke FTC_ImageCache_New, [FTCManager], FTCImageCache
        cinvoke FTC_CMapCache_New, [FTCManager], FTCCMapCache

; clipboard initialization.
if __UseClipboard = 1
        stdcall   __InitLinuxClipboard
end if

        clc
        return

.error_ft:

        DebugMsg 'Error initializing FreeType library.'
        jmp      .exit_error

.error_disp:
        DebugMsg 'Error open display.'

.exit_error:
        stc
        return

endp



cXErrorMsg  text 'X server error:'
cXErrorMsg2 text 10, 0
cXErrorMsg3 text 'Request: '
cXErrorMsg4 text 'Minor code: '
cXErrorMsg5 text 'ResourceID: $'

proc __FreshXErrorHandler, .display, .error
.buff rb 512
begin
if defined options.DebugMode.XErrors & options.DebugMode.XErrors

        cmp     [fGlobalTerminate], 0
        jne     .exit

        stdcall Output, cXErrorMsg
        mov      ebx, [.error]

        movzx    eax, [ebx+XErrorEvent.error_code]
        lea      ecx, [.buff]
        cinvoke XGetErrorText, [.display], eax, ecx, 512

        lea     ecx, [.buff]
        stdcall Output, ecx
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg3
        movzx    eax, [ebx+XErrorEvent.request_code]
        stdcall OutputNumber, eax, 10, 3
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg4
        movzx    eax, [ebx+XErrorEvent.minor_code]
        stdcall OutputNumber, eax, 10, 3
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg5
        stdcall OutputNumber, [ebx+XErrorEvent.resourceid], 16, 8
        stdcall Output, cXErrorMsg2
        stdcall Output, cXErrorMsg2
end if
.exit:
        cret
endp


proc XAfterFunction, .display
begin
        DebugMsg "XAfterFunction call"
        cret
endp



; This code and data possibly will be used in FreshLib, but I hope, not very soon. :)

;        cinvoke XInternAtom, [hApplicationDisplay], _cWinSyncRequest, 0
;        mov     [atomSyncRequest], eax
;
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cAtomTypeAtom, 0
;        mov     [atomTypeATOM], eax
;
;; _NET_WM_WINDOW_TYPE
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeAtomName, 0
;        mov     [atomWMType], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDlg, 0
;        mov     [atomWinTypeDlg], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeTool, 0
;        mov     [atomWinTypeTool], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDock, 0
;        mov     [atomWinTypeDock], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeNormal, 0
;        mov     [atomWinTypeNormal], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.text, 0
;        mov     [atomAllowedActions], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.minimize.text, 0
;        mov     [atomAllowedActions.minimize], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.close.text, 0
;        mov     [atomAllowedActions.close], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomWMState.text, 0
;        mov     [atomWMState], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomWMState.modal.text, 0
;        mov     [atomWMState.modal], eax
;

;_cWinTypeAtomName text '_NET_WM_WINDOW_TYPE'
;  _cWinTypeDlg      text '_NET_WM_WINDOW_TYPE_DIALOG'
;  _cWinTypeTool     text '_NET_WM_WINDOW_TYPE_TOOLBAR'          ; it is with normal toolbar, but with only close button.
;  _cWinTypeDock     text '_NET_WM_WINDOW_TYPE_DOCK'             ; without title bar and above all other windows???
;  _cWinTypeNormal   text '_NET_WM_WINDOW_TYPE_NORMAL'

;_cWinSyncRequest  text '_NET_WM_SYNC_REQUEST'
;_cAtomTypeAtom  text 'ATOM'

; notes on different types, regarding XFWM window manager:
;  _NET_WM_WINDOW_TYPE_SPLASH - no title, goes up on activation.
;  _NET_WM_WINDOW_TYPE_DOCK   - no title, always on top
;  _NET_WM_WINDOW_TYPE_DROPDOWN_MENU - ???
;  _NET_WM_WINDOW_TYPE_NOTIFICATION - ???
;  _
;


;macro atomset lbl, name, [valname, value] {
;common
;  lbl dd ?
;forward
;  valname dd ?
;common
;  lbl#.text text `name
;forward
;  lbl#valname#.text text `value
;}
;

;uglobal
;  atomSyncRequest dd ?
;
;  atomTypeATOM  dd ?
;
;  atomWMType          dd ?
;    atomWinTypeDlg      dd ?
;    atomWinTypeTool     dd ?
;    atomWinTypeDock     dd ?
;    atomWinTypeNormal   dd ?
;endg
;
;
;iglobal
;  atomset atomAllowedActions, _NET_WM_ALLOWED_ACTIONS,    \
;            .move, _NET_WM_ACTION_MOVE,                     \
;            .resize, _NET_WM_ACTION_RESIZE,                 \
;            .minimize, _NET_WM_ACTION_MINIMIZE,             \
;            .shade, _NET_WM_ACTION_SHADE,                   \
;            .stick, _NET_WM_ACTION_STICK,                   \
;            .maximize_horz, _NET_WM_ACTION_MAXIMIZE_HORZ,   \
;            .maximize_vert, _NET_WM_ACTION_MAXIMIZE_VERT,   \
;            .fullscreen, _NET_WM_ACTION_FULLSCREEN,         \
;            .change_desktop, _NET_WM_ACTION_CHANGE_DESKTOP, \
;            .close, _NET_WM_ACTION_CLOSE
;
;  atomset atomWMState, _NET_WM_STATE,           \
;            .modal, _NET_WM_STATE_MODAL
;
;endg
;
