📄 scr_x11.c
字号:
* What we want to do: * * Given the RGB components: * 0 <= r <= 255, * 0 <= g <= 255, * 0 <= b <= 255 * * We need to compute the X11 color, c: * * xr = ((r << 24) >> r_shift) & r_mask; * xg = ((g << 24) >> g_shift) & g_mask; * xb = ((b << 24) >> b_shift) & b_mask; * * c = xr | xg | xb; * * This code computes appropriate values for r/g/b_shift, given * the r/g/b_mask values (which are taken from the X11 Visual). * * * The reason for doing the wierd <<24 before the >>r_shift is * that without it we may have to shift in either direction (<< or * >>). You can't shift by a negative amount, so you end up with * either an "if" (slow!) or two shifts. The <<24 actually has no * cost, since "r" is created using a shift, we just change that * shift. */ x11_r_mask = x11_vis->red_mask; x11_g_mask = x11_vis->green_mask; x11_b_mask = x11_vis->blue_mask; /* Calculate red shift */ mask = x11_r_mask; shift = 0; assert(mask); if (mask) { while ((mask & 0x80000000UL) == 0) { mask <<= 1; shift++; } } x11_r_shift = shift; /* Calculate green shift */ mask = x11_g_mask; shift = 0; assert(mask); if (mask) { while ((mask & 0x80000000UL) == 0) { mask <<= 1; shift++; } } x11_g_shift = shift; /* Calculate blue shift */ mask = x11_b_mask; shift = 0; assert(mask); if (mask) { while ((mask & 0x80000000UL) == 0) { mask <<= 1; shift++; } } x11_b_shift = shift; } else { assert(0); return -1; } x11_gc = XDefaultGC(x11_dpy, x11_scr);#if MWPIXEL_FORMAT != MWPF_PALETTE for (i = 0; i < COLOR_CACHE_SIZE; i++) ccache[i].init = 1;#endif set_mode(gr_mode);#if 0 /* SLOW!!!*/ /* synchronize display - required to simulate framebuffer */ XSynchronize(x11_dpy, True);#endif setup_needed = 0; } return 0;}/* Note: only single screen */static PSDX11_open(PSD psd){ XSetWindowAttributes attr; Pixmap cur_empty; unsigned long valuemask; unsigned int event_mask; XColor color; Cursor cursor; /*XEvent ev; */ PSUBDRIVER subdriver; int size, linelen; XSizeHints *sizehints; if (x11_setup_display() < 0) return NULL; x11_event_mask = ColormapChangeMask | FocusChangeMask; /*x11_event_mask |= EnterWindowMask | LeaveWindowMask;*/ event_mask = x11_event_mask | ExposureMask | KeyPressMask | /* handled by kbd_x11 */ KeyReleaseMask | /* handled by kbd_x11 */ ButtonPressMask | /* handled by mou_x11 */ ButtonReleaseMask | /* handled by mou_x11 */ PointerMotionMask; /* handled by mou_x11 */#ifdef USE_EXPOSURE valuemask = CWSaveUnder | CWEventMask;#else valuemask = CWSaveUnder | CWEventMask | CWBackingStore;#endif attr.backing_store = Always; /* auto expose */ attr.save_under = True; /* popups ... */ attr.event_mask = event_mask;#if 1 /* Patch by Jon to try for 8-bit TrueColor */ x11_colormap = XCreateColormap(x11_dpy, XDefaultRootWindow(x11_dpy), x11_vis, AllocNone); attr.colormap = x11_colormap; valuemask |= CWColormap;#endif x11_win = XCreateWindow(x11_dpy, XDefaultRootWindow(x11_dpy), 100, /* x */ 100, /* y */ x11_width, /* width */ x11_height, /* height */ 2, /* border */ CopyFromParent, /* depth */ InputOutput, /* class */ x11_vis, /* Visual */ valuemask, /* valuemask */ &attr /* attributes */ ); sizehints = XAllocSizeHints(); if (sizehints != NULL) { sizehints->flags = PMinSize | PMaxSize; sizehints->min_width = x11_width; sizehints->min_height = x11_height; sizehints->max_width = x11_width; sizehints->max_height = x11_height; XSetWMNormalHints(x11_dpy, x11_win, sizehints); XFree(sizehints); } x11_depth = XDefaultDepth(x11_dpy, x11_scr); /* Create a new empty colormap, the colormap will be ** filled by lookup_color in the case of ** GrayScale, PseduoColor and DirectColor, ** or looked up in the case of ** StaticGray, StaticColor and TrueColor */#if 0 /* REMOVED by Patch by Jon to try for 8-bit TrueColor */ x11_colormap = XDefaultColormap(x11_dpy, x11_scr); if (x11_vis->class & 1) x11_colormap = XCopyColormapAndFree(x11_dpy, x11_colormap);#endif /* If you need more colors, create it from scratch * * x11_colormap = XCreateColormap(x11_dpy, x11_win, x11_vis, * AllocNone); * * or: for same visual etc. * x11_colormap = XCopyColormapAndFree(x11_dpy, x11_colormap); */ /* Create an empty (invisible) cursor. This is because * Microwindows will draw it's own cursor. */ cur_empty = XCreateBitmapFromData(x11_dpy, x11_win, "\0", 1, 1); cursor = XCreatePixmapCursor(x11_dpy, cur_empty, cur_empty, &color, &color, 0, 0); XDefineCursor(x11_dpy, x11_win, cursor); XStoreName(x11_dpy, x11_win, "Microwindows"); XMapWindow(x11_dpy, x11_win); XFlush(x11_dpy); /* * The following code insures that the colormap * is installed before display */#if 0 XMaskEvent(x11_dpy, x11_event_mask, &ev); XPutBackEvent(x11_dpy, &ev);#endif XInstallColormap(x11_dpy, x11_colormap); psd->xres = psd->xvirtres = x11_width; psd->yres = psd->yvirtres = x11_height; psd->linelen = x11_width; psd->planes = 1; psd->pixtype = MWPIXEL_FORMAT; switch (psd->pixtype) {#if MWPIXEL_FORMAT == MWPF_PALETTE case MWPF_PALETTE: psd->bpp = SCREEN_DEPTH; break;#endif case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR8888: default: psd->bpp = 32; break; case MWPF_TRUECOLOR888: psd->bpp = 24; break; case MWPF_TRUECOLOR565: case MWPF_TRUECOLOR555: psd->bpp = 16; break; case MWPF_TRUECOLOR332: psd->bpp = 8; break; } /* Calculate the correct linelen here */ GdCalcMemGCAlloc(psd, psd->xres, psd->yres, psd->planes, psd->bpp, &size, &psd->linelen); psd->ncolors = psd->bpp >= 24 ? (1 << 24) : (1 << psd->bpp); psd->flags = PSF_SCREEN | PSF_HAVEBLIT; psd->size = 0; psd->addr = NULL; psd->portrait = MWPORTRAIT_NONE; /* create permanent savebits memory device from screen device */ savebits = *psd; savebits.flags = PSF_MEMORY | PSF_HAVEBLIT; /* select a fb subdriver matching our planes and bpp */ subdriver = select_fb_subdriver(&savebits); if (!subdriver) return NULL; /* calc size and linelen of savebits alloc */ GdCalcMemGCAlloc(&savebits, savebits.xvirtres, savebits.yvirtres, 0, 0, &size, &linelen); savebits.linelen = linelen; savebits.size = size; if ((savebits.addr = malloc(size)) == NULL) return NULL; set_subdriver(&savebits, subdriver, TRUE); /* set X11 psd to savebits memaddr for screen->offscreen blits... */ psd->addr = savebits.addr; return psd;}static voidX11_close(PSD psd){ /* free savebits memory */ free(savebits.addr); XCloseDisplay(x11_dpy);}static voidX11_getscreeninfo(PSD psd, PMWSCREENINFO psi){ psi->rows = psd->yvirtres; psi->cols = psd->xvirtres; psi->planes = psd->planes; psi->bpp = psd->bpp; psi->ncolors = psd->ncolors; psi->portrait = psd->portrait; psi->fonts = NUMBER_FONTS; psi->xdpcm = (DisplayWidth(x11_dpy, x11_scr) * 10) / DisplayWidthMM(x11_dpy, x11_scr); psi->ydpcm = (DisplayHeight(x11_dpy, x11_scr) * 10) / DisplayHeightMM(x11_dpy, x11_scr); psi->fbdriver = FALSE; /* not running fb driver, no direct map */ psi->pixtype = psd->pixtype; switch (psd->pixtype) { case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR8888: case MWPF_TRUECOLOR888: psi->rmask = 0xff0000; psi->gmask = 0x00ff00; psi->bmask = 0x0000ff; break; case MWPF_TRUECOLOR565: psi->rmask = 0xf800; psi->gmask = 0x07e0; psi->bmask = 0x001f; break; case MWPF_TRUECOLOR555: psi->rmask = 0x7c00; psi->gmask = 0x03e0; psi->bmask = 0x001f; break; case MWPF_TRUECOLOR332: psi->rmask = 0xe0; psi->gmask = 0x1c; psi->bmask = 0x03; break; case MWPF_PALETTE: default: psi->rmask = 0xff; psi->gmask = 0xff; psi->bmask = 0xff; break; }}static voidX11_setpalette(PSD psd, int first, int count, MWPALENTRY * pal){ int i; int n; for (i = 0; i < count; i++) { char spec[20]; unsigned short r, g, b; XColor exact; XColor def; r = pal[i].r; g = pal[i].g; b = pal[i].b; sprintf(spec, "#%02x%02x%02x", r, g, b); XLookupColor(x11_dpy, x11_colormap, spec, &exact, &def); XAllocColor(x11_dpy, x11_colormap, &def); /* DPRINTF("lookup: exact(%d,%d,%d) = %d, def(%d,%d,%d)=%d\n", exact.red, exact.green, exact.blue, exact.pixel, def.red, def.green, def.blue, def.pixel); */ x11_palette[first + i] = def; } n = first + count - 1; if (n > x11_pal_max) x11_pal_max = n;}static voidX11_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c){ /* draw savebits for readpixel or blit */ savebits.DrawPixel(&savebits, x, y, c); if (gr_mode == MWMODE_COPY) { set_color(c); set_mode(gr_mode); XDrawPoint(x11_dpy, x11_win, x11_gc, x, y); } else { update_from_savebits(x, y, 1, 1); }}static MWPIXELVALX11_readpixel(PSD psd, MWCOORD x, MWCOORD y){ /* read savebits for pixel value, rather than ask X11 */ return savebits.ReadPixel(&savebits, x, y);}static voidX11_drawhline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c){ /* draw savebits for readpixel or blit */ savebits.DrawHorzLine(&savebits, x1, x2, y, c); if (gr_mode == MWMODE_COPY) { set_color(c); set_mode(gr_mode); XDrawLine(x11_dpy, x11_win, x11_gc, x1, y, x2, y); } else { update_from_savebits((x1 < x2 ? x1 : x2), y, (x1 < x2 ? x2 - x1 + 1 : x1 - x2 + 1), 1); }}static voidX11_drawvline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c){ savebits.DrawVertLine(&savebits, x, y1, y2, c); if (gr_mode == MWMODE_COPY) { set_color(c); set_mode(gr_mode); XDrawLine(x11_dpy, x11_win, x11_gc, x, y1, x, y2); } else { update_from_savebits(x, (y1 < y2 ? y1 : y2), 1, (y1 < y2 ? y2 - y1 + 1 : y1 - y2 + 1)); }}static voidX11_fillrect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c){ /* draw savebits for readpixel or blit */ savebits.FillRect(&savebits, x1, y1, x2, y2, c); if (gr_mode == MWMODE_COPY) { set_color(c); set_mode(gr_mode); XFillRectangle(x11_dpy, x11_win, x11_gc, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1); } else { update_from_savebits(x1, y1, (x2-x1)+1, (y2-y1)+1); }}static voidX11_blit(PSD dstpsd, MWCOORD destx, MWCOORD desty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op){ if (op == MWMODE_NOOP) { return; } if (srcpsd->flags & PSF_SCREEN) { /* Use offscreen equivalent as the source */ srcpsd = &savebits; } if (!(dstpsd->flags & PSF_SCREEN)) { /* memory to memory blit, use offscreen blitter */ dstpsd->Blit(dstpsd, destx, desty, w, h, srcpsd, srcx, srcy, op); return; } /* Update "savebits" off-screen buffer */ savebits.Blit(&savebits, destx, desty, w, h, srcpsd, srcx, srcy, op);#if 1 /* Faster blitting for simple cases */#if 1 /* Pixel-perfect - only trust X11 with copies. In palette modes, this * is essential. In true color, it's good to test the NanoGUI blit. */ if ((srcpsd == &savebits) && (op == MWMODE_COPY))#else /* Not perfect, but faster */ if ((srcpsd == &savebits) && (op >= 0) && (op <= MWMODE_MAX))#endif { /* * Can do simple onscreen copy. * * The raster op is one of the first 16 (the simple ones), so is * supported by X. */ /* DPRINTF("Nano-X: X11_blit() doing onscreen copy\n"); */ set_mode(op); XCopyArea(x11_dpy, x11_win, x11_win, x11_gc, srcx, srcy, w, h, destx, desty); } else#endif { /* More complex operation. Since we've already done this into * the offscreen buffer, we can simply copy it over. * * For memory->screen cases, this cannot be slower than a * direct blit (since we have to do the blit to the ofscreen * buffer anyway) and it'll be much faster for complex blits * such as alpha blending. * * For screen->screen, this is just simpler. */ update_from_savebits(destx, desty, w, h); }}static voidX11_stretchblitex(PSD dstpsd, PSD srcpsd, MWCOORD dest_x_start, MWCOORD dest_y_start, MWCOORD width, MWCOORD height, int x_denominator, int y_denominator, int src_x_fraction, int src_y_fraction, int x_step_fraction, int y_step_fraction, long op){ if (op == MWMODE_NOOP) { return; } /* DPRINTF("Nano-X: X11_stretchblitex( dest=(%d,%d) %dx%d )\n", dest_x_start, dest_y_start, width, height); */ if (srcpsd->flags & PSF_SCREEN) { /* Use offscreen equivalent as the source */ srcpsd = &savebits; } if (!(dstpsd->flags & PSF_SCREEN)) { /* memory to memory blit, use offscreen blitter */ dstpsd->StretchBlitEx(dstpsd, srcpsd, dest_x_start, dest_y_start, width, height, x_denominator, y_denominator, src_x_fraction, src_y_fraction, x_step_fraction, y_step_fraction, op); return; } /* Update "savebits" off-screen buffer */ savebits.StretchBlitEx(&savebits, srcpsd, dest_x_start, dest_y_start, width, height, x_denominator, y_denominator, src_x_fraction, src_y_fraction, x_step_fraction, y_step_fraction, op); /* Since we've already done this into * the offscreen buffer, we can simply copy it over. */ update_from_savebits(dest_x_start, dest_y_start, width, height);}static voidX11_drawarea(PSD psd, driver_gc_t * gc, int op){ assert(psd->addr != 0); /*assert(gc->dstw <= gc->srcw); */ assert(gc->dstx >= 0 && gc->dstx + gc->dstw <= psd->xres); /*assert(gc->dsty >= 0 && gc->dsty+gc->dsth <= psd->yres); */ /*assert(gc->srcx >= 0 && gc->srcx+gc->dstw <= gc->srcw); */ assert(gc->srcy >= 0); savebits.DrawArea(&savebits, gc, op); update_from_savebits(gc->dstx, gc->dsty, gc->dstw, gc->dsth);}/* perform pre-select() duties*/static voidX11_preselect(PSD psd){ XFlush(x11_dpy);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -