rename the directory
[AROS.git] / arch / all-hosted / hidd / x11 / bitmap_common.c
blob172407aca4d9404ad7f6410993b525a7d135375c
1 /*
2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "x11_debug.h"
8 #include <hidd/graphics.h>
9 #include <proto/utility.h>
11 #include "x11_types.h"
12 #include "x11.h"
13 #include "x11_hostlib.h"
14 #include "bitmap.h"
15 #include "xshm.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
25 #if DO_ENDIAN_FIX
27 #if AROS_BIG_ENDIAN
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
32 #else
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
37 #endif
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)
44 #endif
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);
53 if (o)
55 struct bitmap_data *data = OOP_INST_DATA(cl, o);
56 BOOL ok = TRUE;
57 BOOL framebuffer;
59 /* Get some info passed to us by the x11gfxhidd class */
60 data->display = (Display *) GetTagData(aHidd_X11BitMap_SysDisplay, 0, msg->attrList);
61 data->screen = GetTagData(aHidd_X11BitMap_SysScreen, 0, msg->attrList);
62 data->cursor = (Cursor) GetTagData(aHidd_X11BitMap_SysCursor, 0, msg->attrList);
63 data->colmap = (Colormap) GetTagData(aHidd_X11BitMap_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);
71 if (framebuffer)
73 /* Framebuffer is X11 window */
74 data->flags |= BMDF_FRAMEBUFFER;
75 ok = X11BM_InitFB(cl, o, msg->attrList);
77 else
79 /* Anything else is a pixmap */
80 ok = X11BM_InitPM(cl, o, msg->attrList);
83 if (ok)
85 /* Create an X11 GC. All objects need it. */
86 XGCValues gcval;
88 gcval.plane_mask = AllPlanes;
89 gcval.graphics_exposures = False;
91 HostLib_Lock();
93 data->gc = XCALL(XCreateGC, data->display, DRAWABLE(data),
94 GCPlaneMask | GCGraphicsExposures, &gcval);
95 HostLib_Unlock();
97 if (!data->gc)
98 ok = FALSE;
99 #if X11SOFTMOUSE
100 else if (framebuffer)
101 X11BM_InitEmptyCursor(data);
102 #endif
105 if (!ok)
107 OOP_MethodID disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
109 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
110 o = NULL;
112 } /* if (object allocated by superclass) */
114 D(bug("[X11Bm] %s: returning object @ 0x%p\n", __PRETTY_FUNCTION__, o));
115 return o;
118 /****************************************************************************************/
120 VOID X11BM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
122 struct bitmap_data *data = OOP_INST_DATA(cl, o);
124 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
126 if (data->gc)
128 HostLib_Lock();
129 XCALL(XFreeGC, data->display, data->gc);
130 HostLib_Unlock();
133 if (data->flags & BMDF_FRAMEBUFFER)
134 X11BM_DisposeFB(data, XSD(cl));
135 else
136 X11BM_DisposePM(data);
138 OOP_DoSuperMethod(cl, o, msg);
141 /****************************************************************************************/
143 VOID X11BM__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_Clear *msg)
145 struct bitmap_data *data = OOP_INST_DATA(cl, o);
147 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
149 HostLib_Lock();
151 if (data->flags & BMDF_FRAMEBUFFER)
152 X11BM_ClearFB(data, GC_BG(msg->gc));
153 else
154 X11BM_ClearPM(data, GC_BG(msg->gc));
156 HostLib_Unlock();
159 /****************************************************************************************/
161 static void SwapImageEndianess(XImage *image)
163 LONG x, y, height, width, bpp;
164 UBYTE *imdata = (UBYTE *) image->data;
166 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
168 width = image->width;
169 height = image->height;
170 bpp = (image->bits_per_pixel + 7) / 8;
172 for (y = 0; y < height; y++)
174 switch (bpp)
176 case 2:
177 for (x = 0; x < width; x++, imdata += 2)
179 UWORD pix = *(UWORD *) imdata;
181 pix = SWAP16(pix);
183 *(UWORD *) imdata = pix;
185 imdata += (image->bytes_per_line - width * 2);
186 break;
188 case 3:
189 for (x = 0; x < width; x++, imdata += 3)
191 UBYTE pix1 = imdata[0];
192 UBYTE pix3 = imdata[2];
194 imdata[0] = pix3;
195 imdata[2] = pix1;
197 imdata += (image->bytes_per_line - width * 3);
198 break;
200 case 4:
201 for (x = 0; x < width; x++, imdata += 4)
203 ULONG pix = *(ULONG *) imdata;
205 pix = SWAP32(pix);
207 *(ULONG *) imdata = pix;
209 imdata += (image->bytes_per_line - width * 4);
210 break;
212 } /* switch(bpp) */
214 } /* for (y = 0; y < height; y ++) */
216 image->byte_order = AROS_BYTEORDER;
219 /****************************************************************************************/
221 #endif /* DO_ENDIAN_FIX */
223 /****************************************************************************************/
225 BOOL MNAME(Hidd_BitMap__SetColors)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
227 struct bitmap_data *data = OOP_INST_DATA(cl, o);
228 HIDDT_PixelFormat *pf;
229 ULONG xc_i, col_i;
231 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
233 if (!OOP_DoSuperMethod(cl, o, &msg->mID))
234 return FALSE;
236 pf = BM_PIXFMT(o);
238 if (vHidd_ColorModel_StaticPalette == HIDD_PF_COLMODEL(pf) || vHidd_ColorModel_TrueColor == HIDD_PF_COLMODEL(pf))
240 /* Superclass has taken care of this case */
241 return TRUE;
244 /* Ve have a vHidd_GT_Palette bitmap */
246 if (data->flags & BMDF_COLORMAP_ALLOCED)
248 LOCK_X11
250 for (xc_i = msg->firstColor, col_i = 0; col_i < msg->numColors; xc_i++, col_i++)
252 XColor xcol;
254 xcol.red = msg->colors[col_i].red;
255 xcol.green = msg->colors[col_i].green;
256 xcol.blue = msg->colors[col_i].blue;
257 xcol.pad = 0;
258 xcol.pixel = xc_i;
259 xcol.flags = DoRed | DoGreen | DoBlue;
261 XCALL(XStoreColor, data->display, data->colmap, &xcol);
265 UNLOCK_X11
267 } /* if (data->flags & BMDF_COLORMAP_ALLOCED) */
269 return TRUE;
272 /****************************************************************************************/
274 VOID MNAME(Hidd_BitMap__PutPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg)
276 struct bitmap_data *data = OOP_INST_DATA(cl, o);
278 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
280 LOCK_X11
282 XCALL(XSetForeground, data->display, data->gc, msg->pixel);
283 XCALL(XSetFunction, data->display, data->gc, GXcopy);
284 XCALL(XDrawPoint, data->display, DRAWABLE(data), data->gc, msg->x, msg->y);
286 UNLOCK_X11
289 /****************************************************************************************/
291 HIDDT_Pixel MNAME(Hidd_BitMap__GetPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetPixel *msg)
293 struct bitmap_data *data = OOP_INST_DATA(cl, o);
294 HIDDT_Pixel pixel = -1;
295 XImage *image;
297 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
299 LOCK_X11
301 XCALL(XSync, data->display, False);
303 image = XCALL(XGetImage, data->display, DRAWABLE(data), msg->x, msg->y, 1, 1, AllPlanes, ZPixmap);
305 if (image)
307 pixel = XGetPixel(image, 0, 0);
308 XDestroyImage(image);
311 UNLOCK_X11
313 return pixel;
317 /****************************************************************************************/
319 ULONG MNAME(Hidd_BitMap__DrawPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawPixel *msg)
321 struct bitmap_data *data = OOP_INST_DATA(cl, o);
322 XGCValues gcval;
324 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
326 gcval.function = GC_DRMD(msg->gc);
327 gcval.foreground = GC_FG(msg->gc);
328 gcval.background = GC_BG(msg->gc);
330 LOCK_X11
331 XCALL(XChangeGC, data->display, data->gc, GCFunction | GCForeground | GCBackground, &gcval);
332 XCALL(XDrawPoint, data->display, DRAWABLE(data), data->gc, msg->x, msg->y);
333 UNLOCK_X11
335 return 0;
338 /****************************************************************************************/
340 VOID MNAME(Hidd_BitMap__FillRect)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawRect *msg)
342 struct bitmap_data *data = OOP_INST_DATA(cl, o);
343 XGCValues gcval;
345 D(bug("[X11Bm] %s(%d,%d,%d,%d)\n", __PRETTY_FUNCTION__, msg->minX, msg->minY, msg->maxX, msg->maxY));
346 D(bug("[X11Bm] %s: Drawmode = %d\n", __PRETTY_FUNCTION__, GC_DRMD(msg->gc)));
348 gcval.function = GC_DRMD(msg->gc);
349 gcval.foreground = GC_FG(msg->gc);
350 gcval.background = GC_BG(msg->gc);
352 LOCK_X11
353 XCALL(XChangeGC, data->display, data->gc, GCFunction | GCForeground | GCBackground, &gcval);
355 XCALL(XFillRectangle, data->display, DRAWABLE(data), data->gc, msg->minX, msg->minY, msg->maxX - msg->minX + 1, msg->maxY - msg->minY + 1);
357 UNLOCK_X11
360 /****************************************************************************************/
362 static ULONG *ximage_to_buf(OOP_Class *cl, OOP_Object *bm, HIDDT_Pixel *buf, XImage *image, ULONG width, ULONG height,
363 ULONG depth, struct pHidd_BitMap_GetImage *msg)
365 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
367 switch (msg->pixFmt)
369 case vHidd_StdPixFmt_Native:
371 UBYTE *imdata = image->data;
372 LONG y;
374 for (y = 0; y < height; y++)
376 memcpy(buf, imdata, msg->width * image->bits_per_pixel / 8);
378 imdata += image->bytes_per_line;
379 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
382 break;
384 case vHidd_StdPixFmt_Native32:
385 switch (image->bits_per_pixel)
387 case 8:
389 UBYTE *imdata = (UBYTE *) image->data;
390 LONG x, y;
392 for (y = 0; y < height; y++)
394 HIDDT_Pixel *p = buf;
396 for (x = 0; x < width; x++)
398 *p++ = *imdata++;
400 imdata += (image->bytes_per_line - width);
401 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
403 break;
406 case 16:
408 UWORD *imdata = (UWORD *) image->data;
409 LONG x, y;
411 for (y = 0; y < height; y++)
413 HIDDT_Pixel *p = buf;
415 for (x = 0; x < width; x++)
417 *p++ = *imdata++;
419 imdata += image->bytes_per_line / 2 - width;
420 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
422 break;
425 case 32:
427 ULONG *imdata = (ULONG *) image->data;
428 LONG x, y;
430 for (y = 0; y < height; y++)
432 HIDDT_Pixel *p = buf;
434 for (x = 0; x < width; x++)
436 *p++ = *imdata++;
438 imdata += image->bytes_per_line / 4 - width;
439 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
441 break;
444 default:
446 LONG x, y;
448 LOCK_X11
449 for (y = 0; y < height; y++)
451 HIDDT_Pixel *p;
453 p = buf;
454 for (x = 0; x < width; x++)
456 *p++ = XGetPixel(image, x, y);
458 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
460 UNLOCK_X11
461 break;
464 } /* switch (image->bits_per_pixel) */
466 break;
468 default:
471 OOP_Object *srcpf, *dstpf, *gfxhidd;
472 APTR srcPixels = image->data, dstBuf = buf;
474 //bug("DEFAULT PIXEL CONVERSION\n");
476 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, (IPTR *) &gfxhidd);
477 dstpf = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
479 OOP_GetAttr(bm, aHidd_BitMap_PixFmt, (IPTR *) &srcpf);
481 //bug("CALLING ConvertPixels()\n");
483 HIDD_BM_ConvertPixels(bm, &srcPixels, (HIDDT_PixelFormat *) srcpf, image->bytes_per_line, &dstBuf,
484 (HIDDT_PixelFormat *) dstpf, msg->modulo, width, height, NULL /* We have no CLUT */
487 //bug("CONVERTPIXELS DONE\n");
489 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo * height);
490 break;
493 } /* switch (msg->pixFmt) */
495 return buf;
498 /****************************************************************************************/
500 #define ABS(a) ((a) < 0 ? -(a) : a)
502 /****************************************************************************************/
504 static inline UBYTE pix_to_lut(HIDDT_Pixel pixel, HIDDT_PixelLUT *plut, HIDDT_PixelFormat *pf)
506 HIDDT_ColComp red, green, blue;
507 ULONG i, best_match = 0;
508 ULONG diff, lowest_diff = 0xFFFFFFFF;
510 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
512 red = RED_COMP(pixel, pf);
513 green = GREEN_COMP(pixel, pf);
514 blue = BLUE_COMP(pixel, pf);
516 for (i = 0; i < plut->entries; i++)
518 register HIDDT_Pixel cur_lut = plut->pixels[i];
520 if (pixel == cur_lut)
521 return i; /* Exact match found */
523 /* How well does these pixels match ? */
524 diff = ABS(red - RED_COMP(cur_lut, pf)) + ABS(green - GREEN_COMP(cur_lut, pf))
525 + ABS(blue - BLUE_COMP(cur_lut, pf));
527 if (diff < lowest_diff)
529 best_match = i;
530 lowest_diff = diff;
535 return best_match;
538 /****************************************************************************************/
540 static UBYTE *ximage_to_buf_lut(OOP_Class *cl, OOP_Object *bm, UBYTE *buf, XImage *image, ULONG width, ULONG height,
541 ULONG depth, struct pHidd_BitMap_GetImageLUT *msg)
543 /* This one is trickier, as we have to reverse-lookup the lut.
544 This costs CPU ! Maybe one could do some kind of caching here ?
545 Ie. one stores the most often used RGB combinations
546 in a trie and looks up this first to see if whe can find an exact match
549 HIDDT_PixelFormat *pf = BM_PIXFMT(bm);
550 UBYTE *pixarray = msg->pixels;
552 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
554 if (image->bits_per_pixel == 16)
556 UWORD *imdata = (UWORD *) image->data;
557 LONG x, y;
559 for (y = 0; y < height; y++)
561 UBYTE *buf = pixarray;
563 for (x = 0; x < width; x++)
565 *buf++ = pix_to_lut((HIDDT_Pixel) *imdata, msg->pixlut, pf);
567 imdata++;
569 imdata += ((image->bytes_per_line / 2) - width); /*sg*/
571 pixarray += msg->modulo;
575 else
577 LONG x, y;
579 LOCK_X11
580 for (y = 0; y < height; y++)
582 UBYTE *buf = pixarray;
583 for (x = 0; x < width; x++)
585 *buf++ = pix_to_lut((HIDDT_Pixel) XGetPixel(image, x, y), msg->pixlut, pf);
588 pixarray += msg->modulo;
591 UNLOCK_X11
595 return pixarray;
599 /****************************************************************************************/
601 #if USE_XSHM
603 /****************************************************************************************/
605 static void getimage_xshm(OOP_Class *cl, OOP_Object *o, LONG x, LONG y,
606 ULONG width, ULONG height, APTR pixarray,
607 APTR (*fromimage_func)(), APTR fromimage_data)
609 struct bitmap_data *data;
610 XImage *image;
611 IPTR depth;
612 ULONG lines_to_copy;
613 LONG ysize;
614 LONG current_y;
615 LONG maxlines;
616 OOP_Object *pf;
617 Pixmap temp_pixmap = 0;
619 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
621 ASSERT(width > 0 && height > 0);
623 data = OOP_INST_DATA(cl, o);
625 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
626 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
628 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
630 LOCK_X11
631 image = create_xshm_ximage(data->display,
632 DefaultVisual(data->display, data->screen),
633 depth,
634 ZPixmap,
635 width,
636 height,
637 XSD(cl)->xshm_info);
638 UNLOCK_X11
640 if (!image)
641 return;
643 ASSERT(image->bytes_per_line > 0);
645 /* Calculate how many scanline can be stored in the buffer */
646 maxlines = XSHM_MEMSIZE / image->bytes_per_line;
648 if (0 == maxlines)
650 bug("ALERT !!! NOT ENOUGH MEMORY TO READ A COMPLETE SCANLINE\n");
651 bug("THROUGH XSHM IN X11GF X HIDD !!!\n");
652 Alert(AT_DeadEnd);
655 current_y = 0;
656 ysize = image->height;
658 ObtainSemaphore(&XSD(cl)->shm_sema);
660 LOCK_X11
662 while (ysize)
664 /* Get some more pixels from the Ximage */
666 lines_to_copy = MIN(maxlines, ysize);
668 ysize -= lines_to_copy;
669 image->height = lines_to_copy;
671 if (!temp_pixmap)
673 if (!(get_xshm_ximage(data->display, DRAWABLE(data), image,
674 x, y + current_y)))
676 /* XGetImage fails if done on a part of a X window which is off
677 screen (OTOH, it's no problem if it is hidden by another window).
678 If get_xshm_image() failed, we assume that this has happened and
679 thefore copy the area to a temp pixmap, and then get the ximage
680 from there. */
682 temp_pixmap = XCALL(XCreatePixmap, data->display, DRAWABLE(data),
683 width, height - current_y, DefaultDepth(data->display, data->screen));
685 if (temp_pixmap)
687 XCALL(XSetFunction, data->display, data->gc, GXcopy);
689 XCALL(XCopyArea, data->display, DRAWABLE(data), temp_pixmap, data->gc,
690 x, y + current_y, width, height - current_y, 0, 0);
692 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(data->gc));
694 x = 0; y = 0; current_y = 0;
699 if (temp_pixmap)
701 get_xshm_ximage(data->display, temp_pixmap, image,
702 x, y + current_y);
705 current_y += lines_to_copy;
707 pixarray = fromimage_func(cl, o, pixarray, image, image->width,
708 lines_to_copy, depth, fromimage_data);
710 } /* while (pixels left to copy) */
712 if (temp_pixmap)
714 XCALL(XFreePixmap,data->display, temp_pixmap);
717 UNLOCK_X11
719 ReleaseSemaphore(&XSD(cl)->shm_sema);
721 LOCK_X11
722 destroy_xshm_ximage(image);
723 UNLOCK_X11
725 return;
729 /****************************************************************************************/
731 #endif
733 /****************************************************************************************/
735 static void getimage_xlib(OOP_Class *cl, OOP_Object *o, LONG x, LONG y, ULONG width, ULONG height, APTR pixels,
736 APTR(*fromimage_func)(), APTR fromimage_data)
738 struct bitmap_data *data;
739 XImage *image;
740 ULONG *pixarray = (ULONG *) pixels;
741 OOP_Object *pf;
742 IPTR depth;
744 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
746 data = OOP_INST_DATA(cl, o);
748 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *) &pf);
749 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
751 LOCK_X11
752 image = XCALL(XGetImage, data->display, DRAWABLE(data), x, y,
753 width, height, AllPlanes, ZPixmap);
754 UNLOCK_X11
756 if (!image)
757 return;
759 #if DO_ENDIAN_FIX
760 if (NEEDS_ENDIAN_FIX(image))
762 SwapImageEndianess(image);
764 LOCK_X11
765 XCALL(XInitImage, image);
766 UNLOCK_X11
768 #endif
770 fromimage_func(cl, o, pixarray, image, width, height, depth, fromimage_data);
772 LOCK_X11
773 XDestroyImage(image);
774 UNLOCK_X11
776 return;
779 /****************************************************************************************/
781 VOID MNAME(Hidd_BitMap__GetImage)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImage *msg)
783 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
785 ASSERT(msg->width > 0 && msg->height > 0);
787 #if USE_XSHM
788 if (XSD(cl)->use_xshm)
790 getimage_xshm(cl, o, msg->x, msg->y, msg->width, msg->height,
791 msg->pixels, (APTR (*)())ximage_to_buf, msg);
793 else
794 #endif
796 getimage_xlib(cl, o, msg->x, msg->y, msg->width, msg->height, msg->pixels, (APTR(*)()) ximage_to_buf, msg);
800 /****************************************************************************************/
802 VOID MNAME(Hidd_BitMap__GetImageLUT)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_GetImageLUT *msg)
804 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
806 ASSERT(msg->width != 0 && msg->height != 0);
807 #if USE_XSHM
808 if (XSD(cl)->use_xshm)
810 getimage_xshm(cl, o, msg->x, msg->y, msg->width, msg->height,
811 msg->pixels, (APTR (*)())ximage_to_buf_lut, msg);
813 else
814 #endif
816 getimage_xlib(cl, o, msg->x, msg->y, msg->width, msg->height, msg->pixels, (APTR(*)()) ximage_to_buf_lut, msg);
820 /****************************************************************************************/
822 #undef DEBUG
823 #define DEBUG 0
824 #include <aros/debug.h>
826 /****************************************************************************************/
828 static ULONG *buf_to_ximage(OOP_Class *cl, OOP_Object *bm, HIDDT_Pixel *buf, XImage *image, ULONG width, ULONG height,
829 ULONG depth, struct pHidd_BitMap_PutImage *msg)
831 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
833 switch (msg->pixFmt)
835 case vHidd_StdPixFmt_Native:
837 UBYTE *imdata = image->data;
838 LONG y;
840 for (y = 0; y < height; y++)
842 memcpy(imdata, buf, msg->width * image->bits_per_pixel / 8);
844 imdata += image->bytes_per_line;
845 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
848 break;
850 case vHidd_StdPixFmt_Native32:
851 switch (image->bits_per_pixel)
853 case 8:
855 UBYTE *imdata = (UBYTE *) image->data;
856 LONG x, y;
858 for (y = 0; y < height; y++)
860 HIDDT_Pixel *p = buf;
862 for (x = 0; x < width; x++)
864 *imdata++ = (UBYTE) *p++;
866 imdata += image->bytes_per_line - width;
867 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
869 break;
872 case 16:
874 UWORD *imdata = (UWORD *) image->data;
875 LONG x, y;
877 for (y = 0; y < height; y++)
879 HIDDT_Pixel *p = buf;
881 for (x = 0; x < width; x++)
883 *imdata++ = (UWORD) *p++;
885 imdata += image->bytes_per_line / 2 - width;
886 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
888 break;
891 case 24:
893 HIDDT_PixelFormat *pf;
894 UBYTE *imdata = image->data;
895 LONG x, y;
897 pf = BM_PIXFMT(bm);
899 for (y = 0; y < height; y++)
902 HIDDT_Pixel *p = buf;
904 for (x = 0; x < width; x++)
906 register HIDDT_Pixel pix;
908 pix = *p++;
909 #if (AROS_BIG_ENDIAN == 1)
910 *imdata ++ = pix >> 16;
911 *imdata ++ = (pix & pf->green_mask) >> 8;
912 *imdata ++ = (pix & pf->blue_mask);
913 #else
914 *imdata++ = (pix & pf->blue_mask);
915 *imdata++ = (pix & pf->green_mask) >> 8;
916 *imdata++ = pix >> 16;
917 #endif
919 imdata += image->bytes_per_line - width * 3;
920 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
922 break;
925 case 32:
927 ULONG *imdata = (ULONG *) image->data;
928 LONG x, y;
930 for (y = 0; y < height; y++)
932 HIDDT_Pixel *p = buf;
934 for (x = 0; x < width; x++)
936 *imdata++ = (ULONG) *p++;
938 imdata += image->bytes_per_line / 4 - width;
939 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
941 break;
944 default:
946 LONG x, y;
948 LOCK_X11
949 for (y = 0; y < height; y++)
951 HIDDT_Pixel *p;
953 p = buf;
954 for (x = 0; x < width; x++)
956 XPutPixel(image, x, y, *p++);
958 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo);
960 UNLOCK_X11
961 break;
964 } /* switch (image->bits_per_pixel) */
966 break;
968 default:
970 OOP_Object *srcpf, *dstpf, *gfxhidd;
971 APTR srcPixels = buf, dstBuf = image->data;
973 //bug("DEFAULT PIXEL CONVERSION\n");
975 OOP_GetAttr(bm, aHidd_BitMap_GfxHidd, (IPTR *) &gfxhidd);
976 srcpf = HIDD_Gfx_GetPixFmt(gfxhidd, msg->pixFmt);
978 OOP_GetAttr(bm, aHidd_BitMap_PixFmt, (IPTR *) &dstpf);
980 //bug("CALLING ConvertPixels()\n");
982 HIDD_BM_ConvertPixels(bm, &srcPixels, (HIDDT_PixelFormat *) srcpf, msg->modulo, &dstBuf,
983 (HIDDT_PixelFormat *) dstpf, image->bytes_per_line, width, height, NULL); /* We have no CLUT */
985 //bug("CONVERTPIXELS DONE\n");
987 buf = (HIDDT_Pixel *) ((UBYTE *) buf + msg->modulo * height);
988 break;
991 } /* switch (msg->pixFmt) */
993 return buf;
996 /****************************************************************************************/
998 static UBYTE *buf_to_ximage_lut(OOP_Class *cl, OOP_Object *bm, UBYTE *pixarray, XImage *image, ULONG width,
999 ULONG height, ULONG depth, struct pHidd_BitMap_PutImageLUT *msg)
1001 HIDDT_Pixel *lut = msg->pixlut->pixels;
1003 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1005 switch (image->bits_per_pixel)
1007 case 8:
1009 UBYTE *imdata = (UBYTE *) image->data;
1010 LONG x, y;
1012 for (y = 0; y < height; y++)
1014 UBYTE *buf = pixarray;
1016 for (x = 0; x < width; x++)
1018 *imdata++ = (UBYTE) lut[*buf++];
1020 pixarray += msg->modulo;
1021 imdata += (image->bytes_per_line - width); /*sg*/
1023 break;
1026 case 16:
1028 UWORD *imdata = (UWORD *) image->data;
1029 LONG x, y;
1031 for (y = 0; y < height; y++)
1033 UBYTE *buf = pixarray;
1035 for (x = 0; x < width; x++)
1037 *imdata++ = (UWORD) lut[*buf++];
1039 pixarray += msg->modulo;
1040 imdata += ((image->bytes_per_line / 2) - width); /*sg*/
1042 break;
1045 case 32:
1047 ULONG *imdata = (ULONG *) image->data;
1048 LONG x, y;
1050 for (y = 0; y < height; y++)
1052 UBYTE *buf = pixarray;
1054 for (x = 0; x < width; x++)
1056 *imdata++ = (ULONG) lut[*buf++];
1059 pixarray += msg->modulo;
1060 imdata += ((image->bytes_per_line / 4) - width); /*sg*/
1062 break;
1065 default:
1067 LONG x, y;
1069 for (y = 0; y < height; y++)
1071 UBYTE *buf = pixarray;
1073 for (x = 0; x < width; x++)
1075 XPutPixel(image, x, y, lut[*buf++]);
1078 pixarray += msg->modulo;
1081 break;
1085 } /* switch(image->bits_per_pixel) */
1087 return pixarray;
1090 /****************************************************************************************/
1092 #if USE_XSHM
1094 /****************************************************************************************/
1096 static void putimage_xshm(OOP_Class *cl, OOP_Object *o, OOP_Object *gc,
1097 LONG x, LONG y, ULONG width, ULONG height,
1098 APTR pixarray, APTR (*toimage_func)(), APTR toimage_data)
1101 struct bitmap_data *data;
1102 XImage *image;
1103 IPTR depth;
1104 ULONG lines_to_copy;
1105 LONG ysize;
1106 LONG current_y;
1107 LONG maxlines;
1108 OOP_Object *pf;
1110 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1112 data = OOP_INST_DATA(cl, o);
1114 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *)&pf);
1115 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1117 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
1119 LOCK_X11
1120 image = create_xshm_ximage(data->display,
1121 DefaultVisual(data->display, data->screen),
1122 depth,
1123 ZPixmap,
1124 width,
1125 height,
1126 XSD(cl)->xshm_info);
1127 UNLOCK_X11
1129 if (!image)
1130 return;
1132 /* Calculate how many scanline can be stored in the buffer */
1133 maxlines = XSHM_MEMSIZE / image->bytes_per_line;
1135 if (0 == maxlines)
1137 bug("ALERT !!! NOT ENOUGH MEMORY TO WRITE A COMPLETE SCANLINE\n");
1138 bug("THROUGH XSHM IN X11GF X HIDD !!!\n");
1139 Alert(AT_DeadEnd);
1142 current_y = 0;
1143 ysize = image->height;
1145 ObtainSemaphore(&XSD(cl)->shm_sema);
1147 while (ysize)
1149 /* Get some more pixels from the HIDD */
1151 lines_to_copy = MIN(maxlines, ysize);
1153 ysize -= lines_to_copy;
1154 image->height = lines_to_copy;
1156 pixarray = toimage_func(cl, o, pixarray, image, image->width,
1157 lines_to_copy, depth, toimage_data);
1159 LOCK_X11
1160 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1162 put_xshm_ximage(data->display,
1163 DRAWABLE(data),
1164 data->gc,
1165 image,
1166 0, 0,
1167 x, y + current_y,
1168 image->width, lines_to_copy,
1169 FALSE);
1171 UNLOCK_X11
1173 current_y += lines_to_copy;
1175 } /* while (pixels left to copy) */
1177 ReleaseSemaphore(&XSD(cl)->shm_sema);
1179 LOCK_X11
1180 destroy_xshm_ximage(image);
1181 UNLOCK_X11
1183 return;
1187 /****************************************************************************************/
1189 #endif
1191 /****************************************************************************************/
1193 static void putimage_xlib(OOP_Class *cl, OOP_Object *o, OOP_Object *gc, LONG x, LONG y, ULONG width, ULONG height,
1194 APTR pixarray, APTR(*toimage_func)(), APTR toimage_data)
1197 struct bitmap_data *data;
1198 XImage *image;
1199 ULONG bperline;
1200 IPTR depth;
1201 OOP_Object *pf;
1203 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1205 data = OOP_INST_DATA(cl, o);
1207 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (IPTR *) &pf);
1208 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
1210 LOCK_X11
1211 image = XCALL(XCreateImage, data->display,
1212 DefaultVisual(data->display, data->screen),
1213 depth,
1214 ZPixmap,
1216 NULL,
1217 width,
1218 height,
1221 UNLOCK_X11
1223 if (!image)
1224 return;
1226 #if DO_ENDIAN_FIX
1227 if (NEEDS_ENDIAN_FIX(image))
1229 image->byte_order = AROS_BYTEORDER;
1231 LOCK_X11
1232 XCALL(XInitImage, image);
1233 UNLOCK_X11
1235 #endif
1237 bperline = image->bytes_per_line;
1238 image->data = (char *) AllocVec((size_t) height * bperline, MEMF_PUBLIC);
1240 if (!image->data)
1242 LOCK_X11
1243 XCALL(XFree, image);
1244 UNLOCK_X11
1246 return;
1249 toimage_func(cl, o, pixarray, image, width, height, depth, toimage_data);
1251 LOCK_X11
1252 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1253 XCALL( XPutImage, data->display, DRAWABLE(data), data->gc, image, 0, 0, x, y, width, height);
1254 UNLOCK_X11
1256 FreeVec(image->data);
1258 LOCK_X11
1259 XCALL(XFree, image);
1260 UNLOCK_X11
1264 /****************************************************************************************/
1266 VOID MNAME(Hidd_BitMap__PutImage)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImage *msg)
1268 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,
1269 msg->height));
1271 #if USE_XSHM
1272 if (XSD(cl)->use_xshm)
1274 putimage_xshm(cl, o, msg->gc, msg->x, msg->y,
1275 msg->width, msg->height, msg->pixels,
1276 (APTR (*)()) buf_to_ximage, msg);
1278 else
1279 #endif
1281 putimage_xlib(cl, o, msg->gc, msg->x, msg->y, msg->width, msg->height, msg->pixels, (APTR(*)()) buf_to_ximage, msg);
1285 /****************************************************************************************/
1287 VOID MNAME(Hidd_BitMap__PutImageLUT)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg)
1289 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,
1290 msg->height));
1292 #if USE_XSHM
1293 if (XSD(cl)->use_xshm)
1295 putimage_xshm(cl, o, msg->gc, msg->x, msg->y,
1296 msg->width, msg->height, msg->pixels,
1297 (APTR (*)())buf_to_ximage_lut, msg);
1299 else
1300 #endif
1302 putimage_xlib(cl, o, msg->gc, msg->x, msg->y, msg->width, msg->height, msg->pixels, (APTR(*)()) buf_to_ximage_lut, msg);
1306 /****************************************************************************************/
1308 VOID MNAME(Root__Get)(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
1310 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1311 ULONG idx;
1313 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1315 if (IS_X11BM_ATTR(msg->attrID, idx))
1317 switch (idx)
1319 case aoHidd_X11BitMap_Drawable:
1320 *msg->storage = (IPTR) DRAWABLE(data);
1321 return;
1323 case aoHidd_X11BitMap_GC:
1324 *msg->storage = (IPTR) data->gc;
1325 return;
1329 OOP_DoSuperMethod(cl, o, &msg->mID);
1332 /****************************************************************************************/
1334 BOOL X11BM__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
1336 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1338 #if ADJUST_XWIN_SIZE
1339 /* This provides support for framebuffer display mode switching */
1340 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1342 if (data->flags & BMDF_FRAMEBUFFER)
1344 struct TagItem *tag = FindTagItem(aHidd_BitMap_ModeID, msg->attrList);
1346 if (tag)
1348 if (!X11BM_SetMode(data, tag->ti_Data, XSD(cl)))
1350 /* Bail out if error happened, see aoHidd_BitMap_ModeID documentation */
1351 return FALSE;
1355 #endif
1356 return OOP_DoSuperMethod(cl, o, &msg->mID);
1359 /****************************************************************************************/
1361 VOID MNAME(Hidd_BitMap__DrawLine)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawLine *msg)
1363 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1364 OOP_Object *gc = msg->gc;
1366 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1368 if (GC_LINEPAT(gc) != (UWORD) ~0)
1370 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
1372 return;
1375 LOCK_X11
1377 if (GC_DOCLIP(gc))
1379 XRectangle cr;
1381 cr.x = GC_CLIPX1(gc);
1382 cr.y = GC_CLIPY1(gc);
1383 cr.width = GC_CLIPX2(gc) - cr.x + 1;
1384 cr.height = GC_CLIPY2(gc) - cr.y + 1;
1386 XCALL(XSetClipRectangles, data->display, data->gc, 0, 0, &cr, 1, Unsorted);
1389 XCALL(XSetForeground, data->display, data->gc, GC_FG(gc));
1390 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1392 XCALL( XDrawLine, data->display, DRAWABLE(data), data->gc, msg->x1, msg->y1, msg->x2, msg->y2);
1394 if (GC_DOCLIP(gc))
1396 XCALL(XSetClipMask, data->display, data->gc, None);
1399 UNLOCK_X11
1402 /****************************************************************************************/
1404 VOID MNAME(Hidd_BitMap__DrawEllipse)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_DrawEllipse *msg)
1406 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1407 OOP_Object *gc = msg->gc;
1409 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1411 LOCK_X11
1413 if (GC_DOCLIP(gc))
1415 XRectangle cr;
1417 /* bug("X11::Drawllipse: clip %d %d %d %d\n"
1418 , GC_CLIPX1(gc), GC_CLIPY1(gc), GC_CLIPX2(gc), GC_CLIPY2(gc));
1421 cr.x = GC_CLIPX1(gc);
1422 cr.y = GC_CLIPY1(gc);
1423 cr.width = GC_CLIPX2(gc) - cr.x + 1;
1424 cr.height = GC_CLIPY2(gc) - cr.y + 1;
1426 XCALL(XSetClipRectangles, data->display, data->gc, 0, 0, &cr, 1, Unsorted);
1429 XCALL(XSetForeground, data->display, data->gc, GC_FG(gc));
1430 XCALL(XSetFunction, data->display, data->gc, GC_DRMD(gc));
1432 /* bug("X11::Drawllipse: coord %d %d %d %d\n"
1433 , msg->x, msg->y, msg->rx, msg->ry);
1437 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);
1439 if (GC_DOCLIP(gc))
1441 XCALL(XSetClipMask, data->display, data->gc, None);
1444 UNLOCK_X11
1447 /****************************************************************************************/
1449 VOID MNAME(Hidd_BitMap__UpdateRect)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg)
1451 struct bitmap_data *data = OOP_INST_DATA(cl, o);
1453 D(bug("[X11Bm] %s()\n", __PRETTY_FUNCTION__));
1455 LOCK_X11
1457 if (data->flags & BMDF_FRAMEBUFFER)
1458 X11BM_ExposeFB(data, msg->x, msg->y, msg->width, msg->height);
1460 XCALL(XFlush, data->display);
1462 UNLOCK_X11