📄 xwin.c
字号:
*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(g_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){ g_current_cursor = (Cursor) cursor; XDefineCursor(g_display, g_wnd, g_current_cursor);}voidui_destroy_cursor(HCURSOR cursor){ XFreeCursor(g_display, (Cursor) cursor);}voidui_set_null_cursor(void){ ui_set_cursor(g_null_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 (!g_owncolmap) { uint32 *map = (uint32 *) xmalloc(sizeof(*g_colmap) * ncolours); XColor xentry; XColor xc_cache[256]; uint32 colour; int colLookup = 256; for (i = 0; i < ncolours; i++) { entry = &colours->colours[i]; MAKE_XCOLOR(&xentry, entry); if (XAllocColor(g_display, g_xcolmap, &xentry) == 0) { /* Allocation failed, find closest match. */ int j = 256; int nMinDist = 3 * 256 * 256; long nDist = nMinDist; /* only get the colors once */ while (colLookup--) { xc_cache[colLookup].pixel = colLookup; xc_cache[colLookup].red = xc_cache[colLookup].green = xc_cache[colLookup].blue = 0; xc_cache[colLookup].flags = 0; XQueryColor(g_display, DefaultColormap(g_display, DefaultScreen(g_display)), &xc_cache[colLookup]); } colLookup = 0; /* approximate the pixel */ while (j--) { if (xc_cache[j].flags) { 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);}/* 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, 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, 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 + -