Squashed commit of 'x11-hostlib' branch
[tangerine.git] / arch / all-x11 / hidd / bitmap_common.c
blob0a89f8f6ea633d63515e7b9fd2546d8f3b1c31d5
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <exec/alerts.h>
7 #include <aros/macros.h>
9 #undef DEBUG
10 #define DEBUG 0
11 #include <aros/debug.h>
13 /****************************************************************************************/
15 /* stegerg: maybe more safe, even if Unix malloc is used and not AROS malloc */
16 #define NO_MALLOC 1
18 #define DO_ENDIAN_FIX 1 /* fix if X11 server running on remote server with different endianess */
20 /****************************************************************************************/
22 #if DO_ENDIAN_FIX
24 /****************************************************************************************/
26 #if AROS_BIG_ENDIAN
27 #define NEEDS_ENDIAN_FIX(image) (((image)->bits_per_pixel >= 15) && ((image)->byte_order != MSBFirst))
28 #define SWAP16(x) AROS_WORD2LE(x)
29 #define SWAP32(x) AROS_LONG2LE(x)
30 #define AROS_BYTEORDER MSBFirst
31 #else
32 #define NEEDS_ENDIAN_FIX(image) (((image)->bits_per_pixel >= 15) && ((image)->byte_order != LSBFirst))
33 #define SWAP16(x) AROS_WORD2BE(x)
34 #define SWAP32(x) AROS_LONG2BE(x)
35 #define AROS_BYTEORDER LSBFirst
36 #endif
38 #if 0 /* stegerg: to test above stuff*/
39 #define NEEDS_ENDIAN_FIX(image) ((image)->bits_per_pixel >= 15)
40 #define AROS_BYTEORDER MSBFirst
41 #define SWAP16(x) AROS_WORD2BE(x)
42 #define SWAP32(x) AROS_LONG2BE(x)
43 #endif
45 #define XFLUSH(x) XCALL(XFlush, x)
46 //#define XFLUSH(x)
48 /****************************************************************************************/
50 static void SwapImageEndianess(XImage *image)
52 LONG x, y, height, width, bpp;
53 UBYTE *imdata = (UBYTE *)image->data;
55 width = image->width;
56 height = image->height;
57 bpp = (image->bits_per_pixel + 7) / 8;
59 for (y = 0; y < height; y ++)
61 switch(bpp)
63 case 2:
64 for (x = 0; x < width; x++, imdata += 2)
66 UWORD pix = *(UWORD *)imdata;
68 pix = SWAP16(pix);
70 *(UWORD *)imdata = pix;
72 imdata += (image->bytes_per_line - width * 2);
73 break;
75 case 3:
76 for (x = 0; x < width; x++, imdata += 3)
78 UBYTE pix1 = imdata[0];
79 UBYTE pix3 = imdata[2];
81 imdata[0] = pix3;
82 imdata[2] = pix1;
84 imdata += (image->bytes_per_line - width * 3);
85 break;
87 case 4:
88 for (x = 0; x < width; x++, imdata += 4)
90 ULONG pix = *(ULONG *)imdata;
92 pix = SWAP32(pix);
94 *(ULONG *)imdata = pix;
96 imdata += (image->bytes_per_line - width * 4);
97 break;
99 } /* switch(bpp) */
101 } /* for (y = 0; y < height; y ++) */
103 image->byte_order = AROS_BYTEORDER;
106 /****************************************************************************************/
108 #endif /* DO_ENDIAN_FIX */
110 /****************************************************************************************/
112 BOOL MNAME(Hidd_BitMap__SetColors)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
114 struct bitmap_data *data = OOP_INST_DATA(cl, o);
115 HIDDT_PixelFormat *pf;
116 ULONG xc_i, col_i;
118 pf = BM_PIXFMT(o);
120 if (vHidd_ColorModel_StaticPalette == HIDD_PF_COLMODEL(pf) ||
121 vHidd_ColorModel_TrueColor == HIDD_PF_COLMODEL(pf) )
123 /* Superclass takes care of this case */
125 return OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
128 /* Ve have a vHidd_GT_Palette bitmap */
130 if (!OOP_DoSuperMethod(cl, o, (OOP_Msg)msg)) return FALSE;
132 if (data->flags & BMDF_COLORMAP_ALLOCED)
134 LOCK_X11
136 for ( xc_i = msg->firstColor, col_i = 0;
137 col_i < msg->numColors;
138 xc_i ++, col_i ++ )
140 XColor xcol;
142 xcol.red = msg->colors[col_i].red;
143 xcol.green = msg->colors[col_i].green;
144 xcol.blue = msg->colors[col_i].blue;
145 xcol.pad = 0;
146 xcol.pixel = xc_i;
147 xcol.flags = DoRed | DoGreen | DoBlue;
149 XCALL(XStoreColor, data->display, data->colmap, &xcol);
153 UNLOCK_X11
155 } /* if (data->flags & BMDF_COLORMAP_ALLOCED) */
158 return TRUE;
161 /****************************************************************************************/
163 VOID MNAME(Hidd_BitMap__PutPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg)
165 struct bitmap_data *data = OOP_INST_DATA(cl, o);
167 LOCK_X11
169 XCALL(XSetForeground, data->display, data->gc, msg->pixel);
170 XCALL(XDrawPoint, data->display, DRAWABLE(data), data->gc, msg->x, msg->y);
171 XFLUSH(data->display);
173 UNLOCK_X11
176 /****************************************************************************************/
178 HIDDT_Pixel MNAME(Hidd_BitMap__GetPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg)
180 struct bitmap_data *data = OOP_INST_DATA(cl, o);
181 HIDDT_Pixel pixel = -1;
182 XImage *image;
184 LOCK_X11
186 XCALL(XSync, data->display, False);
188 image = XCALL(XGetImage, data->display, DRAWABLE(data), msg->x, msg->y,
189 1, 1, AllPlanes, ZPixmap);
191 if (image)
193 pixel = XGetPixel(image, 0, 0);
194 XDestroyImage(image);
197 UNLOCK_X11
199 return pixel;
203 /****************************************************************************************/
205 ULONG MNAME(Hidd_BitMap__DrawPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPixel *msg)
207 struct bitmap_data *data = OOP_INST_DATA(cl, o);
208 XGCValues gcval;
210 gcval.function = GC_DRMD(msg->gc);
211 gcval.foreground = GC_FG(msg->gc);
212 gcval.background = GC_BG(msg->gc);
214 LOCK_X11
215 XCALL(XChangeGC, data->display, data->gc, GCFunction | GCForeground | GCBackground, &gcval);
216 XCALL(XDrawPoint, data->display, DRAWABLE(data), data->gc, msg->x, msg->y);
217 XFLUSH(data->display); /* stegerg: uncommented */
218 UNLOCK_X11
220 return 0;
223 /****************************************************************************************/
225 VOID MNAME(Hidd_BitMap__FillRect)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg)
227 struct bitmap_data *data = OOP_INST_DATA(cl, o);
228 XGCValues gcval;
230 EnterFunc(bug("X11Gfx.BitMap::FillRect(%d,%d,%d,%d)\n",
231 msg->minX, msg->minY, msg->maxX, msg->maxY));
233 D(bug("Drawmode: %d\n", mode));
235 gcval.function = GC_DRMD(msg->gc);
236 gcval.foreground = GC_FG(msg->gc);
237 gcval.background = GC_BG(msg->gc);
239 LOCK_X11
240 XCALL(XChangeGC, data->display, data->gc, GCFunction | GCForeground | GCBackground, &gcval);
242 XCALL(XFillRectangle, data->display, DRAWABLE(data), data->gc,
243 msg->minX, msg->minY,
244 msg->maxX - msg->minX + 1, msg->maxY - msg->minY + 1);
246 XFLUSH(data->display);
247 UNLOCK_X11
249 ReturnVoid("X11Gfx.BitMap::FillRect");
252 /****************************************************************************************/
254 static ULONG *ximage_to_buf(OOP_Class *cl, OOP_Object *bm, HIDDT_Pixel *buf,
255 XImage *image, ULONG width, ULONG height, ULONG depth,
256 struct pHidd_BitMap_GetImage *msg)
258 switch (msg->pixFmt)
260 case vHidd_StdPixFmt_Native:
262 UBYTE *imdata = image->data;
263 LONG y;
265 for (y = 0; y < height; y ++)
267 memcpy(buf, imdata, msg->width * image->bits_per_pixel / 8);
269 imdata += image->bytes_per_line;
270 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
273 break;
275 case vHidd_StdPixFmt_Native32:
276 switch (image->bits_per_pixel)
278 case 8:
280 UBYTE *imdata = (UBYTE *)image->data;
281 LONG x, y;
283 for (y = 0; y < height; y ++)
285 HIDDT_Pixel *p = buf;
287 for (x = 0; x < width; x ++)
289 *p++ = *imdata++;
291 imdata += (image->bytes_per_line - width);
292 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
294 break;
297 case 16:
299 UWORD *imdata = (UWORD *)image->data;
300 LONG x, y;
302 for (y = 0; y < height; y ++)
304 HIDDT_Pixel *p = buf;
306 for (x = 0; x < width; x ++)
308 *p++ = *imdata++;
310 imdata += image->bytes_per_line/2 - width;
311 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
313 break;
316 case 32:
318 ULONG *imdata = (ULONG *)image->data;
319 LONG x, y;
321 for (y = 0; y < height; y ++)
323 HIDDT_Pixel *p = buf;
325 for (x = 0; x < width; x ++)
327 *p++ = *imdata++;
329 imdata += image->bytes_per_line/4 - width;
330 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
332 break;
335 default:
337 LONG x, y;
339 LOCK_X11
340 for (y = 0; y < height; y ++)
342 HIDDT_Pixel *p;
344 p = buf;
345 for (x = 0; x < width; x ++)
347 *p++ = XGetPixel(image, x, y);
349 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
351 UNLOCK_X11
352 break;
355 } /* switch (image->bits_per_pixel) */
357 break;
359 default:
362 OOP_Object *srcpf, *dstpf, *gfxhidd;
363 APTR srcPixels = image->data, dstBuf = buf;
365 //kprintf("DEFAULT PIXEL CONVERSION\n");
367 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
368 dstpf = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
370 OOP_GetAttr(bm, aHidd_BitMap_PixFmt, (IPTR *)&srcpf);
372 //kprintf("CALLING ConvertPixels()\n");
374 HIDD_BM_ConvertPixels(bm, &srcPixels, (HIDDT_PixelFormat *)srcpf,
375 image->bytes_per_line, &dstBuf,
376 (HIDDT_PixelFormat *)dstpf, msg->modulo,
377 width, height, NULL /* We have no CLUT */
380 //kprintf("CONVERTPIXELS DONE\n");
382 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo * height);
383 break;
386 } /* switch (msg->pixFmt) */
388 return buf;
391 /****************************************************************************************/
393 #define ABS(a) ((a) < 0 ? -(a) : a)
395 /****************************************************************************************/
397 static inline UBYTE pix_to_lut(HIDDT_Pixel pixel, HIDDT_PixelLUT *plut,
398 HIDDT_PixelFormat *pf)
400 HIDDT_ColComp red, green, blue;
401 ULONG i, best_match;
402 ULONG diff, lowest_diff = 0xFFFFFFFF;
404 red = RED_COMP(pixel, pf);
405 green = GREEN_COMP(pixel, pf);
406 blue = BLUE_COMP(pixel, pf);
408 for (i = 0; i < plut->entries; i ++)
410 register HIDDT_Pixel cur_lut = plut->pixels[i];
412 if (pixel == cur_lut)
413 return i; /* Exact match found */
415 /* How well does these pixels match ? */
416 diff = ABS(red - RED_COMP(cur_lut, pf)) +
417 ABS(green - GREEN_COMP(cur_lut, pf)) +
418 ABS(blue - BLUE_COMP(cur_lut, pf));
420 if (diff < lowest_diff)
422 best_match = i;
423 lowest_diff = diff;
428 return best_match;
431 /****************************************************************************************/
433 static UBYTE *ximage_to_buf_lut(OOP_Class *cl, OOP_Object *bm, UBYTE *buf,
434 XImage *image, ULONG width, ULONG height,
435 ULONG depth, struct pHidd_BitMap_GetImageLUT *msg)
437 /* This one is trickier, as we have to reverse-lookup the lut.
438 This costs CPU ! Maybe one could do some kind of caching here ?
439 Ie. one stores the most often used RGB combinations
440 in a trie and looks up this first to see if whe can find an exact match
443 HIDDT_PixelFormat *pf = BM_PIXFMT(bm);
444 UBYTE *pixarray = msg->pixels;
446 if (image->bits_per_pixel == 16)
448 UWORD *imdata = (UWORD *)image->data;
449 LONG x, y;
451 for (y = 0; y < height; y ++)
453 UBYTE *buf = pixarray;
455 for (x = 0; x < width; x ++)
457 *buf ++ = pix_to_lut((HIDDT_Pixel)*imdata, msg->pixlut, pf);
459 imdata ++;
461 imdata += ((image->bytes_per_line / 2) - width); /*sg*/
463 pixarray += msg->modulo;
467 else
469 LONG x, y;
471 LOCK_X11
472 for (y = 0; y < height; y ++)
474 UBYTE *buf = pixarray;
475 for (x = 0; x < width; x ++)
477 *buf ++ = pix_to_lut((HIDDT_Pixel)XGetPixel(image, x, y), msg->pixlut, pf);;
479 pixarray += msg->modulo;
482 UNLOCK_X11
486 return pixarray;
490 /****************************************************************************************/
492 #if USE_XSHM
494 /****************************************************************************************/
496 static void getimage_xshm(OOP_Class *cl, OOP_Object *o, LONG x, LONG y,
497 ULONG width, ULONG height, APTR pixarray,
498 APTR (*fromimage_func)(), APTR fromimage_data)
500 struct bitmap_data *data;
501 XImage *image;
502 IPTR depth;
503 ULONG bperline;
504 ULONG lines_to_copy;
505 LONG ysize;
506 LONG current_y;
507 LONG maxlines;
508 OOP_Object *pf;
510 ASSERT(width > 0 && height > 0);
512 data = OOP_INST_DATA(cl, o);
514 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
515 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
517 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
519 LOCK_X11
520 image = create_xshm_ximage(data->display,
521 DefaultVisual(data->display, data->screen),
522 depth,
523 ZPixmap,
524 width,
525 height,
526 XSD(cl)->xshm_info);
527 UNLOCK_X11
529 if (!image)
530 ReturnVoid("X11Gfx.BitMap::PutImage(XShmCreateImage failed)");
532 bperline = image->bytes_per_line;
534 ASSERT(image->bytes_per_line > 0);
536 /* Calculate how many scanline can be stored in the buffer */
537 maxlines = XSHM_MEMSIZE / image->bytes_per_line;
539 if (0 == maxlines)
541 kprintf("ALERT !!! NOT ENOUGH MEMORY TO READ A COMPLETE SCANLINE\n");
542 kprintf("THROUGH XSHM IN X11GF X HIDD !!!\n");
543 Alert(AT_DeadEnd);
546 current_y = 0;
547 ysize = image->height;
549 ObtainSemaphore(&XSD(cl)->shm_sema);
551 while (ysize)
553 /* Get some more pixels from the Ximage */
555 lines_to_copy = MIN(maxlines, ysize);
557 ysize -= lines_to_copy;
558 image->height = lines_to_copy;
560 LOCK_X11
561 get_xshm_ximage(data->display, DRAWABLE(data), image,
562 x, y + current_y);
563 UNLOCK_X11
565 current_y += lines_to_copy;
567 pixarray = fromimage_func(cl, o, pixarray, image, image->width,
568 lines_to_copy, depth, fromimage_data);
570 } /* while (pixels left to copy) */
572 ReleaseSemaphore(&XSD(cl)->shm_sema);
574 LOCK_X11
575 destroy_xshm_ximage(image);
576 UNLOCK_X11
578 return;
582 /****************************************************************************************/
584 #endif
586 /****************************************************************************************/
588 static void getimage_xlib(OOP_Class *cl, OOP_Object *o, LONG x, LONG y,
589 ULONG width, ULONG height, APTR pixels,
590 APTR (*fromimage_func)(), APTR fromimage_data)
592 struct bitmap_data *data;
593 XImage *image;
594 ULONG *pixarray = (ULONG *)pixels;
595 OOP_Object *pf;
596 IPTR depth;
598 data = OOP_INST_DATA(cl, o);
600 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
601 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
603 LOCK_X11
604 image = XCALL(XGetImage, data->display, DRAWABLE(data), x, y,
605 width, height, AllPlanes, ZPixmap);
606 UNLOCK_X11
608 if (!image)
609 return;
611 #if DO_ENDIAN_FIX
612 if (NEEDS_ENDIAN_FIX(image))
614 SwapImageEndianess(image);
616 LOCK_X11
617 XCALL(XInitImage, image);
618 UNLOCK_X11
620 #endif
622 fromimage_func(cl, o, pixarray, image, width, height, depth, fromimage_data);
624 LOCK_X11
625 XDestroyImage(image);
626 UNLOCK_X11
628 return;
631 /****************************************************************************************/
633 VOID MNAME(Hidd_BitMap__GetImage)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg)
635 ASSERT(msg->width > 0 && msg->height > 0);
637 #if USE_XSHM
638 if (XSD(cl)->use_xshm)
640 getimage_xshm(cl, o, msg->x, msg->y, msg->width, msg->height,
641 msg->pixels, (APTR (*)())ximage_to_buf, msg);
643 else
644 #endif
646 getimage_xlib(cl, o, msg->x, msg->y, msg->width, msg->height,
647 msg->pixels, (APTR (*)())ximage_to_buf, msg);
651 /****************************************************************************************/
653 VOID MNAME(Hidd_BitMap__GetImageLUT)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImageLUT *msg)
655 ASSERT(msg->width != 0 && msg->height != 0);
656 #if USE_XSHM
657 if (XSD(cl)->use_xshm)
659 getimage_xshm(cl, o, msg->x, msg->y, msg->width, msg->height,
660 msg->pixels, (APTR (*)())ximage_to_buf_lut, msg);
662 else
663 #endif
665 getimage_xlib(cl, o, msg->x, msg->y, msg->width, msg->height,
666 msg->pixels, (APTR (*)())ximage_to_buf_lut, msg);
670 /****************************************************************************************/
673 #undef DEBUG
674 #define DEBUG 0
675 #include <aros/debug.h>
677 /****************************************************************************************/
679 static ULONG *buf_to_ximage(OOP_Class *cl, OOP_Object *bm, HIDDT_Pixel *buf,
680 XImage *image, ULONG width, ULONG height, ULONG depth,
681 struct pHidd_BitMap_PutImage *msg)
683 switch (msg->pixFmt)
685 case vHidd_StdPixFmt_Native:
687 UBYTE *imdata = image->data;
688 LONG y;
690 for (y = 0; y < height; y ++)
692 memcpy(imdata, buf, msg->width * image->bits_per_pixel / 8);
694 imdata += image->bytes_per_line;
695 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
698 break;
700 case vHidd_StdPixFmt_Native32:
701 switch (image->bits_per_pixel)
703 case 8:
705 UBYTE *imdata = (UBYTE *)image->data;
706 LONG x, y;
708 for (y = 0; y < height; y ++)
710 HIDDT_Pixel *p = buf;
712 for (x = 0; x < width; x ++)
714 *imdata ++ = (UBYTE)*p++;
716 imdata += image->bytes_per_line - width;
717 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
719 break;
722 case 16:
724 UWORD *imdata = (UWORD *)image->data;
725 LONG x, y;
727 for (y = 0; y < height; y ++)
729 HIDDT_Pixel *p = buf;
731 for (x = 0; x < width; x ++)
733 *imdata ++ = (UWORD)*p ++;
735 imdata += image->bytes_per_line/2 - width;
736 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
738 break;
742 case 24:
744 HIDDT_PixelFormat *pf;
745 UBYTE *imdata = image->data;
746 LONG x, y;
748 pf = BM_PIXFMT(bm);
750 for (y = 0; y < height; y ++)
753 HIDDT_Pixel *p = buf;
755 for (x = 0; x < width; x ++)
757 register HIDDT_Pixel pix;
759 pix = *p ++;
760 #if (AROS_BIG_ENDIAN == 1)
761 *imdata ++ = pix >> 16;
762 *imdata ++ = (pix & pf->green_mask) >> 8;
763 *imdata ++ = (pix & pf->blue_mask);
764 #else
765 *imdata ++ = (pix & pf->blue_mask);
766 *imdata ++ = (pix & pf->green_mask) >> 8;
767 *imdata ++ = pix >> 16;
768 #endif
770 imdata += image->bytes_per_line - width * 3;
771 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
773 break;
776 case 32:
778 ULONG *imdata = (ULONG *)image->data;
779 LONG x, y;
781 for (y = 0; y < height; y ++)
783 HIDDT_Pixel *p = buf;
785 for (x = 0; x < width; x ++)
787 *imdata ++ = (ULONG)*p ++;
789 imdata += image->bytes_per_line/4 - width;
790 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
792 break;
795 default:
797 LONG x, y;
799 LOCK_X11
800 for (y = 0; y < height; y ++)
802 HIDDT_Pixel *p;
804 p = buf;
805 for (x = 0; x < width; x ++)
807 XPutPixel(image, x, y, *p ++);
809 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo);
811 UNLOCK_X11
812 break;
815 } /* switch (image->bits_per_pixel) */
817 break;
820 default:
822 OOP_Object *srcpf, *dstpf, *gfxhidd;
823 APTR srcPixels = buf, dstBuf = image->data;
825 //kprintf("DEFAULT PIXEL CONVERSION\n");
827 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
828 srcpf = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
830 OOP_GetAttr(bm, aHidd_BitMap_PixFmt, (IPTR *)&dstpf);
832 //kprintf("CALLING ConvertPixels()\n");
834 HIDD_BM_ConvertPixels(bm, &srcPixels, (HIDDT_PixelFormat *)srcpf,
835 msg->modulo, &dstBuf, (HIDDT_PixelFormat *)dstpf,
836 image->bytes_per_line, width, height, NULL); /* We have no CLUT */
838 //kprintf("CONVERTPIXELS DONE\n");
840 buf = (HIDDT_Pixel *)((UBYTE *)buf + msg->modulo * height);
841 break;
844 } /* switch (msg->pixFmt) */
846 return buf;
850 /****************************************************************************************/
852 static UBYTE *buf_to_ximage_lut(OOP_Class *cl, OOP_Object *bm, UBYTE *pixarray,
853 XImage *image, ULONG width, ULONG height, ULONG depth,
854 struct pHidd_BitMap_PutImageLUT *msg)
856 HIDDT_Pixel *lut = msg->pixlut->pixels;
858 switch(image->bits_per_pixel)
860 case 8:
862 UBYTE *imdata = (UBYTE *)image->data;
863 LONG x, y;
865 for (y = 0; y < height; y ++)
867 UBYTE *buf = pixarray;
869 for (x = 0; x < width; x ++)
871 *imdata ++ = (UBYTE)lut[*buf ++];
873 pixarray += msg->modulo;
874 imdata += (image->bytes_per_line - width); /*sg*/
876 break;
879 case 16:
881 UWORD *imdata = (UWORD *)image->data;
882 LONG x, y;
884 for (y = 0; y < height; y ++)
886 UBYTE *buf = pixarray;
888 for (x = 0; x < width; x ++)
890 *imdata ++ = (UWORD)lut[*buf ++];
892 pixarray += msg->modulo;
893 imdata += ((image->bytes_per_line / 2) - width); /*sg*/
895 break;
898 case 32:
900 ULONG *imdata = (ULONG *)image->data;
901 LONG x, y;
903 for (y = 0; y < height; y ++)
905 UBYTE *buf = pixarray;
907 for (x = 0; x < width; x ++)
909 *imdata ++ = (ULONG)lut[*buf ++];
912 pixarray += msg->modulo;
913 imdata += ((image->bytes_per_line / 4) - width); /*sg*/
915 break;
918 default:
920 LONG x, y;
922 for (y = 0; y < height; y ++)
924 UBYTE *buf = pixarray;
926 for (x = 0; x < width; x ++)
928 XPutPixel(image, x, y, lut[*buf ++]);
931 pixarray += msg->modulo;
934 break;
938 } /* switch(image->bits_per_pixel) */
940 return pixarray;
943 /****************************************************************************************/
945 #if USE_XSHM
947 /****************************************************************************************/
949 static void putimage_xshm(OOP_Class *cl, OOP_Object *o, OOP_Object *gc,
950 LONG x, LONG y, ULONG width, ULONG height,
951 APTR pixarray, APTR (*toimage_func)(), APTR toimage_data)
954 struct bitmap_data *data;
955 XImage *image;
956 ULONG bperline;
957 IPTR depth;
958 ULONG lines_to_copy;
959 LONG ysize;
960 LONG current_y;
961 LONG maxlines;
962 OOP_Object *pf;
964 data = OOP_INST_DATA(cl, o);
966 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
967 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
969 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
971 LOCK_X11
972 image = create_xshm_ximage(data->display,
973 DefaultVisual(data->display, data->screen),
974 depth,
975 ZPixmap,
976 width,
977 height,
978 XSD(cl)->xshm_info);
979 UNLOCK_X11
981 if (!image)
982 ReturnVoid("X11Gfx.BitMap::PutImage(XShmCreateImage failed)");
984 bperline = image->bytes_per_line;
986 /* Calculate how many scanline can be stored in the buffer */
987 maxlines = XSHM_MEMSIZE / image->bytes_per_line;
989 if (0 == maxlines)
991 kprintf("ALERT !!! NOT ENOUGH MEMORY TO WRITE A COMPLETE SCANLINE\n");
992 kprintf("THROUGH XSHM IN X11GF X HIDD !!!\n");
993 Alert(AT_DeadEnd);
996 current_y = 0;
997 ysize = image->height;
999 ObtainSemaphore(&XSD(cl)->shm_sema);
1001 while (ysize)
1003 /* Get some more pixels from the HIDD */
1005 lines_to_copy = MIN(maxlines, ysize);
1007 ysize -= lines_to_copy;
1008 image->height = lines_to_copy;
1010 pixarray = toimage_func(cl, o, pixarray, image, image->width,
1011 lines_to_copy, depth, toimage_data);
1013 LOCK_X11
1014 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1016 put_xshm_ximage(data->display,
1017 DRAWABLE(data),
1018 data->gc,
1019 image,
1020 0, 0,
1021 x, y + current_y,
1022 image->width, lines_to_copy,
1023 FALSE);
1025 UNLOCK_X11
1027 current_y += lines_to_copy;
1029 } /* while (pixels left to copy) */
1031 ReleaseSemaphore(&XSD(cl)->shm_sema);
1033 LOCK_X11
1034 XFLUSH(data->display); /* stegerg: added */
1035 destroy_xshm_ximage(image);
1036 UNLOCK_X11
1038 return;
1042 /****************************************************************************************/
1044 #endif
1046 /****************************************************************************************/
1048 static void putimage_xlib(OOP_Class *cl, OOP_Object *o, OOP_Object *gc,
1049 LONG x, LONG y, ULONG width, ULONG height,
1050 APTR pixarray, APTR (*toimage_func)(), APTR toimage_data)
1053 struct bitmap_data *data;
1054 XImage *image;
1055 ULONG bperline;
1056 IPTR depth;
1057 OOP_Object *pf;
1059 data = OOP_INST_DATA(cl, o);
1061 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1062 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1064 LOCK_X11
1065 image = XCALL(XCreateImage, data->display,
1066 DefaultVisual(data->display, data->screen),
1067 depth,
1068 ZPixmap,
1070 NULL,
1071 width,
1072 height,
1075 UNLOCK_X11
1077 if (!image)
1078 ReturnVoid("X11Gfx.BitMap::PutImage(XCreateImage failed)");
1080 #if DO_ENDIAN_FIX
1081 if (NEEDS_ENDIAN_FIX(image))
1083 image->byte_order = AROS_BYTEORDER;
1085 LOCK_X11
1086 XCALL(XInitImage, image);
1087 UNLOCK_X11
1089 #endif
1091 bperline = image->bytes_per_line;
1093 #if NO_MALLOC
1094 image->data = (char *)AllocVec((size_t)height * bperline, MEMF_PUBLIC);
1095 #else
1096 image->data = (char *)malloc((size_t)height * bperline);
1097 #endif
1099 if (!image->data)
1101 LOCK_X11
1102 XCALL(XFree, image);
1103 UNLOCK_X11
1105 ReturnVoid("X11Gfx.BitMap::PutImage(malloc(image data) failed)");
1108 toimage_func(cl, o, pixarray, image, width, height, depth, toimage_data);
1110 LOCK_X11
1111 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1112 XCALL(XPutImage, data->display, DRAWABLE(data), data->gc, image,
1113 0, 0, x, y, width, height);
1114 XFLUSH(data->display);
1115 UNLOCK_X11
1117 #if NO_MALLOC
1118 FreeVec(image->data);
1119 #else
1120 free(image->data);
1121 #endif
1123 LOCK_X11
1124 XCALL(XFree, image);
1125 UNLOCK_X11
1129 /****************************************************************************************/
1131 VOID MNAME(Hidd_BitMap__PutImage)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg)
1133 EnterFunc(bug("X11Gfx.BitMap::PutImage(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
1134 msg->pixels, msg->x, msg->y, msg->width, msg->height));
1136 #if USE_XSHM
1137 if (XSD(cl)->use_xshm)
1139 putimage_xshm(cl, o, msg->gc, msg->x, msg->y,
1140 msg->width, msg->height, msg->pixels,
1141 (APTR (*)()) buf_to_ximage, msg);
1143 else
1144 #endif
1146 putimage_xlib(cl, o, msg->gc, msg->x, msg->y,
1147 msg->width, msg->height, msg->pixels,
1148 (APTR (*)()) buf_to_ximage, msg);
1151 ReturnVoid("X11Gfx.BitMap::PutImage");
1154 /****************************************************************************************/
1156 VOID MNAME(Hidd_BitMap__PutImageLUT)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg)
1158 EnterFunc(bug("X11Gfx.BitMap::PutImage(pa=%p, x=%d, y=%d, w=%d, h=%d)\n",
1159 msg->pixels, msg->x, msg->y, msg->width, msg->height));
1161 #if USE_XSHM
1162 if (XSD(cl)->use_xshm)
1164 putimage_xshm(cl, o, msg->gc, msg->x, msg->y,
1165 msg->width, msg->height, msg->pixels,
1166 (APTR (*)())buf_to_ximage_lut, msg);
1168 else
1169 #endif
1171 putimage_xlib(cl, o, msg->gc, msg->x, msg->y,
1172 msg->width, msg->height, msg->pixels,
1173 (APTR (*)())buf_to_ximage_lut, msg);
1176 ReturnVoid("X11Gfx.BitMap::PutImageLUT");
1179 /****************************************************************************************/
1181 #undef DEBUG
1182 #define DEBUG 0
1183 #include <aros/debug.h>
1185 /****************************************************************************************/
1187 VOID MNAME(Hidd_BitMap__BlitColorExpansion)(OOP_Class *cl, OOP_Object *o,
1188 struct pHidd_BitMap_BlitColorExpansion *msg
1191 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1192 XImage *dest_im;
1193 HIDDT_Pixel fg, bg;
1194 ULONG cemd;
1195 LONG x, y;
1196 Drawable d = 0;
1198 EnterFunc(bug("X11Gfx.BitMap::BlitColorExpansion(%p, %d, %d, %d, %d, %d, %d)\n",
1199 msg->srcBitMap, msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height));
1202 OOP_GetAttr(msg->srcBitMap, aHidd_X11BitMap_Drawable, (IPTR *)&d);
1204 if (0 == d)
1206 /* We know nothing about the source bitmap. Let the superclass handle this */
1207 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1208 return;
1211 fg = GC_FG(msg->gc);
1212 bg = GC_BG(msg->gc);
1213 cemd = GC_COLEXP(msg->gc);
1215 if (0 != d)
1217 LOCK_X11
1219 XCALL(XSetForeground, data->display, data->gc, fg);
1221 if (cemd & vHidd_GC_ColExp_Opaque)
1223 XCALL(XSetBackground, data->display, data->gc, bg);
1224 XCALL(XSetFunction, data->display, data->gc, GXcopy);
1226 XCALL(XCopyPlane, data->display, d, DRAWABLE(data), data->gc,
1227 msg->srcX, msg->srcY, msg->width, msg->height,
1228 msg->destX, msg->destY, 0x01);
1230 else
1232 /* Do transparent blit */
1234 XGCValues val;
1236 val.stipple = d;
1237 val.ts_x_origin = msg->destX - msg->srcX;
1238 val.ts_y_origin = msg->destY - msg->srcY;
1239 val.fill_style = FillStippled;
1241 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(msg->gc));
1243 XCALL(XChangeGC, data->display, data->gc,
1244 GCStipple|GCTileStipXOrigin|GCTileStipYOrigin|GCFillStyle,
1245 &val);
1247 XCALL(XFillRectangle, data->display, DRAWABLE(data), data->gc,
1248 msg->destX, msg->destY, msg->width, msg->height);
1250 XCALL(XSetFillStyle, data->display, data->gc, FillSolid);
1254 UNLOCK_X11
1257 else
1259 /* We know nothing about the format of the source bitmap
1260 an must get single pixels
1263 LOCK_X11
1264 dest_im = XCALL(XGetImage, data->display, DRAWABLE(data),
1265 msg->destX, msg->destY, msg->width, msg->height,
1266 AllPlanes, ZPixmap);
1267 UNLOCK_X11
1269 if (!dest_im)
1270 ReturnVoid("X11Gfx.BitMap::BlitColorExpansion()");
1272 D(bug("Src bm: %p\n", msg->srcBitMap));
1274 for (y = 0; y < msg->height; y ++)
1276 for (x = 0; x < msg->width; x ++)
1278 ULONG is_set;
1280 is_set = HIDD_BM_GetPixel(msg->srcBitMap, x + msg->srcX, y + msg->srcY);
1282 if (is_set)
1284 XPutPixel(dest_im, x, y, fg);
1287 else
1289 if (cemd & vHidd_GC_ColExp_Opaque)
1291 XPutPixel(dest_im, x, y, bg);
1295 } /* for (each x) */
1297 } /* for (each y) */
1299 /* Put image back into display */
1301 LOCK_X11
1302 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(msg->gc));
1303 XCALL(XPutImage, data->display, DRAWABLE(data), data->gc, dest_im,
1304 0, 0, msg->destX, msg->destY, msg->width, msg->height);
1305 XDestroyImage(dest_im);
1306 UNLOCK_X11
1309 LOCK_X11
1310 XFLUSH(data->display);
1311 UNLOCK_X11
1313 ReturnVoid("X11Gfx.BitMap::BlitColorExpansion");
1316 /****************************************************************************************/
1318 #undef DEBUG
1319 #define DEBUG 0
1320 #include <aros/debug.h>
1322 /****************************************************************************************/
1324 VOID MNAME(Root__Get)(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
1326 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1327 ULONG idx;
1329 if (IS_X11BM_ATTR(msg->attrID, idx))
1331 switch (idx)
1333 case aoHidd_X11BitMap_Drawable:
1334 *msg->storage = (IPTR)DRAWABLE(data);
1335 break;
1337 case aoHidd_X11BitMap_MasterWindow:
1338 *msg->storage = (IPTR)data->masterxwindow;
1339 break;
1341 default:
1342 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1343 break;
1346 else
1348 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1353 /****************************************************************************************/
1355 VOID MNAME(Hidd_BitMap__DrawLine)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawLine *msg)
1357 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1358 OOP_Object *gc = msg->gc;
1360 if (GC_LINEPAT(gc) != (UWORD)~0)
1362 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
1364 return;
1367 LOCK_X11
1369 if (GC_DOCLIP(gc))
1371 XRectangle cr;
1373 cr.x = GC_CLIPX1(gc);
1374 cr.y = GC_CLIPY1(gc);
1375 cr.width = GC_CLIPX2(gc) - cr.x + 1;
1376 cr.height = GC_CLIPY2(gc) - cr.y + 1;
1378 XCALL(XSetClipRectangles, data->display, data->gc,
1379 0, 0, &cr, 1, Unsorted);
1382 XCALL(XSetForeground, data->display, data->gc, GC_FG(gc));
1383 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1385 XCALL(XDrawLine, data->display, DRAWABLE(data), data->gc,
1386 msg->x1, msg->y1, msg->x2, msg->y2);
1388 if (GC_DOCLIP(gc))
1390 XCALL(XSetClipMask, data->display, data->gc, None);
1393 XFLUSH(data->display);
1395 UNLOCK_X11
1398 /****************************************************************************************/
1400 VOID MNAME(Hidd_BitMap__DrawEllipse)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawEllipse *msg)
1402 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1403 OOP_Object *gc = msg->gc;
1405 LOCK_X11
1407 if (GC_DOCLIP(gc))
1409 XRectangle cr;
1411 /* kprintf("X11::Drawllipse: clip %d %d %d %d\n"
1412 , GC_CLIPX1(gc), GC_CLIPY1(gc), GC_CLIPX2(gc), GC_CLIPY2(gc));
1415 cr.x = GC_CLIPX1(gc);
1416 cr.y = GC_CLIPY1(gc);
1417 cr.width = GC_CLIPX2(gc) - cr.x + 1;
1418 cr.height = GC_CLIPY2(gc) - cr.y + 1;
1420 XCALL(XSetClipRectangles, data->display, data->gc,
1421 0, 0, &cr, 1, Unsorted);
1424 XCALL(XSetForeground, data->display, data->gc, GC_FG(gc));
1425 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1427 /* kprintf("X11::Drawllipse: coord %d %d %d %d\n"
1428 , msg->x, msg->y, msg->rx, msg->ry);
1432 XCALL(XDrawArc, data->display, DRAWABLE(data), data->gc,
1433 msg->x - msg->rx, msg->y - msg->ry,
1434 msg->rx * 2, msg->ry * 2, 0, 360 * 64);
1436 if (GC_DOCLIP(gc))
1438 XCALL(XSetClipMask, data->display, data->gc, None);
1441 XFLUSH(data->display);
1443 UNLOCK_X11
1446 /****************************************************************************************/