Skip to content

Commit 78c60f5

Browse files
committed
Notes/refactor
1 parent e603e47 commit 78c60f5

File tree

9 files changed

+93
-31
lines changed

9 files changed

+93
-31
lines changed

dlls/advapi32/advapi32.hexa

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,40 @@ fun regCreateKeyExW(key SizeOfPointer, lpSubKey ConstArrayPointer<ClangWideChar>
2424
// TODO
2525
tofitaDebugLog("regCreateKeyExW(%S)\n".utf16(), lpSubKey as! UInt64)
2626
return 0
27+
2728
}
2829

2930
@dllExport('RegOpenKeyExW')
3031
fun regOpenKeyExW(key SizeOfPointer, lpSubKey ConstArrayPointer<ClangWideChar>) SizeOfPointer {
3132
// TODO
3233
tofitaDebugLog("regOpenKeyExW(%S)\n".utf16(), lpSubKey as! UInt64)
3334
return 0
35+
3436
}
3537

3638
@dllExport('RegQueryValueExW')
3739
fun regQueryValueExW(key SizeOfPointer, lpValueName ConstArrayPointer<ClangWideChar>) SizeOfPointer {
3840
// TODO
3941
tofitaDebugLog("regQueryValueExW(%S)\n".utf16(), lpValueName as! UInt64)
4042
return 0
43+
4144
}
4245

4346
@dllExport('RegSetValueExW')
4447
fun regSetValueExW(key SizeOfPointer, lpValueName ConstArrayPointer<ClangWideChar>) SizeOfPointer {
4548
// TODO
4649
tofitaDebugLog("regSetValueExW(%S)\n".utf16(), lpValueName as! UInt64)
4750
return 0
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
4861
}
4962

5063
@linkName('_DllMainCRTStartup_TODO')
@@ -53,10 +66,10 @@ fun regSetValueExW(key SizeOfPointer, lpValueName ConstArrayPointer<ClangWideCha
5366
#else
5467
@fastcall
5568
#end
56-
fun _DllMainCRTStartup(
57-
unusedX Any,
58-
unusedY Any,
59-
unusedZ Any
69+
fun _DllMainCRTStartupTODO(
70+
hinstDLL SizeOfPointer,
71+
fdwReason UInt32,
72+
lpvReserved SizeOfPointer
6073
) Void {
61-
// TODO
74+
// TODO unused
6275
}

dlls/kernel32/kernel32.hexa

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fun exitProcess(@hide exitCode UInt32) {
2424
fun localAlloc(flags UInt32, bytes SizeOfPointer) HLocal {
2525
// TODO better way to take pointer to array element `&buffer[bufferOffset]`
2626
let result = (buffer as! UInt64) + bufferOffset
27+
2728
bufferOffset += bytes as! UInt64 // TODO .toInt()
2829

2930
// Align to 8 bytes

dlls/msvcrt/msvcrt.hexa

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,11 @@ fun _initterm(first ConstArrayPointer<PVFV>, last ConstArrayPointer<PVFV>) Void
121121
if callback == null { continue }
122122

123123
callback()
124-
tofitaDebugLog("_initterm done call (%8)\n".utf16(), callback as! UInt64)
125124
tofitaDebugLog("_initterm calls (%8)".utf16(), callback as! UInt64)
125+
tofitaDebugLog("_initterm done call (%8)".utf16(), callback as! UInt64)
126126
}
127+
128+
tofitaDebugLog("_initterm all done".utf16())
127129
}
128130

129131
@dllExport('_iob')
@@ -310,6 +312,7 @@ fun malloc(size SizeOfPointer) SizeOfPointer {
310312
}
311313

312314
var stub = Malloc()
315+
// TODO use HeapAlloc
313316
tofitaDebugLog("[msvcrt] malloc done allocation %8".utf16(), stub as! UInt64)
314317
return stub as! SizeOfPointer
315318
}

dlls/ntdll/ntdllMain.hexa

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@
217217
STUB(OpenClipboard)
218218
STUB(PeekConsoleInputA)
219219
STUB(PostMessageW)
220+
// TODO delete
220221
STUB(ReadConsoleA)
221222
STUB(RegCloseKey)
222223
STUB(RegCreateKeyExW)
@@ -285,7 +286,6 @@
285286
STUB(lstrcatW)
286287
STUB(lstrcpynA)
287288
STUB(lstrcpyW)
288-
STUB(lstrlenW)
289289
STUB(MapVirtualKeyExW)
290290

291291
STUB(wcschr)

dlls/user32/dialogs.hexa

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class RadioGroup {
5959
// TODO docs
6060
fun dialog_GetControl32(p ConstArrayPointer<UInt16>, info DlgControlInfo, dialogEx Bool32) ConstArrayPointer<UInt16> {
6161
tofitaDebugLog("dialog_GetControl32 called p = %8".utf16(), p as! UInt64)
62+
tofitaDebugLog("dialog_GetControl32 called info = %8".utf16(), info as! UInt64)
6263

6364
var p = p
6465
if dialogEx == Bool32.True {

dlls/user32/extras.hexa

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ fun intersectRect(lprcDst Rect, lprcSrc1 Rect, lprcSrc2 Rect) Bool32 {
793793
return Bool32.False
794794
}
795795

796+
// TODO move to crt
796797
fun max(a Int32, b Int32) Int32 {
797798
return a > b ? a : b
798799
}
@@ -988,6 +989,8 @@ fun bitBlt(
988989
}*/
989990
// Handle different bit depths
990991
if bppSrc == 8i16 and bppDest == 32i16 {
992+
tofitaDebugLog("> bppSrc == 8i16 and bppDest == 32i16".utf16())
993+
991994
// 8-bit source (indexed) to 32-bit destination (RGBA)
992995
if colorTable == null or colorTableSize == 0 {
993996
tofitaDebugLog("> Color table missing for 8-bit source".utf16())
@@ -1023,7 +1026,7 @@ fun bitBlt(
10231026
)
10241027
}
10251028
} else {
1026-
tofitaDebugLog("> Invalid pixel index: %u".utf16(), srcPixel as! UInt64)
1029+
// tofitaDebugLog("> Invalid pixel index: %u".utf16(), srcPixel as! UInt64)
10271030
// Invalid index: use black
10281031
bitsDest[destPixelOffset] = 0u8
10291032
bitsDest[destPixelOffset + 1] = 0u8
@@ -1033,6 +1036,8 @@ fun bitBlt(
10331036
}
10341037
}
10351038
} else if bppSrc == 32i16 and bppDest == 32i16 {
1039+
tofitaDebugLog("> bppSrc == 32i16 and bppDest == 32i16".utf16())
1040+
10361041
// 32-bit to 32-bit copy
10371042
for row in 0 ... cy - 1 {
10381043
let srcOffset = ((ySrc + row) * bytesPerRowSrc + xSrc * 4) as! Int
@@ -1115,6 +1120,8 @@ fun srand(seed UInt32) Void {
11151120

11161121
@dllExport('memcmp')
11171122
fun memcmp(stub SizeOfPointer) SizeOfPointer {
1123+
// TODO Global item `memcmp` declared in `/extras` already defined at `Hexa\library\c\c.hexa` line `493`
1124+
// ^ must only type-check `declare` vs `fun`
11181125
// TODO
11191126
tofitaDebugLog("memcmp called".utf16())
11201127
return 0
@@ -1381,16 +1388,16 @@ fun lstrcmpW(lpString1 ConstArrayPointer<ClangWideChar>, lpString2 ConstArrayPoi
13811388

13821389
var i = 0
13831390
// TODO Hexa: `ClangWideChar.nullTerminator`
1384-
while lpString1[i] != 0 as! ClangWideChar or lpString2[i] != 0 as! ClangWideChar {
1385-
if (lpString1[i] as! UInt16) < (lpString2[i] as! UInt16) {
1386-
tofitaDebugLog("> lpString1 < lpString2".utf16())
1387-
return -1
1388-
} else if (lpString1[i] as! UInt16) > (lpString2[i] as! UInt16) {
1389-
tofitaDebugLog("> lpString1 > lpString2".utf16())
1390-
return 1
1391-
}
1392-
i += 1
1393-
}
1391+
while lpString1[i] != 0 as! ClangWideChar or lpString2[i] != 0 as! ClangWideChar {
1392+
if (lpString1[i] as! UInt16) < (lpString2[i] as! UInt16) {
1393+
tofitaDebugLog("> lpString1 < lpString2".utf16())
1394+
return - 1
1395+
} else if (lpString1[i] as! UInt16) > (lpString2[i] as! UInt16) {
1396+
tofitaDebugLog("> lpString1 > lpString2".utf16())
1397+
return 1
1398+
}
1399+
i += 1
1400+
}
13941401

13951402
tofitaDebugLog("> Strings equal".utf16())
13961403
return 0
@@ -1445,7 +1452,7 @@ fun vswprintf(stub SizeOfPointer) SizeOfPointer {
14451452
@dllExport('wcsncpy')
14461453
fun wcsncpy(dest ArrayPointer<ClangWideChar>, src ConstArrayPointer<ClangWideChar>, count SizeOfPointer) ArrayPointer<ClangWideChar> {
14471454
// TODO
1448-
tofitaDebugLog("wcsncpy called %S %u\n".utf16(), src as! UInt64, count as! UInt64)
1455+
tofitaDebugLog("wcsncpy called %S %u".utf16(), src as! UInt64, count as! UInt64)
14491456

14501457
var i = 0u32
14511458
while i < count {
@@ -1755,11 +1762,13 @@ fun getObjectW(hObject SizeOfPointer, nSize Int32, lpvObject SizeOfPointer) Int3
17551762
bitmap.bmWidthBytes = 72
17561763
bitmap.bmType = 0
17571764
var bmBits ArrayByValue<ClangWideChar, 8064> = [0]
1765+
// TODO currently `bmBits` field never used or its a unnecessary `BITMAP` type alias?
17581766
bitmap.bmBits = bmBits as! SizeOfPointer // TODO .address
17591767

17601768
return 0
17611769
}
17621770

1771+
tofitaDebugLog("> not recognised".utf16())
17631772
return 0
17641773
}
17651774

@@ -2006,7 +2015,7 @@ fun patBlt(hdc HDc, x Int32, y Int32, cx Int32, cy Int32, dwRop RasterOperation)
20062015
let patternWidth = pattern.width
20072016
let patternHeight = pattern.height
20082017
let patternBits = pattern.bits
2009-
let patternBytesPerRow = pattern.bytesPerRow
2018+
let patternBytesPerRow = pattern.bytesPerRow // Should be 4 for 8-pixel monochrome (4-byte aligned)
20102019

20112020
// Get colors from DC
20122021
let fgColor = dc.textColor
@@ -2015,6 +2024,9 @@ fun patBlt(hdc HDc, x Int32, y Int32, cx Int32, cy Int32, dwRop RasterOperation)
20152024
let brushOrgY = dc.brushOrgY
20162025

20172026
// Apply pattern
2027+
tofitaDebugLog("> brushOrgX %d brushOrgY %d".utf16(), brushOrgX as! UInt64, brushOrgY as! UInt64)
2028+
tofitaDebugLog("> fgColor %8 bgColor %8".utf16(), fgColor as! UInt64, bgColor as! UInt64)
2029+
20182030
for row in 0 ... cy - 1 {
20192031
let destY = y + row
20202032
let patternY = ((row + brushOrgY) % patternHeight) as! Int32
@@ -2350,7 +2362,7 @@ fun isTextUnicode(stub SizeOfPointer) SizeOfPointer {
23502362
return 0
23512363
}
23522364

2353-
@dllExport('RegOpenKeyW')
2365+
@dllExport('RegOpenKeyW') // TODO move to adv
23542366
fun regOpenKeyW(stub SizeOfPointer) SizeOfPointer {
23552367
// TODO
23562368
tofitaDebugLog("RegOpenKeyW called".utf16())

dlls/user32/user32.header.hexa

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,16 @@ fun gdiGetCharDimensions(
105105
// Win32 Spec: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setrect
106106
@dllExport('SetRect')
107107
fun setRect(
108-
lprc Rect, // LPRECT -> Pointer to ClangRect (assuming LPRECT is a pointer to a RECT structure)
109-
xLeft Int, // int -> Int
108+
lprc Rect?, // LPRECT -> Pointer to ClangRect
109+
xLeft Int, // int -> Int // TODO remove -> comments
110110
yTop Int, // int -> Int
111111
xRight Int, // int -> Int
112112
yBottom Int // int -> Int
113113
) Bool32 // BOOL -> Bool (return type)
114114
{
115115
tofitaDebugLog("SetRect called with lprc %8".utf16(), lprc as! UInt64)
116-
tofitaDebugLog("left %d top %d".utf16(), xLeft as! UInt64, yTop as! UInt64)
117-
tofitaDebugLog("right %d bottom %d".utf16(), xRight as! UInt64, yBottom as! UInt64)
116+
tofitaDebugLog("> left %d top %d".utf16(), xLeft as! UInt64, yTop as! UInt64)
117+
tofitaDebugLog("> right %d bottom %d".utf16(), xRight as! UInt64, yBottom as! UInt64)
118118
if let rc = lprc {
119119
rc.left = xLeft
120120
rc.top = yTop
@@ -462,7 +462,7 @@ class ExeResourceLoader<SIZE, HEADER> {
462462

463463
if entry.unionName.ref.id == lpType {
464464
// serialPrintf("[ExeResourceLoader] Found RT_ICON at %d offset %8\n", id as! Int, entry.unionOffset.ref.offsetToData as! UInt64)
465-
tofitaDebugLog("[ExeResourceLoader] Found by type %8...\n".utf16(), lpType)
465+
tofitaDebugLog("[ExeResourceLoader] Found by type %8...".utf16(), lpType)
466466
} else {
467467
tofitaDebugLog("[ExeResourceLoader] Ignoring by type %8...".utf16(), entry.unionName.ref.id)
468468
continue
@@ -524,7 +524,7 @@ fun findResourceExW(hModule HModule, lpType ConstArrayPointer<ClangWideChar>, lp
524524
var simpleResource = true
525525

526526
if not is_int_resource(lpName as! UInt64) {
527-
tofitaDebugLog("findResourceExW lpType %S".utf16(), lpType as! UInt64)
527+
tofitaDebugLog("findResourceExW lpType %8 %S".utf16(), lpType as! UInt64, lpType as! UInt64)
528528
simpleResource = false
529529
}
530530

dlls/user32/user32.hexa

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@ fun registerClassW(wc WindowClass) Atom {
8484
}
8585

8686
// TODO sizeOf struct by value(!)
87-
// TODO `new ClassesLinkedList()`
87+
// TODO `new ClassesLinkedList()` but on the heap
8888
// TODO just use Hexa Map here
8989
// TODO use SEH for string pointer validation? At least check it is not null ptr
9090
let className = isAtom(wc.utf16zClassName as! UInt64) ? '#' + (wc.utf16zClassName as! UInt64) : String.fromUTF16zUpTo(wc.utf16zClassName as! ConstArrayPointer<UInt16>, classNameLimit)
9191
tofitaDebugLog('registerClassW className "%S"'.utf16(), className.utf16() as! UInt64)
9292
let list = ClassesLinkedList(named: className)
9393
list.next = null
9494

95+
// TODO on heap `list.wc = @heap WindowClass()` and `list.wc = @malloc/@calloc WindowClass()`
96+
// ^ `@heap` is more flexible cause offers RC for native libraries memory management
9597
list.wc = WindowClass()
9698
// TODO `new T() { ...wc }` to make a copy
9799
memcpy(list.wc as! ArrayPointer<UInt8>, wc as! ConstArrayPointer<UInt8>, sizeOf<WindowClass>() as! Int)
@@ -139,7 +141,7 @@ fun createWindowExW(
139141
list = list.next
140142

141143
if list.name == className {
142-
tofitaDebugLog("CreateWindowExW found class {%S}\n".utf16(), className.utf16() as! UInt64)
144+
tofitaDebugLog("> CreateWindowExW found class \"%S\"".utf16(), className.utf16() as! UInt64)
143145
found = true
144146
wc = list.wc
145147
break
@@ -172,6 +174,7 @@ fun createWindowExW(
172174
payload.x = x
173175
payload.y = y
174176
// TODO test zero-width
177+
// TODO Hexa: encode as `enum WindowSize { CW_USE_DEFAULT = 123 Custom = .../_ } case Custom(value):`
175178
// TODO respect CW_USE_DEFAULT etc for pos and size
176179
payload.nWidth = nWidth <= 0? 316 : nWidth
177180
payload.nHeight = nHeight <= 0? 163 : nHeight
@@ -205,6 +208,7 @@ fun createWindowExW(
205208
window.proc = wc.lpfnWndProc
206209
tofitaDebugLog("> window.proc = {%8}".utf16(), window.proc as! UInt64)
207210

211+
// TODO `payload.x` must be updated in the syscall instead
208212
window.x = x
209213
window.y = y
210214
window.width = payload.nWidth
@@ -430,6 +434,18 @@ fun render(window Window, msg Msg) LResult? {
430434
child.clipHeight = child.height
431435

432436
render(child, msg)
437+
// TODO Hexa: `render(child, {...msg, hwnd: child as! HWnd})` + ensure its on stack
438+
// let childMsg = Msg() // TODO ensure allocated on stack
439+
440+
/*
441+
TODO Probably adding local message queue for speed makes sense (for messages produced within the app like this one)
442+
443+
Correct Behavior (Win32 Standard):
444+
Children don’t inherit the parent’s WM_PAINT message. Instead, when a child’s region is invalidated (e.g., via InvalidateRect(child_hwnd, ...)), the system posts a separate WM_PAINT message to the child’s HWND, which DispatchMessage routes to the child’s proc.
445+
You’d see separate log entries like:
446+
dispatchMessageW called (parent WM_PAINT, hwnd=parent_hwnd)
447+
dispatchMessageW called (child WM_PAINT, hwnd=child_hwnd)
448+
*/
433449
}
434450

435451
return result
@@ -455,12 +471,14 @@ fun dispatchMessageW(msg Msg) LResult? {
455471
} else {
456472
tofitaDebugLog("> not_WM_PAINT".utf16())
457473
result = window.proc(msg.hwnd, msg.message, msg.wParam, msg.lParam)
474+
tofitaDebugLog(">> msg.message = %8".utf16(), msg.message as! UInt64)
475+
458476
}
459477
// TODO result = ERROR_SUCCESS
460478
} else {
461479
// TODO
462480
}
463-
tofitaDebugLog("DispatchMessageW done".utf16())
481+
tofitaDebugLog("> DispatchMessageW done".utf16())
464482
return result
465483
}
466484

@@ -843,7 +861,7 @@ fun getClipboardData(stub SizeOfPointer) SizeOfPointer {
843861
i++
844862
}
845863

846-
tofitaDebugLog("lstrlenW %S %d".utf16(), str as! UInt64, i as! UInt64)
864+
tofitaDebugLog("lstrlenW '%S' %d".utf16(), str as! UInt64, i as! UInt64)
847865
return i
848866
}
849867

@@ -1180,13 +1198,15 @@ fun getClientRect(
11801198
lpRect Rect
11811199
) Bool32 {
11821200
tofitaDebugLog("GetClientRect called with hWnd %8 lpRect %8".utf16(), hWnd as! UInt64, lpRect as! UInt64)
1201+
// TODO verify that window.x and window.y are relative to the parent window’s client area (which they should be for child windows).
11831202
if let window = handleToWindow(hWnd) {
11841203
lpRect.left = window.x
11851204
lpRect.top = window.y
11861205
lpRect.right = window.width
11871206
lpRect.bottom = window.height
11881207
return Bool32.True
11891208
}
1209+
11901210
return Bool32.False
11911211
}
11921212

dlls/user32/userMain.hexa

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,13 @@ fun buttonWindowProcW(hWnd HWnd, uMsg Message, wParam WParam, lParam LParam) LRe
369369
case _:
370370
// Includes BS_PUSH_BUTTON and BS_DEF_PUSH_BUTTON
371371

372+
// TODO
373+
// Draw push button
374+
// - black frame
375+
// - shadow etc.
376+
// - title string
377+
// - rectangle with dash line it means focus
378+
// (and strong black frame for default button)
372379
let r = ByValue<Rect>()
373380
getClientRect(hWnd, r.ref)
374381
let fmt DrawTextFormat = DrawTextFormat.DT_CENTER // TODO | DrawTextFormat.DT_VCENTER
@@ -384,6 +391,11 @@ fun buttonWindowProcW(hWnd HWnd, uMsg Message, wParam WParam, lParam LParam) LRe
384391
drawTextW(hdc, title, -1, r.ref, fmt)
385392
}
386393
}
394+
395+
// TODO
396+
// if focus
397+
// - drawEdge(hdc, &r, BDR_RAISEDINNER, BF_MIDDLE | BF_RECT);
398+
// - drawFocusRect(hdc, &r);
387399
}
388400

389401
// TODO restore font and bkg

0 commit comments

Comments
 (0)