Changeset 429acb9 in mainline


Ignore:
Timestamp:
2006-06-03T17:38:24Z (19 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.

Files:
7 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       
  • console/gcons.c

    rdc5a0fe1 r429acb9  
    126126        if (!use_gcons)
    127127                return;
    128        
    129         draw_stat(active_console, CONS_IDLE);
     128
     129        if (active_console != -1)
     130                draw_stat(active_console, CONS_IDLE);
    130131        active_console = consnum;
    131132        draw_stat(consnum, CONS_ACTIVE);
     
    135136}
    136137
     138/** Notification function that gets called on new output to virtual console */
    137139void gcons_notify_char(int consnum)
    138140{
     
    144146
    145147        console_has_input[consnum] = 1;
     148
     149        if (active_console == -1)
     150                return;
     151
    146152        draw_stat(consnum, CONS_HAS_INPUT);
    147153       
    148154        vp_switch(console_vp);
    149 }
    150 
     155
     156}
     157
     158/** Change to kernel console */
     159void gcons_in_kernel(void)
     160{
     161        draw_stat(active_console, CONS_IDLE);
     162        active_console = -1; /* Set to kernel console */
     163        vp_switch(0);
     164}
     165
     166/** Draw a PPM pixmap to framebuffer
     167 *
     168 * @param logo Pointer to PPM data
     169 * @param size Size of PPM data
     170 * @param x Coordinate of upper left corner
     171 * @param y Coordinate of upper left corner
     172 */
    151173static void draw_pixmap(char *logo, size_t size, int x, int y)
    152174{
  • console/gcons.h

    rdc5a0fe1 r429acb9  
    3333void gcons_change_console(int consnum);
    3434void gcons_notify_char(int consnum);
     35void gcons_in_kernel(void);
    3536
    3637#endif
  • console/screenbuffer.h

    rdc5a0fe1 r429acb9  
    3131
    3232
    33 #define DEFAULT_FOREGROUND_COLOR 0xffffff       /**< default console foreground color */
    34 #define DEFAULT_BACKGROUND_COLOR 0x00003f       /**< default console background color */
     33#define DEFAULT_FOREGROUND 0xffff00     /**< default console foreground color */
     34#define DEFAULT_BACKGROUND 0x000080     /**< default console background color */
    3535
    3636typedef struct {
  • fb/fb.c

    rdc5a0fe1 r429acb9  
    8484} viewport_t;
    8585
     86/** Maximum number of saved pixmaps
     87 * Pixmap is a saved rectangle
     88 */
     89#define MAX_PIXMAPS        256
     90typedef struct {
     91        unsigned int width;
     92        unsigned int height;
     93        void *data;
     94} pixmap_t;
     95static pixmap_t pixmaps[MAX_PIXMAPS];
     96
     97/* Viewport is a rectangular area on the screen */
    8698#define MAX_VIEWPORTS 128
    8799static viewport_t viewports[128];
     
    287299}
    288300
    289 static void draw_logo(int vp,unsigned int startx, unsigned int starty)
    290 {
    291         unsigned int x;
    292         unsigned int y;
    293         unsigned int byte;
    294         unsigned int rowbytes;
    295 
    296         rowbytes = (helenos_width - 1) / 8 + 1;
    297 
    298         for (y = 0; y < helenos_height; y++)
    299                 for (x = 0; x < helenos_width; x++) {
    300                         byte = helenos_bits[rowbytes * y + x / 8];
    301                         byte >>= x % 8;
    302                         if (byte & 1)
    303                                 putpixel(vp ,startx + x, starty + y, viewports[vp].style.fg_color);
    304                 }
    305 }
    306 
    307301/***************************************************************/
    308302/* Stdout specific functions */
     
    396390}
    397391
     392/** Hide cursor if it is shown */
    398393static void cursor_hide(int vp)
    399394{
     
    406401}
    407402
     403/** Show cursor if cursor showing is enabled */
    408404static void cursor_print(int vp)
    409405{
     
    417413}
    418414
     415/** Invert cursor, if it is enabled */
    419416static void cursor_blink(int vp)
    420417{
     
    458455}
    459456
     457/** Draw text data to viewport
     458 *
     459 * @param vp Viewport id
     460 * @param data Text data fitting exactly into viewport
     461 */
    460462static void draw_text_data(int vp, keyfield_t *data)
    461463{
     
    476478}
    477479
     480/** Handle shared memory communication calls
     481 *
     482 * Protocol for drawing pixmaps:
     483 * - FB_PREPARE_SHM(client shm identification)
     484 * - IPC_M_SEND_AS_AREA
     485 * - FB_DRAW_PPM(startx,starty)
     486 * - FB_DROP_SHM
     487 *
     488 * Protocol for text drawing
     489 * - IPC_M_SEND_AS_AREA
     490 * - FB_DRAW_TEXT_DATA
     491 *
     492 * @param callid Callid of the current call
     493 * @param call Current call data
     494 * @param vp Active viewport
     495 * @return 0 if the call was not handled byt this function, 1 otherwise
     496 *
     497 * note: this function is not threads safe, you would have
     498 * to redefine static variables with __thread
     499 */
    478500static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    479501{
     
    559581}
    560582
     583/** Return first free pixmap */
     584static int find_free_pixmap(void)
     585{
     586        int i;
     587       
     588        for (i=0;i < MAX_PIXMAPS;i++)
     589                if (!pixmaps[i].data)
     590                        return i;
     591        return -1;
     592}
     593
     594/** Save viewport to pixmap */
     595static int save_vp_to_pixmap(int vp)
     596{
     597        int pm;
     598        pixmap_t *pmap;
     599        viewport_t *vport = &viewports[vp];
     600        int x,y;
     601        int rowsize;
     602        int tmp;
     603
     604        pm = find_free_pixmap();
     605        if (pm == -1)
     606                return ELIMIT;
     607       
     608        pmap = &pixmaps[pm];
     609        pmap->data = malloc(screen.pixelbytes * vport->width * vport->height);
     610        if (!pmap->data)
     611                return ENOMEM;
     612
     613        pmap->width = vport->width;
     614        pmap->height = vport->height;
     615       
     616        rowsize = vport->width * screen.pixelbytes;
     617        for (y=0;y < vport->height; y++) {
     618                tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
     619                memcpy(pmap->data + rowsize*y, screen.fbaddress + tmp, rowsize);
     620        }
     621        return pm;
     622}
     623
     624/** Draw pixmap on screen
     625 *
     626 * @param vp Viewport to draw on
     627 * @param pm Pixmap identifier
     628 */
     629static int draw_pixmap(int vp, int pm)
     630{
     631        pixmap_t *pmap = &pixmaps[pm];
     632        viewport_t *vport = &viewports[vp];
     633        int x,y;
     634        int tmp, srcrowsize;
     635        int realwidth, realheight, realrowsize;
     636
     637        if (!pmap->data)
     638                return EINVAL;
     639
     640        realwidth = pmap->width <= vport->width ? pmap->width : vport->width;
     641        realheight = pmap->height <= vport->height ? pmap->height : vport->height;
     642
     643        srcrowsize = vport->width * screen.pixelbytes;
     644        realrowsize = realwidth * screen.pixelbytes;
     645
     646        for (y=0; y < realheight; y++) {
     647                tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
     648                memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize, realrowsize);
     649        }
     650}
     651
     652/** Handler for messages concerning pixmap handling */
     653static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
     654{
     655        int handled = 1;
     656        int retval = 0;
     657        int i,nvp;
     658
     659        switch (IPC_GET_METHOD(*call)) {
     660        case FB_VP_DRAW_PIXMAP:
     661                nvp = IPC_GET_ARG1(*call);
     662                if (nvp == -1)
     663                        nvp = vp;
     664                if (nvp < 0 || nvp >= MAX_VIEWPORTS || !viewports[nvp].initialized) {
     665                        retval = EINVAL;
     666                        break;
     667                }
     668                i = IPC_GET_ARG2(*call);
     669                retval = draw_pixmap(nvp, i);
     670                break;
     671        case FB_VP2PIXMAP:
     672                nvp = IPC_GET_ARG1(*call);
     673                if (nvp == -1)
     674                        nvp = vp;
     675                if (nvp < 0 || nvp >= MAX_VIEWPORTS || !viewports[nvp].initialized)
     676                        retval = EINVAL;
     677                else
     678                        retval = save_vp_to_pixmap(nvp);
     679                break;
     680        case FB_DROP_PIXMAP:
     681                i = IPC_GET_ARG1(*call);
     682                if (i >= MAX_PIXMAPS) {
     683                        retval = EINVAL;
     684                        break;
     685                }
     686                if (pixmaps[i].data) {
     687                        free(pixmaps[i].data);
     688                        pixmaps[i].data = NULL;
     689                }
     690                break;
     691        default:
     692                handled = 0;
     693        }
     694
     695        if (handled)
     696                ipc_answer_fast(callid, retval, 0, 0);
     697        return handled;
     698       
     699}
     700
    561701/** Function for handling connections to FB
    562702 *
     
    588728                }
    589729                if (shm_handle(callid, &call, vp))
     730                        continue;
     731                if (pixmap_handle(callid, &call, vp))
    590732                        continue;
    591733
  • libc/include/async.h

    rdc5a0fe1 r429acb9  
    7171        return rc;
    7272}
     73#define sync_send(phoneid, method, arg1, r1) sync_send_2(phoneid, method, arg1, 0, r1, 0)
     74
    7375static inline ipcarg_t sync_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
    7476                                   ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *r1,
  • libc/include/ipc/fb.h

    rdc5a0fe1 r429acb9  
    2424#define FB_PREPARE_SHM       1039
    2525#define FB_DROP_SHM          1040
     26#define FB_SHM2PIXMAP        1041
     27
     28#define FB_VP_DRAW_PIXMAP    1042
     29#define FB_VP2PIXMAP         1043
     30#define FB_DROP_PIXMAP       1044
    2631
    2732#endif
Note: See TracChangeset for help on using the changeset viewer.