; _______________________________________________________________________________________
;|                                                                                       |
;| ..::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 CApplication
    hApplicationDisplay dd ?
    hRootWindow         dd ?

    hInputMethod        dd ?
    hInputContext       dd ?

    _SystemFont         dd ?

    atomWMDelete        dd ?
  end if
endg

;cDefaultFont text 'Tahoma-8'
cDefaultFont text 'Liberation Sans-9'
cDefaultFontSize = 9
;cDefaultFont text 'Ubuntu-9:rgba=rgb'
;cDefaultFont text 'Unifont-12' ; this one have unicode support;


; String constants needed for XLib
; Why, they needed so many strings????????????????? For arguments!??????????
_cWinDeleteName   text 'WM_DELETE_WINDOW'

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"




proc TApplication.Create, .obj
.ptr dd ?
begin
        push    eax ecx edx

        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     .exit_error

.continue:
        DebugMsg 'Display opened.'
        mov     [hApplicationDisplay], eax

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

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

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

        lea     eax, [.ptr]
        cinvoke XGetIMValues, [hInputMethod], XNQueryInputStyle, eax, 0

        mov     eax, [.ptr]
        mov     eax, [eax+4]
        cinvoke XCreateIC, [hInputMethod], XNInputStyle, [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], _cWinDeleteName, 0
        mov     [atomWMDelete], eax

        cinvoke XftFontOpenName, [hApplicationDisplay], 0, cDefaultFont
        mov     [_SystemFont], eax


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

        clc
        pop     edx ecx eax
        return


.exit_error:
        Message 'Error open display.'
        stc
        pop     edx ecx eax
        return




endp



proc TApplication.Get, .obj, .paramID
begin
        stc
        return
endp



proc TApplication.Set, .obj, .paramID, .value
begin
        stc
        return
endp



proc TApplication.SysEventHandler
begin
        clc
        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 & options.DebugMode

        int3

        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
;
