📄 xwin.c
字号:
XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height); XFree(image); if (!owncolmap) xfree(tdata); return (HBITMAP) bitmap;}voidui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 *data){ XImage *image; uint8 *tdata; tdata = (owncolmap ? data : translate_image(width, height, data)); image = XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width, height, 8, 0); if (ownbackstore) { XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy); XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y); } else { XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy); } XFree(image); if (!owncolmap) xfree(tdata);}voidui_destroy_bitmap(HBITMAP bmp){ XFreePixmap(display, (Pixmap)bmp);}HGLYPHui_create_glyph(int width, int height, uint8 *data){ XImage *image; Pixmap bitmap; int scanline; GC gc; scanline = (width + 7) / 8; bitmap = XCreatePixmap(display, wnd, width, height, 1); gc = XCreateGC(display, bitmap, 0, NULL); image = XCreateImage(display, visual, 1, ZPixmap, 0, data, width, height, 8, scanline); image->byte_order = MSBFirst; image->bitmap_bit_order = MSBFirst; XInitImage(image); XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height); XFree(image); XFreeGC(display, gc); return (HGLYPH)bitmap;}voidui_destroy_glyph(HGLYPH glyph){ XFreePixmap(display, (Pixmap)glyph);}HCURSORui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 *andmask, uint8 *xormask){ HGLYPH maskglyph, cursorglyph; XColor bg, fg; Cursor xcursor; uint8 *cursor, *pcursor; uint8 *mask, *pmask; uint8 nextbit; int scanline, offset; int i, j; scanline = (width + 7) / 8; offset = scanline * height; cursor = xmalloc(offset); memset(cursor, 0, offset); mask = xmalloc(offset); memset(mask, 0, offset); /* approximate AND and XOR masks with a monochrome X pointer */ for (i = 0; i < height; i++) { offset -= scanline; pcursor = &cursor[offset]; pmask = &mask[offset]; for (j = 0; j < scanline; j++) { for (nextbit = 0x80; nextbit != 0; nextbit >>= 1) { if (xormask[0] || xormask[1] || xormask[2]) { *pcursor |= (~(*andmask) & nextbit); *pmask |= nextbit; } else { *pcursor |= ((*andmask) & nextbit); *pmask |= (~(*andmask) & nextbit); } xormask += 3; } andmask++; pcursor++; pmask++; } } fg.red = fg.blue = fg.green = 0xffff; bg.red = bg.blue = bg.green = 0x0000; fg.flags = bg.flags = DoRed | DoBlue | DoGreen; cursorglyph = ui_create_glyph(width, height, cursor); maskglyph = ui_create_glyph(width, height, mask); xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph, (Pixmap)maskglyph, &fg, &bg, x, y); ui_destroy_glyph(maskglyph); ui_destroy_glyph(cursorglyph); xfree(mask); xfree(cursor); return (HCURSOR)xcursor;}voidui_set_cursor(HCURSOR cursor){ XDefineCursor(display, wnd, (Cursor)cursor);}voidui_destroy_cursor(HCURSOR cursor){ XFreeCursor(display, (Cursor)cursor);}#define MAKE_XCOLOR(xc,c) \ (xc)->red = ((c)->red << 8) | (c)->red; \ (xc)->green = ((c)->green << 8) | (c)->green; \ (xc)->blue = ((c)->blue << 8) | (c)->blue; \ (xc)->flags = DoRed | DoGreen | DoBlue;HCOLOURMAPui_create_colourmap(COLOURMAP *colours){ COLOURENTRY *entry; int i, ncolours = colours->ncolours; if (owncolmap) { XColor *xcolours, *xentry; Colormap map; xcolours = xmalloc(sizeof(XColor) * ncolours); for (i = 0; i < ncolours; i++) { entry = &colours->colours[i]; xentry = &xcolours[i]; xentry->pixel = i; MAKE_XCOLOR(xentry, entry); } map = XCreateColormap(display, wnd, visual, AllocAll); XStoreColors(display, map, xcolours, ncolours); xfree(xcolours); return (HCOLOURMAP)map; } else { uint32 *map = xmalloc(sizeof(*colmap) * ncolours); XColor xentry; uint32 colour; for (i = 0; i < ncolours; i++) { entry = &colours->colours[i]; MAKE_XCOLOR(&xentry, entry); if (XAllocColor(display, xcolmap, &xentry) != 0) colour = xentry.pixel; else colour = white; /* byte swap here to make translate_image faster */ map[i] = translate_colour(colour); } return map; }}voidui_destroy_colourmap(HCOLOURMAP map){ if (owncolmap) XFreeColormap(display, (Colormap)map); else xfree(map);}voidui_set_colourmap(HCOLOURMAP map){ if (owncolmap) XSetWindowColormap(display, wnd, (Colormap)map); else colmap = map;}voidui_set_clip(int x, int y, int cx, int cy){ XRectangle rect; rect.x = x; rect.y = y; rect.width = cx; rect.height = cy; XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);}voidui_reset_clip(){ XRectangle rect; rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);}voidui_bell(){ XBell(display, 0);}voidui_destblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy){ SET_FUNCTION(opcode); FILL_RECTANGLE(x, y, cx, cy); RESET_FUNCTION(opcode);}voidui_patblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* brush */ BRUSH *brush, int bgcolour, int fgcolour){ Pixmap fill; SET_FUNCTION(opcode); switch (brush->style) { case 0: /* Solid */ SET_FOREGROUND(fgcolour); FILL_RECTANGLE(x, y, cx, cy); break; case 3: /* Pattern */ fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern); SET_FOREGROUND(bgcolour); SET_BACKGROUND(fgcolour); XSetFillStyle(display, gc, FillOpaqueStippled); XSetStipple(display, gc, fill); XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin); FILL_RECTANGLE(x, y, cx, cy); XSetFillStyle(display, gc, FillSolid); ui_destroy_glyph((HGLYPH)fill); break; default: unimpl("brush %d\n", brush->style); } RESET_FUNCTION(opcode);}voidui_screenblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* src */ int srcx, int srcy){ SET_FUNCTION(opcode); XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y); if (ownbackstore) XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y); RESET_FUNCTION(opcode);}voidui_memblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* src */ HBITMAP src, int srcx, int srcy){ SET_FUNCTION(opcode); XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y); if (ownbackstore) XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy, cx, cy, x, y); RESET_FUNCTION(opcode);}voidui_triblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* src */ HBITMAP src, int srcx, int srcy, /* brush */ BRUSH *brush, int bgcolour, int fgcolour){ /* This is potentially difficult to do in general. Until someone comes up with a more efficient way of doing it I am using cases. */ switch (opcode) { case 0x69: /* PDSxxn */ ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy); ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour); break; case 0xb8: /* PSDPxax */ ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour); ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy); ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour); break; case 0xc0: /* PSa */ ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy); ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour); break; default: unimpl("triblt 0x%x\n", opcode); ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy); }}voidui_line(uint8 opcode, /* dest */ int startx, int starty, int endx, int endy, /* pen */ PEN *pen){ SET_FUNCTION(opcode); SET_FOREGROUND(pen->colour); XDrawLine(display, wnd, gc, startx, starty, endx, endy); if (ownbackstore) XDrawLine(display, backstore, gc, startx, starty, endx, endy); RESET_FUNCTION(opcode);}voidui_rect( /* dest */ int x, int y, int cx, int cy, /* brush */ int colour){ SET_FOREGROUND(colour); FILL_RECTANGLE(x, y, cx, cy);}voidui_draw_glyph(int mixmode, /* dest */ int x, int y, int cx, int cy, /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour){ SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled); XSetStipple(display, gc, (Pixmap)glyph); XSetTSOrigin(display, gc, x, y); FILL_RECTANGLE(x, y, cx, cy); XSetFillStyle(display, gc, FillSolid);}voidui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y, int clipx, int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy, int bgcolour, int fgcolour, uint8 *text, uint8 length){ FONTGLYPH *glyph; int i, offset; SET_FOREGROUND(bgcolour); if (boxcx > 1) { FILL_RECTANGLE(boxx, boxy, boxcx, boxcy); } else if (mixmode == MIX_OPAQUE) { FILL_RECTANGLE(clipx, clipy, clipcx, clipcy); } /* Paint text, character by character */ for (i = 0; i < length; i++) { glyph = cache_get_font(font, text[i]); if (!(flags & TEXT2_IMPLICIT_X)) { offset = text[++i]; if (offset & 0x80) offset = ((offset & 0x7f) << 8) | text[++i]; if (flags & TEXT2_VERTICAL) y += offset; else x += offset; } if (glyph != NULL) { ui_draw_glyph(mixmode, x + (short) glyph->offset, y + (short) glyph->baseline, glyph->width, glyph->height, glyph->pixmap, 0, 0, bgcolour, fgcolour); if (flags & TEXT2_IMPLICIT_X) x += glyph->width; } }}voidui_desktop_save(uint32 offset, int x, int y, int cx, int cy){ Pixmap pix; XImage *image; if (ownbackstore) { image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap); } else { pix = XCreatePixmap(display, wnd, cx, cy, depth); XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0); image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap); XFreePixmap(display, pix); } offset *= bpp/8; cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp/8, (uint8 *)image->data); XDestroyImage(image);}voidui_desktop_restore(uint32 offset, int x, int y, int cx, int cy){ XImage *image; uint8 *data; offset *= bpp/8; data = cache_get_desktop(offset, cx, cy, bpp/8); if (data == NULL) return; image = XCreateImage(display, visual, depth, ZPixmap, 0, data, cx, cy, BitmapPad(display), cx * bpp/8); if (ownbackstore) { XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy); XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y); } else { XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy); } XFree(image);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -