📄 scr_x11.c
字号:
/* * 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 1001struct 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 longlookup_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 longPIXELVAL_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_EXPOSUREstatic 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 + -