| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# sortling.htm
Data
Data
Procedures
Arg2Gui
EditField
Goto
Gui2Arg
MainGui
PaintWindow

This is a GUI module of EuroTool program EuroSort for Linux.

             EUROASM CPU=X64,Unicode=No
    sortling PROGRAM Format=coff,Width=64
    ;;         EXTERN LinABI@RT, StdOutputLin64@RT, StoD64@RT
             %DROPMACRO *
             INCLUDEHEAD1 argument.htm
             INCLUDE1 linabi.htm, cpuext64.htm,cpuext.htm,linsfile.htm,lins.htm,string64.htm,time.htm,status32.htm

↑ Data

    [.rodata]
    NameArray:                                       ; Codepage name, space-padded, justified to center.
    uName %FOR '  Autodetect  ',\
               '    ASCII     ',\
               '    UTF-8     ',\
               '   UTF-16LE   ',\
               '   UTF-16BE   ',\
               '   UTF-32LE   ',\
               '   UTF-32BE   '
           DB "%uName[2..%&-1]"
          %ENDFOR uName
    CP    %MACRO CPid,Name,Altname,url,Table         ; Redefine macro CP.
            %IF "%Table" !=== ""
    %uName    %SET %Name[2..%&-1]
    %NameSize %SETS %uName
              %IF %NameSize>14
    %NameSize   %SETA 14
              %ENDIF
    %SpLeft   %SETA (14-%NameSize)/2
    %SpRight  %SETA 14-%NameSize-%SpLeft
              DB %SpLeft * BYTE ' '
              DB "%uName[1..14]"
              DB %SpRight * BYTE ' '
            %ENDIF
          %ENDMACRO CP
     INCLUDE "codepage.htm"                          ; Expand the macro CP with each line of the table CodePages.
    NameArrayEnd:
    EDIT            STRUC     ; A structure for passing parameters for the procedure EditField.
    .Address          D QWORD ; Address of the field in memory. The field is in UTF-8, NUL-terminated.
    .MaxSize          D WORD  ; Maximal possible size of the field in memory (bytes).
    .ScreenSize       D WORD  ; Size of the visible field on the screen.
    .ScreenRow        D WORD  ; Row of the edit field in the terminal window (1, 2, 3,,).
    .ScreenCol        D WORD  ; Left column of the edit field in the terminal window (1, 2, 3,,).
                    ENDSTRUC EDIT
    MinRows         EQU  64   ; Minimal terminal dimensions.
    MinCols         EQU  48
    Indentation     EQU 24    ; Titles "Input file", "Encoding" etc.

    [.rodata]                 ; Constant data.
    BoxV              DB BYTE '│',0          ; BOX DRAWINGS LIGHT VERTICAL       2502
    BoxDR             DB BYTE '┌',0          ; BOX DRAWINGS LIGHT DOWN AND RIGHT 250C
    BoxDL             DB BYTE '┐',0          ; BOX DRAWINGS LIGHT DOWN AND LEFT  2510
    BoxUR             DB BYTE '└',0          ; BOX DRAWINGS LIGHT UP AND RIGHT   2514
    BoxUL             DB BYTE '┘',0          ; BOX DRAWINGS LIGHT UP AND LEFT    2518
    Box2V             DB BYTE '║',0          ; BOX DRAWINGS DOUBLE VERTICAL      2551
    Boxes             DB NAME_MAX*2*BYTE '─' ; BOX DRAWINGS LIGHT HORIZONTAL     2500
    Checked           DB '■',0               ; BLACK SQUARE                      25A0
    Unchecked         DB '□',0               ; WHITE SQUARE                      25A1
    Spaces            DB NAME_MAX * 2 * BYTE ' ',0
    Box3U             DB '┌─┐',0
    Box3D             DB '└─┘',0
    Box4U             DB '┌──┐',0
    Box4D             DB '└──┘',0
    Box6U             DB '┌────┐',0
    Box6D             DB '└────┘',0
    Box14U            DB '╔════════════╗',0
    Box14D            DB '╚════════════╝',0
    EscRight          DB 27,'[C'
    EscLeft           DB 27,'[D'
    EscHome           DB 27,'[H'
    EscEnd            DB 27,'[F'
    EscShiftTab       DB 27,'[Z'
    EscDelete         DB 27,'[3~'
    EscBaseColor::    DB 27,'[30;47m',0    ; Zero-terminated sequences for writing to terminal.
    EscDefColor::     DB 27,'[39;49m',0
    EscEnhColor::     DB 27,'[38;5;160m',0
    EscDimColor       DB 27,'[38;5;243m',0
    EscFileColor      DB 27,'[48;5;195m',0
    EscEditColor      DB 27,'[30;107m',0
    EscErase::        DB 27,'[2J',0
    EscEscape         DB 27,0
    EscEnableMouse    DB 27,'[?1000;1006;1015h',0
    EscDisableMouse:: DB 27,'[?1000;1006;1015l',0
    EscHideCursor     DB 27,'[?25l',0
    EscShowCursor::   DB 27,'[?25h',0
    EscTab            DB 9

    [.data]                                ; Variable data.
    EscResize         DB 27,'[8;'
    ValResize         DB 'xxxxxxxxx'       ; Replaced by '24;150t',0
    EscGoto           DB 27,'['
    EscGotoRowColH    DB 'row;colH',0
      line %FOR 1..21 ; Define EscLine1, EscLine2 etc.
    EscLine%line      DB 27,'[%line{}H',0
           %ENDFOR line
    Back4             DB 8
    Back3             DB 8
    Back2             DB 8,8,0
    EuroSort          DB ' EuroSort',0
    Version           DB ' version %^Date',0
    GuiRecordSize     DB '0',19*B 0 ; GUI-maintained arguments in text form.
    GuiHeaderSize     DB '0',19*B 0
    GuiHeaderLength   DB '0',19*B 0
    GuiFooterSize     DB '0',19*B 0
    GuiFooterLength   DB '0',19*B 0
    GuiKeyOffset      DB '0',19*B 0
    GuiKeyLength      DB '-1',18*B 0
    GuiLocale         DB '--'

    [.bss]                                 ; Working data.
    Edit              DS EDIT
    TtySize           DS TTYSIZE
    TermIO            DS TERMIO
    MainWidth         D DWORD    ; The width of the window.
    NrOfEncodingCol   D DWORD    ; How many encoding names will fit on one terminal line.
    NrOfLocalesCol    D DWORD    ; How many locale names will fit on one terminal line.
    MainHeight        D DWORD    ; Number of lines in the main window.
    EncodingLastRow   D DWORD    ; Encoding buttons are between 22 and this value.
    LocaleFirstRow    D DWORD    ; Row of the first locale button.
    LocaleInterSpaces D DWORD    ; Number of spaces between Locale buttons.
    NumInterSpaces    D DWORD    ; Number of spaces between numeric buttons -RS,-HS,-HL,-FS,-FL.
    BoxInterSpaces    D DWORD    ; Number of spaces between boxes -KO,-KS,-KR etc.
    OneFifth          D DWORD    ; One fifth of MainWidth.
    CancelSortRow     D DWORD    ; Row if the buttons [Cancel] and [Sort].
    TabSelected       D DWORD    ; 0,5,10,15,20,25,30,,,index of jump.
    KeyBuffer         D 32*BYTE  ; Buffer for reading the keyboard.
    Number            D 24*BYTE  ; Ordinary number in decadic form.

MainGui
  This is the graphic entry procedure which calls MainWindow to paint the window and then it reads mouse and keyboard from the terminal.
Called by
  MainCon.
Calls
  PaintWindow.

    [.text]
    MainGui:: PROC
        CALL Arg2Gui                       ; Convert numeric arguments to decimal form.
        CALL PaintWindow
        MOV [TabSelected],-5
        MOV EAX,[MainWidth]
        XOR EDX,EDX
        MOV ECX,5
        DIV RCX                            ; EAX is MainWidth/5.
        MOV [OneFifth],EAX
        MOV ESI,[MainWidth]
        SUB ESI,5*6
        SHR ESI,2                          ; Number of spaces between five NumFields.
        MOV [NumInterSpaces],ESI
        MOV EAX,[MainWidth]
        SUB EAX,2*6+5*3
        MOV ECX,6
        XOR EDX,EDX
        DIV RCX
        MOV [BoxInterSpaces],EAX
        LEA RBX,[TermIO]
        LinABI ioctl,0,TCGETS,RBX          ; Load current local terminal status.
        RstSt [RBX+TERMIO.c_lflag],ICANON+ECHO
        LinABI ioctl,0,TCSETS,RBX          ; Disable terminal echo.
        StdOutput EscEnableMouse
    .10:XOR EDI,EDI                        ; Read the keyboard in the main window.
        LEA RSI,[KeyBuffer]
        MOV R8,RSI
        MOV [RSI],RDI
        MOV EDX,SIZE# KeyBuffer
        LinABI read,RDI,RSI,RDX
        TEST EAX
        JNA .10:
        XOR ECX,ECX
        MOV EBX,[SelectedLineNr::]
    key %FOR  EscShiftTab,EscTab,EscEscape
           LEA RDI,[%key]
           MOV CL,SIZE# %key
           MOV RSI,R8            ; KeyBuffer.
           REPE CMPSB
           JE .%key:
        %ENDFOR key
        MOV RSI,R8               ; Read the mouse.
        LODSW
        CMP AX,0x5B1B            ; Esc [
        JNE .10:
        LODSB
        CMP AL,0x3C              ; Less-than?
        JNE .10:
        LodD                     ; Mouse button.
        JC  .10:
        CMP AL,0
        JNE .10:
        LODSB
        CMP AL,';'
        JNE .10:
        LodD
        JC .10:
        MOV EBX,EAX              ; X-coordinate of mouse cursor.
        SHL EBX,16
        LODSB
        CMP AL,';'
        JNE .10:
        LodD
        JC .10:
        MOV BX,AX                ; Y-coordinate of mouse cursor.
        LODSB
        CMP AL,'m'
        JNE .10:
        CMP BX,3                 ; Mouse cursor coordinates are in EBX. Row number is in BX.
        JB .23:
        CMP BX,5
        JA .23:
    .TabIF:
        LEA RSI,[ArgInputFile::] ; Input file clicked.
        MOV [Edit.Address],RSI
        MOV [Edit.MaxSize],NAME_MAX
        MOV EAX,[MainWidth]
        SUB EAX,2
        MOV [Edit.ScreenSize],AX
        MOV [Edit.ScreenRow],4
        MOV [Edit.ScreenCol],2
    .13:CALL EditField
        CALL Gui2Arg
    .16:CALL PaintWindow
        JMP .10:
    .TabRS:
        XOR EBX,EBX
        JMP .20:
    .TabHS:
        MOV EBX,[OneFifth]
        JMP .20:
    .TabHL:
        MOV EBX,[OneFifth]
        ADD EBX,EBX
        JMP .20:
    .TabFS:
        MOV EBX,[OneFifth]
        LEA EBX,[EBX+2*EBX]
        JMP .20:
    .TabFL:
        MOV EBX,[MainWidth]
    .20:MOV ESI,[NumInterSpaces]
        MOV EAX,[OneFifth]
        JMP .30:
    .TabKO:
        SUB EBX,EBX
        JMP .40:
    .TabKL:
        MOV EBX,[BoxInterSpaces]
        ADD EBX,12
        JMP .40:
    .23:CMP BX,12
        JB .26:
        CMP BX,14
        JA .26:
    .TabOF:
        LEA RSI,[ArgOutputFile::]; Output file clicked.
        MOV [Edit.Address],RSI
        MOV [Edit.MaxSize],NAME_MAX
        MOV EAX,[MainWidth]
        SUB EAX,2
        MOV [Edit.ScreenSize],AX
        MOV [Edit.ScreenRow],13
        MOV [Edit.ScreenCol],2
        JMP .13:
    .26:CMP BX,8
        JB .36:
        CMP BX,10
        JA .36:
        SHR EBX,16               ; Numfield clicked.
        MOV EAX,[OneFifth]
        MOV ESI,[NumInterSpaces]
    .30:MOV EDX,2
        LEA RDI,[GuiRecordSize]
        SUB EBX,EAX
        JB .33:
        LEA EDX,[EDX+ESI+6]
        LEA RDI,[GuiHeaderSize]
        SUB EBX,EAX
        JB .33:
        LEA EDX,[EDX+ESI+6]
        LEA RDI,[GuiHeaderLength]
        SUB EBX,EAX
        JB .33:
        LEA EDX,[EDX+ESI+6]
        LEA RDI,[GuiFooterSize]
        SUB EBX,EAX
        JB .33:
        LEA EDX,[EDX+ESI+6]
        LEA RDI,[GuiFooterLength]
    .33:MOV [Edit.Address],RDI
        MOV [Edit.MaxSize],20
        MOV [Edit.ScreenSize],4
        MOV [Edit.ScreenRow],9
        MOV [Edit.ScreenCol],DX
        JMP .13:
    .36:CMP BX,17
        JB .50:
        CMP BX,19
        JA .50:
        SHR EBX,16                         ; Boxfield clicked. EBX is column.
    .40:MOV EAX,[BoxInterSpaces]
        MOV EDX,6                          ; EAX is the number of spaces between elements.
        LEA RDI,[GuiKeyOffset]
        CMP EBX,EDX
        JBE .46:
        LEA RDI,[GuiKeyLength]
        LEA EDX,[EDX+EAX+6]
        CMP EBX,EDX
        JBE .46:
    arg %FOR KeyReverse,DigitFirst,PunctuationFirst,UpperFirst,MergeSpaces
          MOV EDI,Arg%arg
          LEA EDX,[EDX+EAX+3]
          CMP EBX,EDX
          JBE .43:
        %ENDFOR arg
    .43:XOR [Status::],EDI
        JMP .16:
    .46:MOV [Edit.Address],RDI
        MOV [Edit.MaxSize],20
        MOV [Edit.ScreenSize],4
        MOV [Edit.ScreenRow],18
        SUB EDX,4
        MOV [Edit.ScreenCol],DX
        JMP .13:
    .50:CMP BX,22
        JB .65:
        MOV EAX,[EncodingLastRow]
        CMP BX,AX
        JAE .65:
        SUB BX,22                ; Clicked on Encodings.
        MOV EAX,[NrOfEncodingCol]
        MOVZXW ECX,BX
        MUL RCX
        SHR EBX,16
    .55:SUB EBX,14
        JB .60:
        INC EAX
        JMP .55:
    .60:LEA RSI,[CPid::]
        MOVZXW EAX,[RSI-2+2*RAX]
        MOV [ArgInputEncoding::],EAX
        JMP .16:
    .65:LEA RDI,[Locales::]
        MOV ESI,[LocaleInterSpaces]
        MOV EAX,[LocaleFirstRow]
        CMP BX,AX
        JB .85:
        ADD EAX,3
        CMP BX,AX
        JB .70:
        CMP BX,[CancelSortRow]
        JAE .85:
        ADD EAX,2
        CMP BX,AX
        JA .85:
        MOV EAX,[NrOfLocalesCol]
        MOV ECX,SIZE# VAL
        MUL RCX
        ADD RDI,RAX                        ; RDI points to the first button on the last row.
    .70:SHR EBX,16                         ; EBX is now the column.
        MOV EDX,6
    .75:CMP EBX,EDX
        JB .80:
        ADD RDI,SIZE# VAL
        CMP RDI,EndLocales::
        JNB .10:
        LEA EDX,[EDX+ESI+4]
        JMP .75:
    .80:MOV EAX,[RDI+VAL.ValValue]
        MOV [ArgLocale::],EAX
        JMP .16:
    .85:MOV EAX,[CancelSortRow]
        CMP BX,AX
        JB .10:
        SHR EBX,16                         ; Clicked on [Cancel] or [Sort].
        CMP EBX,16
        JA .EscEscape:
        SetSt [Status::],ArgCancel
        JMP .EscEscape:
    TabSelTable:                           ; Each jump is encoded to 5 bytes long instruction.
       JMP .TabIF:
       JMP .TabRS:
       JMP .TabHS:
       JMP .TabHL:
       JMP .TabFS:
       JMP .TabFL:
       JMP .TabOF:
       JMP .TabKO:
       JMP .TabKL:
    TabSize EQU 9
    .EscShiftTab:
        MOV EAX,[TabSelected]
        SUB EAX,5
        JNB .90:
        MOV EAX,5*(TabSize-1)
        JMP .90:
    .EscTab:                               ; Tab pressed.
        MOV EAX,[TabSelected]
        ADD EAX,5
        CMP AL,5*TabSize
        JB  .90:
        SUB EAX,EAX
    .90:MOV [TabSelected],EAX              ; RAX=0,5,10,,,
        LEA RCX,[TabSelTable+RAX]
        JMP RCX
    .EscEscape:
        StdOutput EscDisableMouse,EscErase
        LEA RBX,[TermIO]
        LinABI ioctl,0,TCGETS,RBX          ; Get current terminal echo.
        SetSt [RBX+TERMIO.c_lflag],ICANON+ECHO
        LinABI ioctl,0,TCSETS,RBX          ; Restore terminal echo.
        RET
       ENDP MainGui

PaintWindow
  Procedure PaintWindow resizes the terminal window when it is too small and then it paints the entire window.
Called by
  MainGui.

    PaintWindow PROC
        LinABI ioctl,0,TIOCGWINSZ,TtySize
        MOVZXW EDX,[TtySize.ts_lines]
        MOVZXW ECX,[TtySize.ts_cols]
        MOV EAX,MinRows          ; Minimal acceptable lines.
        CMP EDX,EAX
        JB .10:
        MOV EAX,EDX
    .10:LEA RDI,[ValResize]
        StoD RDI
        MOV AL,';'
        STOSB
        MOV EAX,MinCols          ; Minimal acceptable columns.
        CMP ECX,EAX
        JB .15:
        MOV EAX,ECX
    .15:StoD RDI
        MOV AX,'t'
        STOSW
        StdOutput EscResize
        LinABI ioctl,0,TIOCGWINSZ,TtySize
        MOVZXW EDX,[TtySize.ts_lines]
        DEC EDX                                      ; Reserve one low line for status.
        MOV [MainHeight],EDX
        MOVZXW ECX,[TtySize.ts_cols]
        MOV [MainWidth],ECX
        ; Start painting.
        StdOutput EscLine1,EscBaseColor,=B' ',EscEnhColor,EuroSort,EscDimColor,Version,Spaces
        StdOutput EscLine2,EscBaseColor              ; Row 2
        StdOutput Spaces,Size=Indentation
        StdOutput =B'Input file',Spaces
        StdOutput EscLine3,BoxDR                     ; Row 3
        MOV ECX,[MainWidth]
        SUB ECX,2
        LEA EDX,[2*ECX+ECX]
        StdOutput Boxes,Size=RDX
        StdOutput BoxDL,EscLine4,BoxV                ; Row 4
        LEA RSI,[ArgInputFile::]
        GetLengthUTF8 RSI
        StdOutput RSI,Size=RCX
        MOV EAX,[MainWidth]
        SUB EAX,2
        SUB EAX,ECX
        JBE .25:
        StdOutput Spaces,Size=RAX
    .25:StdOutput BoxV,EscLine5,BoxUR                ; Row 5
        StdOutput Boxes,Size=RDX
        StdOutput BoxUL,EscLine6                     ; Row 6
        MOV ESI,[MainWidth]
        SUB ESI,5*6
        SHR ESI,2                                    ; Number of spaces between five NumFields.
        StdOutput =B'Record'
        LEA ECX,[ESI+1]
        StdOutput Spaces,Size=RCX
        StdOutput =B'Head'
        LEA ECX,[ESI+2]
        StdOutput Spaces,Size=RCX
        StdOutput =B'Head'
        StdOutput Spaces,Size=RCX
        StdOutput =B'Foot'
        StdOutput Spaces,Size=RCX
        StdOutput =B'Foot'
        StdOutput Spaces,Size=RCX
        StdOutput EscLine7,=B' size'                 ; Row 7
        LEA ECX,[ESI+2]
        StdOutput Spaces,Size=RCX
        StdOutput =B'Size'
        StdOutput Spaces,Size=RCX
        StdOutput =B'Length'
        SUB ECX,2
        StdOutput Spaces,Size=RCX
        StdOutput =B'Size'
        StdOutput Spaces,Size=RCX
        StdOutput =B'Length',Spaces
        StdOutput EscLine8                           ; Row 8
        MOV ECX,5
    .30:StdOutput Box6U
        StdOutput Spaces,Size=RSI
        LOOP .30:
        StdOutput EscLine9                           ; Row 9
        MOV EAX,[ArgRecordSize::]
        CALL .NumField:
        MOV EAX,[ArgHeaderSize::]
        CALL .NumField:
        MOV EAX,[ArgHeaderLength::]
        CALL .NumField:
        MOV EAX,[ArgFooterSize::]
        CALL .NumField:
        MOV EAX,[ArgFooterLength::]
        CALL .NumField:
        StdOutput EscLine10                          ; Row 10
        MOV ECX,5
    .35:StdOutput Box6D
        StdOutput Spaces,Size=RSI
        LOOP .35:
        StdOutput EscLine11                          ; Row 11
        StdOutput Spaces,Size=Indentation
        StdOutput =B'Output file',Spaces
        StdOutput EscLine12,BoxDR                    ; Row 12
        StdOutput Boxes,Size=RDX
        StdOutput BoxDL,EscLine13,BoxV               ; Row 13
        LEA RSI,[ArgOutputFile::]
        GetLengthUTF8 RSI
        StdOutput RSI,Size=RCX
        MOV ESI,[MainWidth]
        SUB ESI,2
        MOV EDI,ESI
        SUB EDI,ECX
        JBE .40:
        StdOutput Spaces,Size=RDI
    .40:StdOutput BoxV,EscLine14,BoxUR                ; Row 14
        StdOutput Boxes,Size=RDX
        StdOutput BoxUL,EscLine15,=B' Key  '          ; Row 15
        MOV EAX,[MainWidth]
        SUB EAX,2*6+5*3
        XOR EDX,EDX
        MOV ECX,6
        DIV RCX
        MOV ESI,EAX                                   ; Spaces between fields.
        StdOutput Spaces,Size=RSI
        StdOutput =B' Key  '
        StdOutput Spaces,Size=RSI
        StdOutput =B' Key  '
        StdOutput Spaces,Size=RSI
        StdOutput Back3,=B'Digit'
        StdOutput Spaces,Size=RSI
        StdOutput Back3,=B'Punct.'
        StdOutput Spaces,Size=RSI
        StdOutput Back3,=B'Upper'
        StdOutput Spaces,Size=RSI
        StdOutput Back2,=B'Merge',Spaces
        StdOutput EscLine16                           ; Row 16
        StdOutput =B'Offset'
        StdOutput Spaces,Size=RSI
        StdOutput =B'Length'
        StdOutput Spaces,Size=RSI
        StdOutput =B'Reverse'
        StdOutput Spaces,Size=RSI
        StdOutput Back4,=B'First'
        StdOutput Spaces,Size=RSI
        StdOutput Back3,=B'First'
        StdOutput Spaces,Size=RSI
        StdOutput Back2,=B'First'
        StdOutput Spaces,Size=RSI
        StdOutput Back3,=B'Spaces'
        StdOutput Spaces,Size=RSI
        StdOutput EscLine17,Box6U                    ; Row 17
        StdOutput Spaces,Size=RSI
        StdOutput Box6U
        StdOutput Spaces,Size=RSI
        StdOutput Box3U
        StdOutput Spaces,Size=RSI
        StdOutput Box3U
        StdOutput Spaces,Size=RSI
        StdOutput Box3U
        StdOutput Spaces,Size=RSI
        StdOutput Box3U
        StdOutput Spaces,Size=RSI
        StdOutput Box3U,Spaces,EscLine18             ; Row 18
        MOV EAX,[ArgKeyOffset::]
        CALL .NumField:
        MOV EAX,[ArgKeyLength::]
        CDQE
        CALL .NumField:
    arg %FOR KeyReverse,DigitFirst,PunctuationFirst,UpperFirst,MergeSpaces
          LEA RDX,[Checked]
          JSt [Status::],Arg%arg,.%arg:
          LEA RDX,[Unchecked]
    .%arg:StdOutput BoxV,RDX,BoxV
          StdOutput Spaces,Size=RSI
        %ENDFOR arg
        StdOutput EscLine19,Box6D                    ; Row 19
        StdOutput Spaces,Size=RSI
        StdOutput Box6D
        StdOutput Spaces,Size=RSI
        StdOutput Box3D
        StdOutput Spaces,Size=RSI
        StdOutput Box3D
        StdOutput Spaces,Size=RSI
        StdOutput Box3D
        StdOutput Spaces,Size=RSI
        StdOutput Box3D
        StdOutput Spaces,Size=RSI
        StdOutput Box3D
        StdOutput Spaces,Size=RSI
        MOV EAX,[MainWidth]
        SUB EAX,2
        MOV ECX,14                                    ; Width of one "button" for encoding selection.
        XOR EDX,EDX
        DIV RCX
        MOV [NrOfEncodingCol],EAX                     ; Columns of encoding buttons.
        StdOutput EscLine20                           ; Row 20
        StdOutput Spaces,Size=Indentation
        StdOutput =B'Encoding',Spaces,EscLine21,BoxDR ; Row 21
        MOV ESI,[MainWidth]
        LEA EDX,[ESI+2*ESI-6]
        StdOutput Boxes,Size=RDX
        StdOutput BoxDL
        MOV R10,22                                   ; Start with Row 22
        LEA RBX,[NameArray]
        LEA R9,[CPid::-2]
    .45:MOV EDX,1                                    ; Loop for Encoding selections.
        CALL Goto:
        StdOutput BoxV
    .50:MOVZXW EAX,[R9]
        CMP EAX,[ArgInputEncoding::]
        LEA RAX,[EscFileColor]
        JE .55:
        LEA RAX,[EscBaseColor]
    .55:StdOutput RAX
        StdOutput RBX,Size=14
        StdOutput EscBaseColor
        ADD RBX,14
        ADD EDX,14
        ADD R9,2
        LEA RAX,[NameArrayEnd]
        CMP RBX,RAX
        JNB .60:
        LEA EAX,[EDX+14-1]
        CMP EAX,[MainWidth]
        JB .50:
    .60:MOV EAX,[MainWidth]
        SUB EAX,1
        SUB EAX,EDX
        JB .65:
        StdOutput Spaces,Size=RAX
    .65:StdOutput BoxV
        INC R10
        MOV [EncodingLastRow],R10D
        LEA RAX,[NameArrayEnd]
        CMP RBX,RAX
        JB .45:
        MOV EDX,1
        CALL Goto:
        StdOutput BoxUR
        MOV EAX,[MainWidth]
        LEA ECX,[EAX+2*EAX-6]
        StdOutput Boxes,Size=RCX
        StdOutput BoxUL
        MOV EDX,1
        INC R10
        CALL Goto:
        StdOutput Spaces, Size=Indentation
        StdOutput =B'Locale',Spaces
        INC R10
        CALL Goto:
        StdOutput BoxDR
        MOV EAX,[MainWidth]
        LEA ECX,[RAX+2*RAX-6]
        StdOutput Boxes,Size=RCX
        StdOutput BoxDL
        INC R10
        MOV [LocaleFirstRow],R10D
        CALL .Frame3:
        LEA RBX,[Locales::]                ; Array of VAL records.
        LEA RAX,[EndLocales::]
        SUB RAX,RBX
        MOV ECX,SIZE# VAL
        XOR EDX,EDX
        DIV RCX                            ; RAX=number of locales.
        MOV R9,RAX
        SHL EAX,2                          ; Each button is 4 characters wide.
        XOR R11,R11                        ; R11 is interbutton spaces.
        XOR R12,R12                        ; R12=button counter.
        MOV ECX,[MainWidth]
        SUB ECX,2
        SUB ECX,EAX
        JB .70:
        MOV EAX,ECX
        DIV R9
        MOV R11,RAX                        ; R11 is interbutton spaces.
        MOV [LocaleInterSpaces],EAX
    .70:MOV EDX,2
    .73:CMP EBX,EndLocales::               ; Start painting buttons.
        JNB .85:
        MOV EAX,[MainWidth]
        SUB EAX,5
        CMP EDX,EAX
        JNB .80:
        CALL Goto:
        StdOutput Box4U
        INC R10
        CALL Goto:
        MOV EAX,[RBX+VAL.ValValue]
        LEA RDI,[GuiLocale]
        MOV [RDI],AX
        CMP EAX,[ArgLocale::]
        LEA RCX,[EscBaseColor]
        JNE .77:
        LEA RCX,[EscFileColor]
    .77:StdOutput BoxV,RCX,RDI,EscBaseColor,BoxV
        INC R12
        INC R10
        CALL Goto:
        StdOutput Box4D
        SUB R10,2
        LEA RDX,[RDX+4+R11]
        ADD RBX,SIZE# VAL
        JMP .73:
    .80:; First row of buttons is full.
        MOV [NrOfLocalesCol],R12D
        ADD R10,3
        CALL .Frame3:
        JMP .70:
    .85:ADD R10,3
        MOV EDX,1
        CALL Goto:
        StdOutput BoxUR
        MOV EAX,[MainWidth]
        LEA ECX,[EAX+2*EAX-6]
        StdOutput Boxes,Size=RCX
        StdOutput BoxUL
        INC R10
        MOV [CancelSortRow],R10D
        CALL .Frame3:
        MOV EDX,1
        CALL Goto:
        StdOutput Box14U
        MOV EDX,[MainWidth]
        SUB EDX,13
        CALL Goto:
        StdOutput Box14U
        INC R10
        MOV EDX,1
        CALL Goto:
        StdOutput Box2V,=B'   Cancel   ',Box2V
        MOV EDX,[MainWidth]
        SUB EDX,13
        CALL Goto:
        StdOutput Box2V,=B'    Sort    ',Box2V
        INC R10
        MOV EDX,1
        CALL Goto:
        StdOutput Box14D
        MOV EDX,[MainWidth]
        SUB EDX,13
        CALL Goto:
        StdOutput Box14D
        INC R10
        MOV EDX,1
        CALL Goto:
        RET

    .NumField: PROC1 ; Paint the number RAX to the edit area between boxes.
         StoD Number,Align=right,Size=4
         StdOutput BoxV
         StdOutput Number,Size=4
         StdOutput BoxV
         StdOutput Spaces,Size=RSI
         RET
        ENDP1 .NumField:

    .Frame3: PROC1  ; Preformat three empty lines. Input:R10=line. Clobbers RAX,RCX,RDX.
        MOV EDX,1
        MOV ECX,3
    .2: CALL Goto:
        StdOutput BoxV
        MOV EAX,[MainWidth]
        SUB EAX,2
        StdOutput Spaces,Size=RAX
        StdOutput BoxV
        INC R10
        LOOP .2:
        SUB R10,3
        RET
       ENDP1 .Frame3:
     ENDP PaintWindow

Goto
  Procedure Goto is called to position the terminal window at certain row and column.
Input
  R10=terminal row, starting with 1.
  RDX=terminal column, starting with 1.
Output
  Terminal was redirected.
Clobbers
  RAX
Called by
  PaintWindow.

    Goto PROC
         PUSH RDI,RAX,RAX,RAX
          MOV RDI,RSP
          MOV AL,27
          STOSB
          MOV AL,'['
          STOSB
          MOV RAX,R10
          StoD RDI
          MOV AL,';'
          STOSB
          MOV EAX,EDX
          StoD RDI
          MOV AX,'H'
          STOSW
          MOV RDI,RSP
          StdOutput RDI
         POP RAX,RAX,RAX,RDI
         RET
        ENDP Goto

Gui2Arg
  Copy numeric arguments from GUI module g** back to global form Arg**.

    Gui2Arg PROC
        PUSH RSI
    arg %FOR RecordSize,HeaderSize,HeaderLength,FooterSize,FooterLength,KeyOffset,KeyLength
          LEA RSI,[Gui%arg]
          LodD RSI
          MOV [Arg%arg::],EAX
        %ENDFOR arg
        POP RSI
        RET
       ENDP Gui2Arg

Arg2Gui
  Copy numeric arguments Arg** to GUI module decimal format g**.

    Arg2Gui PROC
        PUSH RDI
    arg %FOR RecordSize,HeaderSize,HeaderLength,FooterSize,FooterLength,KeyOffset,KeyLength
         MOV EAX,[Arg%arg::]
         CDQE
         LEA RDI,[Gui%arg]
         StoD RDI,Signed=yes,Align=left
        %ENDFOR arg
        POP RDI
        RET
       ENDP Arg2Gui

EditField
  Procedure EditField is called when the user selects or clicks on the editable window. It allows to change the field contents. Input parameters are supplied by the structured variable EDIT.
Called by
  MainGui.

    EditField PROC
         LEA RBX,[Edit]
         MOV RSI,[RBX+EDIT.Address]
         GetLengthUTF8 RSI
         MOV R11,RCX
    .10: ; R11 is cursor position withing the visible field in characters (0,1,2,,).
         PUSH R11
          XOR R11,R11
          CALL .CursorAtR11:
          MOV RSI,[RBX+EDIT.Address]
          MOV R9,RSI              ; R9 points at the beginning of the edit field in memory.
          MOVZX EAX,[RBX+EDIT.ScreenSize]
          GetLengthUTF8 RSI
          SUB EAX,ECX
          JA .20:
          XOR EAX,EAX
    .20:  ADD R11,RCX
          StdOutput EscShowCursor,EscEditColor,RSI
          StdOutput Spaces,Size=RAX
         POP R11
    .30: CALL .CursorAtR11:     ; Display (perhaps new) cursor position.
    .40: XOR EDI,EDI            ; Read the keyboard.
         LEA RSI,[KeyBuffer]
         MOV [RSI],RDI          ; Clear the buffer.
         MOV R8,RSI             ; R8 points at the beginning of the keyboard buffer.
         MOV EDX,SIZE# KeyBuffer
         LinABI read,RDI,RSI,RDX
         TEST EAX
         JNA .40:
         XOR ECX,ECX
         MOV RDX,RAX             ; Number of read bytes.
         MOV EAX,[RSI]
         AND EAX,0x00FFFFFF
         CMP EAX,0x3C5B1B        ; Mouse ANSI sequence
         JE .0x0A:               ;  treat as an escape from edit window.
         Dispatch AL,0x7F,0x09,0x08,0x0A,0x0D ; First try the control characters BS, TAB, NL.
    key  %FOR EscDelete,EscLeft,EscRight,EscHome,EscEnd,EscShiftTab,EscEscape ; Then try kursor keys.
           LEA RDI,[%key]
           MOV CL,SIZE# %key
           MOV RSI,R8
           REPE CMPSB
           JE .%key:
         %ENDFOR key
         CMP AL,27               ; Other special key in ANSI sequence?
         JE .40:                 ; Ignore other ANSI sequences.
         ; Ordinary key was pressed, perhaps multibyte (UTF-8). Its size is in RDX (1..4).
         CALL .Cursor2Physical
         ; Insert RDX bytes at R8 to the current physical position represented by R12.
         GetLength$ R9
         LEA RSI,[R9+RCX-1]
         LEA RDI,[RSI+RDX]
         SUB RCX,R12
         STD
          REP MOVSB
         CLD
         LEA RDI,[R9+R12]
         MOV RSI,R8
         MOV ECX,EDX
         REP MOVSB
         INC R11                 ; Finally, increment cursor position.
         JMP .10:
    .EscHome:
         XOR R11,R11
         JMP .30:
    .EscEnd:
         GetLengthUTF8 R9
         MOV R11,RCX
         JMP .30:
    .EscLeft:
         TEST R11
         JZ .30:
         DEC R11
         JMP .30:
    .EscRight:
         GetLengthUTF8 R9
         CMP R11,RCX
         JAE .30:
         INC R11
         JMP .30:
    .0x08:
    .0x7F:                       ; Move the cursor left and then perform .EscDelete.
         TEST R11
         JZ .30:
         DEC R11
    .EscDelete:                  ; Erase the character at cursor position R11. Move chars on the left by one position.
         CALL .Cursor2Physical
         MOV EDX,1               ; Size of the erased character.
         MOVZXB EAX,[R9+R12]
         CMP AL,0x80
         JB .60:
         NEG AL                  ; Scan bits 7..0 of the inverted first byte.
         BSR EAX,EAX             ; Returns  EAX= 5, 4, 3 for 2, 3, 4 bytes long UTF-8 character.
         NEG RAX                 ;          RAX=-5,-4,-3 for 2, 3, 4 bytes long UTF-8 character.
         LEA RDX,[RDX+RAX+6]
    .60: LEA RDI,[R9+R12]
         LEA RSI,[RDI+RDX]
         GetLength$ R9
         INC ECX
         SUB RCX,R12
         REP MOVSB
         JMP .10:
    .0x0D:
    .0x0A:
    .0x09:
    .EscShiftTab:
    .EscEscape:
    .80: StdOutput EscBaseColor,EscHideCursor
         RET

    .Cursor2Physical PROC        ; Convert the cursor position R11 (0,1,2,,GetLengthUTF8)
         XOR R12,R12             ;  to physical position R12 (0,1,2,,GetLength$). Clobbers RAX,RCX.
         XOR ECX,ECX             ; Cursor position.
    .1:  CMP RCX,R11
         JAE .8:
         MOVZXB EAX,[R9+R12]
         INC RCX
         INC R12
         CMP AL,0x80
         JB .1:
         NEG AL                  ; Scan bits 7..0 of the inverted first byte.
         BSR EAX,EAX             ; Returns  EAX= 5, 4, 3 for 2, 3, 4 bytes long UTF-8 character.
         NEG RAX                 ;          RAX=-5,-4,-3 for 2, 3, 4 bytes long UTF-8 character.
         LEA R12,[R12+RAX+6]
         JMP .1:
    .8:  ; R12 is physical offset (0,1,2,,GetLength$) corresponding with cursor offset in R11.
         RET
        ENDP .Cursor2Physical

    .CursorAtR11 PROC ; Place the cursor in the edit field at column R11 (0,1,2,,GetLengthUTF8).
                      ; R11 represents the visible position, not the position in strings bytes. It clobbers RAX,RDI.
         LEA RDI,[EscGotoRowColH]
         MOVZX EAX,[RBX+EDIT.ScreenRow]
         StoD RDI
         MOV AL,';'
         STOSB
         MOVZX EAX,[RBX+EDIT.ScreenCol]
         ADD RAX,R11
         StoD RDI
         MOV AX,'H'
         STOSW
         StdOutput EscGoto
         RET
        ENDP .CursorAtR11
       ENDP EditField

      ENDPROGRAM sortling

▲Back to the top▲