Rev 3674 | Rev 4338 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3674 | Rev 4337 | ||
|---|---|---|---|
| Line 84... | Line 84... | ||
| 84 | static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared |
84 | static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared |
| 85 | * with framebufer used for |
85 | * with framebufer used for |
| 86 | * faster virtual console |
86 | * faster virtual console |
| 87 | * switching */ |
87 | * switching */ |
| 88 | 88 | ||
| 89 | static int kernel_pixmap = -1; /**< Number of fb pixmap, where kernel |
- | |
| 90 | * console is stored */ |
- | |
| 91 | - | ||
| 92 | 89 | ||
| 93 | /** Find unused virtual console. |
90 | /** Find unused virtual console. |
| 94 | * |
91 | * |
| 95 | */ |
92 | */ |
| 96 | static int find_free_connection(void) |
93 | static int find_free_connection(void) |
| Line 107... | Line 104... | ||
| 107 | static void clrscr(void) |
104 | static void clrscr(void) |
| 108 | { |
105 | { |
| 109 | async_msg_0(fb_info.phone, FB_CLEAR); |
106 | async_msg_0(fb_info.phone, FB_CLEAR); |
| 110 | } |
107 | } |
| 111 | 108 | ||
| 112 | static void curs_visibility(int v) |
109 | static void curs_visibility(bool visible) |
| - | 110 | { |
|
| - | 111 | async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); |
|
| - | 112 | } |
|
| - | 113 | ||
| - | 114 | static void curs_hide_sync(void) |
|
| 113 | { |
115 | { |
| 114 | async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, v); |
116 | ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); |
| 115 | } |
117 | } |
| 116 | 118 | ||
| 117 | static void curs_goto(int row, int col) |
119 | static void curs_goto(int row, int col) |
| 118 | { |
120 | { |
| 119 | async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); |
121 | async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); |
| Line 185... | Line 187... | ||
| 185 | if (console == active_console) |
187 | if (console == active_console) |
| 186 | curs_goto(scr->position_y, scr->position_x); |
188 | curs_goto(scr->position_y, scr->position_x); |
| 187 | 189 | ||
| 188 | } |
190 | } |
| 189 | 191 | ||
| 190 | /** Save current screen to pixmap, draw old pixmap |
- | |
| 191 | * |
- | |
| 192 | * @param oldpixmap Old pixmap |
- | |
| 193 | * @return ID of pixmap of current screen |
- | |
| 194 | */ |
- | |
| 195 | static int switch_screens(int oldpixmap) |
- | |
| 196 | { |
- | |
| 197 | int newpmap; |
- | |
| 198 | - | ||
| 199 | /* Save screen */ |
- | |
| 200 | newpmap = async_req_0_0(fb_info.phone, FB_VP2PIXMAP); |
- | |
| 201 | if (newpmap < 0) |
- | |
| 202 | return -1; |
- | |
| 203 | - | ||
| 204 | if (oldpixmap != -1) { |
- | |
| 205 | /* Show old screen */ |
- | |
| 206 | async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap); |
- | |
| 207 | /* Drop old pixmap */ |
- | |
| 208 | async_msg_1(fb_info.phone, FB_DROP_PIXMAP, oldpixmap); |
- | |
| 209 | } |
- | |
| 210 | - | ||
| 211 | return newpmap; |
- | |
| 212 | } |
- | |
| 213 | - | ||
| 214 | /** Switch to new console */ |
192 | /** Switch to new console */ |
| 215 | static void change_console(int newcons) |
193 | static void change_console(int newcons) |
| 216 | { |
194 | { |
| 217 | connection_t *conn; |
195 | connection_t *conn; |
| 218 | static int console_pixmap = -1; |
- | |
| 219 | int i, j, rc; |
196 | int i, j, rc; |
| 220 | keyfield_t *field; |
197 | keyfield_t *field; |
| 221 | style_t *style; |
198 | style_t *style; |
| 222 | 199 | ||
| 223 | if (newcons == active_console) |
200 | if (newcons == active_console) |
| 224 | return; |
201 | return; |
| 225 | 202 | ||
| 226 | if (newcons == KERNEL_CONSOLE) { |
203 | if (newcons == KERNEL_CONSOLE) { |
| 227 | if (active_console == KERNEL_CONSOLE) |
- | |
| 228 | return; |
- | |
| 229 | active_console = KERNEL_CONSOLE; |
- | |
| 230 | curs_visibility(0); |
- | |
| 231 | - | ||
| 232 | async_serialize_start(); |
204 | async_serialize_start(); |
| 233 | if (kernel_pixmap == -1) { |
- | |
| 234 | /* store/restore unsupported */ |
- | |
| 235 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
- | |
| 236 | clrscr(); |
205 | curs_hide_sync(); |
| 237 | } else { |
- | |
| 238 | gcons_in_kernel(); |
206 | gcons_in_kernel(); |
| 239 | console_pixmap = switch_screens(kernel_pixmap); |
- | |
| 240 | kernel_pixmap = -1; |
- | |
| 241 | } |
- | |
| 242 | async_serialize_end(); |
207 | async_serialize_end(); |
| 243 | 208 | ||
| 244 | __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); |
209 | if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) |
| 245 | return; |
- | |
| 246 | } |
- | |
| 247 | - | ||
| 248 | async_serialize_start(); |
- | |
| 249 | - | ||
| 250 | if (console_pixmap != -1) { |
210 | active_console = KERNEL_CONSOLE; |
| 251 | kernel_pixmap = switch_screens(console_pixmap); |
- | |
| 252 | console_pixmap = -1; |
- | |
| 253 | } |
211 | else |
| 254 | active_console = newcons; |
- | |
| 255 | gcons_change_console(newcons); |
- | |
| 256 | conn = &connections[active_console]; |
212 | newcons = active_console; |
| 257 | - | ||
| 258 | set_style(&conn->screenbuffer.style); |
- | |
| 259 | curs_visibility(0); |
- | |
| 260 | if (interbuffer) { |
- | |
| 261 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
- | |
| 262 | for (j = 0; j < conn->screenbuffer.size_y; j++) { |
- | |
| 263 | unsigned int size_x; |
- | |
| 264 | - | ||
| 265 | size_x = conn->screenbuffer.size_x; |
- | |
| 266 | interbuffer[i + j * size_x] = |
- | |
| 267 | *get_field_at(&conn->screenbuffer, i, j); |
- | |
| 268 | } |
- | |
| 269 | /* This call can preempt, but we are already at the end */ |
- | |
| 270 | rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA); |
- | |
| 271 | } |
213 | } |
| 272 | 214 | ||
| 273 | if ((!interbuffer) || (rc != 0)) { |
215 | if (newcons != KERNEL_CONSOLE) { |
| - | 216 | async_serialize_start(); |
|
| - | 217 | ||
| - | 218 | if (active_console == KERNEL_CONSOLE) |
|
| - | 219 | gcons_redraw_console(); |
|
| - | 220 | ||
| - | 221 | active_console = newcons; |
|
| - | 222 | gcons_change_console(newcons); |
|
| - | 223 | conn = &connections[active_console]; |
|
| - | 224 | ||
| 274 | set_style(&conn->screenbuffer.style); |
225 | set_style(&conn->screenbuffer.style); |
| - | 226 | curs_visibility(false); |
|
| - | 227 | if (interbuffer) { |
|
| - | 228 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
|
| - | 229 | for (j = 0; j < conn->screenbuffer.size_y; j++) { |
|
| - | 230 | unsigned int size_x; |
|
| - | 231 | ||
| - | 232 | size_x = conn->screenbuffer.size_x; |
|
| - | 233 | interbuffer[i + j * size_x] = |
|
| - | 234 | *get_field_at(&conn->screenbuffer, i, j); |
|
| - | 235 | } |
|
| - | 236 | /* This call can preempt, but we are already at the end */ |
|
| - | 237 | rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA); |
|
| - | 238 | } |
|
| - | 239 | ||
| - | 240 | if ((!interbuffer) || (rc != 0)) { |
|
| - | 241 | set_style(&conn->screenbuffer.style); |
|
| 275 | clrscr(); |
242 | clrscr(); |
| 276 | style = &conn->screenbuffer.style; |
243 | style = &conn->screenbuffer.style; |
| 277 | 244 | ||
| 278 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
245 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
| 279 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
246 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
| 280 | field = get_field_at(&conn->screenbuffer, i, j); |
247 | field = get_field_at(&conn->screenbuffer, i, j); |
| 281 | if (!style_same(*style, field->style)) |
248 | if (!style_same(*style, field->style)) |
| 282 | set_style(&field->style); |
249 | set_style(&field->style); |
| 283 | style = &field->style; |
250 | style = &field->style; |
| 284 | if ((field->character == ' ') && |
251 | if ((field->character == ' ') && |
| 285 | (style_same(field->style, |
252 | (style_same(field->style, |
| 286 | conn->screenbuffer.style))) |
253 | conn->screenbuffer.style))) |
| 287 | continue; |
254 | continue; |
| 288 | 255 | ||
| 289 | prtchr(field->character, j, i); |
256 | prtchr(field->character, j, i); |
| 290 | } |
257 | } |
| - | 258 | } |
|
| - | 259 | ||
| - | 260 | curs_goto(conn->screenbuffer.position_y, |
|
| - | 261 | conn->screenbuffer.position_x); |
|
| - | 262 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
|
| - | 263 | ||
| - | 264 | async_serialize_end(); |
|
| 291 | } |
265 | } |
| 292 | - | ||
| 293 | curs_goto(conn->screenbuffer.position_y, |
- | |
| 294 | conn->screenbuffer.position_x); |
- | |
| 295 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
- | |
| 296 | - | ||
| 297 | async_serialize_end(); |
- | |
| 298 | } |
266 | } |
| 299 | 267 | ||
| 300 | /** Handler for keyboard */ |
268 | /** Handler for keyboard */ |
| 301 | static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall) |
269 | static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall) |
| 302 | { |
270 | { |
| Line 495... | Line 463... | ||
| 495 | if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) |
463 | if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) |
| 496 | return -1; |
464 | return -1; |
| 497 | async_new_connection(phonehash, 0, NULL, keyboard_events); |
465 | async_new_connection(phonehash, 0, NULL, keyboard_events); |
| 498 | 466 | ||
| 499 | /* Connect to framebuffer driver */ |
467 | /* Connect to framebuffer driver */ |
| 500 | - | ||
| 501 | fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
468 | fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
| 502 | while (fb_info.phone < 0) { |
469 | while (fb_info.phone < 0) { |
| 503 | usleep(10000); |
470 | usleep(10000); |
| 504 | fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
471 | fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
| 505 | } |
472 | } |
| 506 | 473 | ||
| 507 | /* Save old kernel screen */ |
- | |
| 508 | kernel_pixmap = switch_screens(-1); |
- | |
| 509 | - | ||
| 510 | /* Initialize gcons */ |
474 | /* Initialize gcons */ |
| 511 | gcons_init(fb_info.phone); |
475 | gcons_init(fb_info.phone); |
| 512 | /* Synchronize, the gcons can have something in queue */ |
476 | /* Synchronize, the gcons can have something in queue */ |
| 513 | async_req_0_0(fb_info.phone, FB_FLUSH); |
477 | async_req_0_0(fb_info.phone, FB_FLUSH); |
| 514 | /* Enable double buffering */ |
- | |
| 515 | async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
- | |
| 516 | 478 | ||
| 517 | async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows, |
479 | async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows, |
| 518 | &fb_info.cols); |
480 | &fb_info.cols); |
| 519 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
481 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
| 520 | clrscr(); |
482 | clrscr(); |