OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [scr_x11.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 2000, 2001 Greg Haerr <greg@censoft.com>
3
 * Copyright (c) 1999 Tony Rogvall <tony@bluetail.com>
4
 *      Rewritten to avoid multiple function calls by Greg Haerr
5
 *      Alpha blending added by Erik Hill
6
 *      (brought to life in a dark laboratory on a stormy night
7
 *      in an ancient castle by Dr. Frankenstein)
8
 *
9
 * X11 screen driver for Microwindows
10
 */
11
#include <stdio.h>
12
#include <string.h>
13
#include <stdlib.h>
14
#include <X11/Xlib.h>
15
#include <X11/Xutil.h>
16
#include <assert.h>
17
#include "device.h"
18
#include "fb.h"
19
#include "genmem.h"
20
#include "genfont.h"
21
 
22
/* define the Casio E-15 (allow override) */
23
#ifdef SCREEN_E15
24
#ifndef SCREEN_WIDTH
25
#define    SCREEN_WIDTH  200
26
#endif
27
#ifndef SCREEN_HEIGHT
28
#define    SCREEN_HEIGHT 320
29
#endif
30
#ifndef SCREEN_DEPTH
31
#define    SCREEN_DEPTH  4
32
#endif
33
#ifndef MWPIXEL_FORMAT
34
#define    MWPIXEL_FORMAT MWPF_PALETTE
35
#endif
36
#endif
37
 
38
#ifndef SCREEN_WIDTH
39
#define SCREEN_WIDTH 200
40
#endif
41
 
42
#ifndef SCREEN_HEIGHT
43
#define SCREEN_HEIGHT 320
44
#endif
45
 
46
#ifndef SCREEN_DEPTH
47
#define SCREEN_DEPTH 4
48
#endif
49
 
50
#ifndef MWPIXEL_FORMAT
51
#if SCREEN_DEPTH <= 8
52
#define MWPIXEL_FORMAT MWPF_PALETTE
53
#elif SCREEN_DEPTH == 16
54
#define MWPIXEL_FORMAT MWPF_TRUECOLOR565
55
#elif SCREEN_DEPTH == 15
56
#define MWPIXEL_FORMAT MWPF_TRUECOLOR555
57
#elif SCREEN_DEPTH == 24
58
#define MWPIXEL_FORMAT MWPF_TRUECOLOR888
59
#elif SCREEN_DEPTH == 32
60
#define MWPIXEL_FORMAT MWPF_TRUECOLOR0888
61
#else
62
#error "bad screen depth"
63
#endif
64
#endif
65
 
66
 
67
/* specific x11 driver entry points*/
68
static PSD  X11_open(PSD psd);
69
static void X11_close(PSD psd);
70
static void X11_getscreeninfo(PSD psd,PMWSCREENINFO psi);
71
static void X11_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);
72
static void X11_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);
73
static MWPIXELVAL X11_readpixel(PSD psd,MWCOORD x, MWCOORD y);
74
static void X11_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);
75
static void X11_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);
76
static void X11_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2,MWPIXELVAL c);
77
static void X11_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
78
                     PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op);
79
static void X11_preselect(PSD psd);
80
 
81
SCREENDEVICE    scrdev = {
82
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
83
        X11_open,
84
        X11_close,
85
        X11_getscreeninfo,
86
        X11_setpalette,
87
        X11_drawpixel,
88
        X11_readpixel,
89
        X11_drawhline,
90
        X11_drawvline,
91
        X11_fillrect,
92
        gen_fonts,
93
        X11_blit,
94
        X11_preselect,
95
        NULL,                   /* DrawArea*/
96
        NULL,                   /* SetIOPermissions*/
97
        gen_allocatememgc,
98
        fb_mapmemgc,
99
        gen_freememgc,
100
        NULL,                   /* StretchBlit subdriver*/
101
        NULL                    /* SetPortrait*/
102
};
103
 
104
/* called from keyboard/mouse/screen */
105
Display*     x11_dpy;
106
int          x11_scr;
107
Visual*      x11_vis;
108
Colormap     x11_colormap;
109
Window       x11_win;
110
GC           x11_gc;
111
unsigned int x11_event_mask;
112
 
113
static int   x11_colormap_installed = 0;
114
static SCREENDEVICE savebits;   /* permanent offscreen drawing buffer*/
115
 
116
DEFINE_applyOpR                 /* define inline rop calculator*/
117
 
118
/* Color cache for true color lookups
119
** FIXME: for 24 bit i belive we could do the pixel direct but...
120
*/
121
 
122
#define COLOR_CACHE_SIZE 1001
123
struct color_cache {
124
        int             init;  /* 1 if first use */
125
        unsigned short  r;
126
        unsigned short  g;
127
        unsigned short  b;
128
        XColor          c;
129
};
130
static struct color_cache ccache[COLOR_CACHE_SIZE];
131
 
132
/* color palette for color indexe */
133
static XColor       x11_palette[256];
134
static int          x11_pal_max = 0;
135
static int          x11_pixtype;
136
 
137
static unsigned long
138
lookup_color(unsigned short r, unsigned short g, unsigned short b)
139
{
140
    int ix = ((r << 16) + (g << 8) + b) % COLOR_CACHE_SIZE;
141
 
142
    if (ccache[ix].init ||
143
        (ccache[ix].r != r) || (ccache[ix].g != g) || (ccache[ix].b != b)) {
144
        char spec[20];
145
        XColor exact;
146
        XColor def;
147
 
148
        ccache[ix].init = 0;
149
        ccache[ix].r = r;
150
        ccache[ix].g = g;
151
        ccache[ix].b = b;
152
        sprintf(spec, "#%02x%02x%02x", r, g, b);
153
        XLookupColor(x11_dpy, x11_colormap, spec, &exact, &def);
154
        XAllocColor(x11_dpy, x11_colormap, &def);
155
        ccache[ix].c = def;
156
 
157
        /* DPRINTF("lookup: exact(%d,%d,%d) = %d, def(%d,%d,%d)=%d\n",
158
           exact.red>>8, exact.green>>8, exact.blue>>8, exact.pixel,
159
           def.red>>8, def.green>>8, def.blue>>8, def.pixel); */
160
    }
161
    return (unsigned long) ccache[ix].c.pixel;
162
}
163
 
164
static unsigned long
165
PIXELVAL_to_pixel(MWPIXELVAL c, int type)
166
{
167
        assert (type == MWPIXEL_FORMAT);
168
 
169
#if (MWPIXEL_FORMAT == MWPF_TRUECOLOR0888) || (MWPIXEL_FORMAT == MWPF_TRUECOLOR888)
170
        /* calc truecolor conversions directly*/
171
        if (x11_vis->class >= TrueColor) {
172
                switch (x11_vis->bits_per_rgb) {
173
                case 8:
174
                        return c;
175
                case 6:
176
                        return RGB2PIXEL565(PIXEL888RED(c), PIXEL888GREEN(c),
177
                                PIXEL888BLUE(c));
178
                case 5:
179
                        return RGB2PIXEL555(PIXEL888RED(c), PIXEL888GREEN(c),
180
                                PIXEL888BLUE(c));
181
                case 3:
182
                case 2:
183
                        return RGB2PIXEL332(PIXEL888RED(c), PIXEL888GREEN(c),
184
                                PIXEL888BLUE(c));
185
                }
186
        }
187
        return lookup_color(PIXEL888RED(c), PIXEL888GREEN(c), PIXEL888BLUE(c));
188
#endif
189
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR565
190
        /* calc truecolor conversions directly*/
191
        if (x11_vis->class >= TrueColor) {
192
                switch (x11_vis->bits_per_rgb) {
193
                case 8:
194
                        return RGB2PIXEL888(PIXEL565RED(c)<<3,
195
                                PIXEL565GREEN(c)<<2, PIXEL565BLUE(c)<<3);
196
                case 6:
197
                case 5:
198
                        return c;
199
                case 3:
200
                case 2:
201
                        return RGB2PIXEL332(PIXEL565RED(c)<<3,
202
                                PIXEL565GREEN(c)<<2, PIXEL565BLUE(c)<<3);
203
                }
204
        }
205
        return lookup_color(PIXEL565RED(c)<<3, PIXEL565GREEN(c)<<2,
206
                        PIXEL565BLUE(c)<<3);
207
#endif
208
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR555
209
        /* calc truecolor conversions directly*/
210
        if (x11_vis->class >= TrueColor) {
211
                switch (x11_vis->bits_per_rgb) {
212
                case 8:
213
                        return RGB2PIXEL888(PIXEL555RED(c)<<3,
214
                                PIXEL555GREEN(c)<<3, PIXEL555BLUE(c)<<3);
215
                case 6:
216
                case 5:
217
                        return c;
218
                case 3:
219
                case 2:
220
                        return RGB2PIXEL332(PIXEL555RED(c)<<3,
221
                                PIXEL555GREEN(c)<<3, PIXEL555BLUE(c)<<3);
222
                }
223
        }
224
        return lookup_color(PIXEL555RED(c)<<3, PIXEL555GREEN(c)<<3,
225
                        PIXEL555BLUE(c)<<3);
226
#endif
227
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR332
228
        /* calc truecolor conversions directly*/
229
        if (x11_vis->class >= TrueColor) {
230
                switch (x11_vis->bits_per_rgb) {
231
                case 8:
232
                        return RGB2PIXEL888(PIXEL332RED(c)<<5,
233
                                PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
234
                case 6:
235
                        return RGB2PIXEL565(PIXEL332RED(c)<<5,
236
                                PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
237
                case 5:
238
                        return RGB2PIXEL555(PIXEL332RED(c)<<5,
239
                                PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
240
                case 3:
241
                case 2:
242
                        return c;
243
                }
244
        }
245
        return lookup_color(PIXEL332RED(c)<<5, PIXEL332GREEN(c)<<5,
246
                        PIXEL332BLUE(c)<<6);
247
#endif
248
#if MWPIXEL_FORMAT == MWPF_PALETTE
249
        if (c > x11_pal_max) {
250
            DPRINTF("Warning: palette index out of range (%ld)\n", c);
251
            return 0;
252
        }
253
        return x11_palette[c].pixel;
254
#endif
255
#if 0
256
    switch(type) {
257
    case MWPF_TRUECOLOR0888:
258
    case MWPF_TRUECOLOR888:
259
        r = PIXEL888RED(c);
260
        g = PIXEL888GREEN(c);
261
        b = PIXEL888BLUE(c);
262
        return lookup_color(r, g, b);
263
 
264
    case MWPF_TRUECOLOR565:
265
        r = PIXEL565RED(c) << 3;
266
        g = PIXEL565GREEN(c) << 2;
267
        b = PIXEL565BLUE(c) << 3;
268
        return lookup_color(r, g, b);
269
 
270
    case MWPF_TRUECOLOR555:
271
        r = PIXEL555RED(c) << 3;
272
        g = PIXEL555GREEN(c) << 3;
273
        b = PIXEL555BLUE(c) << 3;
274
        return lookup_color(r, g, b);
275
 
276
    case MWPF_TRUECOLOR332:
277
        r = PIXEL332RED(c) << 5;
278
        g = PIXEL332GREEN(c) << 5;
279
        b = PIXEL332BLUE(c) << 6;
280
        return lookup_color(r, g, b);
281
 
282
    case MWPF_PALETTE:
283
        if (c > x11_pal_max) {
284
            DPRINTF("Warning: palette index out of range (%ld)\n", c);
285
            return 0;
286
        }
287
        return x11_palette[c].pixel;
288
    }
289
#endif
290
    return 0;
291
}
292
 
293
 
294
static void set_color(MWPIXELVAL c)
295
{
296
    static unsigned long oldc = 0x80000001;
297
 
298
    if (c != oldc) {
299
        oldc = c;
300
        XSetForeground(x11_dpy, x11_gc, PIXELVAL_to_pixel(c, x11_pixtype));
301
    }
302
}
303
 
304
 
305
static void set_mode(int new_mode)
306
{
307
    static int old_mode = -1;
308
 
309
    if (new_mode != old_mode) {
310
        int func = GXcopy;
311
        switch(new_mode) {
312
        case MWMODE_COPY:               func = GXcopy; break;
313
        case MWMODE_XOR:                func = GXxor; break;
314
        case MWMODE_OR:                 func = GXor; break;
315
        case MWMODE_AND:                func = GXand; break;
316
        case MWMODE_CLEAR:              func = GXclear; break;
317
        case MWMODE_SETTO1:             func = GXset; break;
318
        case MWMODE_EQUIV:              func = GXequiv; break;
319
        case MWMODE_NOR :               func = GXnor; break;
320
        case MWMODE_NAND:               func = GXnand; break;
321
        case MWMODE_INVERT:             func = GXinvert; break;
322
        case MWMODE_COPYINVERTED:       func = GXcopyInverted; break;
323
        case MWMODE_ORINVERTED:         func = GXorInverted; break;
324
        case MWMODE_ANDINVERTED:        func = GXandInverted; break;
325
        case MWMODE_ORREVERSE:          func = GXorReverse; break;
326
        case MWMODE_ANDREVERSE:         func = GXandReverse; break;
327
        case MWMODE_NOOP:               func = GXnoop; break;
328
        default: return;
329
        }
330
        XSetFunction(x11_dpy, x11_gc, func);
331
        old_mode = new_mode;
332
    }
333
}
334
 
335
#ifdef USE_EXPOSURE
336
static void _expose(int _x, int _y, int w, int h)
337
{
338
  XImage* img;
339
  int depth = XDefaultDepth(x11_dpy, x11_scr);
340
  int x = _x, y = _y;
341
  char* data;
342
 
343
  /* allocate buffer */
344
  if (depth >= 24)
345
    data = malloc(w*4*h);
346
  else if (depth > 8) /* 15, 16 */
347
    data = malloc(w*2*h);
348
  else  /* 1,2,4,8 */
349
    data = malloc((w*depth+7)/8 * h);
350
 
351
  /* copy from offscreen to screen */
352
  img = XCreateImage(x11_dpy, x11_vis, depth, ZPixmap,
353
                     0, data, w, h, 8, 0);
354
  for (y = _y; y < h + _y; y++) {
355
    for (x = _x; x < w + _x; x++) {
356
      MWPIXELVAL c = savebits.ReadPixel(&savebits,x,y);
357
      unsigned long pixel = PIXELVAL_to_pixel(c, savebits.pixtype);
358
      XPutPixel(img, x - _x, y - _y, pixel);
359
    }
360
  }
361
 
362
  XPutImage(x11_dpy, x11_win, x11_gc, img, 0, 0, _x, _y, w, h);
363
  XDestroyImage(img);
364
}
365
#endif
366
 
367
/* called from mou_x11 (handels x11_event_mask events) */
368
void x11_handle_event(XEvent* ev)
369
{
370
    static int inited = 0;
371
 
372
    if (ev->type == ColormapNotify) {
373
        if (ev->xcolormap.window == x11_win) {
374
            if (ev->xcolormap.state == ColormapInstalled) {
375
                DPRINTF("colormap uninstalled\n");
376
                x11_colormap_installed = 0;
377
            }
378
            else if (ev->xcolormap.state == ColormapInstalled) {
379
                x11_colormap_installed = 1;
380
                DPRINTF("colormap installed\n");
381
            }
382
        }
383
    }
384
    else if (ev->type == FocusIn) {
385
        if (!x11_colormap_installed) {
386
            DPRINTF("setting colormap\n");
387
            XInstallColormap(x11_dpy, x11_colormap);
388
            inited = 1;
389
        }
390
    }
391
    else if(ev->type == MappingNotify) {
392
        DPRINTF("Refreshing keyboard mapping\n");
393
        XRefreshKeyboardMapping(&ev->xmapping);
394
    }
395
#if 0
396
    else if (ev->type == EnterNotify) {
397
            if(inited)
398
            GdShowCursor(&scrdev);
399
    } else if (ev->type == LeaveNotify) {
400
            if(inited)
401
            GdHideCursor(&scrdev);
402
    }
403
#endif
404
 
405
#ifdef USE_EXPOSURE
406
    else if(ev->type == Expose) {
407
      _expose(ev->xexpose.x,ev->xexpose.y, ev->xexpose.width,ev->xexpose.height);
408
    }
409
#endif
410
}
411
 
412
 
413
static int x11_error(Display* dpy, XErrorEvent* ev)
414
{
415
    char err_string[256];
416
 
417
    XGetErrorText(dpy, ev->error_code, err_string, 256);
418
    EPRINTF("X11 error: %s\n", err_string);
419
    return 0;
420
}
421
 
422
char* classnm[] = { "StaticGray", "GrayScale", "StaticColor",
423
                    "PseudoColor", "TrueColor", "DirectColor" };
424
 
425
static void show_visual(Visual* v)
426
{
427
    char* name = ((v->class < 0) || (v->class > 5)) ? "???" :
428
        classnm[v->class];
429
    DPRINTF("  Visual  class: %s (%d)\n", name, v->class);
430
    DPRINTF("             id: %ld\n", v->visualid);
431
    DPRINTF("   bits_per_rgb: %d\n", v->bits_per_rgb);
432
    DPRINTF("    map_entries: %d\n", v->map_entries);
433
}
434
 
435
static Visual* select_visual(Display* dpy, int scr)
436
{
437
    Visual* vis = XDefaultVisual(dpy, scr);
438
    Screen* screen = XScreenOfDisplay(dpy, scr);
439
    int d;
440
 
441
    DPRINTF("XDefaultVisual:\n");
442
    show_visual(vis);
443
 
444
    DPRINTF("Screen RootDepth: %d\n", screen->root_depth);
445
 
446
    DPRINTF("Screen RootVisual\n");
447
    show_visual(screen->root_visual);
448
 
449
    /* print all depths/visuals */
450
 
451
    for (d = 0; d < screen->ndepths; d++) {
452
        Depth* dp = screen->depths + d;
453
        int v;
454
        DPRINTF("Depth: %d\n", dp->depth);
455
        for (v = 0; v < dp->nvisuals; v++) {
456
            DPRINTF("Visual: %d\n", v);
457
            show_visual(dp->visuals + v);
458
        }
459
    }
460
    return vis;
461
}
462
 
463
 
464
int x11_setup_display()
465
{
466
    static int setup_needed = 1;
467
 
468
    if (setup_needed) {
469
        char* name;
470
        int i;
471
 
472
        if ((name = getenv("DISPLAY")) == NULL)
473
            name = ":0";
474
        if ((x11_dpy = XOpenDisplay(name)) == NULL)
475
            return -1;
476
 
477
        XSetErrorHandler(x11_error);
478
 
479
        x11_scr = XDefaultScreen(x11_dpy);
480
        x11_vis = select_visual(x11_dpy, x11_scr);
481
 
482
        x11_gc = XDefaultGC(x11_dpy, x11_scr);
483
 
484
        for (i = 0; i < COLOR_CACHE_SIZE; i++)
485
            ccache[i].init = 1;
486
 
487
        set_mode(gr_mode);
488
 
489
        setup_needed = 0;
490
        return 0;
491
    }
492
    return 0;
493
}
494
 
495
/* Note: only single screen */
496
static PSD
497
X11_open(PSD psd)
498
{
499
    XSetWindowAttributes attr;
500
    Pixmap cur_empty;
501
    unsigned long valuemask;
502
    unsigned int  event_mask;
503
    XColor color;
504
    Cursor cursor;
505
    /*XEvent ev;*/
506
    PSUBDRIVER subdriver;
507
    int size, linelen;
508
 
509
    if (x11_setup_display() < 0)
510
        return NULL;
511
 
512
    x11_event_mask = ColormapChangeMask | FocusChangeMask;
513
/*x11_event_mask |= EnterWindowMask | LeaveWindowMask;*/
514
 
515
    event_mask = x11_event_mask |
516
                     ExposureMask |
517
                     KeyPressMask |       /* handled by kbd_x11 */
518
                     KeyReleaseMask |     /* handled by kbd_x11 */
519
                     ButtonPressMask |    /* handled by mou_x11 */
520
                     ButtonReleaseMask |  /* handled by mou_x11 */
521
                     PointerMotionMask;   /* handled by mou_x11 */
522
 
523
 
524
#ifdef USE_EXPOSURE
525
    valuemask = CWSaveUnder |
526
      CWEventMask;
527
#else
528
    valuemask = CWSaveUnder |
529
      CWEventMask |
530
      CWBackingStore;
531
#endif
532
 
533
    attr.backing_store = Always;     /* auto expose */
534
    attr.save_under    = True;       /* popups ... */
535
    attr.event_mask    = event_mask;
536
 
537
    x11_win = XCreateWindow(x11_dpy,
538
                            XDefaultRootWindow(x11_dpy),
539
                            100,             /* x */
540
                            100,             /* y */
541
                            SCREEN_WIDTH,    /* width */
542
                            SCREEN_HEIGHT,   /* height */
543
                            2,               /* border */
544
                            CopyFromParent,  /* depth */
545
                            CopyFromParent,  /* depth */
546
                            x11_vis,         /* Visual */
547
                            valuemask,       /* valuemask */
548
                            &attr            /* attributes */
549
                            );
550
 
551
    /* Create a new empty colormap, the colormap will be
552
     ** filled by lookup_color in the case of
553
     ** GrayScale, PseduoColor and DirectColor,
554
     ** or looked up in the case of
555
     **  StaticGray, StaticColor and TrueColor
556
     */
557
 
558
    x11_colormap = XDefaultColormap(x11_dpy, x11_scr);
559
    if (x11_vis->class & 1)
560
        x11_colormap = XCopyColormapAndFree(x11_dpy, x11_colormap);
561
 
562
    /* If you need more colors, create it from scratch
563
     *
564
     * x11_colormap = XCreateColormap(x11_dpy, x11_win, x11_vis,
565
     * AllocNone);
566
     *
567
     * or: for same visual etc.
568
     * x11_colormap = XCopyColormapAndFree(x11_dpy, x11_colormap);
569
     */
570
 
571
    /* Create an empty (invisible) cursor */
572
    cur_empty = XCreateBitmapFromData(x11_dpy, x11_win, "\0", 1, 1);
573
    cursor = XCreatePixmapCursor(x11_dpy, cur_empty, cur_empty,
574
                                 &color, &color, 0, 0);
575
    XDefineCursor(x11_dpy, x11_win, cursor);
576
    XStoreName(x11_dpy, x11_win, "Microwindows");
577
 
578
    XMapWindow(x11_dpy, x11_win);
579
    XFlush(x11_dpy);
580
 
581
    /*
582
     * The following code insures that the colormap
583
     * is installed before display
584
     */
585
#if 0
586
    XMaskEvent(x11_dpy, x11_event_mask, &ev);
587
    XPutBackEvent(x11_dpy, &ev);
588
#endif
589
    XInstallColormap(x11_dpy, x11_colormap);
590
 
591
    psd->xres    = psd->xvirtres    = SCREEN_WIDTH;
592
    psd->yres    = psd->yvirtres    = SCREEN_HEIGHT;
593
    psd->linelen = SCREEN_WIDTH;
594
    psd->planes  = 1;
595
    psd->pixtype = x11_pixtype = MWPIXEL_FORMAT;
596
    switch(psd->pixtype) {
597
    case MWPF_PALETTE:
598
            psd->bpp = SCREEN_DEPTH;
599
            break;
600
    case MWPF_TRUECOLOR0888:
601
    default:
602
            psd->bpp = 32;
603
            break;
604
    case MWPF_TRUECOLOR888:
605
            psd->bpp = 24;
606
            break;
607
    case MWPF_TRUECOLOR565:
608
    case MWPF_TRUECOLOR555:
609
            psd->bpp = 16;
610
            break;
611
    case MWPF_TRUECOLOR332:
612
            psd->bpp = 8;
613
            break;
614
    }
615
 
616
    /* Calculate the correct linelen here */
617
 
618
    GdCalcMemGCAlloc(psd, psd->xres, psd->yres, psd->planes,
619
                     psd->bpp, &size, &psd->linelen);
620
 
621
    psd->ncolors = psd->bpp >= 24? (1 << 24): (1 << psd->bpp);
622
    psd->flags   = PSF_SCREEN | PSF_HAVEBLIT;
623
    psd->size = 0;
624
    psd->addr = NULL;
625
    psd->portrait = MWPORTRAIT_NONE;
626
 
627
    /* create permanent savebits memory device from screen device*/
628
    savebits = *psd;
629
    savebits.flags = PSF_MEMORY | PSF_HAVEBLIT;
630
 
631
    /* select a fb subdriver matching our planes and bpp*/
632
    subdriver = select_fb_subdriver(&savebits);
633
    if (!subdriver)
634
            return NULL;
635
 
636
    /* calc size and linelen of savebits alloc*/
637
    /* JHC - Is this redundant now?? */
638
 
639
    GdCalcMemGCAlloc(&savebits, savebits.xvirtres, savebits.yvirtres, 0, 0,
640
                &size, &linelen);
641
    savebits.linelen = linelen;
642
    savebits.size = size;
643
    if ((savebits.addr = malloc(size)) == NULL)
644
        return NULL;
645
 
646
    set_subdriver(&savebits, subdriver, TRUE);
647
 
648
 
649
    /* set X11 psd to savebits memaddr for screen->offscreen blits...*/
650
    psd->addr = savebits.addr;
651
 
652
    return psd;
653
}
654
 
655
static void
656
X11_close(PSD psd)
657
{
658
    /* free savebits memory*/
659
    free(savebits.addr);
660
 
661
    XCloseDisplay(x11_dpy);
662
}
663
 
664
 
665
static void
666
X11_getscreeninfo(PSD psd,PMWSCREENINFO psi)
667
{
668
    psi->rows = psd->yvirtres;
669
    psi->cols = psd->xvirtres;
670
    psi->planes = psd->planes;
671
    psi->bpp = psd->bpp;
672
    psi->ncolors = psd->ncolors;
673
    psi->portrait = psd->portrait;
674
    psi->fonts = NUMBER_FONTS;
675
    psi->xdpcm = (DisplayWidth(x11_dpy,x11_scr)*10)/
676
            DisplayWidthMM(x11_dpy,x11_scr);
677
    psi->ydpcm = (DisplayHeight(x11_dpy,x11_scr)*10)/
678
            DisplayHeightMM(x11_dpy,x11_scr);
679
 
680
        psi->fbdriver = FALSE;  /* not running fb driver, no direct map*/
681
        psi->pixtype = psd->pixtype;
682
        switch (psd->pixtype) {
683
        case MWPF_TRUECOLOR0888:
684
        case MWPF_TRUECOLOR888:
685
                psi->rmask      = 0xff0000;
686
                psi->gmask      = 0x00ff00;
687
                psi->bmask      = 0x0000ff;
688
                break;
689
        case MWPF_TRUECOLOR565:
690
                psi->rmask      = 0xf800;
691
                psi->gmask      = 0x07e0;
692
                psi->bmask      = 0x001f;
693
                break;
694
        case MWPF_TRUECOLOR555:
695
                psi->rmask      = 0x7c00;
696
                psi->gmask      = 0x03e0;
697
                psi->bmask      = 0x001f;
698
                break;
699
        case MWPF_TRUECOLOR332:
700
                psi->rmask      = 0xe0;
701
                psi->gmask      = 0x1c;
702
                psi->bmask      = 0x03;
703
                break;
704
        case MWPF_PALETTE:
705
        default:
706
                psi->rmask      = 0xff;
707
                psi->gmask      = 0xff;
708
                psi->bmask      = 0xff;
709
                break;
710
        }
711
}
712
 
713
static void
714
X11_setpalette(PSD psd, int first, int count, MWPALENTRY *pal)
715
{
716
    int i;
717
    int n;
718
 
719
    for (i = 0; i < count; i++) {
720
        char spec[20];
721
        unsigned short r, g, b;
722
        XColor exact;
723
        XColor def;
724
 
725
        r = pal[i].r;
726
        g = pal[i].g;
727
        b = pal[i].b;
728
        sprintf(spec, "#%02x%02x%02x", r, g, b);
729
        XLookupColor(x11_dpy, x11_colormap, spec, &exact, &def);
730
        XAllocColor(x11_dpy, x11_colormap, &def);
731
         /* DPRINTF("lookup: exact(%d,%d,%d) = %d, def(%d,%d,%d)=%d\n",
732
           exact.red, exact.green, exact.blue, exact.pixel,
733
           def.red, def.green, def.blue, def.pixel); */
734
        x11_palette[first+i] = def;
735
    }
736
    n = first + count - 1;
737
    if (n > x11_pal_max)
738
        x11_pal_max = n;
739
}
740
 
741
 
742
static void
743
X11_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
744
{
745
        set_color(c);
746
        set_mode(gr_mode);
747
        XDrawPoint(x11_dpy, x11_win, x11_gc, x, y);
748
 
749
        /* draw savebits for readpixel or blit*/
750
        savebits.DrawPixel(&savebits, x, y, c);
751
}
752
 
753
static MWPIXELVAL
754
X11_readpixel(PSD psd, MWCOORD x, MWCOORD y)
755
{
756
        /* read savebits for pixel value, rather than ask X11*/
757
        return savebits.ReadPixel(&savebits,x,y);
758
}
759
 
760
static void
761
X11_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
762
{
763
        set_color(c);
764
        set_mode(gr_mode);
765
        XDrawLine(x11_dpy, x11_win, x11_gc, x1, y, x2, y);
766
 
767
        /* draw savebits for readpixel or blit*/
768
        savebits.DrawHorzLine(&savebits, x1, x2, y, c);
769
}
770
 
771
static void
772
X11_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
773
{
774
        set_color(c);
775
        set_mode(gr_mode);
776
        XDrawLine(x11_dpy, x11_win, x11_gc, x, y1, x, y2);
777
        savebits.DrawVertLine(&savebits, x, y1, y2, c);
778
}
779
 
780
static void
781
X11_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
782
{
783
        set_color(c);
784
        set_mode(gr_mode);
785
        XFillRectangle(x11_dpy, x11_win, x11_gc, x1, y1, (x2-x1)+1, (y2-y1)+1);
786
 
787
        /* draw savebits for readpixel or blit*/
788
        savebits.FillRect(&savebits, x1, y1, x2, y2, c);
789
}
790
 
791
static void
792
X11_srccopyblit_screen_to_screen(PMWBLITARGS pb)
793
{
794
}
795
 
796
static void
797
X11_blendconstantblit_screen_to_mem(PMWBLITARGS pb)
798
{
799
}
800
 
801
static void
802
X11_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
803
         PSD srcpsd,MWCOORD srcx,MWCOORD srcy, long op)
804
{
805
#if ALPHABLEND
806
    unsigned int alpha;
807
#endif
808
 
809
    set_mode(gr_mode);
810
    if (dstpsd == srcpsd) {
811
        if (dstpsd->flags & PSF_SCREEN) {
812
            XCopyArea(x11_dpy, x11_win, x11_win, x11_gc,
813
                      srcx, srcy, w, h, destx, desty);
814
 
815
            /* update screen savebits as well*/
816
            savebits.Blit(&savebits, destx, desty, w, h,
817
                        &savebits, srcx, srcy, op);
818
        }
819
        else
820
            /* memory to memory blit, use offscreen blitter*/
821
            dstpsd->Blit(dstpsd, destx, desty, w, h, srcpsd, srcx, srcy, op);
822
    }
823
    else if (dstpsd->flags & PSF_SCREEN) {
824
        XImage* img;
825
        int depth = XDefaultDepth(x11_dpy, x11_scr);
826
        int x, y;
827
        char* data;
828
 
829
        /* allocate buffer */
830
        if (depth >= 24)
831
            data = malloc(w*4*h);
832
        else if (depth > 8) /* 15, 16 */
833
            data = malloc(w*2*h);
834
        else  /* 1,2,4,8 */
835
            data = malloc((w*depth+7)/8 * h);
836
 
837
        /* copy from offscreen to screen */
838
        img = XCreateImage(x11_dpy, x11_vis, depth, ZPixmap,
839
                           0, data, w, h, 8, 0);
840
#if ALPHABLEND && (MWPIXEL_FORMAT != MWPF_PALETTE)
841
        if ((op & MWROP_EXTENSION) == MWROP_BLENDCONSTANT) {
842
                alpha = op & 0xff;
843
 
844
                for (y = 0; y < h; y++) {
845
                        for (x = 0; x < w; x++) {
846
                                MWPIXELVAL c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
847
                                MWPIXELVAL cd = dstpsd->ReadPixel(dstpsd,destx+x,desty+y);
848
                                unsigned char nred = ALPHAPIXELRED(c, cd, alpha);
849
                                unsigned char ngreen = ALPHAPIXELGREEN(c, cd, alpha);
850
                                unsigned char nblue = ALPHAPIXELBLUE(c, cd, alpha);
851
                                unsigned long pixel = PIXELVAL_to_pixel(RGB2PIXEL(nred, ngreen, nblue), srcpsd->pixtype);
852
                                XPutPixel(img, x, y, pixel);
853
 
854
                                /* update screen savebits*/
855
                                savebits.DrawPixel(&savebits, destx+x, desty+y, RGB2PIXEL(nred, ngreen, nblue));
856
                        }
857
                }
858
        }
859
        else {
860
                MWPIXELVAL c = 0;
861
                unsigned long pixel;
862
 
863
                for (y = 0; y < h; y++) {
864
                        for (x = 0; x < w; x++) {
865
                                if (op == MWROP_COPY)
866
                                        c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
867
                                else {
868
                                        c = applyOpR(op,
869
                                                srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y),
870
                                                dstpsd->ReadPixel(dstpsd,destx+x,desty+y));
871
                                        pixel = PIXELVAL_to_pixel(c, srcpsd->pixtype);
872
                                        XPutPixel(img, x, y, pixel);
873
                                }
874
                                pixel = PIXELVAL_to_pixel(c, srcpsd->pixtype);
875
                                XPutPixel(img, x, y, pixel);
876
 
877
                                /* update screen savebits*/
878
                                savebits.DrawPixel(&savebits, destx+x, desty+y, c);
879
                        }
880
                }
881
        }
882
#else
883
        for (y = 0; y < h; y++) {
884
            for (x = 0; x < w; x++) {
885
                MWPIXELVAL c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
886
                unsigned long pixel = PIXELVAL_to_pixel(c, srcpsd->pixtype);
887
                XPutPixel(img, x, y, pixel);
888
                /* update screen savebits*/
889
                savebits.DrawPixel(&savebits, destx+x, desty+y, c);
890
            }
891
        }
892
#endif
893
 
894
        XPutImage(x11_dpy, x11_win, x11_gc, img, 0, 0, destx, desty, w, h);
895
        XDestroyImage(img);
896
    }
897
    else if (srcpsd->flags & PSF_SCREEN) {
898
        int x, y;
899
 
900
#if ALPHABLEND && (MWPIXEL_FORMAT != MWPF_PALETTE)
901
        if ((op & MWROP_EXTENSION) == MWROP_BLENDCONSTANT) {
902
                alpha = op & 0xff;
903
 
904
                for (y = 0; y < h; y++) {
905
                        for (x = 0; x < w; x++) {
906
                                MWPIXELVAL c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
907
                                MWPIXELVAL cd = dstpsd->ReadPixel(dstpsd,destx+x,desty+y);
908
                                unsigned char nred = ALPHAPIXELRED(c, cd, alpha);
909
                                unsigned char ngreen = ALPHAPIXELGREEN(c, cd, alpha);
910
                                unsigned char nblue = ALPHAPIXELBLUE(c, cd, alpha);
911
                                dstpsd->DrawPixel(dstpsd, destx+x, desty+y, RGB2PIXEL(nred, ngreen, nblue));
912
                        }
913
                }
914
        }
915
        else {
916
                /* copy from screen to offscreen,
917
                 * emulated by copy from offscreen bits, no alpha
918
                 */
919
                for (y = 0; y < h; y++) {
920
                        for (x = 0; x < w; x++) {
921
                                MWPIXELVAL c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
922
                                dstpsd->DrawPixel(dstpsd, destx+x, desty+y, c);
923
                        }
924
                }
925
        }
926
#else
927
        /* copy from screen to offscreen, emulated by copy from offscreen bits*/
928
        for (y = 0; y < h; y++) {
929
            for (x = 0; x < w; x++) {
930
                MWPIXELVAL c = srcpsd->ReadPixel(srcpsd,srcx+x,srcy+y);
931
                dstpsd->DrawPixel(dstpsd, destx+x, desty+y, c);
932
            }
933
        }
934
#endif
935
    }
936
}
937
 
938
/* perform pre-select() duties*/
939
static void
940
X11_preselect(PSD psd)
941
{
942
        XFlush(x11_dpy);
943
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.