Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 7ddc2c7 in mainline


Ignore:
Timestamp:
2014-03-17T15:00:13Z (7 years ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
9df6b0f
Parents:
e1fc679
Message:

add support for framebuffer history paging (using Page Up and Page Down keys), inspiration taken from the code by Sebastian Köln
add support for input device out-of-band signalling

Location:
kernel
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia64/src/drivers/ski.c

    re1fc679 r7ddc2c7  
    6161static outdev_operations_t skidev_ops = {
    6262        .write = ski_putchar,
    63         .redraw = NULL
     63        .redraw = NULL,
     64        .scroll_up = NULL,
     65        .scroll_down = NULL
    6466};
    6567
  • kernel/arch/mips32/src/mach/malta/malta.c

    re1fc679 r7ddc2c7  
    9292static outdev_operations_t yamon_outdev_ops = {
    9393        .write = yamon_putchar,
    94         .redraw = NULL
     94        .redraw = NULL,
     95        .scroll_up = NULL,
     96        .scroll_down = NULL
    9597};
    9698
  • kernel/arch/sparc64/src/drivers/niagara.c

    re1fc679 r7ddc2c7  
    6363static outdev_operations_t niagara_ops = {
    6464        .write = niagara_putchar,
    65         .redraw = NULL
     65        .redraw = NULL,
     66        .scroll_up = NULL,
     67        .scroll_down = NULL
    6668};
    6769
  • kernel/genarch/src/drivers/dsrln/dsrlnout.c

    re1fc679 r7ddc2c7  
    6363static outdev_operations_t dsrlndev_ops = {
    6464        .write = dsrlnout_putchar,
    65         .redraw = NULL
     65        .redraw = NULL,
     66        .scroll_up = NULL,
     67        .scroll_down = NULL
    6668};
    6769
  • kernel/genarch/src/drivers/ega/ega.c

    re1fc679 r7ddc2c7  
    7676static outdev_operations_t egadev_ops = {
    7777        .write = ega_putchar,
    78         .redraw = ega_redraw
     78        .redraw = ega_redraw,
     79        .scroll_up = NULL,
     80        .scroll_down = NULL
    7981};
    8082
  • kernel/genarch/src/drivers/grlib/uart.c

    re1fc679 r7ddc2c7  
    100100static outdev_operations_t grlib_uart_ops = {
    101101        .write = grlib_uart_putchar,
    102         .redraw = NULL
     102        .redraw = NULL,
     103        .scroll_up = NULL,
     104        .scroll_down = NULL
    103105};
    104106
  • kernel/genarch/src/drivers/omap/uart.c

    re1fc679 r7ddc2c7  
    6161
    6262static outdev_operations_t omap_uart_ops = {
     63        .write = omap_uart_putchar,
    6364        .redraw = NULL,
    64         .write = omap_uart_putchar,
     65        .scroll_up = NULL,
     66        .scroll_down = NULL
    6567};
    6668
  • kernel/genarch/src/drivers/pl011/pl011.c

    re1fc679 r7ddc2c7  
    7272        .write = pl011_uart_putchar,
    7373        .redraw = NULL,
     74        .scroll_up = NULL,
     75        .scroll_down = NULL
    7476};
    7577
  • kernel/genarch/src/drivers/s3c24xx/uart.c

    re1fc679 r7ddc2c7  
    9595static outdev_operations_t s3c24xx_uart_ops = {
    9696        .write = s3c24xx_uart_putchar,
    97         .redraw = NULL
     97        .redraw = NULL,
     98        .scroll_up = NULL,
     99        .scroll_down = NULL
    98100};
    99101
  • kernel/genarch/src/fb/fb.c

    re1fc679 r7ddc2c7  
    5656#define INV_COLOR    0xaaaaaa
    5757
     58#define FB_PAGES  8
     59
    5860#define RED(x, bits)    (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
    5961#define GREEN(x, bits)  (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
     
    7072
    7173#define BB_POS(instance, col, row) \
    72         ((row) * (instance)->cols + (col))
     74        ((((instance)->start_row + (row)) % (instance)->rows) * \
     75            (instance)->cols + (col))
    7376
    7477#define GLYPH_POS(instance, glyph, y) \
     
    9295        unsigned int yres;
    9396       
     97        /** Number of rows that fit on framebuffer */
    9498        unsigned int rowtrim;
    9599       
     
    101105        unsigned int bgscanbytes;
    102106       
     107        /** Number of columns in the backbuffer */
    103108        unsigned int cols;
     109        /** Number of rows in the backbuffer */
    104110        unsigned int rows;
    105111       
     112        /** Starting row in the cyclic backbuffer */
     113        unsigned int start_row;
     114       
     115        /** Top-most visible row (relative to start_row) */
     116        unsigned int offset_row;
     117       
     118        /** Current backbuffer position */
    106119        unsigned int position;
    107120} fb_instance_t;
    108121
    109 static void fb_putchar(outdev_t *dev, wchar_t ch);
    110 static void fb_redraw_internal(fb_instance_t *instance);
    111 static void fb_redraw(outdev_t *dev);
     122static void fb_putchar(outdev_t *, wchar_t);
     123static void fb_redraw(outdev_t *);
     124static void fb_scroll_up(outdev_t *);
     125static void fb_scroll_down(outdev_t *);
    112126
    113127static outdev_operations_t fbdev_ops = {
    114128        .write = fb_putchar,
    115         .redraw = fb_redraw
     129        .redraw = fb_redraw,
     130        .scroll_up = fb_scroll_up,
     131        .scroll_down = fb_scroll_down
    116132};
    117133
     
    216232    unsigned int col, unsigned int row, bool overlay)
    217233{
    218         unsigned int x = COL2X(col);
    219         unsigned int y = ROW2Y(row);
    220         unsigned int yd;
    221        
    222234        if (!overlay)
    223235                instance->backbuf[BB_POS(instance, col, row)] = glyph;
    224236       
     237        /* Do not output if the framebuffer is used by user space */
     238        if ((instance->parea.mapped) && (!console_override))
     239                return;
     240       
     241        /* Check whether the glyph should be visible */
     242        if (row < instance->offset_row)
     243                return;
     244       
     245        unsigned int rel_row = row - instance->offset_row;
     246        if (rel_row >= instance->rowtrim)
     247                return;
     248       
     249        unsigned int x = COL2X(col);
     250        unsigned int y = ROW2Y(rel_row);
     251       
     252        for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++)
     253                memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
     254                    &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
     255                    instance->glyphscanline);
     256}
     257
     258/** Scroll screen down by one row
     259 *
     260 */
     261static void screen_scroll(fb_instance_t *instance)
     262{
    225263        if ((!instance->parea.mapped) || (console_override)) {
    226                 for (yd = 0; yd < FONT_SCANLINES; yd++)
    227                         memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
    228                             &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
    229                             instance->glyphscanline);
    230         }
    231 }
    232 
    233 /** Scroll screen down by one row
    234  *
    235  *
    236  */
    237 static void screen_scroll(fb_instance_t *instance)
    238 {
    239         if ((!instance->parea.mapped) || (console_override)) {
    240                 unsigned int row;
    241                
    242                 for (row = 0; row < instance->rows; row++) {
    243                         unsigned int y = ROW2Y(row);
    244                         unsigned int yd;
     264                for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
     265                        unsigned int y = ROW2Y(rel_row);
     266                        unsigned int row = rel_row + instance->offset_row;
    245267                       
    246                         for (yd = 0; yd < FONT_SCANLINES; yd++) {
     268                        for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {
    247269                                unsigned int x;
    248270                                unsigned int col;
     
    269291        }
    270292       
    271         memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)],
    272             instance->cols * (instance->rows - 1) * sizeof(uint16_t));
     293        /*
     294         * Implement backbuffer scrolling by wrapping around
     295         * the cyclic buffer.
     296         */
     297       
     298        instance->start_row++;
     299        if (instance->start_row == instance->rows)
     300                instance->start_row = 0;
     301       
    273302        memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],
    274303            instance->cols, 0);
     
    334363}
    335364
    336 /** Print character to screen
    337  *
    338  * Emulate basic terminal commands.
    339  *
    340  */
    341 static void fb_putchar(outdev_t *dev, wchar_t ch)
    342 {
    343         fb_instance_t *instance = (fb_instance_t *) dev->data;
    344         spinlock_lock(&instance->lock);
    345        
    346         switch (ch) {
    347         case '\n':
    348                 cursor_remove(instance);
    349                 instance->position += instance->cols;
    350                 instance->position -= instance->position % instance->cols;
    351                 break;
    352         case '\r':
    353                 cursor_remove(instance);
    354                 instance->position -= instance->position % instance->cols;
    355                 break;
    356         case '\b':
    357                 cursor_remove(instance);
    358                 if (instance->position % instance->cols)
    359                         instance->position--;
    360                 break;
    361         case '\t':
    362                 cursor_remove(instance);
    363                 do {
    364                         glyph_draw(instance, fb_font_glyph(' '),
    365                             instance->position % instance->cols,
    366                             instance->position / instance->cols, false);
    367                         instance->position++;
    368                 } while (((instance->position % instance->cols) % 8 != 0) &&
    369                     (instance->position < instance->cols * instance->rows));
    370                 break;
    371         default:
    372                 glyph_draw(instance, fb_font_glyph(ch),
    373                     instance->position % instance->cols,
    374                     instance->position / instance->cols, false);
    375                 instance->position++;
    376         }
    377        
    378         if (instance->position >= instance->cols * instance->rows) {
    379                 instance->position -= instance->cols;
    380                 screen_scroll(instance);
    381         }
    382        
    383         cursor_put(instance);
    384        
    385         spinlock_unlock(&instance->lock);
    386 }
    387 
    388365static void fb_redraw_internal(fb_instance_t *instance)
    389366{
    390         unsigned int row;
    391        
    392         for (row = 0; row < instance->rowtrim; row++) {
    393                 unsigned int y = ROW2Y(row);
    394                 unsigned int yd;
     367        for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
     368                unsigned int y = ROW2Y(rel_row);
     369                unsigned int row = rel_row + instance->offset_row;
    395370               
    396                 for (yd = 0; yd < FONT_SCANLINES; yd++) {
     371                for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {
    397372                        unsigned int x;
    398373                        unsigned int col;
     
    428403}
    429404
     405/** Print character to screen
     406 *
     407 * Emulate basic terminal commands.
     408 *
     409 */
     410static void fb_putchar(outdev_t *dev, wchar_t ch)
     411{
     412        fb_instance_t *instance = (fb_instance_t *) dev->data;
     413        spinlock_lock(&instance->lock);
     414       
     415        switch (ch) {
     416        case '\n':
     417                cursor_remove(instance);
     418                instance->position += instance->cols;
     419                instance->position -= instance->position % instance->cols;
     420                break;
     421        case '\r':
     422                cursor_remove(instance);
     423                instance->position -= instance->position % instance->cols;
     424                break;
     425        case '\b':
     426                cursor_remove(instance);
     427                if (instance->position % instance->cols)
     428                        instance->position--;
     429                break;
     430        case '\t':
     431                cursor_remove(instance);
     432                do {
     433                        glyph_draw(instance, fb_font_glyph(' '),
     434                            instance->position % instance->cols,
     435                            instance->position / instance->cols, false);
     436                        instance->position++;
     437                } while (((instance->position % instance->cols) % 8 != 0) &&
     438                    (instance->position < instance->cols * instance->rows));
     439                break;
     440        default:
     441                glyph_draw(instance, fb_font_glyph(ch),
     442                    instance->position % instance->cols,
     443                    instance->position / instance->cols, false);
     444                instance->position++;
     445        }
     446       
     447        if (instance->position >= instance->cols * instance->rows) {
     448                instance->position -= instance->cols;
     449                screen_scroll(instance);
     450        }
     451       
     452        cursor_put(instance);
     453       
     454        spinlock_unlock(&instance->lock);
     455}
     456
     457/** Scroll the framebuffer up
     458 *
     459 */
     460static void fb_scroll_up(outdev_t *dev)
     461{
     462        fb_instance_t *instance = (fb_instance_t *) dev->data;
     463        spinlock_lock(&instance->lock);
     464       
     465        if (instance->offset_row >= instance->rowtrim / 2)
     466                instance->offset_row -= instance->rowtrim / 2;
     467        else
     468                instance->offset_row = 0;
     469       
     470        fb_redraw_internal(instance);
     471        cursor_put(instance);
     472       
     473        spinlock_unlock(&instance->lock);
     474}
     475
     476/** Scroll the framebuffer down
     477 *
     478 */
     479static void fb_scroll_down(outdev_t *dev)
     480{
     481        fb_instance_t *instance = (fb_instance_t *) dev->data;
     482        spinlock_lock(&instance->lock);
     483       
     484        if (instance->offset_row + instance->rowtrim / 2 <=
     485            instance->rows - instance->rowtrim)
     486                instance->offset_row += instance->rowtrim / 2;
     487        else
     488                instance->offset_row = instance->rows - instance->rowtrim;
     489       
     490        fb_redraw_internal(instance);
     491        cursor_put(instance);
     492       
     493        spinlock_unlock(&instance->lock);
     494}
     495
    430496/** Refresh the screen
    431497 *
     
    523589        instance->yres = props->y;
    524590        instance->scanline = props->scan;
    525         instance->position = 0;
     591       
     592        instance->rowtrim = Y2ROW(instance->yres);
    526593       
    527594        instance->cols = X2COL(instance->xres);
    528         instance->rows = Y2ROW(instance->yres);
    529        
    530         instance->rowtrim = instance->rows;
     595        instance->rows = FB_PAGES * instance->rowtrim;
     596       
     597        instance->start_row = instance->rows - instance->rowtrim;
     598        instance->offset_row = instance->start_row;
     599        instance->position = instance->start_row * instance->cols;
    531600       
    532601        instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
  • kernel/genarch/src/kbrd/kbrd.c

    re1fc679 r7ddc2c7  
    5656#include <arch.h>
    5757#include <macros.h>
     58#include <str.h>
    5859
    5960#define IGNORE_CODE  0x7f
     
    6566
    6667static indev_operations_t kbrd_raw_ops = {
    67         .poll = NULL
     68        .poll = NULL,
     69        .signal = NULL
    6870};
    6971
     
    104106        bool shift;
    105107        bool capslock;
     108        wchar_t ch;
    106109       
    107110        spinlock_lock(&instance->keylock);
     
    127130               
    128131                if (shift)
    129                         indev_push_character(instance->sink, sc_secondary_map[sc]);
     132                        ch = sc_secondary_map[sc];
    130133                else
    131                         indev_push_character(instance->sink, sc_primary_map[sc]);
     134                        ch = sc_primary_map[sc];
     135               
     136                switch (ch) {
     137                case U_PAGE_UP:
     138                        indev_signal(instance->sink, INDEV_SIGNAL_SCROLL_UP);
     139                        break;
     140                case U_PAGE_DOWN:
     141                        indev_signal(instance->sink, INDEV_SIGNAL_SCROLL_DOWN);
     142                        break;
     143                default:
     144                        indev_push_character(instance->sink, ch);
     145                }
     146               
    132147                break;
    133148        }
  • kernel/genarch/src/srln/srln.c

    re1fc679 r7ddc2c7  
    4343
    4444static indev_operations_t srln_raw_ops = {
    45         .poll = NULL
     45        .poll = NULL,
     46        .signal = NULL
    4647};
    4748
  • kernel/generic/include/console/chardev.h

    re1fc679 r7ddc2c7  
    4343#define INDEV_BUFLEN  512
    4444
     45/** Input character device out-of-band signal type. */
     46typedef enum {
     47        INDEV_SIGNAL_SCROLL_UP = 0,
     48        INDEV_SIGNAL_SCROLL_DOWN
     49} indev_signal_t;
     50
    4551struct indev;
    4652
    47 /* Input character device operations interface. */
     53/** Input character device operations interface. */
    4854typedef struct {
    4955        /** Read character directly from device, assume interrupts disabled. */
    5056        wchar_t (* poll)(struct indev *);
     57       
     58        /** Signal out-of-band condition. */
     59        void (* signal)(struct indev *, indev_signal_t);
    5160} indev_operations_t;
    5261
     
    6776} indev_t;
    6877
    69 
    7078struct outdev;
    7179
    72 /* Output character device operations interface. */
     80/** Output character device operations interface. */
    7381typedef struct {
    7482        /** Write character to output. */
     
    7785        /** Redraw any previously cached characters. */
    7886        void (* redraw)(struct outdev *);
     87       
     88        /** Scroll up in the device cache. */
     89        void (* scroll_up)(struct outdev *);
     90       
     91        /** Scroll down in the device cache. */
     92        void (* scroll_down)(struct outdev *);
    7993} outdev_operations_t;
    8094
     
    99113extern void indev_push_character(indev_t *, wchar_t);
    100114extern wchar_t indev_pop_character(indev_t *);
     115extern void indev_signal(indev_t *, indev_signal_t);
    101116
    102117extern void outdev_initialize(const char *, outdev_t *,
  • kernel/generic/src/console/chardev.c

    re1fc679 r7ddc2c7  
    9494{
    9595        if (atomic_get(&haltstate)) {
    96                 /* If we are here, we are hopefully on the processor that
     96                /*
     97                 * If we are here, we are hopefully on the processor that
    9798                 * issued the 'halt' command, so proceed to read the character
    9899                 * directly from input
     
    115116        waitq_sleep(&indev->wq);
    116117        irq_spinlock_lock(&indev->lock, true);
    117         wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
     118        wchar_t ch = indev->buffer[(indev->index - indev->counter) %
     119            INDEV_BUFLEN];
    118120        indev->counter--;
    119121        irq_spinlock_unlock(&indev->lock, true);
    120122       
    121123        return ch;
     124}
     125
     126/** Signal out-of-band condition
     127 *
     128 * @param indev  Input character device.
     129 * @param signal Out-of-band condition to signal.
     130 *
     131 */
     132void indev_signal(indev_t *indev, indev_signal_t signal)
     133{
     134        if ((indev != NULL) && (indev->op != NULL) &&
     135            (indev->op->signal != NULL))
     136                indev->op->signal(indev, signal);
    122137}
    123138
  • kernel/generic/src/console/console.c

    re1fc679 r7ddc2c7  
    8484static outdev_t stdout_source;
    8585
     86static void stdin_signal(indev_t *, indev_signal_t);
     87
    8688static indev_operations_t stdin_ops = {
    87         .poll = NULL
     89        .poll = NULL,
     90        .signal = stdin_signal
    8891};
    8992
    9093static void stdout_write(outdev_t *, wchar_t);
    9194static void stdout_redraw(outdev_t *);
     95static void stdout_scroll_up(outdev_t *);
     96static void stdout_scroll_down(outdev_t *);
    9297
    9398static outdev_operations_t stdout_ops = {
    9499        .write = stdout_write,
    95         .redraw = stdout_redraw
     100        .redraw = stdout_redraw,
     101        .scroll_up = stdout_scroll_up,
     102        .scroll_down = stdout_scroll_down
    96103};
    97104
     
    113120}
    114121
     122static void stdin_signal(indev_t *indev, indev_signal_t signal)
     123{
     124        switch (signal) {
     125        case INDEV_SIGNAL_SCROLL_UP:
     126                if (stdout != NULL)
     127                        stdout_scroll_up(stdout);
     128                break;
     129        case INDEV_SIGNAL_SCROLL_DOWN:
     130                if (stdout != NULL)
     131                        stdout_scroll_down(stdout);
     132                break;
     133        }
     134}
     135
    115136void stdout_wire(outdev_t *outdev)
    116137{
     
    136157                if ((sink) && (sink->op->redraw))
    137158                        sink->op->redraw(sink);
     159        }
     160}
     161
     162static void stdout_scroll_up(outdev_t *dev)
     163{
     164        list_foreach(dev->list, link, outdev_t, sink) {
     165                if ((sink) && (sink->op->scroll_up))
     166                        sink->op->scroll_up(sink);
     167        }
     168}
     169
     170static void stdout_scroll_down(outdev_t *dev)
     171{
     172        list_foreach(dev->list, link, outdev_t, sink) {
     173                if ((sink) && (sink->op->scroll_down))
     174                        sink->op->scroll_down(sink);
    138175        }
    139176}
     
    229266                        }
    230267                }
     268               
    231269                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    232270                        putchar(ch);
     
    264302
    265303/** Flush characters that are stored in the output buffer
    266  * 
     304 *
    267305 */
    268306void kio_flush(void)
     
    294332
    295333/** Put a character into the output buffer.
    296  * 
     334 *
    297335 * The caller is required to hold kio_lock
    298336 */
Note: See TracChangeset for help on using the changeset viewer.