The top_of_window() function puts the cursor on the top line, then you can use p_line, no?
Oh, and internally it uses p_cursor_y - so you can calculate it then without moving the cursor.
The tricky bit is likely to be wrapped lines ... lines that are really long get split (without adding a newline) by Slick on load.
(See Tools > Options > File Options > Load "Wrap Line Length" )
My findLongest() function deals with this pretty well using p_RLine. p_RLine has the same value on each segment of a split line, while p_line does not.