2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
9 #include <proto/utility.h>
11 #include "x11_types.h"
13 #include "x11_hostlib.h"
14 #include "x11gfx_bitmap.h"
17 /****************************************************************************************/
19 #define DO_ENDIAN_FIX 1 /* fix if X11 server running on remote server with different endianess */
21 /****************************************************************************************/
23 #define MNAME(x) X11BM__ ## x
28 #define NEEDS_ENDIAN_FIX(image) (((image)->bits_per_pixel >= 15) && ((image)->byte_order != MSBFirst))
29 #define SWAP16(x) AROS_WORD2LE(x)
30 #define SWAP32(x) AROS_LONG2LE(x)
31 #define AROS_BYTEORDER MSBFirst
33 #define NEEDS_ENDIAN_FIX(image) (((image)->bits_per_pixel >= 15) && ((image)->byte_order != LSBFirst))
34 #define SWAP16(x) AROS_WORD2BE(x)
35 #define SWAP32(x) AROS_LONG2BE(x)
36 #define AROS_BYTEORDER LSBFirst
39 #if 0 /* stegerg: to test above stuff*/
40 #define NEEDS_ENDIAN_FIX(image) ((image)->bits_per_pixel >= 15)
41 #define AROS_BYTEORDER MSBFirst
42 #define SWAP16(x) AROS_WORD2BE(x)
43 #define SWAP32(x) AROS_LONG2BE(x)
46 /****************************************************************************************/
48 OOP_Object
*X11BM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
50 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
52 o
= (OOP_Object
*) OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
55 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
59 /* Get some info passed to us by the x11gfxhidd class */
60 data
->display
= (Display
*) GetTagData(aHidd_BitMap_X11_SysDisplay
, 0, msg
->attrList
);
61 data
->screen
= GetTagData(aHidd_BitMap_X11_SysScreen
, 0, msg
->attrList
);
62 data
->cursor
= (Cursor
) GetTagData(aHidd_BitMap_X11_SysCursor
, 0, msg
->attrList
);
63 data
->colmap
= (Colormap
) GetTagData(aHidd_BitMap_X11_ColorMap
, 0, msg
->attrList
);
64 framebuffer
= GetTagData(aHidd_BitMap_FrameBuffer
, FALSE
, msg
->attrList
);
67 bug("[X11Bm] %s: display @ 0x%p, screen #%d\n", __PRETTY_FUNCTION__
, data
->display
, data
->screen
);
68 bug("[X11Bm] %s: cursor @ 0x%p, colormap @ 0x%p\n", __PRETTY_FUNCTION__
, data
->cursor
, data
->colmap
);
73 /* Framebuffer is X11 window */
74 data
->flags
|= BMDF_FRAMEBUFFER
;
75 ok
= X11BM_InitFB(cl
, o
, msg
->attrList
);
79 /* Anything else is a pixmap */
80 ok
= X11BM_InitPM(cl
, o
, msg
->attrList
);
85 /* Create an X11 GC. All objects need it. */
88 gcval
.plane_mask
= AllPlanes
;
89 gcval
.graphics_exposures
= False
;
93 data
->gc
= XCALL(XCreateGC
, data
->display
, DRAWABLE(data
),
94 GCPlaneMask
| GCGraphicsExposures
, &gcval
);
100 else if (framebuffer
)
101 X11BM_InitEmptyCursor(data
);
105 if (ok
&& (data
->flags
& BMDF_FRAMEBUFFER
) != 0)
107 ok
= X11BM_NotifyFB(cl
, o
);
112 OOP_MethodID disp_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
114 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
117 } /* if (object allocated by superclass) */
119 D(bug("[X11Bm] %s: returning object @ 0x%p\n", __PRETTY_FUNCTION__
, o
));
123 /****************************************************************************************/
125 VOID
X11BM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
127 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
129 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
134 XCALL(XFreeGC
, data
->display
, data
->gc
);
138 if (data
->flags
& BMDF_FRAMEBUFFER
)
139 X11BM_DisposeFB(data
, XSD(cl
));
141 X11BM_DisposePM(data
);
143 OOP_DoSuperMethod(cl
, o
, msg
);
146 /****************************************************************************************/
148 VOID
X11BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_Clear
*msg
)
150 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
152 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
156 if (data
->flags
& BMDF_FRAMEBUFFER
)
157 X11BM_ClearFB(data
, GC_BG(msg
->gc
));
159 X11BM_ClearPM(data
, GC_BG(msg
->gc
));
164 /****************************************************************************************/
166 static void SwapImageEndianess(XImage
*image
)
168 LONG x
, y
, height
, width
, bpp
;
169 UBYTE
*imdata
= (UBYTE
*) image
->data
;
171 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
173 width
= image
->width
;
174 height
= image
->height
;
175 bpp
= (image
->bits_per_pixel
+ 7) / 8;
177 for (y
= 0; y
< height
; y
++)
182 for (x
= 0; x
< width
; x
++, imdata
+= 2)
184 UWORD pix
= *(UWORD
*) imdata
;
188 *(UWORD
*) imdata
= pix
;
190 imdata
+= (image
->bytes_per_line
- width
* 2);
194 for (x
= 0; x
< width
; x
++, imdata
+= 3)
196 UBYTE pix1
= imdata
[0];
197 UBYTE pix3
= imdata
[2];
202 imdata
+= (image
->bytes_per_line
- width
* 3);
206 for (x
= 0; x
< width
; x
++, imdata
+= 4)
208 ULONG pix
= *(ULONG
*) imdata
;
212 *(ULONG
*) imdata
= pix
;
214 imdata
+= (image
->bytes_per_line
- width
* 4);
219 } /* for (y = 0; y < height; y ++) */
221 image
->byte_order
= AROS_BYTEORDER
;
224 /****************************************************************************************/
226 #endif /* DO_ENDIAN_FIX */
228 /****************************************************************************************/
230 BOOL
MNAME(Hidd_BitMap__SetColors
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
232 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
233 HIDDT_PixelFormat
*pf
;
236 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
238 if (!OOP_DoSuperMethod(cl
, o
, &msg
->mID
))
243 if (vHidd_ColorModel_StaticPalette
== HIDD_PF_COLMODEL(pf
) || vHidd_ColorModel_TrueColor
== HIDD_PF_COLMODEL(pf
))
245 /* Superclass has taken care of this case */
249 /* Ve have a vHidd_GT_Palette bitmap */
251 if (data
->flags
& BMDF_COLORMAP_ALLOCED
)
255 for (xc_i
= msg
->firstColor
, col_i
= 0; col_i
< msg
->numColors
; xc_i
++, col_i
++)
259 xcol
.red
= msg
->colors
[col_i
].red
;
260 xcol
.green
= msg
->colors
[col_i
].green
;
261 xcol
.blue
= msg
->colors
[col_i
].blue
;
264 xcol
.flags
= DoRed
| DoGreen
| DoBlue
;
266 XCALL(XStoreColor
, data
->display
, data
->colmap
, &xcol
);
272 } /* if (data->flags & BMDF_COLORMAP_ALLOCED) */
277 /****************************************************************************************/
279 VOID
MNAME(Hidd_BitMap__PutPixel
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
281 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
283 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
287 XCALL(XSetForeground
, data
->display
, data
->gc
, msg
->pixel
);
288 XCALL(XSetFunction
, data
->display
, data
->gc
, GXcopy
);
289 XCALL(XDrawPoint
, data
->display
, DRAWABLE(data
), data
->gc
, msg
->x
, msg
->y
);
294 /****************************************************************************************/
296 HIDDT_Pixel
MNAME(Hidd_BitMap__GetPixel
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetPixel
*msg
)
298 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
299 HIDDT_Pixel pixel
= -1;
302 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
306 XCALL(XSync
, data
->display
, False
);
308 image
= XCALL(XGetImage
, data
->display
, DRAWABLE(data
), msg
->x
, msg
->y
, 1, 1, AllPlanes
, ZPixmap
);
312 pixel
= XGetPixel(image
, 0, 0);
313 XDestroyImage(image
);
322 /****************************************************************************************/
324 ULONG
MNAME(Hidd_BitMap__DrawPixel
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawPixel
*msg
)
326 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
329 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
331 gcval
.function
= GC_DRMD(msg
->gc
);
332 gcval
.foreground
= GC_FG(msg
->gc
);
333 gcval
.background
= GC_BG(msg
->gc
);
336 XCALL(XChangeGC
, data
->display
, data
->gc
, GCFunction
| GCForeground
| GCBackground
, &gcval
);
337 XCALL(XDrawPoint
, data
->display
, DRAWABLE(data
), data
->gc
, msg
->x
, msg
->y
);
343 /****************************************************************************************/
345 VOID
MNAME(Hidd_BitMap__FillRect
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
347 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
350 D(bug("[X11Bm] %s(%d,%d,%d,%d)\n", __PRETTY_FUNCTION__
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->maxY
));
351 D(bug("[X11Bm] %s: Drawmode = %d\n", __PRETTY_FUNCTION__
, GC_DRMD(msg
->gc
)));
353 gcval
.function
= GC_DRMD(msg
->gc
);
354 gcval
.foreground
= GC_FG(msg
->gc
);
355 gcval
.background
= GC_BG(msg
->gc
);
358 XCALL(XChangeGC
, data
->display
, data
->gc
, GCFunction
| GCForeground
| GCBackground
, &gcval
);
360 XCALL(XFillRectangle
, data
->display
, DRAWABLE(data
), data
->gc
, msg
->minX
, msg
->minY
, msg
->maxX
- msg
->minX
+ 1, msg
->maxY
- msg
->minY
+ 1);
365 /****************************************************************************************/
367 static ULONG
*ximage_to_buf(OOP_Class
*cl
, OOP_Object
*bm
, HIDDT_Pixel
*buf
, XImage
*image
, ULONG width
, ULONG height
,
368 ULONG depth
, struct pHidd_BitMap_GetImage
*msg
)
370 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
374 case vHidd_StdPixFmt_Native
:
376 UBYTE
*imdata
= image
->data
;
379 for (y
= 0; y
< height
; y
++)
381 memcpy(buf
, imdata
, msg
->width
* image
->bits_per_pixel
/ 8);
383 imdata
+= image
->bytes_per_line
;
384 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
389 case vHidd_StdPixFmt_Native32
:
390 switch (image
->bits_per_pixel
)
394 UBYTE
*imdata
= (UBYTE
*) image
->data
;
397 for (y
= 0; y
< height
; y
++)
399 HIDDT_Pixel
*p
= buf
;
401 for (x
= 0; x
< width
; x
++)
405 imdata
+= (image
->bytes_per_line
- width
);
406 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
413 UWORD
*imdata
= (UWORD
*) image
->data
;
416 for (y
= 0; y
< height
; y
++)
418 HIDDT_Pixel
*p
= buf
;
420 for (x
= 0; x
< width
; x
++)
424 imdata
+= image
->bytes_per_line
/ 2 - width
;
425 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
432 ULONG
*imdata
= (ULONG
*) image
->data
;
435 for (y
= 0; y
< height
; y
++)
437 HIDDT_Pixel
*p
= buf
;
439 for (x
= 0; x
< width
; x
++)
443 imdata
+= image
->bytes_per_line
/ 4 - width
;
444 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
454 for (y
= 0; y
< height
; y
++)
459 for (x
= 0; x
< width
; x
++)
461 *p
++ = XGetPixel(image
, x
, y
);
463 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
469 } /* switch (image->bits_per_pixel) */
476 OOP_Object
*srcpf
, *dstpf
, *gfxhidd
;
477 APTR srcPixels
= image
->data
, dstBuf
= buf
;
479 //bug("DEFAULT PIXEL CONVERSION\n");
481 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, (IPTR
*) &gfxhidd
);
482 dstpf
= HIDD_Gfx_GetPixFmt(gfxhidd
, msg
->pixFmt
);
484 OOP_GetAttr(bm
, aHidd_BitMap_PixFmt
, (IPTR
*) &srcpf
);
486 //bug("CALLING ConvertPixels()\n");
488 HIDD_BM_ConvertPixels(bm
, &srcPixels
, (HIDDT_PixelFormat
*) srcpf
, image
->bytes_per_line
, &dstBuf
,
489 (HIDDT_PixelFormat
*) dstpf
, msg
->modulo
, width
, height
, NULL
/* We have no CLUT */
492 //bug("CONVERTPIXELS DONE\n");
494 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
* height
);
498 } /* switch (msg->pixFmt) */
503 /****************************************************************************************/
505 #define ABS(a) ((a) < 0 ? -(a) : a)
507 /****************************************************************************************/
509 static inline UBYTE
pix_to_lut(HIDDT_Pixel pixel
, HIDDT_PixelLUT
*plut
, HIDDT_PixelFormat
*pf
)
511 HIDDT_ColComp red
, green
, blue
;
512 ULONG i
, best_match
= 0;
513 ULONG diff
, lowest_diff
= 0xFFFFFFFF;
515 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
517 red
= RED_COMP(pixel
, pf
);
518 green
= GREEN_COMP(pixel
, pf
);
519 blue
= BLUE_COMP(pixel
, pf
);
521 for (i
= 0; i
< plut
->entries
; i
++)
523 register HIDDT_Pixel cur_lut
= plut
->pixels
[i
];
525 if (pixel
== cur_lut
)
526 return i
; /* Exact match found */
528 /* How well does these pixels match ? */
529 diff
= ABS(red
- RED_COMP(cur_lut
, pf
)) + ABS(green
- GREEN_COMP(cur_lut
, pf
))
530 + ABS(blue
- BLUE_COMP(cur_lut
, pf
));
532 if (diff
< lowest_diff
)
543 /****************************************************************************************/
545 static UBYTE
*ximage_to_buf_lut(OOP_Class
*cl
, OOP_Object
*bm
, UBYTE
*buf
, XImage
*image
, ULONG width
, ULONG height
,
546 ULONG depth
, struct pHidd_BitMap_GetImageLUT
*msg
)
548 /* This one is trickier, as we have to reverse-lookup the lut.
549 This costs CPU ! Maybe one could do some kind of caching here ?
550 Ie. one stores the most often used RGB combinations
551 in a trie and looks up this first to see if whe can find an exact match
554 HIDDT_PixelFormat
*pf
= BM_PIXFMT(bm
);
555 UBYTE
*pixarray
= msg
->pixels
;
557 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
559 if (image
->bits_per_pixel
== 16)
561 UWORD
*imdata
= (UWORD
*) image
->data
;
564 for (y
= 0; y
< height
; y
++)
566 UBYTE
*buf
= pixarray
;
568 for (x
= 0; x
< width
; x
++)
570 *buf
++ = pix_to_lut((HIDDT_Pixel
) *imdata
, msg
->pixlut
, pf
);
574 imdata
+= ((image
->bytes_per_line
/ 2) - width
); /*sg*/
576 pixarray
+= msg
->modulo
;
585 for (y
= 0; y
< height
; y
++)
587 UBYTE
*buf
= pixarray
;
588 for (x
= 0; x
< width
; x
++)
590 *buf
++ = pix_to_lut((HIDDT_Pixel
) XGetPixel(image
, x
, y
), msg
->pixlut
, pf
);
593 pixarray
+= msg
->modulo
;
604 /****************************************************************************************/
608 /****************************************************************************************/
610 static void getimage_xshm(OOP_Class
*cl
, OOP_Object
*o
, LONG x
, LONG y
,
611 ULONG width
, ULONG height
, APTR pixarray
,
612 APTR (*fromimage_func
)(), APTR fromimage_data
)
614 struct bitmap_data
*data
;
622 Pixmap temp_pixmap
= 0;
624 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
626 ASSERT(width
> 0 && height
> 0);
628 data
= OOP_INST_DATA(cl
, o
);
630 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
631 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
633 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
636 image
= create_xshm_ximage(data
->display
,
637 DefaultVisual(data
->display
, data
->screen
),
648 ASSERT(image
->bytes_per_line
> 0);
650 /* Calculate how many scanline can be stored in the buffer */
651 maxlines
= XSHM_MEMSIZE
/ image
->bytes_per_line
;
655 bug("ALERT !!! NOT ENOUGH MEMORY TO READ A COMPLETE SCANLINE\n");
656 bug("THROUGH XSHM IN X11GF X HIDD !!!\n");
661 ysize
= image
->height
;
663 ObtainSemaphore(&XSD(cl
)->shm_sema
);
669 /* Get some more pixels from the Ximage */
671 lines_to_copy
= MIN(maxlines
, ysize
);
673 ysize
-= lines_to_copy
;
674 image
->height
= lines_to_copy
;
678 if (!(get_xshm_ximage(data
->display
, DRAWABLE(data
), image
,
681 /* XGetImage fails if done on a part of a X window which is off
682 screen (OTOH, it's no problem if it is hidden by another window).
683 If get_xshm_image() failed, we assume that this has happened and
684 thefore copy the area to a temp pixmap, and then get the ximage
687 temp_pixmap
= XCALL(XCreatePixmap
, data
->display
, DRAWABLE(data
),
688 width
, height
- current_y
, DefaultDepth(data
->display
, data
->screen
));
692 XCALL(XSetFunction
, data
->display
, data
->gc
, GXcopy
);
694 XCALL(XCopyArea
, data
->display
, DRAWABLE(data
), temp_pixmap
, data
->gc
,
695 x
, y
+ current_y
, width
, height
- current_y
, 0, 0);
697 XCALL(XSetFunction
, data
->display
, data
->gc
, GC_DRMD(data
->gc
));
699 x
= 0; y
= 0; current_y
= 0;
706 get_xshm_ximage(data
->display
, temp_pixmap
, image
,
710 current_y
+= lines_to_copy
;
712 pixarray
= fromimage_func(cl
, o
, pixarray
, image
, image
->width
,
713 lines_to_copy
, depth
, fromimage_data
);
715 } /* while (pixels left to copy) */
719 XCALL(XFreePixmap
,data
->display
, temp_pixmap
);
724 ReleaseSemaphore(&XSD(cl
)->shm_sema
);
727 destroy_xshm_ximage(image
);
734 /****************************************************************************************/
738 /****************************************************************************************/
740 static void getimage_xlib(OOP_Class
*cl
, OOP_Object
*o
, LONG x
, LONG y
, ULONG width
, ULONG height
, APTR pixels
,
741 APTR(*fromimage_func
)(), APTR fromimage_data
)
743 struct bitmap_data
*data
;
745 ULONG
*pixarray
= (ULONG
*) pixels
;
749 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
751 data
= OOP_INST_DATA(cl
, o
);
753 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*) &pf
);
754 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
757 image
= XCALL(XGetImage
, data
->display
, DRAWABLE(data
), x
, y
,
758 width
, height
, AllPlanes
, ZPixmap
);
765 if (NEEDS_ENDIAN_FIX(image
))
767 SwapImageEndianess(image
);
770 XCALL(XInitImage
, image
);
775 fromimage_func(cl
, o
, pixarray
, image
, width
, height
, depth
, fromimage_data
);
778 XDestroyImage(image
);
784 /****************************************************************************************/
786 VOID
MNAME(Hidd_BitMap__GetImage
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
788 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
790 ASSERT(msg
->width
> 0 && msg
->height
> 0);
793 if (XSD(cl
)->use_xshm
)
795 getimage_xshm(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
,
796 msg
->pixels
, (APTR (*)())ximage_to_buf
, msg
);
801 getimage_xlib(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, msg
->pixels
, (APTR(*)()) ximage_to_buf
, msg
);
805 /****************************************************************************************/
807 VOID
MNAME(Hidd_BitMap__GetImageLUT
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImageLUT
*msg
)
809 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
811 ASSERT(msg
->width
!= 0 && msg
->height
!= 0);
813 if (XSD(cl
)->use_xshm
)
815 getimage_xshm(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
,
816 msg
->pixels
, (APTR (*)())ximage_to_buf_lut
, msg
);
821 getimage_xlib(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, msg
->pixels
, (APTR(*)()) ximage_to_buf_lut
, msg
);
825 /****************************************************************************************/
829 #include <aros/debug.h>
831 /****************************************************************************************/
833 static ULONG
*buf_to_ximage(OOP_Class
*cl
, OOP_Object
*bm
, HIDDT_Pixel
*buf
, XImage
*image
, ULONG width
, ULONG height
,
834 ULONG depth
, struct pHidd_BitMap_PutImage
*msg
)
836 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
840 case vHidd_StdPixFmt_Native
:
842 UBYTE
*imdata
= image
->data
;
845 for (y
= 0; y
< height
; y
++)
847 memcpy(imdata
, buf
, msg
->width
* image
->bits_per_pixel
/ 8);
849 imdata
+= image
->bytes_per_line
;
850 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
855 case vHidd_StdPixFmt_Native32
:
856 switch (image
->bits_per_pixel
)
860 UBYTE
*imdata
= (UBYTE
*) image
->data
;
863 for (y
= 0; y
< height
; y
++)
865 HIDDT_Pixel
*p
= buf
;
867 for (x
= 0; x
< width
; x
++)
869 *imdata
++ = (UBYTE
) *p
++;
871 imdata
+= image
->bytes_per_line
- width
;
872 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
879 UWORD
*imdata
= (UWORD
*) image
->data
;
882 for (y
= 0; y
< height
; y
++)
884 HIDDT_Pixel
*p
= buf
;
886 for (x
= 0; x
< width
; x
++)
888 *imdata
++ = (UWORD
) *p
++;
890 imdata
+= image
->bytes_per_line
/ 2 - width
;
891 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
898 HIDDT_PixelFormat
*pf
;
899 UBYTE
*imdata
= image
->data
;
904 for (y
= 0; y
< height
; y
++)
907 HIDDT_Pixel
*p
= buf
;
909 for (x
= 0; x
< width
; x
++)
911 register HIDDT_Pixel pix
;
914 #if (AROS_BIG_ENDIAN == 1)
915 *imdata
++ = pix
>> 16;
916 *imdata
++ = (pix
& pf
->green_mask
) >> 8;
917 *imdata
++ = (pix
& pf
->blue_mask
);
919 *imdata
++ = (pix
& pf
->blue_mask
);
920 *imdata
++ = (pix
& pf
->green_mask
) >> 8;
921 *imdata
++ = pix
>> 16;
924 imdata
+= image
->bytes_per_line
- width
* 3;
925 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
932 ULONG
*imdata
= (ULONG
*) image
->data
;
935 for (y
= 0; y
< height
; y
++)
937 HIDDT_Pixel
*p
= buf
;
939 for (x
= 0; x
< width
; x
++)
941 *imdata
++ = (ULONG
) *p
++;
943 imdata
+= image
->bytes_per_line
/ 4 - width
;
944 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
954 for (y
= 0; y
< height
; y
++)
959 for (x
= 0; x
< width
; x
++)
961 XPutPixel(image
, x
, y
, *p
++);
963 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
);
969 } /* switch (image->bits_per_pixel) */
975 OOP_Object
*srcpf
, *dstpf
, *gfxhidd
;
976 APTR srcPixels
= buf
, dstBuf
= image
->data
;
978 //bug("DEFAULT PIXEL CONVERSION\n");
980 OOP_GetAttr(bm
, aHidd_BitMap_GfxHidd
, (IPTR
*) &gfxhidd
);
981 srcpf
= HIDD_Gfx_GetPixFmt(gfxhidd
, msg
->pixFmt
);
983 OOP_GetAttr(bm
, aHidd_BitMap_PixFmt
, (IPTR
*) &dstpf
);
985 //bug("CALLING ConvertPixels()\n");
987 HIDD_BM_ConvertPixels(bm
, &srcPixels
, (HIDDT_PixelFormat
*) srcpf
, msg
->modulo
, &dstBuf
,
988 (HIDDT_PixelFormat
*) dstpf
, image
->bytes_per_line
, width
, height
, NULL
); /* We have no CLUT */
990 //bug("CONVERTPIXELS DONE\n");
992 buf
= (HIDDT_Pixel
*) ((UBYTE
*) buf
+ msg
->modulo
* height
);
996 } /* switch (msg->pixFmt) */
1001 /****************************************************************************************/
1003 static UBYTE
*buf_to_ximage_lut(OOP_Class
*cl
, OOP_Object
*bm
, UBYTE
*pixarray
, XImage
*image
, ULONG width
,
1004 ULONG height
, ULONG depth
, struct pHidd_BitMap_PutImageLUT
*msg
)
1006 HIDDT_Pixel
*lut
= msg
->pixlut
->pixels
;
1008 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1010 switch (image
->bits_per_pixel
)
1014 UBYTE
*imdata
= (UBYTE
*) image
->data
;
1017 for (y
= 0; y
< height
; y
++)
1019 UBYTE
*buf
= pixarray
;
1021 for (x
= 0; x
< width
; x
++)
1023 *imdata
++ = (UBYTE
) lut
[*buf
++];
1025 pixarray
+= msg
->modulo
;
1026 imdata
+= (image
->bytes_per_line
- width
); /*sg*/
1033 UWORD
*imdata
= (UWORD
*) image
->data
;
1036 for (y
= 0; y
< height
; y
++)
1038 UBYTE
*buf
= pixarray
;
1040 for (x
= 0; x
< width
; x
++)
1042 *imdata
++ = (UWORD
) lut
[*buf
++];
1044 pixarray
+= msg
->modulo
;
1045 imdata
+= ((image
->bytes_per_line
/ 2) - width
); /*sg*/
1052 ULONG
*imdata
= (ULONG
*) image
->data
;
1055 for (y
= 0; y
< height
; y
++)
1057 UBYTE
*buf
= pixarray
;
1059 for (x
= 0; x
< width
; x
++)
1061 *imdata
++ = (ULONG
) lut
[*buf
++];
1064 pixarray
+= msg
->modulo
;
1065 imdata
+= ((image
->bytes_per_line
/ 4) - width
); /*sg*/
1074 for (y
= 0; y
< height
; y
++)
1076 UBYTE
*buf
= pixarray
;
1078 for (x
= 0; x
< width
; x
++)
1080 XPutPixel(image
, x
, y
, lut
[*buf
++]);
1083 pixarray
+= msg
->modulo
;
1090 } /* switch(image->bits_per_pixel) */
1095 /****************************************************************************************/
1099 /****************************************************************************************/
1101 static void putimage_xshm(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*gc
,
1102 LONG x
, LONG y
, ULONG width
, ULONG height
,
1103 APTR pixarray
, APTR (*toimage_func
)(), APTR toimage_data
)
1106 struct bitmap_data
*data
;
1109 ULONG lines_to_copy
;
1115 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1117 data
= OOP_INST_DATA(cl
, o
);
1119 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
1120 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
1122 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
1125 image
= create_xshm_ximage(data
->display
,
1126 DefaultVisual(data
->display
, data
->screen
),
1131 XSD(cl
)->xshm_info
);
1137 /* Calculate how many scanline can be stored in the buffer */
1138 maxlines
= XSHM_MEMSIZE
/ image
->bytes_per_line
;
1142 bug("ALERT !!! NOT ENOUGH MEMORY TO WRITE A COMPLETE SCANLINE\n");
1143 bug("THROUGH XSHM IN X11GF X HIDD !!!\n");
1148 ysize
= image
->height
;
1150 ObtainSemaphore(&XSD(cl
)->shm_sema
);
1154 /* Get some more pixels from the HIDD */
1156 lines_to_copy
= MIN(maxlines
, ysize
);
1158 ysize
-= lines_to_copy
;
1159 image
->height
= lines_to_copy
;
1161 pixarray
= toimage_func(cl
, o
, pixarray
, image
, image
->width
,
1162 lines_to_copy
, depth
, toimage_data
);
1165 XCALL(XSetFunction
, data
->display
, data
->gc
, GC_DRMD(gc
));
1167 put_xshm_ximage(data
->display
,
1173 image
->width
, lines_to_copy
,
1178 current_y
+= lines_to_copy
;
1180 } /* while (pixels left to copy) */
1182 ReleaseSemaphore(&XSD(cl
)->shm_sema
);
1185 destroy_xshm_ximage(image
);
1192 /****************************************************************************************/
1196 /****************************************************************************************/
1198 static void putimage_xlib(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*gc
, LONG x
, LONG y
, ULONG width
, ULONG height
,
1199 APTR pixarray
, APTR(*toimage_func
)(), APTR toimage_data
)
1202 struct bitmap_data
*data
;
1208 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1210 data
= OOP_INST_DATA(cl
, o
);
1212 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*) &pf
);
1213 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
1216 image
= XCALL(XCreateImage
, data
->display
,
1217 DefaultVisual(data
->display
, data
->screen
),
1232 if (NEEDS_ENDIAN_FIX(image
))
1234 image
->byte_order
= AROS_BYTEORDER
;
1237 XCALL(XInitImage
, image
);
1242 bperline
= image
->bytes_per_line
;
1243 image
->data
= (char *) AllocVec((size_t) height
* bperline
, MEMF_PUBLIC
);
1248 XCALL(XFree
, image
);
1254 toimage_func(cl
, o
, pixarray
, image
, width
, height
, depth
, toimage_data
);
1257 XCALL(XSetFunction
, data
->display
, data
->gc
, GC_DRMD(gc
));
1258 XCALL( XPutImage
, data
->display
, DRAWABLE(data
), data
->gc
, image
, 0, 0, x
, y
, width
, height
);
1261 FreeVec(image
->data
);
1264 XCALL(XFree
, image
);
1269 /****************************************************************************************/
1271 VOID
MNAME(Hidd_BitMap__PutImage
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
1273 D(bug("[X11Bm] %s(pa=%p, x=%d, y=%d, w=%d, h=%d)\n", __PRETTY_FUNCTION__
, msg
->pixels
, msg
->x
, msg
->y
, msg
->width
,
1277 if (XSD(cl
)->use_xshm
)
1279 putimage_xshm(cl
, o
, msg
->gc
, msg
->x
, msg
->y
,
1280 msg
->width
, msg
->height
, msg
->pixels
,
1281 (APTR (*)()) buf_to_ximage
, msg
);
1286 putimage_xlib(cl
, o
, msg
->gc
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, msg
->pixels
, (APTR(*)()) buf_to_ximage
, msg
);
1290 /****************************************************************************************/
1292 VOID
MNAME(Hidd_BitMap__PutImageLUT
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
1294 D(bug("[X11Bm] %s(pa=%p, x=%d, y=%d, w=%d, h=%d)\n", __PRETTY_FUNCTION__
, msg
->pixels
, msg
->x
, msg
->y
, msg
->width
,
1298 if (XSD(cl
)->use_xshm
)
1300 putimage_xshm(cl
, o
, msg
->gc
, msg
->x
, msg
->y
,
1301 msg
->width
, msg
->height
, msg
->pixels
,
1302 (APTR (*)())buf_to_ximage_lut
, msg
);
1307 putimage_xlib(cl
, o
, msg
->gc
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, msg
->pixels
, (APTR(*)()) buf_to_ximage_lut
, msg
);
1311 /****************************************************************************************/
1313 VOID
MNAME(Root__Get
)(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
1315 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
1318 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1320 if (IS_X11BM_ATTR(msg
->attrID
, idx
))
1324 case aoHidd_BitMap_X11_Drawable
:
1325 *msg
->storage
= (IPTR
) DRAWABLE(data
);
1328 case aoHidd_BitMap_X11_GC
:
1329 *msg
->storage
= (IPTR
) data
->gc
;
1334 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1337 /****************************************************************************************/
1339 BOOL
X11BM__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
1341 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1343 #if ADJUST_XWIN_SIZE
1344 /* This provides support for framebuffer display mode switching */
1345 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
1347 if (data
->flags
& BMDF_FRAMEBUFFER
)
1349 struct TagItem
*tag
= FindTagItem(aHidd_BitMap_ModeID
, msg
->attrList
);
1353 if (!X11BM_SetMode(data
, tag
->ti_Data
, XSD(cl
)))
1355 /* Bail out if error happened, see aoHidd_BitMap_ModeID documentation */
1361 return OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
1364 /****************************************************************************************/
1366 VOID
MNAME(Hidd_BitMap__DrawLine
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawLine
*msg
)
1368 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
1369 OOP_Object
*gc
= msg
->gc
;
1371 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1373 if (GC_LINEPAT(gc
) != (UWORD
) ~0)
1375 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
1386 cr
.x
= GC_CLIPX1(gc
);
1387 cr
.y
= GC_CLIPY1(gc
);
1388 cr
.width
= GC_CLIPX2(gc
) - cr
.x
+ 1;
1389 cr
.height
= GC_CLIPY2(gc
) - cr
.y
+ 1;
1391 XCALL(XSetClipRectangles
, data
->display
, data
->gc
, 0, 0, &cr
, 1, Unsorted
);
1394 XCALL(XSetForeground
, data
->display
, data
->gc
, GC_FG(gc
));
1395 XCALL(XSetFunction
, data
->display
, data
->gc
, GC_DRMD(gc
));
1397 XCALL( XDrawLine
, data
->display
, DRAWABLE(data
), data
->gc
, msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
);
1401 XCALL(XSetClipMask
, data
->display
, data
->gc
, None
);
1407 /****************************************************************************************/
1409 VOID
MNAME(Hidd_BitMap__DrawEllipse
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawEllipse
*msg
)
1411 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
1412 OOP_Object
*gc
= msg
->gc
;
1414 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1422 /* bug("X11::Drawllipse: clip %d %d %d %d\n"
1423 , GC_CLIPX1(gc), GC_CLIPY1(gc), GC_CLIPX2(gc), GC_CLIPY2(gc));
1426 cr
.x
= GC_CLIPX1(gc
);
1427 cr
.y
= GC_CLIPY1(gc
);
1428 cr
.width
= GC_CLIPX2(gc
) - cr
.x
+ 1;
1429 cr
.height
= GC_CLIPY2(gc
) - cr
.y
+ 1;
1431 XCALL(XSetClipRectangles
, data
->display
, data
->gc
, 0, 0, &cr
, 1, Unsorted
);
1434 XCALL(XSetForeground
, data
->display
, data
->gc
, GC_FG(gc
));
1435 XCALL(XSetFunction
, data
->display
, data
->gc
, GC_DRMD(gc
));
1437 /* bug("X11::Drawllipse: coord %d %d %d %d\n"
1438 , msg->x, msg->y, msg->rx, msg->ry);
1442 XCALL(XDrawArc
, data
->display
, DRAWABLE(data
), data
->gc
, msg
->x
- msg
->rx
, msg
->y
- msg
->ry
, msg
->rx
* 2, msg
->ry
* 2, 0, 360 * 64);
1446 XCALL(XSetClipMask
, data
->display
, data
->gc
, None
);
1452 /****************************************************************************************/
1454 VOID
MNAME(Hidd_BitMap__UpdateRect
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
1456 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
1458 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__
));
1462 if (data
->flags
& BMDF_FRAMEBUFFER
)
1463 X11BM_ExposeFB(data
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
1465 XCALL(XFlush
, data
->display
);