EuroAssembler Index Manual Download Source Macros


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▲