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
75 ColorAlpha foreground, background;
80 X11Picture colorPicture;
84 class XBitmap : struct
89 X11Picture maskPicture;
92 XRenderPictFormat * GetXRenderFormat(PixelFormat pixelFormat, bool alphaBlend)
94 XRenderPictFormat * format = null;
97 case pixelFormatAlpha:
98 format = XRenderFindStandardFormat(xGlobalDisplay, PictStandardA8);
101 format = XRenderFindStandardFormat(xGlobalDisplay, alphaBlend ? PictStandardARGB32 : PictStandardRGB24);
102 // printf("R: %d G: %d B: %d\n", format->direct.red, format->direct.green, format->direct.blue);
106 XRenderPictFormat info = { 0 };
109 info.type = PictTypeDirect;
110 info.direct.red = 10;
111 info.direct.green = 5;
112 info.direct.blue = 0;
113 info.direct.redMask = 0x1F;
114 info.direct.greenMask = 0x1F;
115 info.direct.blueMask = 0x1F;
117 format = XRenderFindFormat(xGlobalDisplay,
118 /*PictFormatDepth|*/PictFormatType| PictFormatAlpha|PictFormatRed|PictFormatGreen|PictFormatBlue|
119 PictFormatRedMask|PictFormatGreenMask|PictFormatBlueMask|PictFormatAlphaMask, &info, 0);
124 XRenderPictFormat info = { 0 };
127 info.type = PictTypeDirect;
128 info.direct.alpha = 0;
129 info.direct.red = 11;
130 info.direct.green = 5;
131 info.direct.blue = 0;
132 info.direct.redMask = 0x1F;
133 info.direct.greenMask = 0x3F;
134 info.direct.blueMask = 0x1F;
135 info.direct.alphaMask = 0;
138 format = XRenderFindFormat(xGlobalDisplay,
139 /*PictFormatDepth|*/PictFormatType|PictFormatAlpha|PictFormatRed|PictFormatGreen|PictFormatBlue|
140 PictFormatRedMask|PictFormatGreenMask|PictFormatBlueMask|PictFormatAlphaMask, &info, 0);
147 static bool ClipBlitCoords(Surface surface, Bitmap src, int *dx, int *dy, int *sx, int *sy, int *w, int *h, bool * flip)
151 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top) return false;
153 if(*w < 0) { *w = -*w; *flip = true; }
155 //Clip against the edges of the source
168 if(*sx+*w>src.width-1)
169 *w-=*sx+*w-(src.width-1)-1;
170 if(*sy+*h>src.height-1)
171 *h-=*sy+*h-(src.height-1)-1;
172 //Clip against the edges of the destination
173 if(*dx<surface.box.left)
175 if(!*flip) *sx+=surface.box.left-*dx;
176 *w-=surface.box.left-*dx;
177 *dx=surface.box.left;
179 if(*dy<surface.box.top)
181 *sy+=surface.box.top-*dy;
182 *h-=surface.box.top-*dy;
185 if((*dx+*w)>surface.box.right)
187 if(*flip) *sx+=(uint)(*dx+*w)-surface.box.right-1;
188 *w-=((uint)(*dx+*w)-surface.box.right-1);
190 if((*dy+*h)>surface.box.bottom)
191 *h-=((*dy+*h)-surface.box.bottom-1);
197 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)
199 float s2dw,s2dh,d2sw,d2sh;
202 if(surface.box.right < surface.box.left || surface.box.bottom < surface.box.top || !src.picture) return false;
204 if(Sgn(*w) != Sgn(*sw))
211 s2dw=(float)*w / *sw;
212 s2dh=(float)*h / *sh;
213 d2sw=(float)*sw / *w;
214 d2sh=(float)*sh / *h;
216 //Clip against the edges of the source
219 *dx += (int)((0-*sx) * s2dw);
220 *w -= (int)((0-*sx) * s2dw);
226 *dy += (int)((0-*sy) * s2dh);
227 *h -= (int)((0-*sy) * s2dh);
232 if(*sx+*sw>src.width-1)
234 *w-=(int)((*sx+*sw-(src.width-1)-1)*s2dw);
235 *sw-=*sx+*sw-(src.width-1)-1;
237 if(*sy+*sh>(src.height-1))
239 *h-=(int)((*sy+*sh-(src.height-1)-1)*s2dh);
240 *sh-=*sy+*sh-(src.height-1)-1;
242 //Clip against the edges of the destination
243 if(*dx < surface.box.left)
245 if(!*flip) *sx += (int)((surface.box.left-*dx)*d2sw);
246 *sw-=(int)((surface.box.left-*dx)*d2sw);
247 *w-=surface.box.left-*dx;
248 *dx=surface.box.left;
250 if(*dy < surface.box.top)
252 *sy += (int)((surface.box.top-*dy)*d2sh);
253 *sh -= (int)((surface.box.top-*dy)*d2sh);
254 *h -= surface.box.top-*dy;
255 *dy =surface.box.top;
257 if((*dx+*w)>surface.box.right)
259 if(*flip) *sx+=(int)(((*dx+*w)-surface.box.right-1)*d2sw);
260 *sw-=(int)(((*dx + *w)-surface.box.right-1)*d2sw);
261 *w-=((*dx+*w)-surface.box.right-1);
263 if((*dy+*h)>surface.box.bottom)
265 *sh-=(int)(((*dy+*h)-surface.box.bottom-1)*d2sh);
266 *h-=((*dy+*h)-surface.box.bottom-1);
268 if((*w<=0)||(*h<=0)||(*sw<=0)||(*sh<=0))
273 static void PutBitmapMask(Pixmap mask, Bitmap bitmap) {
275 GC maskGC = XCreateGC(xGlobalDisplay, mask, 0, null);
276 uint wordWidth = (bitmap.width+31) >> 5;
279 uint32 *b = new0 uint32[wordWidth * bitmap.height];
282 XSetGraphicsExposures(xGlobalDisplay, maskGC, False);
284 image.width = bitmap.width;
285 image.height = bitmap.height;
287 image.format = XYBitmap;
288 #ifdef __BIG_ENDIAN__
289 image.byte_order = MSBFirst;
291 image.byte_order = LSBFirst;
293 image.bitmap_unit = 32;
294 image.bitmap_bit_order = LSBFirst;
295 image.bitmap_pad = 32;
297 image.bytes_per_line = wordWidth << 2;
299 image.data = (char*)b;
303 switch(bitmap.pixelFormat) {
308 byte *p = (byte*)bitmap.picture;
310 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
311 for(x = 0; x<bitmap.width; x++) {
313 *b |= f; //XPutPixel(&image, x,y, 1);
323 case pixelFormat565: {
324 uint16 *p = (uint16*)bitmap.picture;
326 PrintLn(bitmap.pixelFormat);
328 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
329 for(x = 0; x<bitmap.width; x++) {
331 *b |= f; //XPutPixel(&image, x,y, 1);
339 case pixelFormat888: {
340 ColorAlpha *p = (ColorAlpha*)bitmap.picture;
341 for(y = 0; y<bitmap.height; y++, p+=bitmap.stride) {
342 for(x = 0; x<bitmap.width; x++) {
344 *b |= f; //XPutPixel(&image, x,y, 1);
352 case pixelFormatAlpha: {
355 case pixelFormatText: {
358 case pixelFormatRGBA: {
363 XSetForeground(xGlobalDisplay, maskGC, 1);
364 XSetBackground(xGlobalDisplay, maskGC, 0);
366 XPutImage(xGlobalDisplay, mask, maskGC, &image,
367 0, 0, 0, 0, //coordinates
368 bitmap.width, bitmap.height);
370 XFreeGC(xGlobalDisplay, maskGC);
374 class XDisplayDriver : DisplayDriver
376 class_property(name) = "X";
378 bool CreateDisplaySystem(DisplaySystem displaySystem)
380 //displaySystem.driverData = calloc(1, sizeof(LFBSystem));
381 displaySystem.flags.memBackBuffer = true;
382 displaySystem.pixelFormat = xSystemPixelFormat;
386 void DestroyDisplaySystem(DisplaySystem displaySystem)
388 // delete displaySystem.driverData;
391 void DestroyDisplay(Display display)
393 XDisplay xDisplay = display.driverData;
395 // Free Shared Memory Pixmap
396 if(xDisplay.shapePixmap)
397 XFreePixmap(xGlobalDisplay, xDisplay.shapePixmap);
399 XFreePixmap(xGlobalDisplay, xDisplay.pixmap);
402 if(xDisplay.shminfoShape.shmid != -1)
404 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
405 if(xDisplay.shminfo.shmaddr != (void *)-1)
406 shmdt(xDisplay.shminfo.shmaddr);
407 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
410 if(xDisplay.shapeImage)
412 if(xDisplay.shminfoShape.shmid != -1)
414 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
415 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
416 shmdt(xDisplay.shminfoShape.shmaddr);
417 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
419 XDestroyImage(xDisplay.shapeImage);
420 xDisplay.shapeImage = None;
423 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
424 if(xDisplay.shapePicture)
425 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
426 if(xDisplay.windowGC)
427 XFreeGC(xGlobalDisplay, xDisplay.windowGC);
429 XFreeGC(xGlobalDisplay, xDisplay.gc);
431 display.driverData = null;
434 void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
440 bool CreateDisplay(Display display)
443 XDisplay xDisplay = display.driverData = XDisplay { };
447 xDisplay.windowGC = XCreateGC(xGlobalDisplay, (X11Window)display.window, 0, null);
448 XSetGraphicsExposures(xGlobalDisplay, xDisplay.windowGC, False);
454 bool DisplaySize(Display display, int width, int height)
456 XDisplay xDisplay = display.driverData;
459 if(width > display.width || height > display.height)
461 display.width = width;
462 display.height = height;
465 XRenderFreePicture(xGlobalDisplay, xDisplay.picture);
468 XRenderPictureAttributes attributes = { 0 };
469 XRenderPictFormat * format = GetXRenderFormat(xSystemPixelFormat, display.alphaBlend);
470 attributes.component_alpha = 1;
471 attributes.poly_mode = PolyModeImprecise;
472 attributes.poly_edge = PolyEdgeSmooth;
476 XFreePixmap(xGlobalDisplay, xDisplay.pixmap);
477 xDisplay.pixmap = None;
479 if(xDisplay.shapePixmap)
481 XFreePixmap(xGlobalDisplay, xDisplay.shapePixmap);
482 xDisplay.shapePixmap = None;
485 // Free Shared Memory Pixmap
488 if(xDisplay.shminfoShape.shmid != -1)
490 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
491 if(xDisplay.shminfo.shmaddr != (void *)-1)
492 shmdt(xDisplay.shminfo.shmaddr);
493 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
495 XDestroyImage(xDisplay.image);
496 xDisplay.image = None;
498 if(xDisplay.shapeImage)
500 if(xDisplay.shminfoShape.shmid != -1)
502 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
503 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
504 shmdt(xDisplay.shminfoShape.shmaddr);
505 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
507 XDestroyImage(xDisplay.shapeImage);
508 xDisplay.shapeImage = None;
511 // Initialize Shared Memory Pixmap
513 if(xSharedMemory && display.useSharedMemory && format)
516 printf("Using shared memory!\n");
518 xDisplay.image = XShmCreateImage(xGlobalDisplay, xSystemVisual /*DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay))*/,
519 format->depth, ZPixmap, null, &xDisplay.shminfo, width, height);
521 else if(display.useSharedMemory && !xSharedMemory)
522 printf("%s", $"Error: Requested shared memory but shared memory pixmaps are not supported by X server.\n");
526 memset(&xDisplay.shminfo, 0, sizeof(XShmSegmentInfo));
527 // printf("shmget: %d\n", xDisplay.image->bytes_per_line * xDisplay.image->height);
528 xDisplay.shminfo.shmid = shmget(IPC_PRIVATE, xDisplay.image->bytes_per_line * xDisplay.image->height, IPC_CREAT|0777);
529 if(xDisplay.shminfo.shmid != -1)
531 xDisplay.shminfo.shmaddr = shmat(xDisplay.shminfo.shmid, 0, 0);
532 if(xDisplay.shminfo.shmaddr != (void *)-1)
534 // printf("%d, %d\n", xDisplay.shminfo.shmid, xDisplay.shminfo.shmaddr);
535 xDisplay.shminfo.readOnly = False;
536 if(XShmAttach(xGlobalDisplay, &xDisplay.shminfo))
538 xDisplay.pixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, xDisplay.shminfo.shmaddr, &xDisplay.shminfo, width, height, format->depth);
540 xDisplay.bitmap.width = width;
541 xDisplay.bitmap.height = height;
542 xDisplay.bitmap.stride = xDisplay.image->bytes_per_line >> GetColorDepthShifts(display.pixelFormat);
543 xDisplay.bitmap.pixelFormat = display.pixelFormat;
544 xDisplay.bitmap.picture = (byte *)xDisplay.shminfo.shmaddr;
545 xDisplay.bitmap.size = width * height;
546 xDisplay.bitmap.sizeBytes = (uint)xDisplay.bitmap.size << GetColorDepthShifts(display.pixelFormat);
552 if(xDisplay.shminfo.shmid != -1)
554 XShmDetach(xGlobalDisplay, &xDisplay.shminfo);
555 if(xDisplay.shminfo.shmaddr != (void *)-1)
556 shmdt(xDisplay.shminfo.shmaddr);
557 shmctl(xDisplay.shminfo.shmid, IPC_RMID, 0);
559 XDestroyImage(xDisplay.image);
560 xDisplay.image = None;
565 // Initialize Shared Memory Shape Pixmap
566 if(xSharedMemory && display.useSharedMemory && display.alphaBlend)
567 xDisplay.shapeImage = XShmCreateImage(xGlobalDisplay, xSystemVisual /*DefaultVisual(xGlobalDisplay, DefaultScreen(xGlobalDisplay))*/,
568 1, ZPixmap, null, &xDisplay.shminfoShape, width, height);
570 if(xDisplay.shapeImage)
572 xDisplay.shminfoShape.shmid = shmget(IPC_PRIVATE, xDisplay.shapeImage->bytes_per_line * xDisplay.shapeImage->height, IPC_CREAT|0777);
573 if(xDisplay.shminfoShape.shmid != -1)
575 xDisplay.shminfoShape.shmaddr = shmat(xDisplay.shminfoShape.shmid, 0, 0);
576 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
578 xDisplay.shminfoShape.readOnly = False;
579 if(XShmAttach(xGlobalDisplay, &xDisplay.shminfoShape))
581 xDisplay.shapePixmap = XShmCreatePixmap(xGlobalDisplay, (X11Window)display.window, xDisplay.shminfoShape.shmaddr, &xDisplay.shminfoShape, width, height, 1);
585 if(!xDisplay.shapePixmap)
587 if(xDisplay.shminfoShape.shmid != -1)
589 XShmDetach(xGlobalDisplay, &xDisplay.shminfoShape);
590 if(xDisplay.shminfoShape.shmaddr != (void *)-1)
591 shmdt(xDisplay.shminfoShape.shmaddr);
592 shmctl(xDisplay.shminfoShape.shmid, IPC_RMID, 0);
594 XDestroyImage(xDisplay.shapeImage);
595 xDisplay.shapeImage = None;
599 if(!xDisplay.pixmap && format)
600 xDisplay.pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, format->depth);
601 if(display.alphaBlend && !xDisplay.shapePixmap)
602 xDisplay.shapePixmap = XCreatePixmap(xGlobalDisplay, (X11Window)display.window, width, height, 1);
605 xDisplay.gc = XCreateGC(xGlobalDisplay, (Pixmap)xDisplay.pixmap, 0, null);
606 XSetGraphicsExposures(xGlobalDisplay, xDisplay.gc, False);
610 xDisplay.picture = XRenderCreatePicture(xGlobalDisplay, xDisplay.pixmap, format, CPComponentAlpha, &attributes);
612 if(display.alphaBlend)
613 xDisplay.shapePicture = XRenderCreatePicture(xGlobalDisplay, xDisplay.shapePixmap, XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), 0, &attributes);
616 xDisplay.updateBox.left = display.width;
617 xDisplay.updateBox.top = display.height;
618 xDisplay.updateBox.right = 0;
619 xDisplay.updateBox.bottom = 0;
625 void DisplayPosition(Display display, int x, int y)
627 XDisplay xDisplay = display.driverData;
628 xDisplay.offset.x = x;
629 xDisplay.offset.y = y;
632 void RestorePalette(Display display)
637 void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
639 XBitmap xBitmap = bitmap.driverData;
643 XFreePixmap(xGlobalDisplay, xBitmap.pixmap);
645 XFreePixmap(xGlobalDisplay, xBitmap.mask);
647 XRenderFreePicture(xGlobalDisplay, xBitmap.picture);
648 if(xBitmap.maskPicture)
649 XRenderFreePicture(xGlobalDisplay, xBitmap.maskPicture);
651 bitmap.driverData = null;
653 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FreeBitmap(displaySystem, bitmap);
656 bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
658 //XDisplay xDisplay = display.driverData;
660 XImage image = { 0 };
663 if(bitmap.pixelFormat != pixelFormatAlpha)
664 bitmap.Convert(null, bitmap.alphaBlend ? pixelFormat888 : xSystemPixelFormat, null);
666 //bitmap.Convert(null, pixelFormatRGBA, null);
667 //bitmap.Convert(null, pixelFormat888, null);
669 XCreatePixmap(xGlobalDisplay, confineWindow /*(X11Window)display.window*/, bitmap.width, bitmap.height,
670 (bitmap.pixelFormat == pixelFormatAlpha) ? 8 : (bitmap.alphaBlend ? 32 : ((bitmap.pixelFormat == pixelFormat888) ? 24 : xSystemDepth)));
671 if(bitmap.transparent)
673 XCreatePixmap(xGlobalDisplay, confineWindow /*(X11Window)display.window*/, bitmap.width, bitmap.height, 1);
676 XRenderPictureAttributes attributes = { 0 };
677 XRenderPictFormat * format = GetXRenderFormat(bitmap.pixelFormat, bitmap.alphaBlend);
678 attributes.component_alpha = 1;
681 xBitmap.picture = XRenderCreatePicture(xGlobalDisplay, xBitmap.pixmap, format, CPComponentAlpha, &attributes);
682 if(bitmap.transparent && bitmap.pixelFormat != pixelFormatAlpha)
683 xBitmap.maskPicture = XRenderCreatePicture(xGlobalDisplay, xBitmap.mask, XRenderFindStandardFormat(xGlobalDisplay, PictStandardA1), CPComponentAlpha, &attributes);
686 gc = XCreateGC(xGlobalDisplay, (Pixmap)xBitmap.pixmap, 0, null);
688 XSetGraphicsExposures(xGlobalDisplay, gc, False);
690 image.width = bitmap.width;
691 image.height = bitmap.height;
693 if(bitmap.pixelFormat == pixelFormatAlpha)
696 image.bitmap_pad = 8;
697 image.bytes_per_line = bitmap.stride;
698 image.bits_per_pixel = 8;
702 image.depth = bitmap.alphaBlend ? 32 : ((bitmap.pixelFormat == pixelFormat888) ? 24 : xSystemDepth);
703 image.bitmap_pad = (bitmap.pixelFormat == pixelFormat888) ? 32 : 16;
704 image.bytes_per_line = ((bitmap.pixelFormat == pixelFormat888) ? 4 : 2) * bitmap.stride;
705 image.bits_per_pixel = (bitmap.pixelFormat == pixelFormat888) ? 32 : 16;
708 image.format = ZPixmap;
709 //image.bitmap_bit_order = MSBFirst;
710 #ifdef __BIG_ENDIAN__
711 image.byte_order = MSBFirst;
713 image.bitmap_unit = 8;
715 image.red_mask = 0xF800;
716 image.green_mask = 0x7E0;
717 image.blue_mask = 0x1F;
721 image.red_mask = 0x0000FF;
722 image.green_mask = 0x00FF00;
723 image.blue_mask = 0xFF0000;
725 // image.red_mask = 0xFFFF0000;
727 image.data = (char *)bitmap.picture;
730 if(bitmap.pixelFormat != pixelFormatAlpha && bitmap.alphaBlend)
733 for(y = 0; y<bitmap.height; y++)
735 for(x = 0; x<bitmap.width; x++)
737 ColorAlpha * p = ((ColorAlpha *)bitmap.picture) + y * bitmap.stride + x;
739 p->color.r = (byte)(p->color.r * alpha / 255);
740 p->color.g = (byte)(p->color.g * alpha / 255);
741 p->color.b = (byte)(p->color.b * alpha / 255);
746 XPutImage(xGlobalDisplay, (Pixmap)xBitmap.pixmap, gc, &image,
747 0, 0, 0, 0, bitmap.width,bitmap.height);
749 if(bitmap.transparent && !bitmap.alphaBlend && bitmap.pixelFormat != pixelFormatAlpha)
750 PutBitmapMask(xBitmap.mask, bitmap);
752 XFreeGC(xGlobalDisplay, gc);
755 delete bitmap.picture;
757 bitmap.driverData = xBitmap;
758 bitmap.driver = displaySystem.driver;
762 void ReleaseSurface(Display display, Surface surface)
764 XSurface xSurface = surface.driverData;
765 XDisplay xDisplay = display ? display.driverData : null;
766 XRectangle rectangle;
768 if(xSurface.colorPicture)
769 XRenderFreePicture(xGlobalDisplay, xSurface.colorPicture);
775 rectangle.width = (uint16)display.width;
776 rectangle.height = (uint16)display.height;
777 XRenderSetPictureClipRectangles(xGlobalDisplay, xDisplay.picture, 0, 0, &rectangle, 1);
780 if(xSurface.colorPixmap)
781 XFreePixmap(xGlobalDisplay, xSurface.colorPixmap);
786 bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
789 XBitmap xBitmap = bitmap.driverData;
792 if((surface.driverData = xSurface = XSurface { }))
794 surface.offset.x = x;
795 surface.offset.y = y;
796 surface.unclippedBox = surface.box = clip;
798 xSurface.pixmap = xBitmap.pixmap;
805 bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
808 XDisplay xDisplay = display.driverData;
810 if((surface.driverData = xSurface = XSurface { }))
812 XRectangle rectangle;
814 surface.offset.x = x;
815 surface.offset.y = y;
816 surface.unclippedBox = surface.box = clip;
817 xSurface.pixmap = xDisplay.pixmap;
818 xSurface.picture = xDisplay.picture;
820 xSurface.colorPixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, 1, 1, /*(xSystemDepth == 16) ? 16 : */32);
822 rectangle.x = (short)(clip.left + x);
823 rectangle.y = (short)(clip.top + y);
824 rectangle.width = (short)(clip.right - clip.left + 1);
825 rectangle.height = (short)(clip.bottom - clip.top + 1);
827 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
828 XRenderSetPictureClipRectangles(xGlobalDisplay, xDisplay.picture, 0, 0, &rectangle, 1);
830 xDisplay.updateBox.left = Min(x + clip.left, xDisplay.updateBox.left);
831 xDisplay.updateBox.top = Min(y + clip.top, xDisplay.updateBox.top);
832 xDisplay.updateBox.right = Max(x + clip.right, xDisplay.updateBox.right);
833 xDisplay.updateBox.bottom = Max(y + clip.bottom, xDisplay.updateBox.bottom);
840 void Clip(Display display, Surface surface, Box clip)
842 XSurface xSurface = surface.driverData;
843 XDisplay xDisplay = display.driverData;
844 bool changed = false;
849 box.Clip(surface.unclippedBox);
853 xSurface.clipped = true;
856 else if(xSurface.clipped)
858 surface.box = surface.unclippedBox;
859 xSurface.clipped = false;
864 XRectangle rectangle =
866 (short)(surface.box.left + surface.offset.x),
867 (short)(surface.box.top + surface.offset.y),
868 (short)(surface.box.right - surface.box.left + 1),
869 (short)(surface.box.bottom - surface.box.top + 1)
871 XSetClipRectangles(xGlobalDisplay, xDisplay.gc,
872 0,0, &rectangle, 1, YXBanded);
876 bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
879 XDisplay xDisplay = display ? display.driverData : null;
881 PixelFormat format = pixelFormat888;
901 if(sx+sw>display.width-1)
902 sw-=sx+sw-(display.width-1)-1;
903 if(sy+sh>display.height-1)
904 sh-=sy+sh-(display.height-1)-1;
908 xImage = XGetImage(xGlobalDisplay, xDisplay.pixmap, sx, sy, sw, sh, MAXDWORD, ZPixmap);
910 xImage = XGetImage(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), sx, sy, sw, sh, MAXDWORD, ZPixmap);
912 source.pixelFormat = format;
913 source.picture = (byte *)xImage->data;
916 source.stride = xImage->bytes_per_line / 4;
918 if(!bitmap || bitmap.pixelFormat != format || bitmap.width < w || bitmap.height < h)
921 bitmap.Allocate(null, w,h,w, format, (format == pixelFormat8)?true:false);
925 Surface surface = bitmap.GetSurface(0, 0, null);
926 surface.Blit(source, dx,dy,0,0,sw,sh);
930 source.picture = null;
933 XDestroyImage(xImage);
937 void SetForeground(Display display, Surface surface, ColorAlpha color)
939 XSurface xSurface = surface.driverData;
940 XDisplay xDisplay = display ? display.driverData : null;
941 XRenderColor renderColor = { (uint16)(color.color.r * color.a), (uint16)(color.color.g * color.a), (uint16)(color.color.b * color.a), (uint16)(color.a * 255) };
943 if(xSurface.colorPicture)
944 XRenderFreePicture(xGlobalDisplay, xSurface.colorPicture);
945 // xSurface.colorPicture = XRenderCreateSolidFill(xGlobalDisplay, &renderColor);
948 XRenderPictureAttributes attributes = { 0 };
949 // XRenderPictFormat * format = myXRenderFindStandardFormat(xGlobalDisplay, PictStandardARGB32 /*PictStandardRGB24 /*PictStandardARGB32*/, 1);
950 XRenderPictFormat * format = /*(xSystemPixelFormat != pixelFormat888) ? GetXRenderFormat(xSystemPixelFormat, false) : */XRenderFindStandardFormat(xGlobalDisplay, PictStandardARGB32);
951 #if !defined(__APPLE__) && !defined(__OLDX__)
952 attributes.repeat = RepeatNormal;
954 attributes.repeat = 1;
956 ///attributes.component_alpha = 0;
958 xSurface.colorPicture = XRenderCreatePicture(xGlobalDisplay, xSurface.colorPixmap, format, /*CPComponentAlpha | */CPRepeat, &attributes);
959 XRenderFillRectangle(xGlobalDisplay, PictOpSrc, xSurface.colorPicture, &renderColor, 0, 0, 1, 1);
962 // xSurface.foreground = ARGB(A(color),B(color),G(color),R(color));
963 xSurface.foreground = color;
966 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.foreground :
967 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.foreground) : ((Color555)xSurface.foreground)));
970 void SetBackground(Display display, Surface surface, ColorAlpha color)
972 XSurface xSurface = surface.driverData;
973 XDisplay xDisplay = display ? display.driverData : null;
974 // xSurface.background = ARGB(A(color),B(color),G(color),R(color));
975 xSurface.background = color;
978 XSetBackground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.background :
979 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.background) : ((Color555)xSurface.background)));
982 ColorAlpha GetPixel(Display display, Surface surface, int x, int y)
987 void PutPixel(Display display, Surface surface,int x,int y)
989 XSurface xSurface = surface.driverData;
990 XDisplay xDisplay = display.driverData;
992 if(xSurface.foreground.a < 255)
993 DrawLine(display, surface, x,y,x,y);
995 XDrawPoint(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
996 x + surface.offset.x,
997 y + surface.offset.y);
1000 void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
1002 XDisplay xDisplay = display ? display.driverData : null;
1003 XSurface xSurface = surface.driverData;
1004 if(!xDisplay || xSurface.foreground.a < 255)
1006 XTrapezoid traps[3];
1008 double offset = 0.5;
1011 x1 += surface.offset.x;
1012 y1 += surface.offset.y;
1013 x2 += surface.offset.x;
1014 y2 += surface.offset.y;
1023 XDoubleToFixed(y1 - width + offset), XDoubleToFixed(y1 + width + offset),
1024 { { XDoubleToFixed(Min(x1, x2) - 0 + offset), XDoubleToFixed(y1 - width + offset) }, { XDoubleToFixed(Min(x1, x2) + 0.0 + offset), XDoubleToFixed(y1 + width+ offset) } },
1025 { { XDoubleToFixed(Max(x1, x2) - 0 + offset), XDoubleToFixed(y1 - width + offset) }, { XDoubleToFixed(Max(x1, x2) + 0.0 + offset), XDoubleToFixed(y1 + width+ offset) } }
1038 XDoubleToFixed(Min(y1, y2) - 0.0 + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset),
1039 { { XDoubleToFixed(x1 - width + offset), XDoubleToFixed(Min(y1, y2) - 0.0 + offset) }, { XDoubleToFixed(x1 - width + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset) } },
1040 { { XDoubleToFixed(x1 + width + offset), XDoubleToFixed(Min(y1, y2) - 0.0 + offset) }, { XDoubleToFixed(x1 + width + offset), XDoubleToFixed(Max(y1, y2) + 0.0 + offset) } }
1049 Pointf A, B, C, D, E, F;
1062 l = sqrt(dx * dx + dy * dy);
1068 A = { (float)(x1 + dy * width), (float)(y1 - dx * width) };
1069 B = { (float)(x1 - dy * width), (float)(y1 + dx * width) };
1070 C = { (float)(A.x + ((B.y - A.y) * dx / dy)), B.y };
1071 E = { (float)(x2 + dy * width), (float)(y2 - dx * width) };
1072 F = { (float)(x2 - dy * width), (float)(y2 + dx * width) };
1073 D = { (float)(F.x + ((E.y - F.y) * dx / dy)), E.y };
1078 XDoubleToFixed(A.y + offset), XDoubleToFixed(B.y + offset),
1079 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) } },
1080 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) } }
1084 XDoubleToFixed(B.y + offset), XDoubleToFixed(D.y + offset),
1085 { { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) }, { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) } },
1086 { { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) }, { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) } }
1090 XDoubleToFixed(D.y + offset), XDoubleToFixed(F.y + offset),
1091 { { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } },
1092 { { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } }
1102 A = { (float)(x1 - dy * width), (float)(y1 + dx * width) };
1103 B = { (float)(x1 + dy * width), (float)(y1 - dx * width) };
1104 C = { (float)(A.x + ((B.y - A.y) * dx / dy)), B.y };
1105 E = { (float)(x2 - dy * width), (float)(y2 + dx * width) };
1106 F = { (float)(x2 + dy * width), (float)(y2 - dx * width) };
1107 D = { (float)(F.x + ((E.y - F.y) * dx / dy)), E.y };
1112 XDoubleToFixed(A.y + offset), XDoubleToFixed(B.y + offset),
1113 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) } },
1114 { { XDoubleToFixed(A.x + offset), XDoubleToFixed(A.y + offset) }, { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) } }
1118 XDoubleToFixed(B.y + offset), XDoubleToFixed(D.y + offset),
1119 { { XDoubleToFixed(C.x + offset), XDoubleToFixed(C.y + offset) }, { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) } },
1120 { { XDoubleToFixed(B.x + offset), XDoubleToFixed(B.y + offset) }, { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) } }
1124 XDoubleToFixed(D.y + offset), XDoubleToFixed(F.y + offset),
1125 { { XDoubleToFixed(E.x + offset), XDoubleToFixed(E.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } },
1126 { { XDoubleToFixed(D.x + offset), XDoubleToFixed(D.y + offset) }, { XDoubleToFixed(F.x + offset), XDoubleToFixed(F.y + offset) } }
1135 printf("Line: (%d, %d)-(%d, %d)\n", x1,y1, x2,y2);
1136 printf("Line: A = (%.2f, %.2f), B = (%.2f, %.2f), C = (%.2f, %.2f)\n", A.x,A.y, B.x,B.y, C.x,C.y);
1137 printf("Line: D = (%.2f, %.2f), E = (%.2f, %.2f), F = (%.2f, %.2f)\n", D.x,D.y, E.x,E.y, F.x,F.y);
1138 printf("Trap1: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1139 traps[0].top / 65536.0, traps[0].bottom / 65536.0,
1140 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,
1141 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);
1142 printf("Trap2: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1143 traps[1].top / 65536.0, traps[1].bottom / 65536.0,
1144 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,
1145 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);
1146 printf("Trap3: top = %.2f, bottom = %.2f, left = (%.2f, %.2f)-(%.2f, %.2f), right = (%.2f, %.2f)-(%.2f, %.2f)\n",
1147 traps[2].top / 65536.0, traps[2].bottom / 65536.0,
1148 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,
1149 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);
1153 XRenderCompositeTrapezoids(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xSurface.picture, None, 0, 0, traps, nTraps);
1156 XDrawLine(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1157 x1 + surface.offset.x,
1158 y1 + surface.offset.y,
1159 x2 + surface.offset.x,
1160 y2 + surface.offset.y);
1163 void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
1165 XDisplay xDisplay = display ? display.driverData : null;
1166 XSurface xSurface = surface.driverData;
1168 if(!xDisplay || xSurface.foreground.a < 255)
1170 DrawLine(display, surface,x1,y1,x2-1,y1);
1171 DrawLine(display, surface,x2,y1,x2,y2-1);
1172 DrawLine(display, surface,x1,y2,x2-1,y2);
1173 DrawLine(display, surface,x1,y1+1,x1,y2-1);
1176 XDrawRectangle(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1177 x1 + surface.offset.x,
1178 y1 + surface.offset.y,
1182 void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
1184 XDisplay xDisplay = display ? display.driverData : null;
1185 XSurface xSurface = surface.driverData;
1186 if(!xDisplay || xSurface.background.a < 255)
1188 XRenderColor renderColor =
1190 (uint16)(xSurface.background.color.r * xSurface.background.a),
1191 (uint16)(xSurface.background.color.g * xSurface.background.a),
1192 (uint16)(xSurface.background.color.b * xSurface.background.a),
1193 (uint16)(xSurface.background.a * 255)
1195 x1 += surface.offset.x;
1196 y1 += surface.offset.y;
1197 x2 += surface.offset.x;
1198 y2 += surface.offset.y;
1199 XRenderFillRectangle(xGlobalDisplay, PictOpOver, xSurface.picture, &renderColor, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1);
1203 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.background :
1204 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.background) : ((Color555)xSurface.background)));
1205 XFillRectangle(xGlobalDisplay, (Pixmap) xDisplay.pixmap, xDisplay.gc,
1206 x1 + surface.offset.x,
1207 y1 + surface.offset.y,
1208 x2 - x1 + 1, y2 - y1 + 1);
1209 XSetForeground(xGlobalDisplay, xDisplay.gc, (xSystemPixelFormat == pixelFormat888) ? xSurface.foreground :
1210 ((xSystemPixelFormat == pixelFormat565) ? ((Color565)xSurface.foreground) : ((Color555)xSurface.foreground)));
1214 void Clear(Display display, Surface surface, ClearType flags)
1216 if(flags != depthBuffer)
1218 // XDisplay xDisplay = display.driverData;
1219 XSurface xSurface = surface.driverData;
1220 if(xSurface.background.a < 255)
1222 int x1 = surface.box.left;
1223 int y1 = surface.box.top;
1224 int x2 = surface.box.right;
1225 int y2 = surface.box.bottom;
1226 XRenderColor renderColor =
1228 (uint16)(xSurface.background.color.r * xSurface.background.a),
1229 (uint16)(xSurface.background.color.g * xSurface.background.a),
1230 (uint16)(xSurface.background.color.b * xSurface.background.a),
1231 (uint16)(xSurface.background.a * 255)
1233 x1 += surface.offset.x;
1234 y1 += surface.offset.y;
1235 x2 += surface.offset.x;
1236 y2 += surface.offset.y;
1237 XRenderFillRectangle(xGlobalDisplay, PictOpSrc, xSurface.picture, &renderColor, x1, y1, (x2 - x1) + 1, (y2 - y1) + 1);
1240 Area(display, surface,surface.box.left,surface.box.top,surface.box.right,surface.box.bottom);
1244 bool ConvertBitmap(DisplaySystem displaySystem, Bitmap src, PixelFormat format, ColorAlpha * palette)
1249 bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
1251 bool result = false;
1252 XBitmap xBitmap = bitmap.driverData = XBitmap { };
1257 switch(GetColorDepthShifts(format))
1259 case 0: stride = (width + 3) & 0xFFFFFFFC; break;
1260 case 1: stride = (width + 1) & 0xFFFFFFFE; break;
1261 case 2: stride = width; break;
1265 bitmap.stride = stride;
1266 bitmap.width = width;
1267 bitmap.height = height;
1268 bitmap.size = (uint)stride * (uint)height;
1269 bitmap.sizeBytes = bitmap.size << GetColorDepthShifts(format);
1270 bitmap.pixelFormat = format;
1271 bitmap.transparent = false;
1272 bitmap.allocatePalette = allocatePalette;
1275 bitmap.palette = new ColorAlpha[256];
1277 CopyBytesBy4(bitmap.palette, GetDefaultPalette(), 256);
1280 bitmap.palette = GetDefaultPalette();
1285 FreeBitmap(displaySystem, bitmap);
1291 void Blit(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1293 XDisplay xDisplay = display.driverData;
1294 XSurface xSurface = surface.driverData;
1295 XBitmap xBitmap = src.driverData;
1299 if(!ClipBlitCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &flip))
1302 dx += surface.offset.x;
1303 dy += surface.offset.y;
1305 if(src.transparent && !src.alphaBlend && !display.alphaBlend)
1307 XSetClipMask(xGlobalDisplay, xDisplay.gc, xBitmap.mask);
1308 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, dx - sx, dy - sy);
1310 if(xSurface.xOffset)
1312 XTransform transform =
1315 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), -(xSurface.xOffset << 10) },
1316 { (int)(0.0f), (int)(-1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1317 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1320 // printf("XOffset: %d\n", xSurface.xOffset);
1321 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &transform);
1324 if(src.alphaBlend || display.alphaBlend)
1326 if(src.pixelFormat == pixelFormatAlpha)
1328 XRenderComposite(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xBitmap.picture, xSurface.picture, 0, 0, sx, sy, dx, dy, w + (xSurface.xOffset ? 1 : 1), h);
1330 else if(src.alphaBlend)
1331 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, None, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1333 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, xBitmap.maskPicture, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1336 XCopyArea(xGlobalDisplay, (Pixmap)xBitmap.pixmap, (Pixmap)xSurface.pixmap, xDisplay.gc,
1337 sx, sy, w, h, dx, dy);
1339 if(xSurface.xOffset)
1341 XTransform identity =
1344 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1345 { (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1346 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1349 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &identity);
1351 if(src.transparent && !src.alphaBlend && !display.alphaBlend)
1353 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, 0, 0);
1355 XRectangle rectangle;
1357 rectangle.x = (short)(surface.unclippedBox.left + surface.offset.x);
1358 rectangle.y = (short)(surface.unclippedBox.top + surface.offset.y);
1359 rectangle.width = (short)(surface.unclippedBox.right - surface.unclippedBox.left + 1);
1360 rectangle.height = (short)(surface.unclippedBox.bottom - surface.unclippedBox.top + 1);
1362 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1368 void Stretch(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1370 XSurface xSurface = surface.driverData;
1371 XBitmap xBitmap = src.driverData;
1374 XTransform transform =
1377 { (int)((float)sw / w * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1378 { (int)(0.0f * (1<<16)), (int)((float)sh / h * (1<<16)), (int)(0.0f * (1<<16)) },
1379 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1382 XTransform identity =
1385 { (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1386 { (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)), (int)(0.0f * (1<<16)) },
1387 { (int)(0.0f * (1<<16)), (int)(0.0f * (1<<16)), (int)(1.0f * (1<<16)) }
1390 dx += surface.offset.x;
1391 dy += surface.offset.y;
1393 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &transform);
1395 if(src.pixelFormat == pixelFormatAlpha)
1396 XRenderComposite(xGlobalDisplay, PictOpOver, xSurface.colorPicture, xBitmap.picture, xSurface.picture, 0, 0, sx, sy, dx, dy, w, h);
1397 else if(src.alphaBlend)
1398 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, None, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1401 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.maskPicture, &transform);
1402 XRenderComposite(xGlobalDisplay, PictOpOver, xBitmap.picture, xBitmap.maskPicture, xSurface.picture, sx, sy, sx, sy, dx, dy, w, h);
1403 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.maskPicture, &identity);
1405 XRenderSetPictureTransform(xGlobalDisplay, xBitmap.picture, &identity);
1409 void Filter(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1411 XBitmap xBitmap = src.driverData;
1414 XRenderSetPictureFilter(xGlobalDisplay, xBitmap.picture, "bilinear", null, 0);
1415 Stretch(display, surface, src, dx, dy, sx, sy, w, h, sw, sh);
1416 XRenderSetPictureFilter(xGlobalDisplay, xBitmap.picture, "nearest", null, 0);
1420 void BlitDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
1422 XImage image = { 0 };
1423 XDisplay xDisplay = display ? display.driverData : null;
1424 XSurface xSurface = surface.driverData;
1427 if(!xDisplay || !src.picture || !ClipBlitCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &flip))
1430 if(src.pixelFormat == display.pixelFormat)
1432 image.width = src.width;
1433 image.height = src.height;
1434 image.depth = (src.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1435 image.bitmap_pad = (src.pixelFormat == pixelFormat888) ? 32 : 16;
1436 image.format = ZPixmap;
1437 image.bitmap_unit = 8;
1438 image.bytes_per_line = ((src.pixelFormat == pixelFormat888) ? 4 : 2) * src.stride;
1439 image.bits_per_pixel = (src.pixelFormat == pixelFormat888) ? 32 : 16;
1441 image.data = (char *)src.picture;
1444 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1445 sx, sy, dx + surface.offset.x, dy + surface.offset.y, w,h);
1451 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1452 s = temp.GetSurface(0,0,null);
1453 s.Blit(src, 0,0, sx,sy, flip ? -w : w, h);
1457 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1458 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1459 image.format = ZPixmap;
1460 image.bitmap_unit = 8;
1461 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1462 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1464 image.data = (char *)temp.picture;
1467 if(!src.transparent)
1469 // 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);
1470 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1471 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1476 GC maskGC = 0, gc = 0;
1477 Pixmap pixmap, mask;
1479 pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, xSystemDepth /*24*/);
1480 mask = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, 1);
1482 gc = XCreateGC(xGlobalDisplay, pixmap, 0, null);
1483 maskGC = XCreateGC(xGlobalDisplay, mask, 0, null);
1484 XSetGraphicsExposures(xGlobalDisplay, gc, False);
1485 XSetGraphicsExposures(xGlobalDisplay, maskGC, False);
1487 XPutImage(xGlobalDisplay, pixmap, gc, &image, 0, 0, 0, 0, w,h);
1488 XSetForeground(xGlobalDisplay, maskGC, 0);
1489 XFillRectangle(xGlobalDisplay, mask, maskGC, 0, 0, w, h);
1490 XSetForeground(xGlobalDisplay, maskGC, 1);
1491 if(temp.pixelFormat == pixelFormat888)
1494 for(y = 0; y<h; y++)
1496 for(x = 0; x<w; x++)
1498 if(((ColorAlpha *)temp.picture)[y * temp.stride + x].a)
1499 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1503 else if(src.pixelFormat == pixelFormat8)
1506 for(y = 0; y<h; y++)
1508 for(x = 0; x<w; x++)
1510 if(src.picture[(y + sy) * src.stride + (flip ? (w-1-(sx + x)) : (sx + x)])
1511 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1518 for(y = 0; y<h; y++)
1520 for(x = 0; x<w; x++)
1522 if(((uint16 *)temp.picture)[y * temp.stride + x])
1523 XDrawPoint(xGlobalDisplay, mask, maskGC, x, y);
1528 XFreeGC(xGlobalDisplay, maskGC);
1531 Pixmap pixmap, mask;
1533 pixmap = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, xSystemDepth /*24*/);
1534 mask = XCreatePixmap(xGlobalDisplay, (X11Window)confineWindow /*display.window*/, w, h, 1);
1536 gc = XCreateGC(xGlobalDisplay, pixmap, 0, null);
1537 XSetGraphicsExposures(xGlobalDisplay, gc, False);
1539 XPutImage(xGlobalDisplay, pixmap, gc, &image, 0, 0, 0, 0, w,h);
1541 PutBitmapMask(mask, temp);
1544 XSetClipMask(xGlobalDisplay, xDisplay.gc, mask);
1545 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, dx + surface.offset.x, dy + surface.offset.y);
1546 XCopyArea(xGlobalDisplay, pixmap, (Pixmap)xSurface.pixmap, xDisplay.gc, 0, 0, w, h, dx + surface.offset.x, dy + surface.offset.y);
1547 XSetClipOrigin(xGlobalDisplay, xDisplay.gc, 0, 0);
1549 XRectangle rectangle;
1551 rectangle.x = (short)(surface.unclippedBox.left + surface.offset.x);
1552 rectangle.y = (short)(surface.unclippedBox.top + surface.offset.y);
1553 rectangle.width = (short)(surface.unclippedBox.right - surface.unclippedBox.left + 1);
1554 rectangle.height = (short)(surface.unclippedBox.bottom - surface.unclippedBox.top + 1);
1556 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1559 XFreeGC(xGlobalDisplay, gc);
1560 XFreePixmap(xGlobalDisplay, pixmap);
1561 XFreePixmap(xGlobalDisplay, mask);
1568 void StretchDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1571 if(ClipStretchCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &sw, &sh, &flip))
1573 XImage image = { 0 };
1574 XDisplay xDisplay = display.driverData;
1575 XSurface xSurface = surface.driverData;
1578 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1579 s = temp.GetSurface(0,0,null);
1580 s.Stretch(src, 0,0, sx,sy, w, h, sw, sh);
1584 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1585 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1586 image.format = ZPixmap;
1587 image.bitmap_unit = 8;
1588 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1589 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1591 image.data = (char *)temp.picture;
1594 // printf("Blitting DI\n");
1595 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1596 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1603 void FilterDI(Display display, Surface surface, Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
1606 if(ClipStretchCoords(surface, src, &dx, &dy, &sx, &sy, &w, &h, &sw, &sh, &flip))
1608 XImage image = { 0 };
1609 XDisplay xDisplay = display.driverData;
1610 XSurface xSurface = surface.driverData;
1613 temp.Allocate(null, w, h, 0, xSystemPixelFormat, false);
1614 s = temp.GetSurface(0,0,null);
1615 s.Filter(src, 0,0, sx,sy, w, h, sw, sh);
1619 image.depth = (temp.pixelFormat == pixelFormat888) ? 24 : xSystemDepth;
1620 image.bitmap_pad = (temp.pixelFormat == pixelFormat888) ? 32 : 16;
1621 image.format = ZPixmap;
1622 image.bitmap_unit = 8;
1623 image.bytes_per_line = ((temp.pixelFormat == pixelFormat888) ? 4 : 2) * temp.stride;
1624 image.bits_per_pixel = (temp.pixelFormat == pixelFormat888) ? 32 : 16;;
1626 image.data = (char *)temp.picture;
1629 // printf("Blitting DI\n");
1630 XPutImage(xGlobalDisplay, (Pixmap)xSurface.pixmap, xDisplay.gc, &image,
1631 0, 0, dx + surface.offset.x, dy + surface.offset.y, w,h);
1638 Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
1641 font = ((subclass(DisplayDriver))class(LFBDisplayDriver)).LoadFont(displaySystem, faceName, size, flags);
1645 void UnloadFont(DisplaySystem displaySystem, Font font)
1647 ((subclass(DisplayDriver))class(LFBDisplayDriver)).UnloadFont(displaySystem, font);
1650 void TextFont(Display display, Surface surface, Font font)
1652 // XSurface xSurface = surface.driverData;
1653 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextFont(display, surface, font);
1656 void TextOpacity(Display display, Surface surface, bool opaque)
1658 XSurface xSurface = surface.driverData;
1659 xSurface.opaque = opaque;
1662 #define CHAR_WIDTH 6
1663 #define CHAR_HEIGHT 14
1665 void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
1667 XSurface xSurface = surface.driverData;
1668 //XDisplay xDisplay = display.driverData;
1671 ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, &tw, &th);
1675 XSetForeground(xGlobalDisplay, xDisplay.gc, xSurface.background);
1677 XFillRectangle(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1678 x + surface.offset.x, y + surface.offset.y,
1679 tw /*len * CHAR_WIDTH*/, th /*CHAR_HEIGHT*/);
1681 XSetForeground(xGlobalDisplay, xDisplay.gc, xSurface.foreground);
1684 XRenderColor renderColor =
1686 (uint16)(xSurface.background.color.r * xSurface.background.a),
1687 (uint16)(xSurface.background.color.g * xSurface.background.a),
1688 (uint16)(xSurface.background.color.b * xSurface.background.a),
1689 (uint16)xSurface.background.a
1691 //printf("Filling rectangle\n");
1692 XRenderFillRectangle(xGlobalDisplay, PictOpSrc /*PictOpOver*/, xSurface.picture, &renderColor,
1693 x + surface.offset.x, y + surface.offset.y, tw, th);
1696 XDrawString(xGlobalDisplay, (Pixmap)xDisplay.pixmap, xDisplay.gc,
1697 x + surface.offset.x, y + surface.offset.y + 12, text, len);
1700 ((subclass(DisplayDriver))class(LFBDisplayDriver)).WriteText(display, surface, x, y, text, len);
1703 void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
1705 XSurface xSurface = surface.driverData;
1708 for(realLen = 0; realLen<len && text[realLen]; realLen++);
1709 if(width) *width = len * CHAR_WIDTH;
1710 if(height) *height = CHAR_HEIGHT;
1713 FontExtent(display.displaySystem, xSurface.font, text, len, width, height);
1716 void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
1719 if(width) *width = len * CHAR_WIDTH;
1720 if(height) *height = CHAR_HEIGHT;
1722 ((subclass(DisplayDriver))class(LFBDisplayDriver)).FontExtent(displaySystem, font, text, len, width, height);
1725 void DrawingChar(Display display, Surface surface, byte character)
1730 void LineStipple(Display display, Surface surface, uint stipple)
1732 XDisplay xDisplay = display.driverData;
1733 char list[32] = { 0 };
1742 for(c = 0; c<32; c++)
1744 if((stipple & 0x8000) == on)
1759 XSetLineAttributes(xGlobalDisplay, xDisplay.gc, 0, LineOnOffDash, CapButt, JoinMiter);
1760 XSetDashes(xGlobalDisplay, xDisplay.gc, offset, list, count);
1766 XSetLineAttributes(xGlobalDisplay, xDisplay.gc, 0, LineSolid, CapButt, JoinMiter);
1767 XSetDashes(xGlobalDisplay, xDisplay.gc, 0, list, count);
1771 bool Lock(Display display)
1773 //XLockDisplay(xGlobalDisplay);
1777 void Unlock(Display display)
1779 //XUnlockDisplay(xGlobalDisplay);
1782 void StartUpdate(Display display)
1787 void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
1792 void Update(Display display, Box updateBox)
1794 XDisplay xDisplay = display.driverData;
1795 Box * box = (updateBox != null) ? updateBox : &xDisplay.updateBox;
1798 XRectangle rectangle;
1801 rectangle.width = (uint16)display.width;
1802 rectangle.height = (uint16)display.height;
1803 XSetClipRectangles(xGlobalDisplay, xDisplay.gc, 0,0, &rectangle, 1, YXBanded);
1805 /*if(display.alphaBlend)
1806 XRenderComposite(xGlobalDisplay, PictOpSrc, xDisplay.picture, None, xDisplay.windowPicture, box->left, box->top, 0, 0, box->left, box->top,
1807 box->right - box->left + 1, box->bottom - box->top + 1);
1809 XCopyArea(xGlobalDisplay, (Pixmap)xDisplay.pixmap, (X11Window)display.window, xDisplay.gc /*windowGC*/,
1810 box->left, box->top,
1811 box->right - box->left + 1,
1812 box->bottom - box->top + 1,
1813 box->left, box->top);
1815 if(display.alphaBlend)
1817 Box * box = &xDisplay.updateBox;
1818 XRenderComposite(xGlobalDisplay, PictOpSrc, xDisplay.picture, None, xDisplay.shapePicture, box->left, box->top, 0, 0, box->left, box->top,
1819 box->right - box->left + 1, box->bottom - box->top + 1);
1820 #if !defined(__APPLE__) && !defined(__OLDX__)
1821 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, ShapeInput, 0, 0, xDisplay.shapePixmap, ShapeSet);
1823 XShapeCombineMask(xGlobalDisplay, (X11Window)display.window, 2, 0, 0, xDisplay.shapePixmap, ShapeSet);
1827 XFlush(xGlobalDisplay);
1828 if(updateBox == null)
1830 xDisplay.updateBox.left = display.width;
1831 xDisplay.updateBox.top = display.height;
1832 xDisplay.updateBox.right = 0;
1833 xDisplay.updateBox.bottom = 0;
1837 void EndUpdate(Display display)
1843 default dllexport long IS_XGetPixmap(Bitmap bitmap)
1845 XBitmap xBitmap = bitmap.driverData;
1846 return xBitmap.pixmap;
1849 default dllexport void IS_XGetSurfaceInfo(Surface surface, Pixmap * pixmap, GC * gc, int *x, int * y)
1851 Display display = surface.display;
1852 XDisplay xDisplay = display.driverData;
1854 *pixmap = xDisplay.pixmap;
1856 *x = surface.offset.x;
1857 *y = surface.offset.y;