1 namespace gfx::drivers;
5 #if (defined(__unix__) || defined(__APPLE__)) && !defined(ECERE_MINIGLX)
9 #define property _property
14 #define Window X11Window
15 #define Cursor X11Cursor
17 #define Display X11Display
19 #define KeyCode X11KeyCode
20 #define Picture X11Picture
23 #include <X11/Xutil.h>
24 #include <X11/extensions/shape.h>
25 #include <X11/extensions/Xrender.h>
26 #include <X11/extensions/XShm.h>
49 static byte defaultRGBLookup[32768];
50 bool rgbLookupSet = false;
52 class XDisplay : LFBDisplay //struct
60 X11Picture shapePicture;
61 XShmSegmentInfo shminfo;
63 XShmSegmentInfo shminfoShape;
67 class XSurface : struct
74 ColorAlpha foreground, background;
79 X11Picture colorPicture;
83 class XBitmap : struct
88 X11Picture maskPicture;
91 XRenderPictFormat * GetXRenderFormat(PixelFormat pixelFormat, bool alphaBlend)
93 XRenderPictFormat * format = null;
96 case pixelFormatAlpha:
97 format = XRenderFindStandardFormat(xGlobalDisplay, PictStandardA8);
100 format = XRenderFindStandardFormat(xGlobalDisplay, alphaBlend ? PictStandardARGB32 : PictStandardRGB24);
101 // printf("R: %d G: %d B: %d\n", format->direct.red, format->direct.green, format->direct.blue);
105 XRenderPictFormat info = { 0 };
108 info.type = PictTypeDirect;
109 info.direct.red = 10;
110 info.direct.green = 5;
111 info.direct.blue = 0;
112 info.direct.redMask = 0x1F;
113 info.direct.greenMask = 0x1F;
114 info.direct.blueMask = 0x1F;
116 format = XRenderFindFormat(xGlobalDisplay,
117 /*PictFormatDepth|*/PictFormatType| PictFormatAlpha|PictFormatRed|PictFormatGreen|PictFormatBlue|
118 PictFormatRedMask|PictFormatGreenMask|PictFormatBlueMask|PictFormatAlphaMask, &info, 0);
123 XRenderPictFormat info = { 0 };
126 info.type = PictTypeDirect;
127 info.direct.alpha = 0;
128 info.direct.red = 11;
129 info.direct.green = 5;
130 info.direct.blue = 0;
131 info.direct.redMask = 0x1F;
132 info.direct.greenMask = 0x3F;
133 info.direct.blueMask = 0x1F;
134 info.direct.alphaMask = 0;
137 format = XRenderFindFormat(xGlobalDisplay,
138 /*PictFormatDepth|*/PictFormatType|PictFormatAlpha|PictFormatRed|PictFormatGreen|PictFormatBlue|
139 PictFormatRedMask|PictFormatGreenMask|PictFormatBlueMask|PictFormatAlphaMask, &info, 0);
146 static bool ClipBlitCoords(Surface surface, Bitmap src, int *dx, int *dy, int *sx, int *sy, int *w, int *h, bool * flip)
150 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top) return false;
152 if(*w < 0) { *w = -*w; *flip = true; }
154 //Clip against the edges of the source
167 if(*sx+*w>src.width-1)
168 *w-=*sx+*w-(src.width-1)-1;
169 if(*sy+*h>src.height-1)
170 *h-=*sy+*h-(src.height-1)-1;
171 //Clip against the edges of the destination
172 if(*dx<surface.box.left)
174 if(!*flip) *sx+=surface.box.left-*dx;
175 *w-=surface.box.left-*dx;
176 *dx=surface.box.left;
178 if(*dy<surface.box.top)
180 *sy+=surface.box.top-*dy;
181 *h-=surface.box.top-*dy;
184 if((*dx+*w)>surface.box.right)
186 if(*flip) *sx+=(uint)(*dx+*w)-surface.box.right-1;
187 *w-=((uint)(*dx+*w)-surface.box.right-1);
189 if((*dy+*h)>surface.box.bottom)
190 *h-=((*dy+*h)-surface.box.bottom-1);
196 static bool ClipStretchCoords(Surface surface, Bitmap src, int *dx, int *dy, int *sx, int *sy, int *w, int *h, int *sw, int *sh, bool * flip)
198 float s2dw,s2dh,d2sw,d2sh;
201 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return false;
203 if(Sgn(*w) != Sgn(*sw))
210 s2dw=(float)*w / *sw;
211 s2dh=(float)*h / *sh;
212 d2sw=(float)*sw / *w;
213 d2sh=(float)*sh / *h;
215 //Clip against the edges of the source
218 *dx += (int)((0-*sx) * s2dw);
219 *w -= (int)((0-*sx) * s2dw);
225 *dy += (int)((0-*sy) * s2dh);
226 *h -= (int)((0-*sy) * s2dh);
231 if(*sx+*sw>src.width-1)
233 *w-=(int)((*sx+*sw-(src.width-1)-1)*s2dw);
234 *sw-=*sx+*sw-(src.width-1)-1;
236 if(*sy+*sh>(src.height-1))
238 *h-=(int)((*sy+*sh-(src.height-1)-1)*s2dh);
239 *sh-=*sy+*sh-(src.height-1)-1;
241 //Clip against the edges of the destination
242 if(*dx < surface.box.left)
244 if(!*flip) *sx += (int)((surface.box.left-*dx)*d2sw);
245 *sw-=(int)((surface.box.left-*dx)*d2sw);
246 *w-=surface.box.left-*dx;
247 *dx=surface.box.left;
249 if(*dy < surface.box.top)
251 *sy += (int)((surface.box.top-*dy)*d2sh);
252 *sh -= (int)((surface.box.top-*dy)*d2sh);
253 *h -= surface.box.top-*dy;
254 *dy =surface.box.top;
256 if((*dx+*w)>surface.box.right)
258 if(*flip) *sx+=(int)(((*dx+*w)-surface.box.right-1)*d2sw);
259 *sw-=(int)(((*dx + *w)-surface.box.right-1)*d2sw);
260 *w-=((*dx+*w)-surface.box.right-1);
262 if((*dy+*h)>surface.box.bottom)
264 *sh-=(int)(((*dy+*h)-surface.box.bottom-1)*d2sh);
265 *h-=((*dy+*h)-surface.box.bottom-1);
267 if((*w<=0)||(*h<=0)||(*sw<=0)||(*sh<=0))
272 static void PutBitmapMask(Pixmap mask, Bitmap bitmap) {
274 GC maskGC = XCreateGC(xGlobalDisplay, mask, 0, null);
275 uint wordWidth = (bitmap.width+31) >> 5;
278 uint32 *b = new0 uint32[wordWidth * bitmap.height];
281 XSetGraphicsExposures(xGlobalDisplay, maskGC, False);
283 image.width = bitmap.width;
284 image.height = bitmap.height;
286 image.format = XYBitmap;
287 #ifdef __BIG_ENDIAN__
288 image.byte_order = MSBFirst;
290 image.byte_order = LSBFirst;
292 image.bitmap_unit = 32;
293 image.bitmap_bit_order = LSBFirst;
294 image.bitmap_pad = 32;
296 image.bytes_per_line = wordWidth << 2;
298 image.data = (char*)b;
302 switch(bitmap.pixelFormat) {
307 byte *p = (byte*)bitmap.picture;
309 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
310 for(x = 0; x<bitmap.width; x++) {
312 *b |= f; //XPutPixel(&image, x,y, 1);
322 case pixelFormat565: {
323 uint16 *p = (uint16*)bitmap.picture;
325 PrintLn(bitmap.pixelFormat);
327 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
328 for(x = 0; x<bitmap.width; x++) {
330 *b |= f; //XPutPixel(&image, x,y, 1);
338 case pixelFormat888: {
339 ColorAlpha *p = (ColorAlpha*)bitmap.picture;
340 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
341 for(x = 0; x<bitmap.width; x++) {
343 *b |= f; //XPutPixel(&image, x,y, 1);
351 case pixelFormatAlpha: {
354 case pixelFormatText: {
357 case pixelFormatRGBA: {
362 XSetForeground(xGlobalDisplay, maskGC, 1);
363 XSetBackground(xGlobalDisplay, maskGC, 0);
365 XPutImage(xGlobalDisplay, mask, maskGC, &image,
366 0, 0, 0, 0, //coordinates
367 bitmap.width, bitmap.height);
369 XFreeGC(xGlobalDisplay, maskGC);
373 class XDisplayDriver : DisplayDriver
375 class_property(name) = "X";
377 bool CreateDisplaySystem(DisplaySystem displaySystem)
379 //displaySystem.driverData = calloc(1, sizeof(LFBSystem));
380 displaySystem.flags.memBackBuffer = true;
381 displaySystem.pixelFormat = xSystemPixelFormat;
385 void DestroyDisplaySystem(DisplaySystem displaySystem)
387 // delete displaySystem.driverData;
390 void DestroyDisplay(Display display)
392 XDisplay xDisplay = display.driverData;
394 // Free Shared Memory Pixmap
395 if(xDisplay.shapePixmap)
396 XFreePixmap(xGlobalDisplay, xDisplay.shapePixmap);
398 XFreePixmap(xGlobalDisplay, xDisplay.pixmap);
401 if(xDisplay.shminfoShape.shmid != -1)
403 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
404 if(xDisplay.shminfo.shmaddr != (void *)-1)
405 shmdt(xDisplay.shminfo.shmaddr);
406 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
409 if(xDisplay.shapeImage)
411 if(xDisplay.shminfoShape.shmid != -1)
413 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
414 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
415 shmdt(xDisplay.shminfoShape.shmaddr);
416 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
418 XDestroyImage(xDisplay.shapeImage);
419 xDisplay.shapeImage = None;
422 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
423 if(xDisplay.shapePicture)
424 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
425 if(xDisplay.windowGC)
426 XFreeGC(xGlobalDisplay, xDisplay.windowGC);
428 XFreeGC(xGlobalDisplay, xDisplay.gc);
430 display.driverData = null;
433 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
439 bool CreateDisplay(Display display)
442 XDisplay xDisplay = display.driverData = XDisplay { };
446 xDisplay.windowGC = XCreateGC(xGlobalDisplay, (X11Window)display.window, 0, null);
447 XSetGraphicsExposures(xGlobalDisplay, xDisplay.windowGC, False);
453 bool DisplaySize(Display display, int width, int height)
455 XDisplay xDisplay = display.driverData;
458 if(width > display.width || height > display.height)
460 display.width = width;
461 display.height = height;
464 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
467 XRenderPictureAttributes attributes = { 0 };
468 XRenderPictFormat * format = GetXRenderFormat(xSystemPixelFormat, display.alphaBlend);
469 attributes.component_alpha = 1;
470 attributes.poly_mode = PolyModeImprecise;
471 attributes.poly_edge = PolyEdgeSmooth;
475 XFreePixmap(xGlobalDisplay, xDisplay.pixmap);
476 xDisplay.pixmap = None;
478 if(xDisplay.shapePixmap)
480 XFreePixmap(xGlobalDisplay, xDisplay.shapePixmap);
481 xDisplay.shapePixmap = None;
484 // Free Shared Memory Pixmap
487 if(xDisplay.shminfoShape.shmid != -1)
489 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
490 if(xDisplay.shminfo.shmaddr != (void *)-1)
491 shmdt(xDisplay.shminfo.shmaddr);
492 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
494 XDestroyImage(xDisplay.image);
495 xDisplay.image = None;
497 if(xDisplay.shapeImage)
499 if(xDisplay.shminfoShape.shmid != -1)
501 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
502 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
503 shmdt(xDisplay.shminfoShape.shmaddr);
504 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
506 XDestroyImage(xDisplay.shapeImage);
507 xDisplay.shapeImage = None;
510 // Initialize Shared Memory Pixmap
512 if(xSharedMemory && display.useSharedMemory && format)
515 printf("Using shared memory!\n");
517 xDisplay.image = XShmCreateImage(xGlobalDisplay, xSystemVisual /*DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay))*/,
518 format->depth, ZPixmap, null, &xDisplay.shminfo, width, height);
523 memset(&xDisplay.shminfo, 0, sizeof(XShmSegmentInfo));
524 // printf("shmget: %d\n", xDisplay.image->bytes_per_line * xDisplay.image->height);
525 xDisplay.shminfo.shmid = shmget(IPC_PRIVATE, xDisplay.image->bytes_per_line * xDisplay.image->height, IPC_CREAT|0777);
526 if(xDisplay.shminfo.shmid != -1)
528 xDisplay.shminfo.shmaddr = shmat(xDisplay.shminfo.shmid, 0, 0);
529 if(xDisplay.shminfo.shmaddr != (void *)-1)
531 // printf("%d, %d\n", xDisplay.shminfo.shmid, xDisplay.shminfo.shmaddr);
532 xDisplay.shminfo.readOnly = False;
533 if(XShmAttach(xGlobalDisplay, &xDisplay.shminfo))
535 xDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, xDisplay.shminfo.shmaddr, &xDisplay.shminfo, width, height, format->depth);
537 xDisplay.bitmap.width = width;
538 xDisplay.bitmap.height = height;
539 xDisplay.bitmap.stride = xDisplay.image->bytes_per_line >> GetColorDepthShifts(display.pixelFormat);
540 xDisplay.bitmap.pixelFormat = display.pixelFormat;
541 xDisplay.bitmap.picture = xDisplay.shminfo.shmaddr;
542 xDisplay.bitmap.size = width * height;
543 xDisplay.bitmap.sizeBytes = (uint)xDisplay.bitmap.size << GetColorDepthShifts(display.pixelFormat);
549 if(xDisplay.shminfo.shmid != -1)
551 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
552 if(xDisplay.shminfo.shmaddr != (void *)-1)
553 shmdt(xDisplay.shminfo.shmaddr);
554 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
556 XDestroyImage(xDisplay.image);
557 xDisplay.image = None;
562 // Initialize Shared Memory Shape Pixmap
563 if(xSharedMemory && display.useSharedMemory && display.alphaBlend)
564 xDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, xSystemVisual /*DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay))*/,
565 1, ZPixmap, null, &xDisplay.shminfoShape, width, height);
567 if(xDisplay.shapeImage)
569 xDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE, xDisplay.shapeImage->bytes_per_line * xDisplay.shapeImage->height, IPC_CREAT|0777);
570 if(xDisplay.shminfoShape.shmid != -1)
572 xDisplay.shminfoShape.shmaddr = shmat(xDisplay.shminfoShape.shmid, 0, 0);
573 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
575 xDisplay.shminfoShape.readOnly = False;
576 if(XShmAttach(xGlobalDisplay, &xDisplay.shminfoShape))
578 xDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, xDisplay.shminfoShape.shmaddr, &xDisplay.shminfoShape, width, height, 1);
582 if(!xDisplay.shapePixmap)
584 if(xDisplay.shminfoShape.shmid != -1)
586 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
587 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
588 shmdt(xDisplay.shminfoShape.shmaddr);
589 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
591 XDestroyImage(xDisplay.shapeImage);
592 xDisplay.shapeImage = None;
596 if(!xDisplay.pixmap && format)
597 xDisplay.pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, format->depth);
598 if(display.alphaBlend && !xDisplay.shapePixmap)
599 xDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
602 xDisplay.gc = XCreateGC(xGlobalDisplay, (Pixmap)xDisplay.pixmap, 0, null);
603 XSetGraphicsExposures(xGlobalDisplay, xDisplay.gc, False);
607 xDisplay.picture = XRenderCreatePicture(xGlobalDisplay, xDisplay.pixmap, format, CPComponentAlpha, &attributes);
609 if(display.alphaBlend)
610 xDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, xDisplay.shapePixmap, XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
613 xDisplay.updateBox.left = display.width;
614 xDisplay.updateBox.top = display.height;
615 xDisplay.updateBox.right = 0;
616 xDisplay.updateBox.bottom = 0;
622 void DisplayPosition(Display display, int x, int y)
624 XDisplay xDisplay = display.driverData;
625 xDisplay.offset.x = x;
626 xDisplay.offset.y = y;
629 void RestorePalette(Display display)
631 XDisplay xDisplay = display.driverData;
634 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
636 XBitmap xBitmap = bitmap.driverData;
639 XFreePixmap(xGlobalDisplay, xBitmap.pixmap);
641 XFreePixmap(xGlobalDisplay, xBitmap.mask);
643 XRenderFreePicture(xGlobalDisplay, xBitmap.picture);
644 if(xBitmap.maskPicture)
645 XRenderFreePicture(xGlobalDisplay, xBitmap.maskPicture);
647 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
650 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
652 //XDisplay xDisplay = display.driverData;
654 XImage image = { 0 };
657 if(bitmap.pixelFormat != pixelFormatAlpha)
658 bitmap.Convert(null, bitmap.alphaBlend ? pixelFormat888 : xSystemPixelFormat, null);
660 //bitmap.Convert(null, pixelFormatRGBA, null);
661 //bitmap.Convert(null, pixelFormat888, null);
663 XCreatePixmap(xGlobalDisplay, confineWindow /*(X11Window)display.window*/, bitmap.width, bitmap.height,
664 (bitmap.pixelFormat == pixelFormatAlpha) ? 8 : (bitmap.alphaBlend ? 32 : ((bitmap.pixelFormat == pixelFormat888) ? 24 : xSystemDepth)));
665 if(bitmap.transparent)
667 XCreatePixmap(xGlobalDisplay, confineWindow /*(X11Window)display.window*/, bitmap.width, bitmap.height, 1);
670 XRenderPictureAttributes attributes = { 0 };
671 XRenderPictFormat * format = GetXRenderFormat(bitmap.pixelFormat, bitmap.alphaBlend);
672 attributes.component_alpha = 1;
675 xBitmap.picture = XRenderCreatePicture(xGlobalDisplay, xBitmap.pixmap, format, CPComponentAlpha, &attributes);
676 if(bitmap.transparent && bitmap.pixelFormat != pixelFormatAlpha)
677 xBitmap.maskPicture = XRenderCreatePicture(xGlobalDisplay, xBitmap.mask, XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), CPComponentAlpha, &attributes);
680 gc = XCreateGC(xGlobalDisplay, (Pixmap)xBitmap.pixmap, 0, null);
682 XSetGraphicsExposures(xGlobalDisplay, gc, False);
684 image.width = bitmap.width;
685 image.height = bitmap.height;
687 if(bitmap.pixelFormat == pixelFormatAlpha)
690 image.bitmap_pad = 8;
691 image.bytes_per_line = bitmap.stride;
692 image.bits_per_pixel = 8;
696 image.depth = bitmap.alphaBlend ? 32 : ((bitmap.pixelFormat == pixelFormat888) ? 24 : xSystemDepth);
697 image.bitmap_pad = (bitmap.pixelFormat == pixelFormat888) ? 32 : 16;
698 image.bytes_per_line = ((bitmap.pixelFormat == pixelFormat888) ? 4 : 2) * bitmap.stride;
699 image.bits_per_pixel = (bitmap.pixelFormat == pixelFormat888) ? 32 : 16;
702 image.format = ZPixmap;
703 //image.bitmap_bit_order = MSBFirst;
704 #ifdef __BIG_ENDIAN__
705 image.byte_order = MSBFirst;
707 image.bitmap_unit = 8;
709 image.red_mask = 0xF800;
710 image.green_mask = 0x7E0;
711 image.blue_mask = 0x1F;
715 image.red_mask = 0x0000FF;
716 image.green_mask = 0x00FF00;
717 image.blue_mask = 0xFF0000;
719 // image.red_mask = 0xFFFF0000;
721 image.data = bitmap.picture;
724 if(bitmap.pixelFormat != pixelFormatAlpha && bitmap.alphaBlend)
727 for(y = 0; y<bitmap.height; y++)
729 for(x = 0; x<bitmap.width; x++)
731 ColorAlpha * p = ((ColorAlpha *)bitmap.picture) + y * bitmap.stride + x;
733 p->color.r = (byte)(p->color.r * alpha / 255);
734 p->color.g = (byte)(p->color.g * alpha / 255);
735 p->color.b = (byte)(p->color.b * alpha / 255);
740 XPutImage(xGlobalDisplay, (Pixmap)xBitmap.pixmap, gc, &image,
741 0, 0, 0, 0, bitmap.width,bitmap.height);
743 if(bitmap.transparent && !bitmap.alphaBlend && bitmap.pixelFormat != pixelFormatAlpha)
744 PutBitmapMask(xBitmap.mask, bitmap);
746 XFreeGC(xGlobalDisplay, gc);
749 delete bitmap.picture;
751 bitmap.driverData = xBitmap;
752 bitmap.driver = displaySystem.driver;
756 void ReleaseSurface(Display display, Surface surface)
758 XSurface xSurface = surface.driverData;
759 XDisplay xDisplay = display.driverData;
760 XRectangle rectangle;
762 if(xSurface.colorPicture)
763 XRenderFreePicture(xGlobalDisplay, xSurface.colorPicture);
767 rectangle.width = (uint16)display.width;
768 rectangle.height = (uint16)display.height;
770 XRenderSetPictureClipRectangles(xGlobalDisplay, xDisplay.picture, 0, 0, &rectangle, 1);
772 if(xSurface.colorPixmap)
773 XFreePixmap(xGlobalDisplay, xSurface.colorPixmap);
778 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
781 XBitmap xBitmap = bitmap.driverData;
784 if((surface.driverData = xSurface = XSurface { }))
786 surface.offset.x = x;
787 surface.offset.y = y;
788 surface.unclippedBox = surface.box = clip;
790 xSurface.pixmap = xBitmap.pixmap;
797 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
800 XDisplay xDisplay = display.driverData;
802 if((surface.driverData = xSurface = XSurface { }))
804 XRectangle rectangle;
806 surface.offset.x = x;
807 surface.offset.y = y;
808 surface.unclippedBox = surface.box = clip;
809 xSurface.pixmap = xDisplay.pixmap;
810 xSurface.picture = xDisplay.picture;
812 xSurface.colorPixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, 1, 1, /*(xSystemDepth == 16) ? 16 : */32);
814 rectangle.x = (short)(clip.left + x);
815 rectangle.y = (short)(clip.top + y);
816 rectangle.width = (short)(clip.right - clip.left + 1);
817 rectangle.height = (short)(clip.bottom - clip.top + 1);
819 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
820 XRenderSetPictureClipRectangles(xGlobalDisplay, xDisplay.picture, 0, 0, &rectangle, 1);
822 xDisplay.updateBox.left = Min(x + clip.left, xDisplay.updateBox.left);
823 xDisplay.updateBox.top = Min(y + clip.top, xDisplay.updateBox.top);
824 xDisplay.updateBox.right = Max(x + clip.right, xDisplay.updateBox.right);
825 xDisplay.updateBox.bottom = Max(y + clip.bottom, xDisplay.updateBox.bottom);
832 void Clip(Display display, Surface surface, Box clip)
834 XSurface xSurface = surface.driverData;
835 XDisplay xDisplay = display.driverData;
836 bool changed = false;
837 XRectangle rectangle;
842 box.Clip(surface.unclippedBox);
846 xSurface.clipped = true;
849 else if(xSurface.clipped)
851 surface.box = surface.unclippedBox;
852 xSurface.clipped = false;
857 XRectangle rectangle =
859 (short)(surface.box.left + surface.offset.x),
860 (short)(surface.box.top + surface.offset.y),
861 (short)(surface.box.right - surface.box.left + 1),
862 (short)(surface.box.bottom - surface.box.top + 1)
864 XSetClipRectangles(xGlobalDisplay, xDisplay.gc,
865 0,0, &rectangle, 1, YXBanded);
869 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
872 XDisplay xDisplay = display ? display.driverData : null;
874 PixelFormat format = pixelFormat888;
894 if(sx+sw>display.width-1)
895 sw-=sx+sw-(display.width-1)-1;
896 if(sy+sh>display.height-1)
897 sh-=sy+sh-(display.height-1)-1;
901 xImage = XGetImage(xGlobalDisplay, xDisplay.pixmap, sx, sy, sw, sh, MAXDWORD, ZPixmap);
903 xImage = XGetImage(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), sx, sy, sw, sh, MAXDWORD, ZPixmap);
905 source.pixelFormat = format;
906 source.picture = xImage->data;
909 source.stride = xImage->bytes_per_line / 4;
911 if(!bitmap || bitmap.pixelFormat != format || bitmap.width < w || bitmap.height < h)
914 bitmap.Allocate(null, w,h,w, format, (format == pixelFormat8)?true:false);
918 Surface surface = bitmap.GetSurface(0, 0, null);
919 surface.Blit(source, dx,dy,0,0,sw,sh);
923 source.picture = null;
926 XDestroyImage(xImage);
930 void SetForeground(Display display, Surface surface, ColorAlpha color)
932 XSurface xSurface = surface.driverData;
933 XDisplay xDisplay = display.driverData;
934 XRenderColor renderColor = { color.color.r * color.a, color.color.g * color.a, color.color.b * color.a, color.a * 255};
935 X11Picture colorPicture;
937 if(xSurface.colorPicture)
938 XRenderFreePicture(xGlobalDisplay, xSurface.colorPicture);
939 // xSurface.colorPicture = XRenderCreateSolidFill(xGlobalDisplay, &renderColor);
942 XRenderPictureAttributes attributes = { 0 };
943 // XRenderPictFormat * format = myXRenderFindStandardFormat(xGlobalDisplay, PictStandardARGB32 /*PictStandardRGB24 /*PictStandardARGB32*/, 1);
944 XRenderPictFormat * format = /*(xSystemPixelFormat != pixelFormat888) ? GetXRenderFormat(xSystemPixelFormat, false) : */XRenderFindStandardFormat(xGlobalDisplay, PictStandardARGB32);
945 #if !defined(__APPLE__) && !defined(__OLDX__)
946 attributes.repeat = RepeatNormal;
948 attributes.repeat = 1;
950 ///attributes.component_alpha = 0;
952 xSurface.colorPicture = XRenderCreatePicture(xGlobalDisplay, xSurface.colorPixmap, format, /*CPComponentAlpha | */CPRepeat, &attributes);
953 XRenderFillRectangle(xGlobalDisplay, PictOpSrc, xSurface.colorPicture, &renderColor, 0, 0, 1, 1);
956 // xSurface.foreground = ARGB(A(color),B(color),G(color),R(color));
957 xSurface.foreground = color;
959 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.foreground :
960 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.foreground) : ((Color555)xSurface.foreground)));
963 void SetBackground(Display display, Surface surface, ColorAlpha color)
965 XSurface xSurface = surface.driverData;
966 XDisplay xDisplay = display.driverData;
967 // xSurface.background = ARGB(A(color),B(color),G(color),R(color));
968 xSurface.background = color;
970 XSetBackground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.background :
971 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.background) : ((Color555)xSurface.background)));
974 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
979 void PutPixel(Display display, Surface surface,int x,int y)
981 XSurface xSurface = surface.driverData;
982 XDisplay xDisplay = display.driverData;
984 if(xSurface.foreground.a < 255)
985 DrawLine(display, surface, x,y,x,y);
987 XDrawPoint(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
988 x + surface.offset.x,
989 y + surface.offset.y);
992 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
994 XDisplay xDisplay = display.driverData;
995 XSurface xSurface = surface.driverData;
996 if(xSurface.foreground.a < 255)
1000 double offset = 0.5;
1003 x1 += surface.offset.x;
1004 y1 += surface.offset.y;
1005 x2 += surface.offset.x;
1006 y2 += surface.offset.y;
1015 XDoubleToFixed(y1 - width + offset), XDoubleToFixed(y1 + width + offset),
1016 { { XDoubleToFixed(Min(x1, x2) - 0 + offset), XDoubleToFixed(y1 - width + offset) }, { XDoubleToFixed(Min(x1, x2) + 0.0 + offset), XDoubleToFixed(y1 + width+ offset) } },
1017 { { XDoubleToFixed(Max(x1, x2) - 0 + offset), XDoubleToFixed(y1 - width + offset) }, { XDoubleToFixed(Max(x1, x2) + 0.0 + offset), XDoubleToFixed(y1 + width+ offset) } },
1030 XDoubleToFixed(Min(y1, y2) - 0.0 + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset),
1031 { { XDoubleToFixed(x1 - width + offset), XDoubleToFixed(Min(y1, y2) - 0.0 + offset) }, { XDoubleToFixed(x1 - width + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset) } },
1032 { { XDoubleToFixed(x1 + width + offset), XDoubleToFixed(Min(y1, y2) - 0.0 + offset) }, { XDoubleToFixed(x1 + width + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset) } },
1041 Pointf A, B, C, D, E, F;
1054 l = sqrt(dx * dx + dy * dy);
1060 A = { (float)(x1 + dy * width), (float)(y1 - dx * width) };
1061 B = { (float)(x1 - dy * width), (float)(y1 + dx * width) };
1062 C = { (float)(A.x + ((B.y - A.y) * dx / dy)), B.y };
1063 E = { (float)(x2 + dy * width), (float)(y2 - dx * width) };
1064 F = { (float)(x2 - dy * width), (float)(y2 + dx * width) };
1065 D = { (float)(F.x + ((E.y - F.y) * dx / dy)), E.y };
1070 XDoubleToFixed(A.y + offset), XDoubleToFixed(B.y + offset),
1071 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) } },
1072 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) } }
1076 XDoubleToFixed(B.y + offset), XDoubleToFixed(D.y + offset),
1077 { { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) }, { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) } },
1078 { { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) }, { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) } }
1082 XDoubleToFixed(D.y + offset), XDoubleToFixed(F.y + offset),
1083 { { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } },
1084 { { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } },
1094 A = { (float)(x1 - dy * width), (float)(y1 + dx * width) };
1095 B = { (float)(x1 + dy * width), (float)(y1 - dx * width) };
1096 C = { (float)(A.x + ((B.y - A.y) * dx / dy)), B.y };
1097 E = { (float)(x2 - dy * width), (float)(y2 + dx * width) };
1098 F = { (float)(x2 + dy * width), (float)(y2 - dx * width) };
1099 D = { (float)(F.x + ((E.y - F.y) * dx / dy)), E.y };
1104 XDoubleToFixed(A.y + offset), XDoubleToFixed(B.y + offset),
1105 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) } },
1106 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) } }
1110 XDoubleToFixed(B.y + offset), XDoubleToFixed(D.y + offset),
1111 { { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) }, { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) } },
1112 { { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) }, { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) } }
1116 XDoubleToFixed(D.y + offset), XDoubleToFixed(F.y + offset),
1117 { { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } },
1118 { { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } }
1127 printf("Line: (%d, %d)-(%d, %d)\n", x1,y1, x2,y2);
1128 printf("Line: A = (%.2f, %.2f), B = (%.2f, %.2f), C = (%.2f, %.2f)\n", A.x,A.y, B.x,B.y, C.x,C.y);
1129 printf("Line: D = (%.2f, %.2f), E = (%.2f, %.2f), F = (%.2f, %.2f)\n", D.x,D.y, E.x,E.y, F.x,F.y);
1130 printf("Trap1: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1131 traps[0].top / 65536.0, traps[0].bottom / 65536.0,
1132 traps[0].left.p1.x / 65536.0, traps[0].left.p1.y / 65536.0, traps[0].left.p2.x / 65536.0, traps[0].left.p2.y / 65536.0,
1133 traps[0].right.p1.x / 65536.0, traps[0].right.p1.y / 65536.0, traps[0].right.p2.x / 65536.0, traps[0].right.p2.y / 65536.0);
1134 printf("Trap2: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1135 traps[1].top / 65536.0, traps[1].bottom / 65536.0,
1136 traps[1].left.p1.x / 65536.0, traps[1].left.p1.y / 65536.0, traps[1].left.p2.x / 65536.0, traps[1].left.p2.y / 65536.0,
1137 traps[1].right.p1.x / 65536.0, traps[1].right.p1.y / 65536.0, traps[1].right.p2.x / 65536.0, traps[1].right.p2.y / 65536.0);
1138 printf("Trap3: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1139 traps[2].top / 65536.0, traps[2].bottom / 65536.0,
1140 traps[2].left.p1.x / 65536.0, traps[2].left.p1.y / 65536.0, traps[2].left.p2.x / 65536.0, traps[2].left.p2.y / 65536.0,
1141 traps[2].right.p1.x / 65536.0, traps[2].right.p1.y / 65536.0, traps[2].right.p2.x / 65536.0, traps[2].right.p2.y / 65536.0);
1145 XRenderCompositeTrapezoids(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xSurface.picture, None, 0, 0, traps, nTraps);
1148 XDrawLine(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1149 x1 + surface.offset.x,
1150 y1 + surface.offset.y,
1151 x2 + surface.offset.x,
1152 y2 + surface.offset.y);
1155 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
1157 XDisplay xDisplay = display.driverData;
1158 XSurface xSurface = surface.driverData;
1160 if(xSurface.foreground.a < 255)
1162 DrawLine(display, surface,x1,y1,x2-1,y1);
1163 DrawLine(display, surface,x2,y1,x2,y2-1);
1164 DrawLine(display, surface,x1,y2,x2-1,y2);
1165 DrawLine(display, surface,x1,y1+1,x1,y2-1);
1168 XDrawRectangle(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1169 x1 + surface.offset.x,
1170 y1 + surface.offset.y,
1174 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
1176 XDisplay xDisplay = display.driverData;
1177 XSurface xSurface = surface.driverData;
1178 if(xSurface.background.a < 255)
1180 XRenderColor renderColor =
1182 (uint16)(xSurface.background.color.r * xSurface.background.a),
1183 (uint16)(xSurface.background.color.g * xSurface.background.a),
1184 (uint16)(xSurface.background.color.b * xSurface.background.a),
1185 (uint16)xSurface.background.a * 255
1187 x1 += surface.offset.x;
1188 y1 += surface.offset.y;
1189 x2 += surface.offset.x;
1190 y2 += surface.offset.y;
1191 XRenderFillRectangle(xGlobalDisplay, PictOpOver, xSurface.picture, &renderColor, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1);
1195 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.background :
1196 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.background) : ((Color555)xSurface.background)));
1197 XFillRectangle(xGlobalDisplay, (Pixmap) xDisplay.pixmap, xDisplay.gc,
1198 x1 + surface.offset.x,
1199 y1 + surface.offset.y,
1200 x2 - x1 + 1, y2 - y1 + 1);
1201 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.foreground :
1202 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.foreground) : ((Color555)xSurface.foreground)));
1206 void Clear(Display display, Surface surface, ClearType flags)
1208 if(flags != depthBuffer)
1210 XDisplay xDisplay = display.driverData;
1211 XSurface xSurface = surface.driverData;
1212 if(xSurface.background.a < 255)
1214 int x1 = surface.box.left;
1215 int y1 = surface.box.top;
1216 int x2 = surface.box.right;
1217 int y2 = surface.box.bottom;
1218 XRenderColor renderColor =
1220 (uint16)(xSurface.background.color.r * xSurface.background.a),
1221 (uint16)(xSurface.background.color.g * xSurface.background.a),
1222 (uint16)(xSurface.background.color.b * xSurface.background.a),
1223 (uint16)xSurface.background.a * 255
1225 x1 += surface.offset.x;
1226 y1 += surface.offset.y;
1227 x2 += surface.offset.x;
1228 y2 += surface.offset.y;
1229 XRenderFillRectangle(xGlobalDisplay, PictOpSrc, xSurface.picture, &renderColor, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1);
1232 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1236 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
1241 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1243 bool result = false;
1244 XBitmap xBitmap = bitmap.driverData = XBitmap { };
1249 switch(GetColorDepthShifts(format))
1251 case 0: stride = (width + 3) & 0xFFFFFFFC; break;
1252 case 1: stride = (width + 1) & 0xFFFFFFFE; break;
1253 case 2: stride = width; break;
1257 bitmap.stride = stride;
1258 bitmap.width = width;
1259 bitmap.height = height;
1260 bitmap.size = (uint)stride * (uint)height;
1261 bitmap.sizeBytes = bitmap.size << GetColorDepthShifts(format);
1262 bitmap.pixelFormat = format;
1263 bitmap.transparent = false;
1264 bitmap.allocatePalette = allocatePalette;
1267 bitmap.palette = new ColorAlpha[256];
1269 CopyBytesBy4(bitmap.palette, GetDefaultPalette(), 256);
1272 bitmap.palette = GetDefaultPalette();
1277 FreeBitmap(displaySystem, bitmap);
1283 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1285 XDisplay xDisplay = display.driverData;
1286 XSurface xSurface = surface.driverData;
1287 XBitmap xBitmap = src.driverData;
1291 if(!ClipBlitCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &flip))
1294 dx += surface.offset.x;
1295 dy += surface.offset.y;
1297 if(src.transparent && !src.alphaBlend && !display.alphaBlend)
1299 XSetClipMask(xGlobalDisplay, xDisplay.gc, xBitmap.mask);
1300 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, dx - sx, dy - sy);
1302 if(xSurface.xOffset)
1304 XTransform transform =
1307 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), -(xSurface.xOffset << 10) },
1308 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1309 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1312 // printf("XOffset: %d\n", xSurface.xOffset);
1313 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &transform);
1316 if(src.alphaBlend || display.alphaBlend)
1318 if(src.pixelFormat == pixelFormatAlpha)
1320 XRenderComposite(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xBitmap.picture, xSurface.picture, 0, 0, sx, sy, dx, dy, w + (xSurface.xOffset ? 1 : 1), h);
1322 else if(src.alphaBlend)
1323 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, None, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1325 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, xBitmap.maskPicture, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1328 XCopyArea(xGlobalDisplay, (Pixmap)xBitmap.pixmap, (Pixmap)xSurface.pixmap, xDisplay.gc,
1329 sx, sy, w, h, dx, dy);
1331 if(xSurface.xOffset)
1333 XTransform identity =
1336 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1337 { (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1338 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1341 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &identity);
1343 if(src.transparent && !src.alphaBlend && !display.alphaBlend)
1345 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, 0, 0);
1347 XRectangle rectangle;
1349 rectangle.x = (short)(surface.unclippedBox.left + surface.offset.x);
1350 rectangle.y = (short)(surface.unclippedBox.top + surface.offset.y);
1351 rectangle.width = (short)(surface.unclippedBox.right - surface.unclippedBox.left + 1);
1352 rectangle.height = (short)(surface.unclippedBox.bottom - surface.unclippedBox.top + 1);
1354 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1360 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1362 XDisplay xDisplay = display.driverData;
1363 XSurface xSurface = surface.driverData;
1364 XBitmap xBitmap = src.driverData;
1367 XTransform transform =
1370 { (int)((float)sw / w * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1371 { (int)(0.0f * (1<<16)), (int)((float)sh / h * (1<<16)), (int)(0.0f * (1<<16)) },
1372 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1375 XTransform identity =
1378 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1379 { (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1380 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1383 dx += surface.offset.x;
1384 dy += surface.offset.y;
1386 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &transform);
1388 if(src.pixelFormat == pixelFormatAlpha)
1389 XRenderComposite(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xBitmap.picture, xSurface.picture, 0, 0, sx, sy, dx, dy, w, h);
1390 else if(src.alphaBlend)
1391 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, None, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1394 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.maskPicture, &transform);
1395 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, xBitmap.maskPicture, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1396 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.maskPicture, &identity);
1398 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &identity);
1402 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1404 XBitmap xBitmap = src.driverData;
1407 XRenderSetPictureFilter(xGlobalDisplay, xBitmap.picture, "bilinear", null, 0);
1408 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
1409 XRenderSetPictureFilter(xGlobalDisplay, xBitmap.picture, "nearest", null, 0);
1413 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1415 XImage image = { 0 };
1416 XDisplay xDisplay = display.driverData;
1417 XSurface xSurface = surface.driverData;
1420 if(!src.picture || !ClipBlitCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &flip))
1423 if(src.pixelFormat == display.pixelFormat)
1425 image.width = src.width;
1426 image.height = src.height;
1427 image.depth = (src.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1428 image.bitmap_pad = (src.pixelFormat == pixelFormat888) ? 32 : 16;
1429 image.format = ZPixmap;
1430 image.bitmap_unit = 8;
1431 image.bytes_per_line = ((src.pixelFormat == pixelFormat888) ? 4 : 2) * src.stride;
1432 image.bits_per_pixel = (src.pixelFormat == pixelFormat888) ? 32 : 16;
1434 image.data = src.picture;
1437 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1438 sx, sy, dx + surface.offset.x, dy + surface.offset.y, w,h);
1444 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1445 s = temp.GetSurface(0,0,null);
1446 s.Blit(src, 0,0, sx,sy, flip ? -w : w, h);
1450 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1451 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1452 image.format = ZPixmap;
1453 image.bitmap_unit = 8;
1454 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1455 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1457 image.data = temp.picture;
1460 if(!src.transparent)
1462 // printf("Stride: %d, dx: %d, dy: %d, w: %d, h: %d, %d\n", temp.stride, dx + surface.offset.x, dy + surface.offset.y, w,h, xSystemDepth);
1463 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1464 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1469 GC maskGC = 0, gc = 0;
1470 Pixmap pixmap, mask;
1472 pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, xSystemDepth /*24*/);
1473 mask = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, 1);
1475 gc = XCreateGC(xGlobalDisplay, pixmap, 0, null);
1476 maskGC = XCreateGC(xGlobalDisplay, mask, 0, null);
1477 XSetGraphicsExposures(xGlobalDisplay, gc, False);
1478 XSetGraphicsExposures(xGlobalDisplay, maskGC, False);
1480 XPutImage(xGlobalDisplay, pixmap, gc, &image, 0, 0, 0, 0, w,h);
1481 XSetForeground(xGlobalDisplay, maskGC, 0);
1482 XFillRectangle(xGlobalDisplay, mask, maskGC, 0, 0, w, h);
1483 XSetForeground(xGlobalDisplay, maskGC, 1);
1484 if(temp.pixelFormat == pixelFormat888)
1487 for(y = 0; y<h; y++)
1489 for(x = 0; x<w; x++)
1491 if(((ColorAlpha *)temp.picture)[y * temp.stride + x].a)
1492 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1496 else if(src.pixelFormat == pixelFormat8)
1499 for(y = 0; y<h; y++)
1501 for(x = 0; x<w; x++)
1503 if(src.picture[(y + sy) * src.stride + (flip ? (w-1-(sx + x)) : (sx + x)])
1504 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1511 for(y = 0; y<h; y++)
1513 for(x = 0; x<w; x++)
1515 if(((uint16 *)temp.picture)[y * temp.stride + x])
1516 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1521 XFreeGC(xGlobalDisplay, maskGC);
1524 Pixmap pixmap, mask;
1526 pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, xSystemDepth /*24*/);
1527 mask = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, 1);
1529 gc = XCreateGC(xGlobalDisplay, pixmap, 0, null);
1530 XSetGraphicsExposures(xGlobalDisplay, gc, False);
1532 XPutImage(xGlobalDisplay, pixmap, gc, &image, 0, 0, 0, 0, w,h);
1534 PutBitmapMask(mask, temp);
1537 XSetClipMask(xGlobalDisplay, xDisplay.gc, mask);
1538 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, dx + surface.offset.x, dy + surface.offset.y);
1539 XCopyArea(xGlobalDisplay, pixmap, (Pixmap)xSurface.pixmap, xDisplay.gc, 0, 0, w, h, dx + surface.offset.x, dy + surface.offset.y);
1540 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, 0, 0);
1542 XRectangle rectangle;
1544 rectangle.x = (short)(surface.unclippedBox.left + surface.offset.x);
1545 rectangle.y = (short)(surface.unclippedBox.top + surface.offset.y);
1546 rectangle.width = (short)(surface.unclippedBox.right - surface.unclippedBox.left + 1);
1547 rectangle.height = (short)(surface.unclippedBox.bottom - surface.unclippedBox.top + 1);
1549 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1552 XFreeGC(xGlobalDisplay, gc);
1553 XFreePixmap(xGlobalDisplay, pixmap);
1554 XFreePixmap(xGlobalDisplay, mask);
1561 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1564 if(ClipStretchCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &sw, &sh, &flip))
1566 XImage image = { 0 };
1567 XDisplay xDisplay = display.driverData;
1568 XSurface xSurface = surface.driverData;
1571 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1572 s = temp.GetSurface(0,0,null);
1573 s.Stretch(src, 0,0, sx,sy, w, h, sw, sh);
1577 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1578 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1579 image.format = ZPixmap;
1580 image.bitmap_unit = 8;
1581 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1582 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1584 image.data = temp.picture;
1587 // printf("Blitting DI\n");
1588 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1589 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1596 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1599 if(ClipStretchCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &sw, &sh, &flip))
1601 XImage image = { 0 };
1602 XDisplay xDisplay = display.driverData;
1603 XSurface xSurface = surface.driverData;
1606 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1607 s = temp.GetSurface(0,0,null);
1608 s.Filter(src, 0,0, sx,sy, w, h, sw, sh);
1612 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1613 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1614 image.format = ZPixmap;
1615 image.bitmap_unit = 8;
1616 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1617 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;;
1619 image.data = temp.picture;
1622 // printf("Blitting DI\n");
1623 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1624 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1631 Font LoadFont(DisplaySystem displaySystem, char * faceName, float size, FontFlags flags)
1634 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1638 void UnloadFont(DisplaySystem displaySystem, Font font)
1640 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
1643 void TextFont(Display display, Surface surface, Font font)
1645 // XSurface xSurface = surface.driverData;
1646 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1649 void TextOpacity(Display display, Surface surface, bool opaque)
1651 XSurface xSurface = surface.driverData;
1652 xSurface.opaque = opaque;
1655 #define CHAR_WIDTH 6
1656 #define CHAR_HEIGHT 14
1658 void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
1660 XSurface xSurface = surface.driverData;
1661 XDisplay xDisplay = display.driverData;
1664 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, &tw, &th);
1668 XSetForeground(xGlobalDisplay, xDisplay.gc, xSurface.background);
1670 XFillRectangle(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1671 x + surface.offset.x, y + surface.offset.y,
1672 tw /*len * CHAR_WIDTH*/, th /*CHAR_HEIGHT*/);
1674 XSetForeground(xGlobalDisplay, xDisplay.gc, xSurface.foreground);
1677 XRenderColor renderColor =
1679 (uint16)(xSurface.background.color.r * xSurface.background.a),
1680 (uint16)(xSurface.background.color.g * xSurface.background.a),
1681 (uint16)(xSurface.background.color.b * xSurface.background.a),
1682 (uint16)xSurface.background.a
1684 //printf("Filling rectangle\n");
1685 XRenderFillRectangle(xGlobalDisplay, PictOpSrc /*PictOpOver*/, xSurface.picture, &renderColor,
1686 x + surface.offset.x, y + surface.offset.y, tw, th);
1689 XDrawString(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1690 x + surface.offset.x, y + surface.offset.y + 12, text, len);
1693 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1696 void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
1698 XSurface xSurface = surface.driverData;
1701 for(realLen = 0; realLen<len && text[realLen]; realLen++);
1702 if(width) *width = len * CHAR_WIDTH;
1703 if(height) *height = CHAR_HEIGHT;
1706 FontExtent(display.displaySystem, xSurface.font, text, len, width, height);
1709 void FontExtent(DisplaySystem displaySystem, Font font, char * text, int len, int * width, int * height)
1712 if(width) *width = len * CHAR_WIDTH;
1713 if(height) *height = CHAR_HEIGHT;
1715 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1718 void DrawingChar(Display display, Surface surface, byte character)
1723 void LineStipple(Display display, Surface surface, uint stipple)
1725 XSurface xSurface = surface.driverData;
1726 XDisplay xDisplay = display.driverData;
1727 char list[32] = { 0 };
1736 for(c = 0; c<32; c++)
1738 if((stipple & 0x8000) == on)
1753 XSetLineAttributes(xGlobalDisplay, xDisplay.gc, 0, LineOnOffDash, CapButt, JoinMiter);
1754 XSetDashes(xGlobalDisplay, xDisplay.gc, offset, list, count);
1760 XSetLineAttributes(xGlobalDisplay, xDisplay.gc, 0, LineSolid, CapButt, JoinMiter);
1761 XSetDashes(xGlobalDisplay, xDisplay.gc, 0, list, count);
1765 bool Lock(Display display)
1767 //XLockDisplay(xGlobalDisplay);
1771 void Unlock(Display display)
1773 //XUnlockDisplay(xGlobalDisplay);
1776 void StartUpdate(Display display)
1781 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1786 void Update(Display display, Box updateBox)
1788 XDisplay xDisplay = display.driverData;
1789 Box * box = (updateBox != null) ? updateBox : &xDisplay.updateBox;
1792 XRectangle rectangle;
1795 rectangle.width = (uint16)display.width;
1796 rectangle.height = (uint16)display.height;
1797 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1799 /*if(display.alphaBlend)
1800 XRenderComposite(xGlobalDisplay, PictOpSrc, xDisplay.picture, None, xDisplay.windowPicture, box->left, box->top, 0, 0, box->left, box->top,
1801 box->right - box->left + 1, box->bottom - box->top + 1);
1803 XCopyArea(xGlobalDisplay, (Pixmap)xDisplay.pixmap, (X11Window)display.window, xDisplay.gc /*windowGC*/,
1804 box->left, box->top,
1805 box->right - box->left + 1,
1806 box->bottom - box->top + 1,
1807 box->left, box->top);
1809 if(display.alphaBlend)
1811 Box * box = &xDisplay.updateBox;
1812 XRenderComposite(xGlobalDisplay, PictOpSrc, xDisplay.picture, None, xDisplay.shapePicture, box->left, box->top, 0, 0, box->left, box->top,
1813 box->right - box->left + 1, box->bottom - box->top + 1);
1814 #if !defined(__APPLE__) && !defined(__OLDX__)
1815 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, xDisplay.shapePixmap, ShapeSet);
1817 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, 2, 0, 0, xDisplay.shapePixmap, ShapeSet);
1821 XFlush(xGlobalDisplay);
1822 if(updateBox == null)
1824 xDisplay.updateBox.left = display.width;
1825 xDisplay.updateBox.top = display.height;
1826 xDisplay.updateBox.right = 0;
1827 xDisplay.updateBox.bottom = 0;
1831 void EndUpdate(Display display)
1837 default dllexport int __attribute__((stdcall)) IS_XGetPixmap(Bitmap bitmap)
1839 XBitmap xBitmap = bitmap.driverData;
1840 return xBitmap.pixmap;
1843 default dllexport void __attribute__((stdcall)) IS_XGetSurfaceInfo(Surface surface, Pixmap * pixmap, GC * gc, int *x, int * y)
1845 Display display = surface.display;
1846 XDisplay xDisplay = display.driverData;
1848 *pixmap = xDisplay.pixmap;
1850 *x = surface.offset.x;
1851 *y = surface.offset.y;