EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

dirsling.htm
Data
Data
Procedures
AddUnderscores
DirWindowPaint
EditField
MainGui
MainWindowPaint
OneLine2Dir

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


     EUROASM CPU=X64,Unicode=No,DumpWidth=36
dirsling PROGRAM Format=COFF,Width=64
     %DROPMACRO *
     INCLUDEHEAD1 argument.htm, dirslinc.htm
     INCLUDE1 linabi.htm, cpuext64.htm, cpuext.htm, linsfile.htm, lins.htm, \
              string64.htm, memory64.htm, time.htm, status32.htm
↑ Data
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
MinWidth          EQU 150  ; Minimal number of columns of the window.
MinHeight         EQU  20  ; Minimal number of rows of the main window.
[.rodata]         ; Constants.
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
Box2DR            DB BYTE '╔',0          ; BOX DRAWINGS DOUBLE DOWN AND LEFT 2554
Box2DL            DB BYTE '╗',0          ; BOX DRAWINGS LIGHT DOWN AND LEFT  2557
Box2UR            DB BYTE '╚',0          ; BOX DRAWINGS DOUBLE UP AND RIGHT  255A
Box2UL            DB BYTE '╝',0          ; BOX DRAWINGS DOUBLE UP AND LEFT   2518
Boxes             DB NAME_MAX*2*BYTE '─' ; BOX DRAWINGS LIGHT HORIZONTAL     2500
Boxes2            DB NAME_MAX * BYTE '═' ; BOX DRAWINGS DOUBLE HORIZONTAL    2550
Space5            DB 5 * BYTE ' ',0
Spaces            DB NAME_MAX * 2 * BYTE ' '
BtnHead1          DB "Inserted ",0
BtnHead2          DB "Increased ",0
BtnHead3          DB "Unchanged ",0
BtnHead4          DB "Decreased ",0
BtnHead5          DB "Deleted ",0
BtnTail1          DB " new directories",0
BtnTail3          DB " directories",0
BtnTail5          DB " old directories",0
; Not zero-terminated sequences for detection of keyboard.
EscUp             DB 27,'[A'
EscDown           DB 27,'[B'
EscRight          DB 27,'[C'
EscLeft           DB 27,'[D'
EscHome           DB 27,'[H'
EscEnd            DB 27,'[F'
EscShiftTab       DB 27,'[Z'
EscPgUp           DB 27,'[5~'
EscPgDn           DB 27,'[6~'
EscDelete         DB 27,'[3~'
EscCtrlHome       DB 27,'[1;5H'
EscCtrlEnd        DB 27,'[1;5F'
; Zero-terminated sequences for writing to terminal.
EscDirsColor::    DB 27,'[30;47m',0
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
EscFindColor      DB 27,'[30;103m',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
EscRightDiv2      DB 27,'['
ValRightDiv2      DB 'xxxxx'      ; Replaced by '123C',0
EscRightEdge      DB 27,'['
ValRightEdge      DB 'xxxxx'      ; Replaced by '123C',0
EscDivN           DB 27,'['
ValDivN           DB 'xxxxx'      ; Replaced by '123C',0
EscLineXX         DB 27,'['
ValLineXX         DB 'XXH',0
EscGoto           DB 27,'['
EscGotoRowColH    DB 'row;colH',0
  line %FOR 1..14 ; Define EscLine1, EscLine2 etc.
EscLine%line      DB 27,'[%line{}H',0
       %ENDFOR line
[.bss]            ; Working data.
Edit              DS EDIT
TtySize           DS TTYSIZE
TermIO::          DS TERMIO
MainWidth         DD DWORD
MainHeight        DD DWORD ; Number of rows in the main window (20..99).
DirHeight         DD DWORD ; Number of rows in the directory window, without borders (5..84).
MainWidthDiv2     DD DWORD
MainWidthDiv5     DD DWORD
Remainder2        DD DWORD
Remainder5        DD DWORD
LineNr            DD DWORD ; Ordinal number of row in DirWindow (0,1,2,...)
LineCnt           DD DWORD ; Row counter in DirWindow (DirHeight, DirHeight-1,,,0).
FindTextSize      DD DWORD
TabSelected       DD DWORD ; 0,5,10,15,20,25,30,35,40 selects editable field or button from TabSelTable with Tab od Shift-Tab.
SelectedLineNr    DD DWORD ; Ordinal number of the row which is in the topmost row of DirWindow.
KeyBuffer         DB 32 * BYTE
PreviousScanDir   DB 264 * BYTE
FindText          DB NAME_MAX * BYTE
[.text]
MainGui
This is the graphic entry procedure which calls MainWindowPaint to paint the window and then it reads mouse and keyboard from the terminal.
Called by
MainCon.
Calls
MainWindowPaint.
MainGui:: PROC
    CALL MainWindowPaint
    CALL DirWindowPaint
    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 EscUp,EscDown,EscCtrlHome,EscCtrlEnd,EscHome,EscEnd,EscPgUp,EscPgDn,EscShiftTab,EscTab,EscEscape
       LEA RDI,[%key]        ; Check if a cursor key was read and dispatch it to .%key.
       MOV CL,SIZE# %key
       MOV RSI,R8
       REPE CMPSB
       JE .%key:
    %ENDFOR key
    MOV RSI,R8               ; Read the mouse. Expected 1B 5B 3C 3b 3B 3r 3r 3B 3c 3c 4D 00
    LODSW                    ;                                 Esc [ lt btn ;   col  ;   row  M
    CMP AX,0x5B1B            ; Esc [
    JNE .10:
    LODSB
    CMP AL,0x3C              ; Less-than?
    JNE .10:
    LodD RSI                 ; Mouse button left=0 right=2 wheelUp=64 wheelDown=65
    JC  .10:
    SUB EBX,3                ; SelectedLineNr for the case wheelUp.
    CMP AL,64                ; Scroll wheel up?
    JE .50:
    ADD EBX,3+3              ; SelectedLineNr for the case wheelDown.
    CMP AL,65                ; Scroll wheel down?
    JE .70:
    XOR EBX,EBX              ; Not scrolled.
    CMP AL,0                 ; Left button?
    JNE .10:
    LODSB                    ; Read the column where it was clicked.
    CMP AL,';'
    JNE .10:
    LodD                     ; Column.
    JC .10:
    MOV EBX,EAX              ; X-coordinate of mouse cursor.
    SHL EBX,16
    LODSB                    ; Read the row where it was clicked.
    CMP AL,';'
    JNE .10:
    LodD                     ; Row.
    JC .10:
    MOV BX,AX                ; Y-coordinate of mouse cursor.
    LODSB
    OR AL,'M'^'m'
    CMP AL,'m'
    JNE .10:
    ; Mouse cursor coordinates at left button click are in EBX. Row number is in BX.
    CMP BX,8
    JB .40:
    CMP BX,10
    JA  .40:
    MOV EAX,1                ; At line 8..10 - one of the five buttons clicked.
    SHR EBX,16               ; Get X-coordinate to EBX.
.20:SUB EBX,[MainWidthDiv5]
    JB .30:
    INC EAX
    JMP .20:
Row9Btn1:MOV AL,1
    JMP .30:
Row9Btn2:MOV AL,2
    JMP .30:
Row9Btn3:MOV AL,3
    JMP .30:
Row9Btn4:MOV AL,4
    JMP .30:
Row9Btn5:MOV AL,5
.30:CMP EAX,5
    JA .10:
    MOVB [ArgViewDirs::],AL  ; Change the view.
    CALL MainWindowPaint
    JMP .10:
.40:CMP BX,11
    JB .42:
    CMP BX,13
    JA .42:
Row12:
    LEA RSI,[Edit]           ; At Row 11..13 - "FindText" clicked.
    LEA RAX,[FindText]
    MOV ECX,SIZE# FindText
    MOV [RSI+EDIT.Address],RAX
    MOV [RSI+EDIT.MaxSize],CX
    MOV [RSI+EDIT.ScreenRow],12
    MOV [RSI+EDIT.ScreenCol],18
    MOV EAX,[MainWidth]
    SUB EAX,18
    MOV [RSI+EDIT.ScreenSize],AX
    Clear KeyBuffer
    CALL EditField
    CALL MainWindowPaint
    CALL DirWindowPaint
    JMP .10:
.42:CMP BX,1
    JB .44:
    CMP BX,3
    JA .44:
    SHR EBX,16               ; At Row 1..3 - ScanDir selection. Get X-coordinate to BX.
    CMP BX,55
    JB .44:                  ; If outside the field.
Row2:
    LEA RSI,[Edit]
    LEA RAX,[ArgScanDir::]
    MOV ECX,NAME_MAX
    MOV [RSI+EDIT.Address],RAX
    MOV [RSI+EDIT.MaxSize],CX
    MOV [RSI+EDIT.ScreenRow],2
    MOV [RSI+EDIT.ScreenCol],56
    MOV ECX,[MainWidth]
    SUB ECX,56
    MOV [RSI+EDIT.ScreenSize],CX
    MOV RSI,RAX              ; ArgScanDir::.
    GetLength$ RAX
    LEA RDI,[PreviousScanDir]
    REP MOVSB                ; Store the last scan directory name.
    CALL EditField
    LEA RSI,[PreviousScanDir]
    GetLength$ RSI
    LEA RDI,[ArgScanDir::]
    REPE CMPSB
    JE .43:
    XOR EAX,EAX              ; ArgScanDir has been changed, invalidate I/O files.
    MOV [ArgInputFile::],EAX
    MOV [ArgOutputFile::],EAX
.43:CALL LoadAndCompareScans::
    CALL MainWindowPaint
    CALL DirWindowPaint
    JMP .10:
Row6ColL:
    MOV EAX,[MainWidth]      ; At Row 6 - selection of scan files.
    SHR EAX,1
    STC
    JMP .45:
Row6ColR:
    MOV EAX,[MainWidth]      ; At Row 6 - selection of scan files.
    SHR EAX,1
    XOR EBX,EBX
    JMP .45:
.44:CMP BX,5
    JB .49:
    CMP BX,7
    JA .49:
    MOV EAX,[MainWidth]      ; At Row 5..7 - selection of scan files.
    SHR EAX,1
    SHR EBX,16               ; Column to EBX.
    CMP EBX,EAX              ; Differenciate (to flags) between older and newer scan.
.45:LEA RBX,[Edit]
    MOV [RBX+EDIT.ScreenRow],6
    MOV [RBX+EDIT.ScreenSize],AX
    MOV [RBX+EDIT.MaxSize],NAME_MAX
    LEA RDX,[ArgInputFile::]
    MOV ECX,2
    JB .47:
    LEA RDX,[ArgOutputFile::]
    LEA ECX,[EAX+2]
.47:MOV [RBX+EDIT.Address],RDX
    MOV [RBX+EDIT.ScreenCol],CX
    SUB EAX,2
    MOV [RBX+EDIT.ScreenSize],AX
    CALL EditField
    CALL LoadAndCompareScans::
.49:CALL MainWindowPaint
    CALL DirWindowPaint
    JMP .10:
.EscUp:
    DEC EBX
.50:TEST EBX
    JNS .60:
    SUB EBX,EBX
.60:MOV [SelectedLineNr::],EBX
    CALL DirWindowPaint
    JMP .10:
.EscDown:
    INC EBX
.70:MOV EAX,[MaxLineNr::]
    CMP EBX,EAX
    JB .60:
    MOV EBX,EAX
    JMP .60:
.EscPgUp:
    SUB EBX,[DirHeight]
    INC EBX
    JMP .50:
.EscPgDn:
    ADD EBX,[DirHeight]
    DEC EBX
    JMP .70:
.EscCtrlHome:
.EscHome:
    MOV EBX,0
    JMP .60:
.EscCtrlEnd:
.EscEnd:
    MOV EBX,[MaxLineNr::]
  ;  SUB EBX,[DirHeight]
  ;  INC EBX,EBX
    JMP .60:
TabSelTable:       ; Each jump is encoded to 5 bytes long instruction.
  JMP Row2
  JMP Row6ColL
  JMP Row6ColR
  JMP Row9Btn1
  JMP Row9Btn2
  JMP Row9Btn3
  JMP Row9Btn4
  JMP Row9Btn5
  JMP Row12
.EscShiftTab:
    MOV EAX,[TabSelected]
    SUB EAX,5
    JNB .80:
    MOV EAX,8*5
    JMP .80:
.EscTab: ; Tab pressed.
    MOV EAX,[TabSelected]
    ADD EAX,5
    CMP AL,8*5
    JNA .80:
    SUB EAX,EAX
.80:MOV [TabSelected],EAX              ; RAX=0,5,10,15,20,25,30,35,40.
    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.
    TerminateProgram 0
   ENDP MainGui
MainWindowPaint
Procedure MainWindowPaint paints the main window.
It is invoked when the folder with scan files or the date od scan file changes, when a button for ViewDirs is clicked, and when the terminal is resized.
MainWindowPaint uses pseudographic frames for painting. The low part (directory window) is cleared with spaces. DirWindowPaint should be called to paint the lower part.
Called by
MainGui.
MainWindowPaint PROC
    LinABI ioctl,0,TIOCGWINSZ,TtySize ; Check if the terminal is big enough.
    MOVZXW EDX,[TtySize.ts_lines]
    MOVZXW ECX,[TtySize.ts_cols]
    MOV EAX,MinHeight        ; Minimal acceptable rows (20..99).
    CMP EDX,EAX
    JB .10:
    MOV EAX,EDX
.10:LEA RDI,[ValResize]
    StoD RDI
    MOV AL,';'
    STOSB
    MOV EAX,MinWidth         ; Minimal acceptable columns.
    CMP ECX,EAX
    JB .13:
    MOV EAX,ECX
.13:StoD RDI
    MOV AX,'t'
    STOSW
    StdOutput EscResize
    LinABI ioctl,0,TIOCGWINSZ,TtySize
    MOVZXW EDX,[TtySize.ts_lines]
    DEC EDX                  ; Reserve one low row for status.
    MOV [MainHeight],EDX
    SUB EDX,15
    MOV [DirHeight],EDX
    MOVZXW ECX,[TtySize.ts_cols]
    MOV [MainWidth],ECX
    MOV EAX,ECX
    XOR EDX,EDX
    SHR ECX,1
    ADC EDX,EDX
    MOV [Remainder2],EDX
    MOV [MainWidthDiv2],ECX
    MOV ECX,5
    XOR EDX,EDX
    DIV RCX
    MOV [MainWidthDiv5],EAX
    MOV [Remainder5],EDX
    MOV EAX,[MainWidthDiv2]
    DEC EAX
    StoD ValRightDiv2        ; Prepare EscRightDiv2
    MOV AX,'C'
    STOSW
    MOV EAX,[MainWidth]
    DEC EAX
    StoD ValRightEdge        ; Prepare EscRightEdge
    MOV AX,'C'
    STOSW
    MOV EAX,[ArgViewDirs::]  ; 1..5.
    LEA RCX,[8*RAX-8+Buffers::]
    MOV [BufferSelected::],RCX
    BufferRetrieve RCX       ; Returns array of SCAN_INDEXes.
    SHR ECX,4                ; Each is 8 bytes long.
    MOV [MaxLineNr::],ECX
    INC ECX
    SUB ECX,[DirHeight]
    JA  .16:
    XOR ECX,ECX
.16:INC ECX
    MOV [SelectedLineNr],ECX
    ; Start painting.
    StdOutput EscLine1,EscDirsColor    ; Row 1
    StdOutput Spaces,Size=54
    CMPD [MainWidth],28
    JNA .Row2:
    StdOutput EscDimColor,BoxDR
    MOV ECX,[MainWidth]
    SUB ECX,56
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxDL,Space5
.Row2: StdOutput EscLine2,=B' ',EscEnhColor,EuroDirs::,EscDimColor,Version::, \
         =B".  A folder with scan files:",BoxV,EscFileColor,ArgScanDir::,EscDirsColor
    CMPD [MainWidth],28                ; Row 2
    JB .22:
    GetLengthUTF8 ArgScanDir::
    MOV EAX,[MainWidth]
    SUB EAX,ECX
    SUB EAX,56
    JB .22:
    StdOutput Spaces,Size=RAX
    JMP .25:
.22:StdOutput EscLine2,EscRightEdge
    JMP .Row3:
.25:StdOutput EscDimColor,BoxV,Space5
.Row3:
    StdOutput EscLine3                 ; Row 3
    StdOutput Spaces,Size=54
    CMPD [MainWidth],28
    JNA .Row4:
    StdOutput BoxUR
    MOV ECX,[MainWidth]
    SUB ECX,56
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxUL,Space5
.Row4:StdOutput EscLine4, =B" Select an older scan file"
    MOV EAX,[MainWidthDiv2]            ; Row 4
    SUB EAX,23
    StdOutput Spaces,Size=RAX
    StdOutput =B"and compare it with a newer scan file"
    StdOutput Spaces,Size=RAX
    StdOutput EscLine5, BoxDR          ; Row 5
    MOV ECX,[MainWidthDiv2]
    SUB ECX,2
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxDL,BoxDR
    ADD ECX,[Remainder2]
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxDL,Space5
    LEA RSI,[ArgInputFile::]
    StdOutput EscLine6, BoxV, EscFileColor, RSI, EscDirsColor
    GetLengthUTF8 RSI                  ; Row 6
    MOV EAX,[MainWidthDiv2]
    SUB EAX,2
    SUB EAX,ECX
    JA .27:
    StdOutput EscLine6,EscRightDiv2
    JMP .30:
.27:StdOutput Spaces,Size=RAX
.30:LEA RSI,[ArgOutputFile::]
    StdOutput EscDimColor,BoxV,BoxV,EscFileColor, RSI,EscDirsColor
    GetLengthUTF8 RSI
    MOV EAX,[MainWidthDiv2]
    ADD EAX,[Remainder2]
    SUB EAX,2
    SUB EAX,ECX
    JA .35:
    StdOutput EscLine6,EscRightEdge
    JMP .41:
.35:StdOutput Spaces,Size=RAX
.41:StdOutput EscDimColor,BoxV,Space5
    StdOutput EscLine7, BoxUR          ; Row 7
    MOV ECX,[MainWidthDiv2]
    SUB ECX,2
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxUL,BoxUR
    ADD ECX,[Remainder2]
    LEA EAX,[2*ECX+ECX]
    StdOutput Boxes,Size=RAX
    StdOutput BoxUL,Space5
    StdOutput EscLine8,EscDirsColor,Box2DR
    MOV ECX,[MainWidthDiv5]            ; Row 8
    SUB ECX,2
    LEA EAX,[2*RCX+RCX]
    StdOutput Boxes2,Size=RAX
    StdOutput Box2DL,Box2DR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2DL,Box2DR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2DL,Box2DR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2DL,Box2DR
    ADD ECX,[Remainder5]
    LEA EAX,[2*RCX+RCX]
    StdOutput Boxes2,Size=RAX
    StdOutput Box2DL,Space5
    StdOutput EscLine9,Box2V           ; Row 9 Button 1 title
    LEA RSI,[Numbers::+00]
    GetLength$ RSI
    ADD ECX,SIZE#BtnHead1 + SIZE#BtnTail1  ; Size of the button title.
    MOV EDX,[MainWidthDiv5]            ; Space inside the button rectangle.

    CMPB [ArgViewDirs::],1
    JNE .44:
    StdOutput EscEditColor
.44:StdOutput BtnHead1,RSI,BtnTail1
    SUB EDX,ECX
    JB  .47:
    StdOutput Spaces,Size=RDX
    JMP .50:
.47:MOV EAX,[MainWidthDiv5]
    DEC EAX
    StoD ValDivN
    MOV AX,'C'
    STOSW
    StdOutput EscLine9,EscDivN
.50:StdOutput EscDirsColor,Box2V,Box2V
    LEA RSI,[Numbers::+20]             ; Row 9  Button 2
    GetLength$ RSI
    CMPB [ArgViewDirs::],2
    JNE .52:
    StdOutput EscEditColor
.52:ADD ECX,SIZE#BtnHead2 + SIZE#BtnTail3  ; Size of the button title.
    MOV EDX,[MainWidthDiv5]
    StdOutput BtnHead2,RSI,BtnTail3
    SUB EDX,ECX
    JB  .55:
    StdOutput Spaces,Size=RDX
    JMP .58:
.55:MOV EAX,[MainWidthDiv5]
    ADD EAX,EAX
    DEC EAX
    StoD ValDivN
    MOV AX,'C'
    STOSW
    StdOutput EscLine9,EscDivN
.58:StdOutput EscDirsColor,Box2V,Box2V
    LEA RSI,[Numbers::+40]             ; Row 9  Button 3
    GetLength$ RSI
    ADD ECX,SIZE#BtnHead3 + SIZE#BtnTail3  ; Size of the button title.
    MOV EDX,[MainWidthDiv5]
    CMPB [ArgViewDirs::],3
    JNE .61:
    StdOutput EscEditColor
.61:StdOutput BtnHead3,RSI,BtnTail3
    SUB EDX,ECX
    JB  .64:
    StdOutput Spaces,Size=RDX
    JMP .67:
.64:MOV EAX,[MainWidthDiv5]
    LEA EAX,[2*EAX+EAX]
    DEC EAX
    StoD ValDivN
    MOV AX,'C'
    STOSW
    StdOutput EscLine9,EscDivN
.67:StdOutput EscDirsColor,Box2V,Box2V
    LEA RSI,[Numbers::+60]             ; Row 9  Button 4
    GetLength$ RSI
    ADD ECX,SIZE#BtnHead4 + SIZE#BtnTail3  ; Size of the button title.
    MOV EDX,[MainWidthDiv5]
    CMPB [ArgViewDirs::],4
    JNE .70:
    StdOutput EscEditColor
.70:StdOutput BtnHead4,RSI,BtnTail3
    SUB EDX,ECX
    JB  .72:
    StdOutput Spaces,Size=RDX
    JMP .75:
.72:MOV EAX,[MainWidthDiv5]
    LEA EAX,[4*EAX]
    DEC EAX
    StoD ValDivN
    MOV AX,'C'
    STOSW
    StdOutput EscLine9,EscDivN
.75:StdOutput EscDirsColor,Box2V,Box2V
    LEA RSI,[Numbers::+80]             ; Row 9 Button 5
    GetLength$ RSI
    ADD ECX,SIZE#BtnHead5 + SIZE#BtnTail5  ; Size of the button title.
    MOV EDX,[MainWidthDiv5]
    ADD EDX,[Remainder5]
    CMPB [ArgViewDirs::],5
    JNE .78:
    StdOutput EscEditColor
.78:StdOutput BtnHead5,RSI,BtnTail5
    SUB EDX,ECX
    JB  .81:
    StdOutput Spaces,Size=RDX
    JMP .84:
.81:MOV EAX,[MainWidthDiv5]
    LEA EAX,[4*EAX+EAX]
    DEC EAX
    StoD ValDivN
    MOV AX,'C'
    STOSW
    StdOutput EscLine9,EscDivN
.84:StdOutput EscDirsColor,Box2V,Space5
    StdOutput EscLine10,Box2UR         ; Row 10
    MOV ECX,[MainWidthDiv5]
    SUB ECX,2
    LEA EAX,[2*RCX+RCX]
    StdOutput Boxes2,Size=RAX
    StdOutput Box2UL,Box2UR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2UL,Box2UR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2UL,Box2UR
    StdOutput Boxes2,Size=RAX
    StdOutput Box2UL,Box2UR
    ADD ECX,[Remainder5]
    LEA EAX,[2*RCX+RCX]
    StdOutput Boxes2,Size=RAX
    StdOutput Box2UL,Space5
    StdOutput EscLine11,EscDimColor    ; Row 11
    StdOutput Spaces,Size=16
    StdOutput BoxDR
    MOV ECX,[MainWidth]
    LEA ECX,[2*RCX+RCX-18*3]
    StdOutput Boxes,Size=RCX
    StdOutput BoxDL,Space5
    StdOutput EscLine12,=B" Find this text:",BoxV,EscFindColor,FindText,EscDirsColor
    GetLengthUTF8 FindText             ; Row 12
    NEG ECX
    ADD ECX,[MainWidth]
    SUB ECX,18
    JB .87:
    StdOutput Spaces,Size=RCX
    JMP .90:
.87:StdOutput EscLine12,EscRightEdge
.90:StdOutput BoxV,Space5
; Row 13
    StdOutput EscLine13
    StdOutput Spaces,Size=16
    StdOutput EscDimColor,BoxUR
    MOV ECX,[MainWidth]
    LEA ECX,[2*RCX+RCX-18*3]
    StdOutput Boxes,Size=RCX
    StdOutput BoxUL,Space5
    StdOutput EscLine14,BoxDR          ; Row 14
    MOV ECX,[MainWidth]
    LEA ECX,[2*RCX+RCX-2*3]
    StdOutput Boxes,Size=RCX
    StdOutput BoxDL,Space5
    GetLength$ FindText                ; Rows 15...
    MOV [FindTextSize],ECX
    CALL DirWindowPaint
    MOV EAX,[MainHeight]               ; The last line (20..99).
    StoD ValLineXX,Size=2
    StdOutput EscDimColor,EscLineXX,BoxUR
    MOV ECX,[MainWidth]
    LEA ECX,[2*RCX+RCX-2*3]
    StdOutput Boxes,Size=RCX
    StdOutput BoxUL,Space5,EscDirsColor
    ; MainWindow is painted; DirWindow is erased to blank.
    RET
 ENDP MainWindowPaint
DirWindowPaint
Procedure DirWindowPaint paints the lower part of the MainWindow which contains volume and directory name, sorted by volume.
Contents of the selected index buffer will be in memory [IndexInMemory::]..[IndexEndInMemory::], number of indexes in [IndexNumber::]. SCAN_INDEX.Ptr refers to [NamesInMemory].
DirWindowPaint begins to paint at row 15 of the main window with index whose ordinal number (0..IndexNumber] has been put to [SelectedLineNr].
[SelectedLineNr] is manipulated with kursor keys. Number of printed rows is max. [DirHeight].
Input
ArgViewDir is ordinal 1..5 of the buffer with SCAN_INDEXes.
SelectedLineNr is ordinal number of the index displayed in the top of DirWindow.
Called by
MainGui, MainWindowPaint.
DirWindowPaint  PROC
    MOV EAX,[ArgViewDirs::]  ; 1..5.
    LEA RBX,[8*EAX-8+Buffers::]
    BufferRetrieve RBX
    ADD RCX,RSI
    MOV EAX,ECX
    SHR EAX,4
    MOV [IndexInMemory::],RSI
    MOV [IndexEndInMemory::],RCX
    MOV [IndexNumber::],RAX
    MOV EAX,[DirHeight]      ; Number of lines in DirWindow.
    MOV [LineCnt],EAX        ; Counter of written lines in DirWindow (0..DirHeight).
    MOV [LineNr],15          ; Ordinal number of row in MainWindowPaint (15..15+DirHeight).
    MOV EBX,[SelectedLineNr] ; Ordinal number of row in the topmost position of DirWindow (0..MaxLineNr::).
.10:MOV EAX,[LineNr]
    StoD ValLineXX,Size=2
    StdOutput EscLineXX,EscDimColor,BoxV,EscDirsColor
    CALL OneLine2Dir::       ; RBX is line number (0,1,2,,). Returns Dir=RSI,RCX with the line.
    TEST RCX
    JZ .70:
    MOV EDX,ECX
    MOV RDI,RSI
    MOV R8,RDI
    LEA RSI,[FindText]
    CMPD [FindTextSize],0
    JZ  .60:
    LODSB
.20:REPNE SCASB
    JNE .60:
    PUSH RCX,RSI,RDI
      MOV ECX,[FindTextSize]
      DEC ECX
      REPE CMPSB
    POP RDI,RSI,RCX
    JNE .20:
    PUSH RDX,RDI
     LEA RCX,[RDI-1]
     SUB RCX,R8
     SUB RDX,RCX
     StdOutput R8,Size=RCX
     StdOutput EscFindColor
     ADD R8,RCX
     MOV ECX,[FindTextSize]
     StdOutput R8,Size=RCX
     StdOutput EscDirsColor
     ADD R8,RCX
     SUB RDX,RCX
     StdOutput R8,Size=RDX
    POP RDI,RDX
    JMP .65:
.60:MOV RDI,R8
    StdOutput RDI,Size=RDX
.65:GetLengthUTF8 RDI,Size=RDX
    MOV EAX,[MainWidth]
    DEC EAX
    SUB EAX,ECX
    JB .70:
    StdOutput Spaces,Size=RAX
    JMP .80:
.70:MOV EAX,[MainWidth]
    SUB EAX,2
    StdOutput Spaces,Size=RAX
.80:StdOutput EscDimColor,BoxV,Space5
    INC EBX
    INC [LineNr]
    DEC [LineCnt]
    JA  .10:
    RET
   ENDP DirWindowPaint
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.
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      ; Length goes to RCX.
      SUB EAX,ECX
      ADD R11,RCX
      StdOutput EscShowCursor,EscEditColor,RSI
      StdOutput Spaces,Size=RAX
     POP R11
.20: CALL .CursorAtR11:     ; Display (perhaps new) cursor position.
.40: XOR EDI,EDI            ; Read the keyboard.
     LEA RSI,[KeyBuffer]
     MOV [RSI],RDI          ; Clear the key 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 Esc [ lt
     JE .40:
     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:
.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.
.50: CMP RCX,R11
     JAE .60:
     MOVZXB EAX,[R9+R12]
     INC RCX
     INC R12
     CMP AL,0x80
     JB .50:
     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 .50:
.60: ; 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
.EscHome:
     XOR R11,R11
     JMP .20:
.EscEnd:
     GetLengthUTF8 R9
     MOV R11,RCX
     JMP .20:
.EscLeft:
     TEST R11
     JZ .20:
     DEC R11
     JMP .20:
.EscRight:
     GetLengthUTF8 R9
     CMP R11,RCX
     JAE .20:
     INC R11
     JMP .20:
.0x08:
.0x7F:                       ; Move the cursor left and then perform .EscDelete.
     TEST R11
     JZ .20:
     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 .D2:
     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]
.D2: LEA RDI,[R9+R12]
     LEA RSI,[RDI+RDX]
     GetLength$ R9
     INC ECX
     SUB RCX,R12
     REP MOVSB
     JMP .10:
.0x0D:
.0x0A:
.0x09:
.EscShiftTab:
.EscEscape:
     XOR R11,R11
     CALL .CursorAtR11:
     MOV RSI,[RBX+EDIT.Address]
     GetLengthUTF8 RSI
     MOV EDX,[MainWidth]
     SUB EDX,18
     SUB EDX,ECX
     StdOutput EscFindColor,RSI, EscDirsColor
     StdOutput Spaces,Size=RDX
     StdOutput EscHideCursor
     RET
   ENDP EditField
OneLine2Dir

Construct a line from the [BufferSelected] into Dir. The line looks like dir_size directory\name\in\UTF8, it is encoded in UTF-8 and zero terminated.
When the input line number RBX is 0, an empty line is returned (CF=1. RCX=0).
When the input line number RBX is 1, first line is returned (CF=0. RCX>0).
When the input line number RBX is 2, sedond line is returned etc.
When the input line number RBX is bigger than the [MaxLineNr], an empty line is returned (CF=1, RCX=0).

Input
RBX= line number (0,1,2,,,).
[ArgViewDirs::]= selected view (1..5 alias ArgViewDirsIns..ArgViewDirsDel).
Output
RSI=Dir is filled with the line containing the differential size and name in WIDE encoding.
RCX= is size of the output line in bytes.
Calls
AddUnderscores
Clobbers
RAX,RDX
OneLine2Dir:: PROC
   PUSH RBX,RDI
    MOV EAX,[ArgViewDirs::]
    MOV RDX,[Buffers+8*RAX-8]
    BufferRetrieve RDX    ; Load the buffer contents to RSI,RCX.
    ADD RCX,RSI           ; The end of buffer contents.
    SAL EBX,4             ; Each SCAN_INDEX in the buffer contents has size=16.
    JZ .10:
    LEA RBX,[RBX+RSI-SIZE# SCAN_INDEX] ; Let RBX point at the selected SCAN_INDEX.
    CMP RBX,RCX           ; Is it out of contents?
    JB .20:
.10:XOR ECX,ECX
    LEA RSI,[Dir::]
    STC
    JMP .90:              ; Abort when the requested line number exceeded the buffer and return CF=1 and empty line.
.20:MOV RDX,[NewerInMemory::]
    CMP AL,ArgViewDirsDel
    JNE .30:
    MOV RDX,[OlderInMemory::] ; Select the mapping of File_scanOlder or File_scanNewer.
.30:MOV RAX,[RBX+SCAN_INDEX.Volume]
    LEA RSI,[NumberA::]
    StoD RSI,Size=20      ; Store the directory volume as a decimal ANSI
    CALL AddUnderscores   ;  and complete it with separators.
    LEA RSI,[Number_A::]
    CMPB [ArgViewDirs::],ArgViewDirsDel
    JNE .50:
    CMPB [RSI],'0'
    JE .50:
    INC RSI               ; Skip the minus sign when viewing deleted direcotires.
.50:LEA RDI,[Dir::]
    CMPB [ArgViewDirs::],ArgViewDirsInc
    JNE .60:
    MOV AL,'+'            ; Add a plus sign when viewing incremented directories.
    JMP .70:
.60:LODSB
    CMP AL,0
    JE .80:
.70:STOSB
    JMP .60:
.80:MOV ECX,[RBX+SCAN_INDEX.Size]
    MOV EAX,[RBX+SCAN_INDEX.Ptr]
    ADD RDX,RAX           ; Let RDX point to the directory name.
    MOV RSI,RDX
    REP MOVSB
    MOV RCX,RDI           ; At the end of directory name.
    MOVB [RDI],0          ; Zero terminate.
    LEA RSI,[Dir]
    SUB RCX,RSI           ; CF=0, RSI,RCX is the target line.
.90:POP RDI,RBX
    RET
  ENDP OneLine2Dir
AddUnderscores

Complete an ASCII decadic number with underscores _ each three digits.

Input
RSI= is pointer to the beginning of the number.
RDI= is pointer at the end of the number.
Output
Number_A is filled with the number and separators, space and zero terminated.
Called by
OneLine2Dir
Clobbers
RAX,RCX,RDI
AddUnderscores PROC
   PUSH RDX
    SUB RDI,RSI
    MOV ECX,3
    MOV EAX,EDI
    XOR EDX,EDX
    LEA RDI,[Number_A::]
    DIV RCX
    CMP EDX,0
    JNE .20:
    REP MOVSB
    DEC EAX
    JMP .40:
.20:CMP EDX,1
    JNE .30:
    MOVSB
    CMPB [RSI-1],'-'
    JNE .40:
    XCHG EAX,EDX
    DEC EDX
    JS .80:
    JMP .60:
.30:MOVSW
.40:XCHG EAX,EDX
.50:DEC RDX
    JS .80:
    MOV AL,'_'
    STOSB
.60:MOV CL,3
    REP MOVSB
    JMP .50:
.80:MOV AX,' '
    STOSW
   POP RDX
   RET
 ENDP AddUnderscores
  ENDPROGRAM dirsling

▲Back to the top▲