| 1 | program fortty |
| 2 | use window_mod |
| 3 | use gl_bindings |
| 4 | use renderer_mod |
| 5 | use pty_mod |
| 6 | implicit none |
| 7 | |
| 8 | type(window_t) :: win |
| 9 | type(renderer_t) :: ren |
| 10 | type(pty_t) :: pty |
| 11 | integer :: win_width, win_height |
| 12 | integer :: prev_width, prev_height |
| 13 | integer :: term_rows, term_cols |
| 14 | integer :: new_rows, new_cols |
| 15 | character(len=256) :: font_path |
| 16 | character(len=4096) :: pty_buffer |
| 17 | integer :: nbytes |
| 18 | integer, parameter :: CELL_WIDTH = 10 ! Approximate char width |
| 19 | integer, parameter :: CELL_HEIGHT = 20 ! Approximate line height |
| 20 | |
| 21 | ! Window dimensions |
| 22 | win_width = 800 |
| 23 | win_height = 600 |
| 24 | |
| 25 | ! Create window with OpenGL context |
| 26 | win = window_create(win_width, win_height, "fortty") |
| 27 | |
| 28 | ! Font path - try common system locations |
| 29 | font_path = "/usr/share/fonts/TTF/DejaVuSansMono.ttf" |
| 30 | |
| 31 | ! Create renderer with font |
| 32 | ren = renderer_create(trim(font_path), 16) |
| 33 | if (.not. ren%initialized) then |
| 34 | print *, "Warning: Could not load font, trying alternate path..." |
| 35 | font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf" |
| 36 | ren = renderer_create(trim(font_path), 16) |
| 37 | end if |
| 38 | |
| 39 | if (.not. ren%initialized) then |
| 40 | print *, "Error: Could not initialize renderer" |
| 41 | print *, "Please ensure DejaVu Sans Mono font is installed" |
| 42 | call window_destroy(win) |
| 43 | stop 1 |
| 44 | end if |
| 45 | |
| 46 | ! Set up projection matrix |
| 47 | call renderer_set_projection(ren, win_width, win_height) |
| 48 | |
| 49 | ! Calculate terminal dimensions based on font metrics |
| 50 | term_cols = win_width / CELL_WIDTH |
| 51 | term_rows = win_height / CELL_HEIGHT |
| 52 | prev_width = win_width |
| 53 | prev_height = win_height |
| 54 | |
| 55 | ! Open PTY with shell |
| 56 | pty = pty_open("", term_rows, term_cols) ! Empty string = use $SHELL |
| 57 | |
| 58 | if (.not. pty%active) then |
| 59 | print *, "Error: Could not open PTY" |
| 60 | call renderer_destroy(ren) |
| 61 | call window_destroy(win) |
| 62 | stop 1 |
| 63 | end if |
| 64 | |
| 65 | print *, "PTY opened successfully" |
| 66 | print *, "Terminal size:", term_cols, "x", term_rows |
| 67 | |
| 68 | ! Main event loop |
| 69 | do while (.not. window_should_close(win) .and. pty_is_alive(pty)) |
| 70 | ! Check for window resize |
| 71 | call window_get_size(win, win_width, win_height) |
| 72 | if (win_width /= prev_width .or. win_height /= prev_height) then |
| 73 | prev_width = win_width |
| 74 | prev_height = win_height |
| 75 | |
| 76 | ! Update projection matrix |
| 77 | call renderer_set_projection(ren, win_width, win_height) |
| 78 | |
| 79 | ! Calculate new terminal size and notify PTY |
| 80 | new_cols = win_width / CELL_WIDTH |
| 81 | new_rows = win_height / CELL_HEIGHT |
| 82 | if (new_cols /= term_cols .or. new_rows /= term_rows) then |
| 83 | term_cols = new_cols |
| 84 | term_rows = new_rows |
| 85 | call pty_resize(pty, term_rows, term_cols) |
| 86 | end if |
| 87 | end if |
| 88 | |
| 89 | ! Read from PTY (non-blocking) |
| 90 | nbytes = pty_read(pty, pty_buffer, 4096) |
| 91 | if (nbytes > 0) then |
| 92 | ! For now, just print to stdout (Phase 4 will render to screen) |
| 93 | write(*,'(A)', advance='no') pty_buffer(1:nbytes) |
| 94 | end if |
| 95 | |
| 96 | ! Clear screen with dark gray background |
| 97 | call glClearColor(0.1, 0.1, 0.12, 1.0) |
| 98 | call glClear(GL_COLOR_BUFFER_BIT) |
| 99 | |
| 100 | ! Begin new frame |
| 101 | call renderer_begin(ren) |
| 102 | |
| 103 | ! Draw status text |
| 104 | call renderer_draw_string(ren, 10.0, 30.0, "fortty - Shell connected", & |
| 105 | 0.0, 1.0, 0.0, 1.0) |
| 106 | |
| 107 | call renderer_draw_string(ren, 10.0, 60.0, "(Shell output goes to stdout for now)", & |
| 108 | 0.5, 0.5, 0.5, 1.0) |
| 109 | |
| 110 | ! Flush to GPU |
| 111 | call renderer_flush(ren) |
| 112 | |
| 113 | ! Swap buffers and poll events |
| 114 | call window_swap_buffers(win) |
| 115 | call window_poll_events() |
| 116 | end do |
| 117 | |
| 118 | print *, "" |
| 119 | print *, "Shell exited or window closed" |
| 120 | |
| 121 | ! Cleanup |
| 122 | call pty_close(pty) |
| 123 | call renderer_destroy(ren) |
| 124 | call window_destroy(win) |
| 125 | |
| 126 | end program fortty |
| 127 |