00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/adi/adi.h>
00016 #include <agnix/memory.h>
00017 #include <agnix/terminal.h>
00018 #include <agnix/display.h>
00019 #include <agnix/panic.h>
00020 #include <agnix/wait.h>
00021 #include <agnix/sprintf.h>
00022 #include <agnix/console.h>
00023
00024 #define SCREEN_SCROLL_LINES 10
00025
00026 extern struct display_s text_display;
00027 extern int kbd_screen_scroll;
00028
00029 int term_cur;
00030 int term_init = 0;
00031 struct terminal_s term_sys[MAX_TERMINALS];
00032 struct terminal_driver_s term_sys_driver;
00033
00034 int syscons_count_offset(struct terminal_s *term, char *buf, int screen_scroll)
00035 {
00036 int lines = 0;
00037 int head = term->term_buf.head;
00038 int size_x = term->term_var->term_size_x;
00039 int size_y = term->term_var->term_size_y;
00040 int term_data_len = term->term_buf.data_len;
00041 int i;
00042 int j;
00043
00044 i = head;
00045 j = 0;
00046
00047 do {
00048 if (i - 1 < 0)
00049 i = term_data_len;
00050 else
00051 i = (i - 1) % term_data_len;
00052
00053 if ((buf[i] == '\n') || (j == size_x - 1)) {
00054 j = 0;
00055 lines++;
00056 }
00057 else
00058 j++;
00059
00060 } while(lines < size_y + screen_scroll * SCREEN_SCROLL_LINES);
00061
00062 return (i + 1) % term_data_len;
00063 }
00064
00065 int syscons_refresh(struct terminal_s *term, int screen_scroll)
00066 {
00067 struct display_s *disp = term->term_driver->display;
00068 char *term_data = term->term_buf.data;
00069 int term_data_len = term->term_buf.data_len;
00070 int size_x = term->term_var->term_size_x;
00071 int size_y = term->term_var->term_size_y;
00072 int i;
00073 int x, y;
00074
00075 i = syscons_count_offset(term, term_data, screen_scroll);
00076
00077 for (y = 0; y < size_y; y++) {
00078 for (x = 0; x < size_x; x++) {
00079 if ((term_data[i] != '\n') && (term_data[i] != 0)) {
00080 disp->ops->putc(disp, term_data[i], x, y, 7);
00081 i = (i + 1) % term_data_len;
00082 }
00083 else
00084 disp->ops->putc(disp, ' ', x, y, 7);
00085 }
00086
00087 if (term_data[i] == '\n')
00088 i = (i + 1) % term_data_len;
00089 }
00090
00091 return 0;
00092 }
00093
00094 int syscons_init(struct terminal_s *term)
00095 {
00096 return 0;
00097 }
00098
00099 int syscons_open(char *filename, int mode)
00100 {
00101 int i;
00102
00103 for (i = 0; i < MAX_TERMINALS; i++) {
00104 if (term_sys[i].term_pgrp == 0)
00105 break;
00106 }
00107
00108 if (i == MAX_TERMINALS)
00109 return -1;
00110
00111 term_sys[i].term_pgrp = current_task->t_pid;
00112 current_task->term = &term_sys[i];
00113
00114 return 0;
00115 }
00116
00117 int syscons_write_char(struct terminal_s *term, char character)
00118 {
00119 int head = term->term_buf.head;
00120 char *term_data = term->term_buf.data;
00121 int term_data_len = term->term_buf.data_len;
00122 int input_head = term->term_buf.input_head;
00123 char *term_input_data = term->term_buf.input;
00124 int term_input_data_len = term->term_buf.input_data_len;
00125
00126 if (term->term_buf.data == NULL) {
00127 term->term_buf.data = (char *)get_free_pages(1);
00128 if (term->term_buf.data == NULL)
00129 return -1;
00130
00131 head = term->term_buf.head = term->term_buf.tail = 0;
00132 term_data_len = term->term_buf.data_len = (2 << PAGE_SHIFT) - 1;
00133 term_data = term->term_buf.data;
00134 }
00135
00136 term_data[head] = character;
00137 head = (head + 1) % term_data_len;
00138 term->term_buf.head = head;
00139 term_data[head] = 0;
00140
00141 if (term->term_buf.input == NULL) {
00142 term->term_buf.input = (char *)get_free_pages(1);
00143 if (term->term_buf.input == NULL)
00144 return -1;
00145
00146 input_head = term->term_buf.input_head = term->term_buf.input_tail = 0;
00147 term_input_data_len = term->term_buf.input_data_len = (2 << PAGE_SHIFT) - 1;
00148 term_input_data = term->term_buf.input;
00149 }
00150
00151 term_input_data[input_head] = character;
00152 input_head = (input_head + 1) % term_input_data_len;
00153 term->term_buf.input_head = input_head;
00154
00155 if (term->term_active) {
00156 if (term->term_driver && term->term_driver->ops->refresh) {
00157 kbd_screen_scroll = 0;
00158 term->term_driver->ops->refresh(term, 0);
00159 }
00160 }
00161
00162 if (character == '\n')
00163 wait_list_wake_up(&term->wait_list);
00164
00165
00166 return 0;
00167 }
00168
00169 int syscons_write(struct terminal_s *term, char *buf, int count)
00170 {
00171 int head = term->term_buf.head;
00172 char *term_data = term->term_buf.data;
00173 int term_data_len = term->term_buf.data_len;
00174 int i = 0;
00175
00176 if (buf[0] == 0)
00177 return 0;
00178
00179 for (i = 0; i < count; i++) {
00180 if (term->term_buf.data == NULL) {
00181 term->term_buf.data = (char *)get_free_pages(1);
00182 if (term->term_buf.data == NULL)
00183 return -1;
00184
00185 head = term->term_buf.head = term->term_buf.tail = 0;
00186 term_data_len = term->term_buf.data_len = (2 << PAGE_SHIFT) - 1;
00187 term_data = term->term_buf.data;
00188 }
00189
00190 term_data[head] = buf[i];
00191 head = (head + 1) % term_data_len;
00192 }
00193
00194 term->term_buf.head = head;
00195 term_data[head] = 0;
00196
00197 if (term->term_active) {
00198 if (term->term_driver && term->term_driver->ops->refresh) {
00199 kbd_screen_scroll = 0;
00200 term->term_driver->ops->refresh(term, 0);
00201 }
00202 }
00203
00204 return i;
00205 }
00206
00207 int syscons_read(struct terminal_s *term, char *buf, int count)
00208 {
00209 int input_head;
00210 int input_tail;
00211 char *input_data;
00212 int term_input_len;
00213 int i, j, len;
00214
00215 if (term->term_pgrp != current_task->t_pid)
00216 return -1;
00217
00218 while (term->term_buf.input == NULL) {
00219 wait_list_sleep_on(current_task, &term->wait_list);
00220 wait_list_remove(current_task, &term->wait_list);
00221 }
00222
00223 do {
00224
00225 input_tail = term->term_buf.input_tail;
00226 input_head = term->term_buf.input_head;
00227 input_data = term->term_buf.input;
00228 term_input_len = term->term_buf.input_data_len;
00229 for (i = input_tail; i != input_head; i = (i + 1) % term_input_len) {
00230 if (input_data[i] == '\n')
00231 break;
00232 }
00233
00234 if (i == input_head) {
00235 wait_list_sleep_on(current_task, &term->wait_list);
00236 wait_list_remove(current_task, &term->wait_list);
00237 continue;
00238 }
00239
00240 } while (i == input_head);
00241
00242 j = 0;
00243 len = 0;
00244 for (i = input_tail; ((i != input_head) && (count));
00245 i = (i + 1) % term_input_len, len++, j++, count--) {
00246
00247 buf[j] = input_data[i];
00248
00249 if (input_data[i] == '\n')
00250 break;
00251 }
00252
00253 buf[j + 1] = 0;
00254 term->term_buf.input_tail = (i + 1) % term_input_len;
00255
00256 return len;
00257 }
00258
00259 int syscons_read_current(char *buf, int count)
00260 {
00261 return syscons_read(&term_sys[term_cur], buf, count);
00262 }
00263
00264 struct terminal_driver_ops_s term_sys_driver_ops = {
00265 .refresh = syscons_refresh
00266 };
00267
00268 struct terminal_var_s term_sys_var = {
00269 .term_size_x = 80,
00270 .term_size_y = 25
00271 };
00272
00273 struct terminal_ops_s term_sys_ops = {
00274 .init = syscons_init,
00275 .read = syscons_read,
00276 .write = syscons_write,
00277 .write_char = syscons_write_char
00278 };
00279
00280 struct terminal_driver_s term_sys_driver = {
00281 .ops = &term_sys_driver_ops,
00282 .display = &text_display
00283 };
00284
00285 int __init adi_sysconsole_init(void)
00286 {
00287 int i;
00288
00289 for (i = 0; i < MAX_TERMINALS; i++) {
00290 memset(&term_sys[i], 0, sizeof(struct terminal_s));
00291
00292 INIT_LIST_HEAD(&(term_sys[i].term_list));
00293 INIT_LIST_HEAD(&(term_sys[i].term_sys_list));
00294 wait_list_init(&(term_sys[i].wait_list));
00295
00296 term_sys[i].term_nr = i;
00297 term_sys[i].term_var = &term_sys_var;
00298 term_sys[i].ops = &term_sys_ops;
00299 term_sys[i].term_active = 0;
00300
00301 if (register_terminal(&term_sys[i]) < 0)
00302 kernel_panic("register_terminal() error\n");
00303
00304 register_terminal_driver(&term_sys[i], &term_sys_driver);
00305 }
00306
00307 term_sys[0].term_active = 1;
00308 term_cur = 0;
00309 term_init = 1;
00310
00311 return 0;
00312 }