@@ -7,6 +7,17 @@ volatile struct limine_framebuffer_request framebuffer_request = {
77 .revision = 0 ,
88};
99
10+
11+ #define MAX_SCROLLABLES 256
12+
13+ typedef struct scrollable_graphics_t {
14+ int64_t start ;
15+ int64_t end ;
16+ } scrollable_graphics_t ;
17+
18+ static scrollable_graphics_t scrollables [MAX_SCROLLABLES ];
19+ static int scrollable_count = 0 ;
20+
1021struct limine_framebuffer * fb = NULL ;
1122static uint64_t bytes_per_pixel = 32 ;
1223static void * rr_fb_front = NULL ;
@@ -91,6 +102,45 @@ static uint8_t font_data[] = { // 8x8
91102 0x00 , 0x2e , 0x33 , 0x33 , 0x33 , 0x00 , 0x00 , 0x00 , 0x38 , 0x08 , 0x38 , 0x20 , 0x38 , 0x00 , 0x00 , 0x00 , 0x00 , 0x18 , 0x18 , 0x18 , 0x18 , 0x18 , 0x18 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
92103};
93104
105+
106+ /* Insert a band [start, end), keeping the list sorted by start */
107+ int add_scrollable (int64_t start , int64_t end ) {
108+ if (scrollable_count >= MAX_SCROLLABLES ) {
109+ return -1 ; /* list full */
110+ }
111+
112+ int pos = 0 ;
113+ while (pos < scrollable_count && scrollables [pos ].start < start ) {
114+ pos ++ ;
115+ }
116+
117+ /* shift up to make room */
118+ for (int i = scrollable_count ; i > pos ; i -- ) {
119+ scrollables [i ] = scrollables [i - 1 ];
120+ }
121+
122+ scrollables [pos ].start = start ;
123+ scrollables [pos ].end = end ;
124+ scrollable_count ++ ;
125+
126+ return 0 ;
127+ }
128+
129+ /* Remove a band matching [start, end) */
130+ int remove_scrollable (int64_t start , int64_t end ) {
131+ for (int i = 0 ; i < scrollable_count ; i ++ ) {
132+ if (scrollables [i ].start == start && scrollables [i ].end == end ) {
133+ /* shift down */
134+ for (int j = i ; j < scrollable_count - 1 ; j ++ ) {
135+ scrollables [j ] = scrollables [j + 1 ];
136+ }
137+ scrollable_count -- ;
138+ return 0 ;
139+ }
140+ }
141+ return -1 ; /* not found */
142+ }
143+
94144void rr_console_init_from_limine (void ) {
95145 fb = framebuffer_request .response -> framebuffers [0 ];
96146 dprintf ("fb front: %lx\n" , (uint64_t )fb -> address );
@@ -218,11 +268,78 @@ void terminal_callback(struct flanterm_context *ctx, uint64_t type, uint64_t x,
218268 switch (type ) {
219269 case FLANTERM_CB_BELL :
220270 beep (1000 );
221- break ;
271+ break ;
222272 case FLANTERM_CB_POS_REPORT :
223273 current_x = x - 1 ;
224274 current_y = y - 1 ;
225- break ;
275+ break ;
276+ case FLANTERM_CB_SCROLL : {
277+ int stride = rr_fb_pitch ;
278+ int delta_px = 8 ;
279+ bool moved = false;
280+
281+ for (int i = 0 ; i < scrollable_count ;) {
282+ if (scrollable_count == 0 ) {
283+ break ;
284+ }
285+
286+ scrollable_graphics_t * s = & scrollables [i ];
287+ int height = (int )(s -> end - s -> start );
288+
289+ if (height <= 0 ) {
290+ /* drop invalid band */
291+ for (int j = i ; j < scrollable_count - 1 ; j ++ ) {
292+ scrollables [j ] = scrollables [j + 1 ];
293+ }
294+ scrollable_count -- ;
295+ continue ;
296+ }
297+
298+ int new_start = s -> start - delta_px ;
299+ int new_end = s -> end - delta_px ;
300+
301+ int dst_row = new_start ;
302+ int src_row = s -> start ;
303+ int rows = height ;
304+
305+ /* trim off rows above the top */
306+ if (dst_row < 0 ) {
307+ int cut = - dst_row ;
308+ dst_row = 0 ;
309+ src_row += cut ;
310+ rows -= cut ;
311+ }
312+
313+ /* trim if bottom goes past screen (end is exclusive) */
314+ if (dst_row + rows > screen_graphics_y ) {
315+ rows = screen_graphics_y - dst_row ;
316+ }
317+
318+ if (rows > 0 ) {
319+ uint8_t * dst = (uint8_t * )rr_fb_back + (long )dst_row * stride ;
320+ uint8_t * src = (uint8_t * )rr_fb_back + (long )src_row * stride ;
321+ memmove (dst , src , (size_t )rows * stride );
322+ moved = true;
323+ }
324+
325+ s -> start = new_start ;
326+ s -> end = new_end ;
327+
328+ if (s -> end <= 0 || s -> start >= screen_graphics_y ) {
329+ for (int j = i ; j < scrollable_count - 1 ; j ++ ) {
330+ scrollables [j ] = scrollables [j + 1 ];
331+ }
332+ scrollable_count -- ;
333+ continue ;
334+ }
335+
336+ i ++ ;
337+ }
338+ if (moved ) {
339+ set_video_dirty_area (0 , screen_graphics_y );
340+ }
341+ break ;
342+ }
226343 }
227344 wait_state = false;
228345}
0 commit comments