⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scr_x11.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2000, 2001 Greg Haerr <greg@censoft.com>
 * Copyright (c) 1999 Tony Rogvall <tony@bluetail.com>
 * 	Rewritten to avoid multiple function calls by Greg Haerr
 *      Alpha blending added by Erik Hill
 *      (brought to life in a dark laboratory on a stormy night
 *      in an ancient castle by Dr. Frankenstein)
 *
 * X11 screen driver for Microwindows
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <assert.h>
#include "device.h"
#include "fb.h"
#include "genmem.h"
#include "genfont.h"

/* define the Casio E-15 (allow override) */
#ifdef SCREEN_E15
#ifndef SCREEN_WIDTH
#define    SCREEN_WIDTH  200
#endif
#ifndef SCREEN_HEIGHT
#define    SCREEN_HEIGHT 320
#endif
#ifndef SCREEN_DEPTH
#define    SCREEN_DEPTH  4
#endif
#ifndef MWPIXEL_FORMAT
#define    MWPIXEL_FORMAT MWPF_PALETTE
#endif
#endif

#ifndef SCREEN_WIDTH
#define SCREEN_WIDTH 200
#endif

#ifndef SCREEN_HEIGHT
#define SCREEN_HEIGHT 320
#endif

#ifndef SCREEN_DEPTH
#define SCREEN_DEPTH 4
#endif

#ifndef MWPIXEL_FORMAT
#if SCREEN_DEPTH <= 8
#define MWPIXEL_FORMAT MWPF_PALETTE
#elif SCREEN_DEPTH == 16
#define MWPIXEL_FORMAT MWPF_TRUECOLOR565
#elif SCREEN_DEPTH == 15
#define MWPIXEL_FORMAT MWPF_TRUECOLOR555
#elif SCREEN_DEPTH == 24
#define MWPIXEL_FORMAT MWPF_TRUECOLOR888
#elif SCREEN_DEPTH == 32
#define MWPIXEL_FORMAT MWPF_TRUECOLOR0888
#else
#error "bad screen depth"
#endif
#endif


/* specific x11 driver entry points*/
static PSD  X11_open(PSD psd);
static void X11_close(PSD psd);
static void X11_getscreeninfo(PSD psd,PMWSCREENINFO psi);
static void X11_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);
static void X11_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);
static MWPIXELVAL X11_readpixel(PSD psd,MWCOORD x, MWCOORD y);
static void X11_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);
static void X11_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);
static void X11_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2,MWPIXELVAL c);
static void X11_blit(PSD dstpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h,
		     PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op);
static void X11_preselect(PSD psd);

SCREENDEVICE	scrdev = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
	X11_open,
	X11_close,
	X11_getscreeninfo,
	X11_setpalette,
	X11_drawpixel,
	X11_readpixel,
	X11_drawhline,
	X11_drawvline,
	X11_fillrect,
	gen_fonts,
	X11_blit,
	X11_preselect,
	NULL,			/* DrawArea*/
	NULL,			/* SetIOPermissions*/
	gen_allocatememgc,
	fb_mapmemgc,
	gen_freememgc,
	NULL,			/* StretchBlit subdriver*/
	NULL			/* SetPortrait*/
};

/* called from keyboard/mouse/screen */
Display*     x11_dpy;
int          x11_scr;
Visual*      x11_vis;
Colormap     x11_colormap;
Window       x11_win;
GC           x11_gc;
unsigned int x11_event_mask;

static int   x11_colormap_installed = 0;
static SCREENDEVICE savebits;	/* permanent offscreen drawing buffer*/

DEFINE_applyOpR			/* define inline rop calculator*/

/* Color cache for true color lookups
** FIXME: for 24 bit i belive we could do the pixel direct but...
*/

#define COLOR_CACHE_SIZE 1001
struct color_cache {
	int    		init;  /* 1 if first use */
	unsigned short	r;
	unsigned short 	g;
	unsigned short 	b;
	XColor 		c;
};
static struct color_cache ccache[COLOR_CACHE_SIZE];

/* color palette for color indexe */
static XColor       x11_palette[256];
static int          x11_pal_max = 0;
static int          x11_pixtype;

static unsigned long
lookup_color(unsigned short r, unsigned short g, unsigned short b)
{
    int ix = ((r << 16) + (g << 8) + b) % COLOR_CACHE_SIZE;

    if (ccache[ix].init ||
	(ccache[ix].r != r) || (ccache[ix].g != g) || (ccache[ix].b != b)) {
	char spec[20];
	XColor exact;
	XColor def;

	ccache[ix].init = 0;
	ccache[ix].r = r;
	ccache[ix].g = g;
	ccache[ix].b = b;
	sprintf(spec, "#%02x%02x%02x", r, g, b);
	XLookupColor(x11_dpy, x11_colormap, spec, &exact, &def);
	XAllocColor(x11_dpy, x11_colormap, &def);
	ccache[ix].c = def;

	/* DPRINTF("lookup: exact(%d,%d,%d) = %d, def(%d,%d,%d)=%d\n",
	   exact.red>>8, exact.green>>8, exact.blue>>8, exact.pixel,
	   def.red>>8, def.green>>8, def.blue>>8, def.pixel); */
    }
    return (unsigned long) ccache[ix].c.pixel;
}

static unsigned long
PIXELVAL_to_pixel(MWPIXELVAL c, int type)
{
	assert (type == MWPIXEL_FORMAT);
	
#if (MWPIXEL_FORMAT == MWPF_TRUECOLOR0888) || (MWPIXEL_FORMAT == MWPF_TRUECOLOR888)
	/* calc truecolor conversions directly*/
	if (x11_vis->class >= TrueColor) {
		switch (x11_vis->bits_per_rgb) {
		case 8:
			return c;
		case 6:
			return RGB2PIXEL565(PIXEL888RED(c), PIXEL888GREEN(c),
				PIXEL888BLUE(c));
		case 5:
			return RGB2PIXEL555(PIXEL888RED(c), PIXEL888GREEN(c),
				PIXEL888BLUE(c));
		case 3:
		case 2:
			return RGB2PIXEL332(PIXEL888RED(c), PIXEL888GREEN(c),
				PIXEL888BLUE(c));
		}
	}
	return lookup_color(PIXEL888RED(c), PIXEL888GREEN(c), PIXEL888BLUE(c));
#endif
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR565
	/* calc truecolor conversions directly*/
	if (x11_vis->class >= TrueColor) {
		switch (x11_vis->bits_per_rgb) {
		case 8:
			return RGB2PIXEL888(PIXEL565RED(c)<<3,
				PIXEL565GREEN(c)<<2, PIXEL565BLUE(c)<<3);
		case 6:
		case 5:
			return c;
		case 3:
		case 2:
			return RGB2PIXEL332(PIXEL565RED(c)<<3,
				PIXEL565GREEN(c)<<2, PIXEL565BLUE(c)<<3);
		}
	}
	return lookup_color(PIXEL565RED(c)<<3, PIXEL565GREEN(c)<<2,
			PIXEL565BLUE(c)<<3);
#endif
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR555
	/* calc truecolor conversions directly*/
	if (x11_vis->class >= TrueColor) {
		switch (x11_vis->bits_per_rgb) {
		case 8:
			return RGB2PIXEL888(PIXEL555RED(c)<<3,
				PIXEL555GREEN(c)<<3, PIXEL555BLUE(c)<<3);
		case 6:
		case 5:
			return c;
		case 3:
		case 2:
			return RGB2PIXEL332(PIXEL555RED(c)<<3,
				PIXEL555GREEN(c)<<3, PIXEL555BLUE(c)<<3);
		}
	}
	return lookup_color(PIXEL555RED(c)<<3, PIXEL555GREEN(c)<<3,
			PIXEL555BLUE(c)<<3);
#endif
#if MWPIXEL_FORMAT == MWPF_TRUECOLOR332
	/* calc truecolor conversions directly*/
	if (x11_vis->class >= TrueColor) {
		switch (x11_vis->bits_per_rgb) {
		case 8:
			return RGB2PIXEL888(PIXEL332RED(c)<<5,
				PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
		case 6:
			return RGB2PIXEL565(PIXEL332RED(c)<<5,
				PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
		case 5:
			return RGB2PIXEL555(PIXEL332RED(c)<<5,
				PIXEL332GREEN(c)<<5, PIXEL332BLUE(c)<<6);
		case 3:
		case 2:
			return c;
		}
	}
	return lookup_color(PIXEL332RED(c)<<5, PIXEL332GREEN(c)<<5,
			PIXEL332BLUE(c)<<6);
#endif
#if MWPIXEL_FORMAT == MWPF_PALETTE
	if (c > x11_pal_max) {
	    DPRINTF("Warning: palette index out of range (%ld)\n", c);
	    return 0;
	}
	return x11_palette[c].pixel;
#endif
#if 0
    switch(type) {
    case MWPF_TRUECOLOR0888:
    case MWPF_TRUECOLOR888:
	r = PIXEL888RED(c);
	g = PIXEL888GREEN(c);
	b = PIXEL888BLUE(c);
	return lookup_color(r, g, b);
	
    case MWPF_TRUECOLOR565:
	r = PIXEL565RED(c) << 3;
	g = PIXEL565GREEN(c) << 2;
	b = PIXEL565BLUE(c) << 3;
	return lookup_color(r, g, b);

    case MWPF_TRUECOLOR555:
	r = PIXEL555RED(c) << 3;
	g = PIXEL555GREEN(c) << 3;
	b = PIXEL555BLUE(c) << 3;
	return lookup_color(r, g, b);

    case MWPF_TRUECOLOR332:
	r = PIXEL332RED(c) << 5;
	g = PIXEL332GREEN(c) << 5;
	b = PIXEL332BLUE(c) << 6;
	return lookup_color(r, g, b);

    case MWPF_PALETTE:
	if (c > x11_pal_max) {
	    DPRINTF("Warning: palette index out of range (%ld)\n", c);
	    return 0;
	}
	return x11_palette[c].pixel;
    }
#endif
    return 0;
}


static void set_color(MWPIXELVAL c)
{
    static unsigned long oldc = 0x80000001;

    if (c != oldc) {
        oldc = c;
        XSetForeground(x11_dpy, x11_gc, PIXELVAL_to_pixel(c, x11_pixtype));
    }
}


static void set_mode(int new_mode)
{
    static int old_mode = -1;
    
    if (new_mode != old_mode) {
	int func = GXcopy;
	switch(new_mode) {
	case MWMODE_COPY: 		func = GXcopy; break;
	case MWMODE_XOR: 		func = GXxor; break;
	case MWMODE_OR:  		func = GXor; break;
	case MWMODE_AND: 		func = GXand; break;
	case MWMODE_CLEAR:		func = GXclear; break;
	case MWMODE_SETTO1:		func = GXset; break;
	case MWMODE_EQUIV:		func = GXequiv; break;
	case MWMODE_NOR	:		func = GXnor; break;
	case MWMODE_NAND:		func = GXnand; break;
	case MWMODE_INVERT:		func = GXinvert; break;
	case MWMODE_COPYINVERTED:	func = GXcopyInverted; break;
	case MWMODE_ORINVERTED:		func = GXorInverted; break;
	case MWMODE_ANDINVERTED:	func = GXandInverted; break;
	case MWMODE_ORREVERSE:		func = GXorReverse; break;
	case MWMODE_ANDREVERSE:		func = GXandReverse; break;
	case MWMODE_NOOP:		func = GXnoop; break;
	default: return;
	}
	XSetFunction(x11_dpy, x11_gc, func);
	old_mode = new_mode;
    }
}

#ifdef USE_EXPOSURE
static void _expose(int _x, int _y, int w, int h)
{
  XImage* img;
  int depth = XDefaultDepth(x11_dpy, x11_scr);
  int x = _x, y = _y;
  char* data;
  
  /* allocate buffer */
  if (depth >= 24)
    data = malloc(w*4*h);
  else if (depth > 8) /* 15, 16 */
    data = malloc(w*2*h);
  else  /* 1,2,4,8 */
    data = malloc((w*depth+7)/8 * h);
  
  /* copy from offscreen to screen */
  img = XCreateImage(x11_dpy, x11_vis, depth, ZPixmap,
		     0, data, w, h, 8, 0);
  for (y = _y; y < h + _y; y++) {
    for (x = _x; x < w + _x; x++) {
      MWPIXELVAL c = savebits.ReadPixel(&savebits,x,y);
      unsigned long pixel = PIXELVAL_to_pixel(c, savebits.pixtype);
      XPutPixel(img, x - _x, y - _y, pixel);
    }
  }
  
  XPutImage(x11_dpy, x11_win, x11_gc, img, 0, 0, _x, _y, w, h);
  XDestroyImage(img);
}
#endif

/* called from mou_x11 (handels x11_event_mask events) */
void x11_handle_event(XEvent* ev)
{
    static int inited = 0;

    if (ev->type == ColormapNotify) {
	if (ev->xcolormap.window == x11_win) {
	    if (ev->xcolormap.state == ColormapInstalled) {
		DPRINTF("colormap uninstalled\n"); 
		x11_colormap_installed = 0;
	    }
	    else if (ev->xcolormap.state == ColormapInstalled) {
		x11_colormap_installed = 1;
		DPRINTF("colormap installed\n");
	    }
	}
    }
    else if (ev->type == FocusIn) {
	if (!x11_colormap_installed) {
	    DPRINTF("setting colormap\n");
	    XInstallColormap(x11_dpy, x11_colormap);
	    inited = 1;
	}
    }
    else if(ev->type == MappingNotify) {
	DPRINTF("Refreshing keyboard mapping\n");
	XRefreshKeyboardMapping(&ev->xmapping);
    }
#if 0
    else if (ev->type == EnterNotify) {
	    if(inited)
	    GdShowCursor(&scrdev);
    } else if (ev->type == LeaveNotify) {
	    if(inited)
	    GdHideCursor(&scrdev);
    }
#endif

#ifdef USE_EXPOSURE
    else if(ev->type == Expose) {
      _expose(ev->xexpose.x,ev->xexpose.y, ev->xexpose.width,ev->xexpose.height);
    }
#endif
}


static int x11_error(Display* dpy, XErrorEvent* ev)
{
    char err_string[256];

    XGetErrorText(dpy, ev->error_code, err_string, 256);
    EPRINTF("X11 error: %s\n", err_string);
    return 0;
}

char* classnm[] = { "StaticGray", "GrayScale", "StaticColor",
		    "PseudoColor", "TrueColor", "DirectColor" };

static void show_visual(Visual* v)
{
    char* name = ((v->class < 0) || (v->class > 5)) ? "???" : 
	classnm[v->class];
    DPRINTF("  Visual  class: %s (%d)\n", name, v->class);
    DPRINTF("             id: %ld\n", v->visualid);
    DPRINTF("   bits_per_rgb: %d\n", v->bits_per_rgb);
    DPRINTF("    map_entries: %d\n", v->map_entries);
}

static Visual* select_visual(Display* dpy, int scr)
{
    Visual* vis = XDefaultVisual(dpy, scr);
    Screen* screen = XScreenOfDisplay(dpy, scr);
    int d;

    DPRINTF("XDefaultVisual:\n");
    show_visual(vis);

    DPRINTF("Screen RootDepth: %d\n", screen->root_depth);
    
    DPRINTF("Screen RootVisual\n");
    show_visual(screen->root_visual);
    
    /* print all depths/visuals */

    for (d = 0; d < screen->ndepths; d++) {
	Depth* dp = screen->depths + d;
	int v;
	DPRINTF("Depth: %d\n", dp->depth);
	for (v = 0; v < dp->nvisuals; v++) {
	    DPRINTF("Visual: %d\n", v);
	    show_visual(dp->visuals + v);
	}
    }
    return vis;
}


int x11_setup_display()
{
    static int setup_needed = 1;
    
    if (setup_needed) {
	char* name;
	int i;

	if ((name = getenv("DISPLAY")) == NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -