Changeset 429acb9 in mainline for console/console.c


Ignore:
Timestamp:
2006-06-03T17:38:24Z (20 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1f36e90
Parents:
dc5a0fe1
Message:

Added nice kernel console switching, currently works on fb devices.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • console/console.c

    rdc5a0fe1 r429acb9  
    7070} connection_t;
    7171
    72 connection_t connections[CONSOLE_COUNT];        /**< Array of data for virtual consoles */
    73 keyfield_t *interbuffer = NULL;                 /**< Pointer to memory shared with framebufer used for faster virt. console switching */
     72static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual consoles */
     73static keyfield_t *interbuffer = NULL;                  /**< Pointer to memory shared with framebufer used for faster virt. console switching */
     74
     75static int kernel_pixmap = -1;      /**< Number of fb pixmap, where kernel console is stored */
    7476
    7577
     
    104106}
    105107
     108static void clrscr(void)
     109{
     110        nsend_call(fb_info.phone, FB_CLEAR, 0);
     111}
     112
     113static void curs_visibility(int v)
     114{
     115        send_call(fb_info.phone, FB_CURSOR_VISIBILITY, v);
     116}
     117
     118static void curs_goto(int row, int col)
     119{
     120        nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
     121       
     122}
     123
     124static void set_style(style_t *style)
     125{
     126        nsend_call_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color);
     127}
     128
     129static void set_style_col(int fgcolor, int bgcolor)
     130{
     131        nsend_call_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);
     132}
     133
     134static void prtchr(char c, int row, int col)
     135{
     136        nsend_call_3(fb_info.phone, FB_PUTCHAR, c, row, col);
     137       
     138}
     139
    106140/** Check key and process special keys.
    107141 *
     
    128162                        scr->position_x--;
    129163
    130                         if (console == active_console) {
    131                                 nsend_call_3(fb_info.phone, FB_PUTCHAR, ' ', scr->position_y, scr->position_x);
    132                         }
     164                        if (console == active_console)
     165                                prtchr(' ', scr->position_y, scr->position_x);
    133166       
    134167                        screenbuffer_putchar(scr, ' ');
     
    136169                        break;
    137170                default:       
    138                         if (console == active_console) {
    139                                 nsend_call_3(fb_info.phone, FB_PUTCHAR, key, scr->position_y, scr->position_x);
    140                         }
     171                        if (console == active_console)
     172                                prtchr(key, scr->position_y, scr->position_x);
    141173       
    142174                        screenbuffer_putchar(scr, key);
     
    155187        scr->position_x = scr->position_x % scr->size_x;
    156188       
    157         if (console == active_console) 
    158                 send_call_2(fb_info.phone, FB_CURSOR_GOTO, scr->position_y, scr->position_x);
    159        
    160 }
    161 
     189        if (console == active_console)
     190                curs_goto(scr->position_y, scr->position_x);
     191       
     192}
     193
     194/** Save current screen to pixmap, draw old pixmap
     195 *
     196 * @param oldpixmap Old pixmap
     197 * @return ID of pixmap of current screen
     198 */
     199static int switch_screens(int oldpixmap)
     200{
     201        int newpmap;
     202       
     203        /* Save screen */
     204        newpmap = sync_send(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
     205        if (newpmap < 0)
     206                return -1;
     207
     208        if (oldpixmap != -1) {
     209                /* Show old screen */
     210                nsend_call_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
     211                /* Drop old pixmap */
     212                nsend_call(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
     213        }
     214       
     215        return newpmap;
     216}
     217
     218/** Switch to new console */
     219static void change_console(int newcons)
     220{
     221        connection_t *conn;
     222        static int console_pixmap = -1;
     223        int i, j;
     224        char c;
     225
     226        if (newcons == active_console)
     227                return;
     228
     229        if (newcons == -1) {
     230                if (active_console == -1)
     231                        return;
     232                active_console = -1;
     233                curs_visibility(0);
     234
     235                if (kernel_pixmap == -1) {
     236                        /* store/restore unsupported */
     237                        set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     238                        clrscr();
     239                } else {
     240                        gcons_in_kernel();
     241                        console_pixmap = switch_screens(kernel_pixmap);
     242                        kernel_pixmap = -1;
     243                }
     244
     245                __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
     246                return;
     247        }
     248       
     249        if (console_pixmap != -1) {
     250                kernel_pixmap = switch_screens(console_pixmap);
     251                console_pixmap = -1;
     252        }
     253       
     254        active_console = newcons;
     255        gcons_change_console(newcons);
     256        conn = &connections[active_console];
     257
     258        curs_visibility(0);
     259        if (interbuffer) {
     260                for (i = 0; i < conn->screenbuffer.size_x; i++)
     261                        for (j = 0; j < conn->screenbuffer.size_y; j++)
     262                                interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
     263               
     264                sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);               
     265        } else {
     266                clrscr();
     267               
     268                for (i = 0; i < conn->screenbuffer.size_x; i++)
     269                        for (j = 0; j < conn->screenbuffer.size_y; j++) {
     270                                c = get_field_at(&(conn->screenbuffer),i, j)->character;
     271                                if (c && c != ' ')
     272                                        prtchr(c, j, i);
     273                        }
     274               
     275        }
     276        curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
     277        set_style(&conn->screenbuffer.style);
     278        curs_visibility(1);
     279}
    162280
    163281/** Handler for keyboard */
     
    167285        ipc_call_t call;
    168286        int retval;
    169         int i, j;
    170         char c,d;
     287        char c;
    171288        connection_t *conn;
    172289       
     
    189306//                      if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
    190307                        if ((c >= '0') && (c < '0' + CONSOLE_COUNT)) {
    191                                 if (c == '0') {
    192                                         /* switch to kernel console*/
    193                                         nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 0);
    194                                         nsend_call_2(fb_info.phone, FB_SET_STYLE, DEFAULT_FOREGROUND_COLOR, DEFAULT_BACKGROUND_COLOR);
    195                                         nsend_call(fb_info.phone, FB_CLEAR, 0);
    196                                         /* FIXME: restore kernel console */
    197                                          __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
    198                                          break;
    199                                          
    200                                 } else {
    201                                         c = c - '1';
    202                                         if (c == active_console)
    203                                                 break;
    204                                         active_console = c;
    205                                         gcons_change_console(c);
    206                                
    207                                 }
    208                                
    209                                 conn = &connections[active_console];
    210 
    211                                 nsend_call(fb_info.phone, FB_CURSOR_VISIBILITY, 0);
    212                
    213                                 if (interbuffer) {
    214                                         for (i = 0; i < conn->screenbuffer.size_x; i++)
    215                                                 for (j = 0; j < conn->screenbuffer.size_y; j++)
    216                                                         interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
    217                                                        
    218                                         sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);               
    219                                 } else {
    220                                         nsend_call(fb_info.phone, FB_CLEAR, 0);
    221                                
    222                                        
    223                                         for (i = 0; i < conn->screenbuffer.size_x; i++)
    224                                                 for (j = 0; j < conn->screenbuffer.size_y; j++) {
    225                                                         d = get_field_at(&(conn->screenbuffer),i, j)->character;
    226                                                         if (d && d != ' ')
    227                                                                 nsend_call_3(fb_info.phone, FB_PUTCHAR, d, j, i);
    228                                                 }
    229 
    230                                 }
    231                                 nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, conn->screenbuffer.position_y, conn->screenbuffer.position_x);
    232                                 nsend_call_2(fb_info.phone, FB_SET_STYLE, conn->screenbuffer.style.fg_color, \
    233                                                 conn->screenbuffer.style.bg_color);
    234                                 send_call(fb_info.phone, FB_CURSOR_VISIBILITY, 1);
    235 
     308                                if (c == '0')
     309                                        change_console(-1);
     310                                else
     311                                        change_console(c - '1');
    236312                                break;
    237313                        }
     
    315391                        screenbuffer_set_style(&(connections[consnum].screenbuffer),arg1, arg2);
    316392                        if (consnum == active_console)
    317                                 nsend_call_2(fb_info.phone, FB_SET_STYLE, arg1, arg2);
     393                                set_style_col(arg1, arg2);
    318394                               
    319395                        break;
     
    362438                usleep(10000);
    363439        }
     440       
     441        /* Save old kernel screen */
     442        kernel_pixmap = switch_screens(-1);
    364443
    365444        /* Initialize gcons */
     
    370449       
    371450        ipc_call_sync_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), &(fb_info.cols));
    372         nsend_call_2(fb_info.phone, FB_SET_STYLE, DEFAULT_FOREGROUND_COLOR, DEFAULT_BACKGROUND_COLOR);
    373         nsend_call(fb_info.phone, FB_CLEAR, 0);
     451        set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     452        clrscr();
    374453       
    375454        /* Init virtual consoles */
     
    395474        }
    396475
    397         /* FIXME: save kernel console screen */
    398        
    399476        async_new_connection(phonehash, 0, NULL, keyboard_events);
    400477       
Note: See TracChangeset for help on using the changeset viewer.