From a1bccd32590cad819d920a6ad7a06b0463207d80 Mon Sep 17 00:00:00 2001 From: raster Date: Fri, 1 Oct 2010 12:31:22 +0000 Subject: [PATCH] implement ecore_x_image to finish - put and convert done. actually no need for convert from argb as that requires what evas already does argb-> screen depth. use evas for that. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@52950 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/ecore_x/Ecore_X.h | 17 +- src/lib/ecore_x/xlib/ecore_x_image.c | 310 ++++++++++++++++++++++++++++++++--- 2 files changed, 290 insertions(+), 37 deletions(-) diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 731e843..68b677c 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -2978,6 +2978,7 @@ EAPI Eina_Bool ecore_x_image_get(Ecore_X_Image *im, int h); EAPI void ecore_x_image_put(Ecore_X_Image *im, Ecore_X_Drawable draw, + Ecore_X_GC gc, int x, int y, int sx, @@ -2988,21 +2989,15 @@ EAPI void * ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp); +EAPI Eina_Bool ecore_x_image_is_argb32_get(Ecore_X_Image *im); + EAPI Eina_Bool ecore_x_image_to_argb_convert(void *src, int sbpp, - int sbpl, int srows, + int sbpl, Ecore_X_Colormap c, Ecore_X_Visual v, int x, int y, int w, int h, - void *dst, int dbpp, - int dbpl, int drows, - int dx, int dy); -EAPI Eina_Bool ecore_x_image_from_argb_convert(void *src, int sbpp, - int sbpl, int srows, - Ecore_X_Colormap c, - Ecore_X_Visual v, - int x, int y, int w, int h, - void *dst, int dbpp, - int dbpl, int drows, + unsigned int *dst, + int dbpl, int dx, int dy); EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); diff --git a/src/lib/ecore_x/xlib/ecore_x_image.c b/src/lib/ecore_x/xlib/ecore_x_image.c index ce36381..151a61e 100644 --- a/src/lib/ecore_x/xlib/ecore_x_image.c +++ b/src/lib/ecore_x/xlib/ecore_x_image.c @@ -215,9 +215,10 @@ ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw, im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp); im->xim->width = w; im->xim->height = h; + XGrabServer(_ecore_x_disp); if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff)) ret = EINA_FALSE; - + XUngrabServer(_ecore_x_disp); ecore_x_sync(); } // unavoidable thanks to mit-shm get api - tmp shm buf + copy into it @@ -270,38 +271,295 @@ ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw, } /* ecore_x_image_get */ EAPI void -ecore_x_image_put(Ecore_X_Image *im __UNUSED__, - Ecore_X_Drawable draw __UNUSED__, - int x __UNUSED__, - int y __UNUSED__, - int sx __UNUSED__, - int sy __UNUSED__, - int w __UNUSED__, - int h __UNUSED__) +ecore_x_image_put(Ecore_X_Image *im, + Ecore_X_Drawable draw, + Ecore_X_GC gc, + int x, + int y, + int sx, + int sy, + int w, + int h) { - LOGFN(__FILE__, __LINE__, __FUNCTION__); - printf("ecore_x_image_put: unimplemented!\n"); + Ecore_X_GC tgc = 0; + + if (!gc) + { + XGCValues gcv; + memset(&gcv, 0, sizeof(gcv)); + gcv.subwindow_mode = IncludeInferiors; + tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv); + gc = tgc; + } + if (!im->xim) _ecore_x_image_shm_create(im); + XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False); + if (tgc) ecore_x_gc_free(tgc); } /* ecore_x_image_put */ EAPI void * ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp) { LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!im->xim) - _ecore_x_image_shm_create(im); - - if (!im->xim) - return NULL; - - if (bpl) - *bpl = im->bpl; - - if (rows) - *rows = im->rows; - - if (bpp) - *bpp = im->bpp; - + if (!im->xim) _ecore_x_image_shm_create(im); + if (!im->xim) return NULL; + if (bpl) *bpl = im->bpl; + if (rows) *rows = im->rows; + if (bpp) *bpp = im->bpp; return im->data; } /* ecore_x_image_data_get */ +EAPI Eina_Bool +ecore_x_image_is_argb32_get(Ecore_X_Image *im) +{ + Visual *vis = im->vis; + if (!im->xim) _ecore_x_image_shm_create(im); + if (((vis->class == TrueColor) || + (vis->class == DirectColor)) && + (im->depth >= 24) && + (vis->red_mask == 0xff0000) && + (vis->green_mask == 0x00ff00) && + (vis->blue_mask == 0x0000ff)) + { +#ifdef WORDS_BIGENDIAN + if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE; +#else + if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE; +#endif + } + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_image_to_argb_convert(void *src, int sbpp, + int sbpl, + Ecore_X_Colormap c, + Ecore_X_Visual v, + int x, int y, int w, int h, + unsigned int *dst, + int dbpl, + int dx, int dy) +{ + Visual *vis = v; + XColor *cols = NULL; + int n = 0, nret = 0, i, row; + unsigned int pal[256], r, g, b; + enum + { + rgbnone = 0, + rgb565, + bgr565, + rgbx555, + argbx888, + abgrx888, + rgba888x, + bgra888x, + argbx666 + }; + int mode = 0; + + sbpp *= 8; + + n = vis->map_entries; + if ((n <= 256) && + ((vis->class == PseudoColor) || + (vis->class == StaticColor) || + (vis->class == GrayScale) || + (vis->class == StaticGray))) + { + if (!c) c = DefaultColormap(_ecore_x_disp, + DefaultScreen(_ecore_x_disp)); + cols = alloca(n * sizeof(XColor)); + for (i = 0; i < n; i++) + { + cols[i].pixel = i; + cols[i].flags = DoRed | DoGreen | DoBlue; + cols[i].red = 0; + cols[i].green = 0; + cols[i].blue = 0; + } + XQueryColors(_ecore_x_disp, c, cols, n); + for (i = 0; i < n; i++) + { + pal[i] = 0xff000000 | + ((cols[i].red >> 8) << 16) | + ((cols[i].green >> 8) << 8 ) | + ((cols[i].blue >> 8) ); + } + nret = n; + } + else if ((vis->class == TrueColor) || + (vis->class == DirectColor)) + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } + for (row = 0; row < h; row++) + { + unsigned char *s8; + unsigned short *s16; + unsigned int *s32; + unsigned int *dp, *de; + + dp = ((unsigned int *)(((unsigned char *)dst) + + ((dy + row) * dbpl))) + dx; + de = dp + w; + switch (sbpp) + { + case 8: + s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + if (nret > 0) + { + while (dp < de) + { + *dp = pal[*s8]; + s8++; dp++; + } + } + else + return EINA_FALSE; + break; + case 16: + s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + switch (mode) + { + case rgb565: + while (dp < de) + { + r = (*s16 & 0xf800) << 8; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + case bgr565: + while (dp < de) + { + r = (*s16 & 0x001f) << 19; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0xf800) >> 8; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + case rgbx555: + while (dp < de) + { + r = (*s16 & 0x7c00) << 9; + g = (*s16 & 0x03e0) << 6; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 5) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + case 24: + case 32: + s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + switch (mode) + { + case argbx888: + while (dp < de) + { + *dp = 0xff000000 | *s32; + s32++; dp++; + } + break; + case abgrx888: + while (dp < de) + { + r = *s32 & 0x000000ff; + g = *s32 & 0x0000ff00; + b = *s32 & 0x00ff0000; + *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); + s32++; dp++; + } + break; + case rgba888x: + while (dp < de) + { + *dp = 0xff000000 | (*s32 >> 8); + s32++; dp++; + } + break; + case bgra888x: + while (dp < de) + { + r = *s32 & 0x0000ff00; + g = *s32 & 0x00ff0000; + b = *s32 & 0xff000000; + *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); + s32++; dp++; + } + break; + case argbx666: + while (dp < de) + { + r = (*s32 & 0x3f000) << 6; + g = (*s32 & 0x00fc0) << 4; + b = (*s32 & 0x0003f) << 2; + r |= (r >> 6) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 6); + *dp = 0xff000000 | r | g | b; + s32++; dp++; + } + break; + default: + return EINA_FALSE; + break; + } + break; + break; + default: + return EINA_FALSE; + break; + } + } + return EINA_TRUE; +} -- 2.7.4