Subversion Repositories HelenOS-historic

Rev

Rev 1552 | Rev 1558 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1552 Rev 1555
Line 52... Line 52...
52
#define DEFAULT_FGCOLOR                0xffff00
52
#define DEFAULT_FGCOLOR                0xffff00
53
 
53
 
54
/***************************************************************/
54
/***************************************************************/
55
/* Pixel specific fuctions */
55
/* Pixel specific fuctions */
56
 
56
 
57
typedef void (*putpixel_fn_t)(unsigned int x, unsigned int y, int color);
57
typedef void (*conv2scr_fn_t)(void *, int);
58
typedef int (*getpixel_fn_t)(unsigned int x, unsigned int y);
58
typedef int (*conv2rgb_fn_t)(void *);
59
 
59
 
60
struct {
60
struct {
61
    __u8 *fbaddress ;
61
    __u8 *fbaddress ;
62
 
62
 
63
    unsigned int xres ;
63
    unsigned int xres ;
64
    unsigned int yres ;
64
    unsigned int yres ;
65
    unsigned int scanline ;
65
    unsigned int scanline ;
66
    unsigned int pixelbytes ;
66
    unsigned int pixelbytes ;
67
 
67
 
68
    putpixel_fn_t putpixel;
68
    conv2scr_fn_t rgb2scr;
69
    getpixel_fn_t getpixel;
69
    conv2rgb_fn_t scr2rgb;
70
} screen;
70
} screen;
71
 
71
 
72
typedef struct {
72
typedef struct {
73
    int initialized;
73
    int initialized;
74
    unsigned int x, y;
74
    unsigned int x, y;
Line 88... Line 88...
88
 */
88
 */
89
#define MAX_PIXMAPS        256
89
#define MAX_PIXMAPS        256
90
typedef struct {
90
typedef struct {
91
    unsigned int width;
91
    unsigned int width;
92
    unsigned int height;
92
    unsigned int height;
93
    void *data;
93
    __u8 *data;
94
} pixmap_t;
94
} pixmap_t;
95
static pixmap_t pixmaps[MAX_PIXMAPS];
95
static pixmap_t pixmaps[MAX_PIXMAPS];
96
 
96
 
97
/* Viewport is a rectangular area on the screen */
97
/* Viewport is a rectangular area on the screen */
98
#define MAX_VIEWPORTS 128
98
#define MAX_VIEWPORTS 128
Line 108... Line 108...
108
#define COL_WIDTH   8
108
#define COL_WIDTH   8
109
#define ROW_BYTES   (screen.scanline * FONT_SCANLINES)
109
#define ROW_BYTES   (screen.scanline * FONT_SCANLINES)
110
 
110
 
111
#define POINTPOS(x, y)  ((y) * screen.scanline + (x) * screen.pixelbytes)
111
#define POINTPOS(x, y)  ((y) * screen.scanline + (x) * screen.pixelbytes)
112
 
112
 
113
/** Put pixel - 24-bit depth, 1 free byte */
113
/* Conversion routines between different color representations */
114
static void putpixel_4byte(unsigned int x, unsigned int y, int color)
114
static void rgb_4byte(void *dst, int rgb)
115
{
115
{
116
    *((__u32 *)(screen.fbaddress + POINTPOS(x, y))) = color;
116
    *(int *)dst = rgb;
117
}
117
}
118
 
118
 
119
/** Return pixel color - 24-bit depth, 1 free byte */
-
 
120
static int getpixel_4byte(unsigned int x, unsigned int y)
119
static int byte4_rgb(void *src)
121
{
120
{
122
    return *((__u32 *)(screen.fbaddress + POINTPOS(x, y))) & 0xffffff;
121
    return (*(int *)src) & 0xffffff;
123
}
122
}
124
 
123
 
125
/** Put pixel - 24-bit depth */
-
 
126
static void putpixel_3byte(unsigned int x, unsigned int y, int color)
124
static void rgb_3byte(void *dst, int rgb)
127
{
125
{
128
    unsigned int startbyte = POINTPOS(x, y);
126
    __u8 *scr = dst;
129
 
-
 
130
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
127
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
131
    screen.fbaddress[startbyte] = RED(color, 8);
128
    scr[0] = RED(rgb, 8);
132
    screen.fbaddress[startbyte + 1] = GREEN(color, 8);
129
    scr[1] = GREEN(rgb, 8);
133
    screen.fbaddress[startbyte + 2] = BLUE(color, 8);
130
    scr[2] = BLUE(rgb, 8);
134
#else
131
#else
135
    screen.fbaddress[startbyte + 2] = RED(color, 8);
132
    scr[2] = RED(rgb, 8);
136
    screen.fbaddress[startbyte + 1] = GREEN(color, 8);
133
    scr[1] = GREEN(rgb, 8);
137
    screen.fbaddress[startbyte + 0] = BLUE(color, 8);
134
    scr[0] = BLUE(rgb, 8);
138
#endif
135
#endif
139
 
136
 
-
 
137
 
140
}
138
}
141
 
139
 
142
/** Return pixel color - 24-bit depth */
-
 
143
static int getpixel_3byte(unsigned int x, unsigned int y)
140
static int byte3_rgb(void *src)
144
{
141
{
145
    unsigned int startbyte = POINTPOS(x, y);
142
    __u8 *scr = src;
146
 
-
 
147
 
-
 
148
 
-
 
149
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
143
#if (defined(BIG_ENDIAN) || defined(FB_BIG_ENDIAN))
150
    return screen.fbaddress[startbyte] << 16 | screen.fbaddress[startbyte + 1] << 8 | screen.fbaddress[startbyte + 2];
144
    return scr[0] << 16 | scr[1] << 8 | scr[2];
151
#else
145
#else
152
    return screen.fbaddress[startbyte + 2] << 16 | screen.fbaddress[startbyte + 1] << 8 | screen.fbaddress[startbyte + 0];
146
    return scr[2] << 16 | scr[1] << 8 | scr[0];
153
#endif
147
#endif  
154
                               
-
 
155
 
-
 
156
}
148
}
157
 
149
 
158
/** Put pixel - 16-bit depth (5:6:5) */
150
/**  16-bit depth (5:6:5) */
159
static void putpixel_2byte(unsigned int x, unsigned int y, int color)
151
static void rgb_2byte(void *dst, int rgb)
160
{
152
{
161
    /* 5-bit, 6-bits, 5-bits */
153
    /* 5-bit, 6-bits, 5-bits */
162
    *((__u16 *)(screen.fbaddress + POINTPOS(x, y))) = RED(color, 5) << 11 | GREEN(color, 6) << 5 | BLUE(color, 5);
154
    *((__u16 *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | BLUE(rgb, 5);
163
}
155
}
164
 
156
 
165
/** Return pixel color - 16-bit depth (5:6:5) */
157
/** 16-bit depth (5:6:5) */
166
static int getpixel_2byte(unsigned int x, unsigned int y)
158
static int byte2_rgb(void *src)
167
{
159
{
168
    int color = *((__u16 *)(screen.fbaddress + POINTPOS(x, y)));
160
    int color = *(__u16 *)(src);
169
    return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
161
    return (((color >> 11) & 0x1f) << (16 + 3)) | (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
170
}
162
}
171
 
163
 
172
/** Put pixel - 8-bit depth (3:2:3) */
164
/** Put pixel - 8-bit depth (3:2:3) */
173
static void putpixel_1byte(unsigned int x, unsigned int y, int color)
165
static void rgb_1byte(void *dst, int rgb)
174
{
166
{
175
    screen.fbaddress[POINTPOS(x, y)] = RED(color, 3) << 5 | GREEN(color, 2) << 3 | BLUE(color, 3);
167
    *(__u8 *)dst = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb, 3);
176
}
168
}
177
 
169
 
178
/** Return pixel color - 8-bit depth (3:2:3) */
170
/** Return pixel color - 8-bit depth (3:2:3) */
179
static int getpixel_1byte(unsigned int x, unsigned int y)
171
static int byte1_rgb(void *src)
180
{
172
{
181
    int color = screen.fbaddress[POINTPOS(x, y)];
173
    int color = *(__u8 *)src;
182
    return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
174
    return (((color >> 5) & 0x7) << (16 + 5)) | (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
183
}
175
}
184
 
176
 
185
/** Put pixel into viewport
177
/** Put pixel into viewport
186
 *
178
 *
Line 189... Line 181...
189
 * @param y Y coord relative to viewport
181
 * @param y Y coord relative to viewport
190
 * @param color RGB color
182
 * @param color RGB color
191
 */
183
 */
192
static void putpixel(int vp, unsigned int x, unsigned int y, int color)
184
static void putpixel(int vp, unsigned int x, unsigned int y, int color)
193
{
185
{
-
 
186
    int dx = viewports[vp].x + x;
-
 
187
    int dy = viewports[vp].y + y;
194
    screen.putpixel(viewports[vp].x + x, viewports[vp].y + y, color);
188
    (*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)],color);
195
}
189
}
196
/** Get pixel from viewport */
190
/** Get pixel from viewport */
197
static int getpixel(int vp, unsigned int x, unsigned int y)
191
static int getpixel(int vp, unsigned int x, unsigned int y)
198
{
192
{
-
 
193
    int dx = viewports[vp].x + x;
-
 
194
    int dy = viewports[vp].y + y;
-
 
195
 
199
    return screen.getpixel(viewports[vp].x + x, viewports[vp].y + y);
196
    return (*screen.scr2rgb)(&screen.fbaddress[POINTPOS(dx,dy)]);
200
}
197
}
201
 
198
 
202
/** Fill line with color BGCOLOR */
199
/** Fill line with color BGCOLOR */
203
static void clear_line(int vp, unsigned int y)
200
static void clear_line(int vp, unsigned int y)
204
{
201
{
Line 356... Line 353...
356
 */
353
 */
357
static void screen_init(void *addr, unsigned int xres, unsigned int yres, unsigned int bpp, unsigned int scan)
354
static void screen_init(void *addr, unsigned int xres, unsigned int yres, unsigned int bpp, unsigned int scan)
358
{
355
{
359
    switch (bpp) {
356
    switch (bpp) {
360
        case 8:
357
        case 8:
361
            screen.putpixel = putpixel_1byte;
358
            screen.rgb2scr = rgb_1byte;
362
            screen.getpixel = getpixel_1byte;
359
            screen.scr2rgb = byte1_rgb;
363
            screen.pixelbytes = 1;
360
            screen.pixelbytes = 1;
364
            break;
361
            break;
365
        case 16:
362
        case 16:
366
            screen.putpixel = putpixel_2byte;
363
            screen.rgb2scr = rgb_2byte;
367
            screen.getpixel = getpixel_2byte;
364
            screen.scr2rgb = byte2_rgb;
368
            screen.pixelbytes = 2;
365
            screen.pixelbytes = 2;
369
            break;
366
            break;
370
        case 24:
367
        case 24:
371
            screen.putpixel = putpixel_3byte;
368
            screen.rgb2scr = rgb_3byte;
372
            screen.getpixel = getpixel_3byte;
369
            screen.scr2rgb = byte3_rgb;
373
            screen.pixelbytes = 3;
370
            screen.pixelbytes = 3;
374
            break;
371
            break;
375
        case 32:
372
        case 32:
376
            screen.putpixel = putpixel_4byte;
373
            screen.rgb2scr = rgb_4byte;
377
            screen.getpixel = getpixel_4byte;
374
            screen.scr2rgb = byte4_rgb;
378
            screen.pixelbytes = 4;
375
            screen.pixelbytes = 4;
379
            break;
376
            break;
380
    }
377
    }
381
 
378
 
382
       
379
       
Line 475... Line 472...
475
        draw_glyph(vp, data[i].character, col * COL_WIDTH, row * FONT_SCANLINES, data[i].style);
472
        draw_glyph(vp, data[i].character, col * COL_WIDTH, row * FONT_SCANLINES, data[i].style);
476
    }
473
    }
477
    cursor_print(vp);
474
    cursor_print(vp);
478
}
475
}
479
 
476
 
-
 
477
 
-
 
478
/** Return first free pixmap */
-
 
479
static int find_free_pixmap(void)
-
 
480
{
-
 
481
    int i;
-
 
482
   
-
 
483
    for (i=0;i < MAX_PIXMAPS;i++)
-
 
484
        if (!pixmaps[i].data)
-
 
485
            return i;
-
 
486
    return -1;
-
 
487
}
-
 
488
 
-
 
489
static void putpixel_pixmap(int pm, unsigned int x, unsigned int y, int color)
-
 
490
{
-
 
491
    pixmap_t *pmap = &pixmaps[pm];
-
 
492
    int pos = (y * pmap->width + x) * screen.pixelbytes;
-
 
493
 
-
 
494
    (*screen.rgb2scr)(&pmap->data[pos],color);
-
 
495
}
-
 
496
 
-
 
497
/** Create a new pixmap and return appropriate ID */
-
 
498
static int shm2pixmap(char *shm, size_t size)
-
 
499
{
-
 
500
    int pm;
-
 
501
    pixmap_t *pmap;
-
 
502
 
-
 
503
    pm = find_free_pixmap();
-
 
504
    if (pm == -1)
-
 
505
        return ELIMIT;
-
 
506
    pmap = &pixmaps[pm];
-
 
507
   
-
 
508
    if (ppm_get_data(shm, size, &pmap->width, &pmap->height))
-
 
509
        return EINVAL;
-
 
510
   
-
 
511
    pmap->data = malloc(pmap->width * pmap->height * screen.pixelbytes);
-
 
512
    if (!pmap->data)
-
 
513
        return ENOMEM;
-
 
514
 
-
 
515
    ppm_draw(shm, size, 0, 0, pmap->width, pmap->height,
-
 
516
         putpixel_pixmap, pm);
-
 
517
 
-
 
518
    return pm;
-
 
519
}
-
 
520
 
480
/** Handle shared memory communication calls
521
/** Handle shared memory communication calls
481
 *
522
 *
482
 * Protocol for drawing pixmaps:
523
 * Protocol for drawing pixmaps:
483
 * - FB_PREPARE_SHM(client shm identification)
524
 * - FB_PREPARE_SHM(client shm identification)
484
 * - IPC_M_SEND_AS_AREA
525
 * - IPC_M_SEND_AS_AREA
Line 500... Line 541...
500
static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
541
static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
501
{
542
{
502
    static keyfield_t *interbuffer = NULL;
543
    static keyfield_t *interbuffer = NULL;
503
    static size_t intersize = 0;
544
    static size_t intersize = 0;
504
 
545
 
505
    static char *pixmap = NULL;
546
    static char *shm = NULL;
506
    static ipcarg_t pixmap_id = 0;
547
    static ipcarg_t shm_id = 0;
507
    static size_t pixmap_size;
548
    static size_t shm_size;
508
 
549
 
509
    int handled = 1;
550
    int handled = 1;
510
    int retval = 0;
551
    int retval = 0;
511
    viewport_t *vport = &viewports[vp];
552
    viewport_t *vport = &viewports[vp];
512
    unsigned int x,y;
553
    unsigned int x,y;
513
 
554
 
514
    switch (IPC_GET_METHOD(*call)) {
555
    switch (IPC_GET_METHOD(*call)) {
515
    case IPC_M_AS_AREA_SEND:
556
    case IPC_M_AS_AREA_SEND:
516
        /* We accept one area for data interchange */
557
        /* We accept one area for data interchange */
517
        if (IPC_GET_ARG1(*call) == pixmap_id) {
558
        if (IPC_GET_ARG1(*call) == shm_id) {
518
            void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
559
            void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
519
            pixmap_size = IPC_GET_ARG2(*call);
560
            shm_size = IPC_GET_ARG2(*call);
520
            if (!ipc_answer_fast(callid, 0, (sysarg_t)dest, 0))
561
            if (!ipc_answer_fast(callid, 0, (sysarg_t)dest, 0))
521
                pixmap = dest;
562
                shm = dest;
522
            else
563
            else
523
                pixmap_id = 0;
564
                shm_id = 0;
524
            if (pixmap[0] != 'P')
565
            if (shm[0] != 'P')
525
                while (1)
566
                while (1)
526
                    ;
567
                    ;
527
            return 1;
568
            return 1;
528
        } else {
569
        } else {
529
            intersize = IPC_GET_ARG2(*call);
570
            intersize = IPC_GET_ARG2(*call);
530
            receive_comm_area(callid,call,(void **)&interbuffer);
571
            receive_comm_area(callid,call,(void **)&interbuffer);
531
        }
572
        }
532
        return 1;
573
        return 1;
533
    case FB_PREPARE_SHM:
574
    case FB_PREPARE_SHM:
534
        if (pixmap_id)
575
        if (shm_id)
535
            retval = EBUSY;
576
            retval = EBUSY;
536
        else
577
        else
537
            pixmap_id = IPC_GET_ARG1(*call);
578
            shm_id = IPC_GET_ARG1(*call);
538
        break;
579
        break;
539
       
580
       
540
    case FB_DROP_SHM:
581
    case FB_DROP_SHM:
541
        if (pixmap) {
582
        if (shm) {
542
            as_area_destroy(pixmap);
583
            as_area_destroy(shm);
543
            pixmap = NULL;
584
            shm = NULL;
544
        }
585
        }
545
        pixmap_id = 0;
586
        shm_id = 0;
-
 
587
        break;
-
 
588
 
-
 
589
    case FB_SHM2PIXMAP:
-
 
590
        if (!shm) {
-
 
591
            retval = EINVAL;
-
 
592
            break;
-
 
593
        }
-
 
594
        retval = shm2pixmap(shm, shm_size);
546
        break;
595
        break;
547
       
-
 
548
    case FB_DRAW_PPM:
596
    case FB_DRAW_PPM:
549
        if (!pixmap) {
597
        if (!shm) {
550
            retval = EINVAL;
598
            retval = EINVAL;
551
            break;
599
            break;
552
        }
600
        }
553
        x = IPC_GET_ARG1(*call);
601
        x = IPC_GET_ARG1(*call);
554
        y = IPC_GET_ARG2(*call);
602
        y = IPC_GET_ARG2(*call);
555
        if (x > vport->width || y > vport->height) {
603
        if (x > vport->width || y > vport->height) {
556
            retval = EINVAL;
604
            retval = EINVAL;
557
            break;
605
            break;
558
        }
606
        }
559
       
607
       
560
        draw_ppm(pixmap, pixmap_size, IPC_GET_ARG1(*call), IPC_GET_ARG2(*call),
608
        ppm_draw(shm, shm_size, IPC_GET_ARG1(*call), IPC_GET_ARG2(*call),
561
             vport->width - x, vport->height - y, putpixel, vp);
609
             vport->width - x, vport->height - y, putpixel, vp);
562
        break;
610
        break;
563
    case FB_DRAW_TEXT_DATA:
611
    case FB_DRAW_TEXT_DATA:
564
        if (!interbuffer) {
612
        if (!interbuffer) {
565
            retval = EINVAL;
613
            retval = EINVAL;
Line 578... Line 626...
578
    if (handled)
626
    if (handled)
579
        ipc_answer_fast(callid, retval, 0, 0);
627
        ipc_answer_fast(callid, retval, 0, 0);
580
    return handled;
628
    return handled;
581
}
629
}
582
 
630
 
583
/** Return first free pixmap */
-
 
584
static 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 */
631
/** Save viewport to pixmap */
595
static int save_vp_to_pixmap(int vp)
632
static int save_vp_to_pixmap(int vp)
596
{
633
{
597
    int pm;
634
    int pm;
598
    pixmap_t *pmap;
635
    pixmap_t *pmap;