@@ -114,6 +114,7 @@ SDL_Surface *rotated_screen; // final frame matching window size
114114
115115static void draw (void );
116116static void draw_region (int , int , int , int );
117+ static void draw_scrollbar (void );
117118static void main_loop (void );
118119int tty_thread (void * unused );
119120
@@ -567,6 +568,9 @@ void x_draw_cursor(void) {
567568 static int oldx = 0 , oldy = 0 ;
568569 int sl ;
569570 Glyph g = {{' ' }, ATTR_NULL , defaultbg , defaultcs , 0 };
571+
572+ /* Don't draw cursor when scrolled */
573+ if (t_get_scroll_offset () > 0 ) return ;
570574
571575 LIMIT (oldx , 0 , term .col - 1 );
572576 LIMIT (oldy , 0 , term .row - 1 );
@@ -603,25 +607,80 @@ void redraw(void) {
603607
604608void draw (void ) {
605609 draw_region (0 , 0 , term .col , term .row );
610+ draw_scrollbar ();
606611 update_render ();
607612}
608613
614+ void draw_scrollbar (void ) {
615+ int scroll_offset = t_get_scroll_offset ();
616+ if (scroll_offset == 0 || main_window .surface == NULL ) return ;
617+
618+ /* Draw scroll indicator in top-right corner */
619+ char scroll_text [64 ];
620+ snprintf (scroll_text , sizeof (scroll_text ), "[%d]^" , scroll_offset );
621+
622+ int text_x = main_window .surface -> w - (strlen (scroll_text ) * main_window .char_width ) - borderpx - 2 ;
623+ int text_y = borderpx ;
624+
625+ SDL_Color indicator_bg = drawing_ctx .colors [defaultcs ];
626+ SDL_Color indicator_fg = drawing_ctx .colors [defaultbg ];
627+
628+ /* Draw background box */
629+ SDL_Rect bg_rect = {
630+ text_x - 2 ,
631+ text_y - 1 ,
632+ strlen (scroll_text ) * main_window .char_width + 4 ,
633+ main_window .char_height + 2
634+ };
635+ SDL_FillRect (main_window .surface , & bg_rect , SDL_MapRGB (main_window .surface -> format , indicator_bg .r , indicator_bg .g , indicator_bg .b ));
636+
637+ /* Draw text */
638+ if (is_ttf_loaded ()) {
639+ draw_string_ttf (main_window .surface , scroll_text , text_x , text_y , indicator_fg , indicator_bg );
640+ } else {
641+ draw_string (main_window .surface , scroll_text , text_x , text_y , SDL_MapRGB (main_window .surface -> format , indicator_fg .r , indicator_fg .g , indicator_fg .b ), embedded_font_name );
642+ }
643+ }
644+
609645void draw_region (int x1 , int y1 , int x2 , int y2 ) {
610646 int ic , ib , x , y , ox , sl ;
611647 Glyph base , new ;
612648 char buf [DRAW_BUF_SIZ ];
649+ int scroll_offset = t_get_scroll_offset ();
650+ Line line_to_draw ;
613651
614652 if (!(main_window .state & WIN_VISIBLE )) return ;
615653
616654 for (y = y1 ; y < y2 ; y ++ ) {
617655 if (!term .dirty [y ]) continue ;
618656
657+ /* Determine which line to draw (from scrollback or current screen) */
658+ if (scroll_offset > 0 && y < scroll_offset ) {
659+ /* Draw from scrollback buffer (circular buffer) */
660+ int sb_idx = (term .scrollback_pos - scroll_offset + y + term .scrollback_size ) % term .scrollback_size ;
661+ if (sb_idx >= 0 && sb_idx < term .scrollback_count ) {
662+ line_to_draw = term .scrollback [sb_idx ];
663+ } else {
664+ line_to_draw = term .line [y ];
665+ }
666+ } else {
667+ /* Draw from current screen, offset by scroll amount */
668+ int screen_y = y - scroll_offset ;
669+ if (screen_y >= 0 && screen_y < term .row ) {
670+ line_to_draw = term .line [screen_y ];
671+ } else {
672+ sdl_term_clear (0 , y , term .col , y );
673+ term .dirty [y ] = 0 ;
674+ continue ;
675+ }
676+ }
677+
619678 sdl_term_clear (0 , y , term .col , y );
620679 term .dirty [y ] = 0 ;
621- base = term . line [ y ] [0 ];
680+ base = line_to_draw [0 ];
622681 ic = ib = ox = 0 ;
623682 for (x = x1 ; x < x2 ; x ++ ) {
624- new = term . line [ y ] [x ];
683+ new = line_to_draw [x ];
625684 if (ib > 0 && (!(new .state & GLYPH_SET ) || ATTRCMP (base , new ) || ib >= DRAW_BUF_SIZ - UTF_SIZ )) {
626685 x_draws (buf , base , ox , y , ic , ib );
627686 ic = ib = 0 ;
@@ -690,6 +749,22 @@ void k_press(SDL_Event *ev) {
690749
691750 // printf("kpress: keysym=%d scancode=%d mod=%d\n", ksym, e->keysym.scancode, e->keysym.mod);
692751
752+ /* Handle scroll up/down for scrollback */
753+ if (ksym == KEY_SCROLLUP ) {
754+ t_scroll_view_up (3 );
755+ draw (); // Force immediate redraw
756+ return ;
757+ } else if (ksym == KEY_SCROLLDOWN ) {
758+ t_scroll_view_down (3 );
759+ draw (); // Force immediate redraw
760+ return ;
761+ }
762+
763+ /* Reset scroll on any other key press */
764+ if (t_get_scroll_offset () > 0 ) {
765+ t_scroll_view_reset ();
766+ }
767+
693768 if ((non_printing_key = k_map (ksym , e -> keysym .mod ))) { /* 1. non printing keys from vt100.h */
694769 // print_non_printing_key_for_debug(non_printing_key, e);
695770 tty_write (non_printing_key , strlen (non_printing_key ));
0 commit comments