📄 xwin.c
字号:
{ nDist = ((long) (xc_cache[j].red >> 8) - (long) (xentry.red >> 8)) * ((long) (xc_cache[j].red >> 8) - (long) (xentry.red >> 8)) + ((long) (xc_cache[j].green >> 8) - (long) (xentry.green >> 8)) * ((long) (xc_cache[j].green >> 8) - (long) (xentry.green >> 8)) + ((long) (xc_cache[j].blue >> 8) - (long) (xentry.blue >> 8)) * ((long) (xc_cache[j].blue >> 8) - (long) (xentry.blue >> 8)); } if (nDist < nMinDist) { nMinDist = nDist; xentry.pixel = j; } } } colour = xentry.pixel; /* update our cache */ if (xentry.pixel < 256) { xc_cache[xentry.pixel].red = xentry.red; xc_cache[xentry.pixel].green = xentry.green; xc_cache[xentry.pixel].blue = xentry.blue; } map[i] = colour; } return map; } else { XColor *xcolours, *xentry; Colormap map; xcolours = (XColor *) 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(g_display, g_wnd, g_visual, AllocAll); XStoreColors(g_display, map, xcolours, ncolours); xfree(xcolours); return (HCOLOURMAP) map; }}voidui_destroy_colourmap(HCOLOURMAP map){ if (!g_owncolmap) xfree(map); else XFreeColormap(g_display, (Colormap) map);}voidui_set_colourmap(HCOLOURMAP map){ if (!g_owncolmap) { if (g_colmap) xfree(g_colmap); g_colmap = (uint32 *) map; } else XSetWindowColormap(g_display, g_wnd, (Colormap) 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(g_display, g_gc, 0, 0, &rect, 1, YXBanded);}voidui_reset_clip(void){ XRectangle rect; rect.x = 0; rect.y = 0; rect.width = g_width; rect.height = g_height; XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);}voidui_bell(void){ XBell(g_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);}static uint8 hatch_patterns[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */ 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */};voidui_patblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* brush */ BRUSH * brush, int bgcolour, int fgcolour){ Pixmap fill; uint8 i, ipattern[8]; SET_FUNCTION(opcode); switch (brush->style) { case 0: /* Solid */ SET_FOREGROUND(fgcolour); FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); break; case 2: /* Hatch */ fill = (Pixmap) ui_create_glyph(8, 8, hatch_patterns + brush->pattern[0] * 8); SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; case 3: /* Pattern */ for (i = 0; i != 8; i++) ipattern[7 - i] = brush->pattern[i]; fill = (Pixmap) ui_create_glyph(8, 8, ipattern); SET_FOREGROUND(bgcolour); SET_BACKGROUND(fgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; default: unimpl("brush %d\n", brush->style); } RESET_FUNCTION(opcode); if (g_ownbackstore) XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);}voidui_screenblt(uint8 opcode, /* dest */ int x, int y, int cx, int cy, /* src */ int srcx, int srcy){ SET_FUNCTION(opcode); if (g_ownbackstore) { if (g_Unobscured) { XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y); } else { XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y); } } else { XCopyArea(g_display, g_wnd, g_wnd, g_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(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y); if (g_ownbackstore) XCopyArea(g_display, (Pixmap) src, g_backstore, g_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(g_display, g_wnd, g_gc, startx, starty, endx, endy); if (g_ownbackstore) XDrawLine(g_display, g_backstore, g_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_polygon(uint8 opcode, /* mode */ uint8 fillmode, /* dest */ POINT * point, int npoints, /* brush */ BRUSH * brush, int bgcolour, int fgcolour){ uint8 style, i, ipattern[8]; Pixmap fill; SET_FUNCTION(opcode); switch (fillmode) { case ALTERNATE: XSetFillRule(g_display, g_gc, EvenOddRule); break; case WINDING: XSetFillRule(g_display, g_gc, WindingRule); break; default: unimpl("fill mode %d\n", fillmode); } if (brush) style = brush->style; else style = 0; switch (style) { case 0: /* Solid */ SET_FOREGROUND(fgcolour); FILL_POLYGON((XPoint *) point, npoints); break; case 2: /* Hatch */ fill = (Pixmap) ui_create_glyph(8, 8, hatch_patterns + brush->pattern[0] * 8); SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); FILL_POLYGON((XPoint *) point, npoints); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; case 3: /* Pattern */ for (i = 0; i != 8; i++) ipattern[7 - i] = brush->pattern[i]; fill = (Pixmap) ui_create_glyph(8, 8, ipattern); SET_FOREGROUND(bgcolour); SET_BACKGROUND(fgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); FILL_POLYGON((XPoint *) point, npoints); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; default: unimpl("brush %d\n", brush->style); } RESET_FUNCTION(opcode);}voidui_polyline(uint8 opcode, /* dest */ POINT * points, int npoints, /* pen */ PEN * pen){ /* TODO: set join style */ SET_FUNCTION(opcode); SET_FOREGROUND(pen->colour); XDrawLines(g_display, g_wnd, g_gc, (XPoint *) points, npoints, CoordModePrevious); if (g_ownbackstore) XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints, CoordModePrevious); RESET_FUNCTION(opcode);}voidui_ellipse(uint8 opcode, /* mode */ uint8 fillmode, /* dest */ int x, int y, int cx, int cy, /* brush */ BRUSH * brush, int bgcolour, int fgcolour){ uint8 style, i, ipattern[8]; Pixmap fill; SET_FUNCTION(opcode); if (brush) style = brush->style; else style = 0; switch (style) { case 0: /* Solid */ SET_FOREGROUND(fgcolour); DRAW_ELLIPSE(x, y, cx, cy, fillmode); break; case 2: /* Hatch */ fill = (Pixmap) ui_create_glyph(8, 8, hatch_patterns + brush->pattern[0] * 8); SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); DRAW_ELLIPSE(x, y, cx, cy, fillmode); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; case 3: /* Pattern */ for (i = 0; i != 8; i++) ipattern[7 - i] = brush->pattern[i]; fill = (Pixmap) ui_create_glyph(8, 8, ipattern); SET_FOREGROUND(bgcolour); SET_BACKGROUND(fgcolour); XSetFillStyle(g_display, g_gc, FillOpaqueStippled); XSetStipple(g_display, g_gc, fill); XSetTSOrigin(g_display, g_gc, brush->xorigin, brush->yorigin); DRAW_ELLIPSE(x, y, cx, cy, fillmode); XSetFillStyle(g_display, g_gc, FillSolid); XSetTSOrigin(g_display, g_gc, 0, 0); ui_destroy_glyph((HGLYPH) fill); break; default: unimpl("brush %d\n", brush->style); } RESET_FUNCTION(opcode);}/* warning, this function only draws on wnd or backstore, not both */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(g_display, g_gc, (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled); XSetStipple(g_display, g_gc, (Pixmap) glyph); XSetTSOrigin(g_display, g_gc, x, y); FILL_RECTANGLE_BACKSTORE(x, y, cx, cy); XSetFillStyle(g_display, g_gc, FillSolid);}#define DO_GLYPH(ttext,idx) \{\ glyph = cache_get_font (font, ttext[idx]);\ if (!(flags & TEXT2_IMPLICIT_X))\ {\ xyoffset = ttext[++idx];\ if ((xyoffset & 0x80))\ {\ if (flags & TEXT2_VERTICAL)\ y += ttext[idx+1] | (ttext[idx+2] << 8);\ else\ x += ttext[idx+1] | (ttext[idx+2] << 8);\ idx += 2;\ }\ else\ {\ if (flags & TEXT2_VERTICAL)\ y += xyoffset;\ else\ x += xyoffset;\ }\ }\ if (glyph != NULL)\ {\ x1 = x + glyph->offset;\ y1 = y + glyph->baseline;\ XSetStipple(g_display, g_gc, (Pixmap) glyph->pixmap);\ XSetTSOrigin(g_display, g_gc, x1, y1);\ FILL_RECTANGLE_BACKSTORE(x1, y1, glyph->width, glyph->height);\ if (flags & TEXT2_IMPLICIT_X)\ x += glyph->width;\ }\}voidui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx, int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy, BRUSH * brush, int bgcolour, int fgcolour, uint8 * text, uint8 length){ /* TODO: use brush appropriately */ FONTGLYPH *glyph; int i, j, xyoffset, x1, y1; DATABLOB *entry; SET_FOREGROUND(bgcolour); /* Sometimes, the boxcx value is something really large, like 32691. This makes XCopyArea fail with Xvnc. The code below is a quick fix. */ if (boxx + boxcx > g_width) boxcx = g_width - boxx; if (boxcx > 1) { FILL_RECTANGLE_BACKSTORE(boxx, boxy, boxcx, boxcy); } else if (mixmode == MIX_OPAQUE) { FILL_RECTANGLE_BACKSTORE(clipx, clipy, clipcx, clipcy); } SET_FOREGROUND(fgcolour); SET_BACKGROUND(bgcolour); XSetFillStyle(g_display, g_gc, FillStippled); /* Paint text, character by character */ for (i = 0; i < length;) { switch (text[i]) { case 0xff: if (i + 2 < length) cache_put_text(text[i + 1], text, text[i + 2]); else { error("this shouldn't be happening\n"); exit(1); } /* this will move pointer from start to first character after FF command */ length -= i + 3; text = &(text[i + 3]); i = 0; break; case 0xfe: entry = cache_get_text(text[i + 1]); if (entry != NULL) { if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X))) { if (flags & TEXT2_VERTICAL) y += text[i + 2]; else x += text[i + 2]; } for (j = 0; j < entry->size; j++) DO_GLYPH(((uint8 *) (entry->data)), j); } if (i + 2 < length) i += 3; else i += 2; length -= i; /* this will move pointer from start to first character after FE command */ text = &(text[i]); i = 0; break; default: DO_GLYPH(text, i); i++; break; } } XSetFillStyle(g_display, g_gc, FillSolid); if (g_ownbackstore) { if (boxcx > 1) XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx, boxy, boxcx, boxcy, boxx, boxy); else XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx, clipy, clipcx, clipcy, clipx, clipy); }}voidui_desktop_save(uint32 offset, int x, int y, int cx, int cy){ Pixmap pix; XImage *image; if (g_ownbackstore) { image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap); } else { pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth); XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0); image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap); XFreePixmap(g_display, pix); } offset *= g_bpp / 8; cache_put_desktop(offset, cx, cy, image->bytes_per_line, g_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 *= g_bpp / 8; data = cache_get_desktop(offset, cx, cy, g_bpp / 8); if (data == NULL) return; image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0, (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8); if (g_ownbackstore) { XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy); XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y); } else { XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy); } XFree(image);}/* these do nothing here but are used in uiports */voidui_begin_update(void){}voidui_end_update(void){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -