Files
kolibrios/programs/system/setup/setup.asm
T
Burer bfb69dd67a
Test PR / Build (en_US) (pull_request) Successful in 1m54s
Test PR / Build (es_ES) (pull_request) Successful in 1m59s
Test PR / Build (ru_RU) (pull_request) Successful in 2m6s
system/setup: grid layout, fix mouse and font height handling
Layout:
- controls 24 px high and 12 px apart, 8 px to the window border
  (12 at the top); text centred on the capitals of the 8x16 font
- value boxes sunken, the -/+ buttons share one frame with them
- checkboxes: box before the label, spread without per-item widths
- group title drawn over the frame with a filled background
- bevel and checkbox colours derived from the skin, no hardcoded white

Fixes:
- the window re-applied the mouse settings read at start, reverting
  changes made meanwhile; mouse is now read and applied by BOOT only
- font height is clamped to 9..99, a larger ini value showed garbage
  and could fault on div
- a GetButton result of 1 (no button) indexed rows out of bounds
- hidden checkbox buttons flashed an XOR frame when pressed
- skip bg_program when it is empty; drop duplicate LBA/PCI strings

Assisted-by: Claude:claude-opus-5-5
2026-09-29 19:42:20 +03:00

407 lines
9.7 KiB
FASM

; SPDX-License-Identifier: NOASSERTION
;
; System settings.
; SETUP BOOT - apply the settings from system.ini (run from AUTORUN.DAT)
; SETUP - window to change and save them
;
; Texts are UTF-8
include '../../macros.inc'
format meos 01
entry START
stack 4096
include '../../proc32.inc'
include '../../dll.inc'
;---------------------------------------------------------------
START:
mcall 68,11
stdcall dll.Load, @IMPORT
test eax,eax
jnz quit
GetCommandLine eax
cmp dword[eax],'BOOT'
jnz @f
call settings_read_boot
call settings_read_ini
call settings_apply_boot
call style_apply
quit:
mcall -1
@@:
call settings_read_system
; the checkbox image is shared by @RESHARE, 0 if it is not running
mcall 68,22,sz_checkbox,0,0
mov [checkboxImage],eax
;---------------------------------------------------------------
draw_window:
mov eax,[language]
mov eax,[texts+eax*4]
mov [text],eax
mcall 12,1
mcall 48,3,sc,sizeof.system_colors
mov byte[sc.work_text+3],FONT
mov byte[sc.work_button_text+3],FONT
mcall 48,4
lea ecx,[eax+(50 shl 16)+CLIENT_H+4]
mov edx,[sc.work]
or edx,0x34000000
mcall 0,<50,CLIENT_W+9>,,,0,title
; a row: label, value (drawn by draw_values), '-' and '+' buttons
xor ebp,ebp
.row:
imul edi,ebp,ROW_STEP
add edi,TOP ; y of the row
mov ecx,edi
shl ecx,16
add ecx,ROW_H-1 ; the button is 1 pixel bigger than given
lea edx,[FIRST_ROW_BUTTON+ebp*2]
mcall 8,<BUTTON1_X,ROW_H-1>,,,[sc.work_button]
lea edx,[FIRST_ROW_BUTTON+1+ebp*2]
mcall 8,<BUTTON2_X,ROW_H-1>
; the kernel leaves the corners of a button out: one frame for both,
; its right corners stay out
mov edx,[sc.work_button]
shr edx,1
and edx,0x7F7F7F ; the border colour of a button
mov cx,1
mcall 13,<BUTTON1_X,BUTTON2_X+ROW_H-1-BUTTON1_X>
add ecx,(ROW_H-1) shl 16
mcall 13
lea ebx,[edi+TEXT_DY+(LABEL_X shl 16)]
mov ecx,ebp
call get_text
mcall 4,,[sc.work_text]
lea ebx,[edi+TEXT_DY+((BUTTON1_X+8) shl 16)]
lea edx,[glyphs+ebp*4]
mcall 4,,[sc.work_button_text]
lea ebx,[edi+TEXT_DY+((BUTTON2_X+8) shl 16)]
lea edx,[glyphs+2+ebp*4]
mcall 4
inc ebp
cmp ebp,ROWS
jb .row
; group box of the checkboxes: a frame, its title over it on the work colour
mcall 13,<GROUP_X,GROUP_W>,<GROUP_Y,GROUP_H>,[sc.work_graph]
mcall 13,<GROUP_X+1,GROUP_W-2>,<GROUP_Y+1,GROUP_H-2>,[sc.work]
mov ecx,T_GROUP
call get_text
mov ecx,[sc.work_text]
or ecx,0x40000000
mcall 4,<GROUP_TITLE_X,GROUP_TITLE_Y>,,,,[sc.work]
; The checkboxes are spread over the group, the last one ends at its end.
; LBA and PCI are fixed, so the step only depends on the speaker label.
mov ecx,T_SPEAKER
call get_text
mov eax,ITEM_END-ITEM_X-CHECK_SIZE-8
.length:
mov cl,[edx]
inc edx
test cl,cl
jz .step
and cl,0xC0
cmp cl,0x80 ; UTF-8 continuation byte
jz .length
sub eax,8
jmp .length
.step:
shr eax,1
mov [checkStep],eax
; a checkbox: the box (drawn by draw_values), then the label, both under
; one button up to the end of the group. The next button covers the rest.
xor ebp,ebp
.check:
mov edi,[checkStep]
imul edi,ebp
add edi,ITEM_X ; x of the box
lea ebx,[edi+CHECK_SIZE+8]
shl ebx,16
add ebx,CHECK_Y+TEXT_DY
call check_label
mcall 4,,[sc.work_text]
mov ebx,edi
shl ebx,16
add ebx,ITEM_END
sub ebx,edi
lea edx,[FIRST_CHECK_BUTTON+BT_HIDE+BT_NOFRAME+ebp]
mcall 8,,<CHECK_Y,ROW_H-1>
inc ebp
cmp ebp,CHECKS
jb .check
mcall 12,2
;---------------------------------------------------------------
draw_values:
mov edx,languageNames
mov ecx,[language]
call nth_string
mov [valueText],edx
mov edx,sz_subpixel
mov ecx,[fontSmoothing]
cmp ecx,2
jae @f
add ecx,T_OFF
call get_text
@@:
mov [valueText+4],edx
mov eax,[fontHeight]
mov bl,10
div bl
add ax,'00'
mov word[heightText],ax
mov [valueText+8],heightText
; each value in a light box framed on three sides, the button is the fourth,
; the left corners are cut off
xor ebp,ebp
.row:
imul edi,ebp,ROW_STEP
add edi,TOP
mov ecx,edi
shl ecx,16
add ecx,ROW_H
mcall 13,<VALUE_X+1,VALUE_W-1>,,[sc.work_graph]
add ecx,(1 shl 16)-2
mcall 13,<VALUE_X,VALUE_W>
; sunken, the inner lines of a button reversed: three boxes, each 1 pixel
; smaller, leave darker lines left and top and lighter right and bottom
mov edx,[sc.work_light]
mov eax,edx
shr eax,3
and eax,0x1F1F1F
sub edx,eax ; 1/8 darker
mcall 13,<VALUE_X+1,VALUE_W-1>
mov edx,[sc.work_light]
or edx,0x1F1F1F ; lighter
add ecx,(1 shl 16)-1
mcall 13,<VALUE_X+2,VALUE_W-2>
dec ecx
mcall 13,<VALUE_X+2,VALUE_W-3>,,[sc.work_light]
lea ebx,[edi+TEXT_DY+((VALUE_X+VALUE_PAD) shl 16)]
mov edx,[valueText+ebp*4]
mcall 4,,[sc.work_text]
inc ebp
cmp ebp,ROWS
jb .row
; checkboxes: a frame, light inside, the @RESHARE image when set
xor ebp,ebp
.check:
mov ebx,[checkStep]
imul ebx,ebp
add ebx,ITEM_X
shl ebx,16
add ebx,CHECK_SIZE
mcall 13,,<CHECK_BOX_Y,CHECK_SIZE>,[sc.work_graph]
add ebx,(1 shl 16)-2
mcall 13,,<CHECK_BOX_Y+1,CHECK_SIZE-2>,[sc.work_light]
mov eax,[checks+ebp*8]
mov eax,[eax]
xor eax,[checks+ebp*8+4]
jz .next
mov edx,ebx
mov dx,CHECK_BOX_Y+1
mov ebx,[checkboxImage]
test ebx,ebx ; no @RESHARE: the box stays empty
jz .next
mcall 7,,<CHECK_SIZE-2,CHECK_SIZE-2>
.next:
inc ebp
cmp ebp,CHECKS
jb .check
;---------------------------------------------------------------
still:
mcall 10
cmp eax,1
jz draw_window
cmp eax,2
jz .key
cmp eax,3
jnz still
mcall 17
shr eax,8
cmp eax,1
jz quit
sub eax,FIRST_ROW_BUTTON
jb still ; 0: no button after all
cmp eax,FIRST_CHECK_BUTTON-FIRST_ROW_BUTTON
jae .check
; '-' or '+' of a row: step the value within the limits of the row
shr eax,1 ; eax = row, CF = '+'
lea esi,[eax*3]
lea esi,[rows+esi*4]
mov edi,[esi]
mov ecx,[edi]
jc .plus
cmp ecx,[esi+4]
jbe still
dec ecx
jmp .set
.plus:
cmp ecx,[esi+8]
jae still
inc ecx
.set:
mov [edi],ecx
push eax
call apply_and_save
pop eax
cmp eax,1 ; the language and the font smoothing
jbe draw_window ; change all the texts: repaint the window
jmp draw_values
.check:
mov eax,[checks-(FIRST_CHECK_BUTTON-FIRST_ROW_BUTTON)*8+eax*8]
xor dword[eax],1
call apply_and_save
jmp draw_values
.key:
mcall 2
jmp still
;---------------------------------------------------------------
; every change takes effect at once and is kept in system.ini
apply_and_save:
call settings_apply
jmp settings_save_ini
; edx = label of the checkbox ebp
check_label:
mov edx,[checkLabels+ebp*4]
test edx,edx
jnz @f
mov ecx,T_SPEAKER
call get_text
@@:
ret
; edx = string number ecx of the window language
get_text:
mov edx,[text]
; edx = string number ecx of the zero separated list at edx
nth_string:
jecxz .done
@@:
inc edx
cmp byte[edx-1],0
jnz @b
loop @b
.done:
ret
;---------------------------------------------------------------
; DATA
@IMPORT:
library libini, 'libini.obj'
import libini, \
ini.get_str, 'ini_get_str',\
ini.get_int, 'ini_get_int',\
ini.set_str, 'ini_set_str',\
ini.set_int, 'ini_set_int'
ROWS = 3
CHECKS = 3
FIRST_ROW_BUTTON = 10 ; row N has '-' = 10+N*2 and '+' = 11+N*2
FIRST_CHECK_BUTTON = 20
FONT = 0xB0 ; text flags: zero terminated, 8x16 UTF-8
; layout of the client area: controls ROW_H high, GAP empty pixels apart,
; EDGE to the window border, GAP at the top
LABEL_CHARS = 20 ; the longest label, Spanish
GAP = 12
EDGE = 8
TOP = GAP
ROW_H = 24
ROW_STEP = ROW_H + GAP
TEXT_DY = 5 ; the capitals, rows 2..11 of the font, centred in ROW_H
LABEL_X = EDGE - 1 ; column 0 of a letter is empty: aligned with the group frame
VALUE_X = LABEL_X + LABEL_CHARS*8 + GAP
VALUE_PAD = GAP
VALUE_W = 8*8 + VALUE_PAD*2
BUTTON1_X = VALUE_X + VALUE_W ; right after the value box
BUTTON2_X = BUTTON1_X + ROW_H - 1 ; the buttons share a border
CLIENT_W = BUTTON2_X + ROW_H + EDGE
GROUP_X = EDGE
GROUP_W = CLIENT_W - EDGE*2
GROUP_Y = TOP + ROWS*ROW_STEP + 5 ; GAP to the capitals of the title
GROUP_TITLE_Y = GROUP_Y - 7 ; the frame crosses the capitals
CHECK_Y = GROUP_Y + 1 + GAP ; the row of the checkboxes
GROUP_H = 1 + GAP + ROW_H + GAP + 1
CHECK_SIZE = 15
CHECK_BOX_Y = CHECK_Y + (ROW_H-CHECK_SIZE)/2
ITEM_X = GROUP_X + 1 + GAP
ITEM_END = GROUP_X + GROUP_W - GAP ; the last column of a letter is empty
GROUP_TITLE_X = ITEM_X - 8 - 1 ; a space, then a letter from its column 1
CLIENT_H = GROUP_Y + GROUP_H + EDGE
; variable, min, max of every row
align 4
rows:
dd language, 0, LANGUAGES-1
dd fontSmoothing, 0, 2
dd fontHeight, FONT_H_MIN, FONT_H_MAX
; variable and the value of it that means 'not checked'
checks dd lba,0, pci,0, speakerMute,1
checkLabels dd sz_lba, sz_pci, 0 ; 0: the speaker label of the language
glyphs db '<',0,'>',0,'<',0,'>',0,'-',0,'+',0
sz_subpixel db 'Subpixel',0
languageNames db 'English',0,'Finnish',0,'German',0,'Russian',0
db 'French',0,'Estonian',0,'Spanish',0,'Italian',0
title db "System settings",0
sz_checkbox db "CHECKBOX",0
; Texts of the window languages: zero terminated strings in this order
; (row labels, group title, speaker label, 'off', 'on')
T_GROUP = ROWS
T_SPEAKER = ROWS + 1
T_OFF = ROWS + 2
; the texts of every kernel language, English where there is no translation
texts dd texteng, texteng, texteng, textrus, texteng, texteng, textspa, texteng
texteng db 'System language',0, 'Font smoothing',0, 'Font height',0
db ' Access settings ',0, 'Speaker',0
db 'Off',0, 'On',0
textspa db 'Idioma del sistema',0, 'Suavizado de fuentes',0, 'Altura de fuente',0
db ' Ajustes de acceso ',0, 'Altavoz',0
db 'No',0, 'Sí',0
textrus db 'Язык системы',0, 'Сглаживание шрифтов',0, 'Высота шрифтов',0
db ' Настройки доступа ',0, 'Динамик',0
db 'Нет',0, 'Да',0
;---------------------------------------------------------------
include 'settings.inc'
text dd ? ; texts of the window language
checkboxImage dd ?
checkStep dd ? ; x distance of two checkboxes
sc system_colors
valueText rd ROWS ; the strings shown in the value boxes
heightText rb 4