adding some stuff for compositing goop!

SVN revision: 44920
This commit is contained in:
Carsten Haitzler 2010-01-06 14:14:23 +00:00
parent c3dc62306f
commit 232be7f24e
5 changed files with 324 additions and 9 deletions

View File

@ -414,7 +414,10 @@ struct _Ecore_X_Event_Window_Visibility_Change
struct _Ecore_X_Event_Window_Create
{
Ecore_X_Window win;
Ecore_X_Window parent;
int override;
int x, y, w, h;
int border;
Ecore_X_Time time;
};
@ -1605,9 +1608,9 @@ typedef struct _Ecore_X_Window_Attributes
unsigned char input_only : 1;
unsigned char save_under : 1;
struct {
Ecore_X_Event_Mask mine;
Ecore_X_Event_Mask all;
Ecore_X_Event_Mask no_propagate;
Ecore_X_Event_Mask mine;
Ecore_X_Event_Mask all;
Ecore_X_Event_Mask no_propagate;
} event_mask;
Ecore_X_Gravity window_gravity;
Ecore_X_Gravity pixel_gravity;
@ -1618,7 +1621,7 @@ typedef struct _Ecore_X_Window_Attributes
* Screen *screen;
*/
} Ecore_X_Window_Attributes;
EAPI void ecore_x_get_window_attributes_prefetch(Ecore_X_Window window);
EAPI void ecore_x_get_window_attributes_fetch(void);
EAPI int ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret);
@ -1747,7 +1750,9 @@ EAPI void ecore_x_composite_redirect_subwindows(Ecore_X_Window win,
EAPI void ecore_x_composite_unredirect_window(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
EAPI void ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, Ecore_X_Composite_Update_Type type);
EAPI Ecore_X_Pixmap ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win);
EAPI Ecore_X_Window ecore_x_composite_render_window_enable(Ecore_X_Window root);
EAPI void ecore_x_composite_render_window_disable(Ecore_X_Window root);
/* XDamage Extension Support */
typedef Ecore_X_ID Ecore_X_Damage;
@ -1800,7 +1805,15 @@ EAPI int ecore_x_test_fake_key_down(const char *key);
EAPI int ecore_x_test_fake_key_up(const char *key);
EAPI int ecore_x_test_fake_key_press(const char *key);
EAPI const char *ecore_x_keysym_string_get(int keysym);
typedef struct _Ecore_X_Image Ecore_X_Image;
EAPI Ecore_X_Image *ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth);
EAPI void ecore_x_image_free(Ecore_X_Image *im);
EAPI void ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw, int x, int y, int sx, int sy, int w, int h);
EAPI void ecore_x_image_put(Ecore_X_Image *im, Ecore_X_Drawable draw, int x, int y, int sx, int sy, int w, int h);
EAPI void *ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *bpp);
#ifdef __cplusplus
}
#endif

View File

@ -57,7 +57,8 @@ ecore_x_drawable.c \
ecore_x_cursor.c \
ecore_x_test.c \
ecore_x_atoms.c \
ecore_x_region.c
ecore_x_region.c \
ecore_x_image.c
libecore_x_xlib_la_LIBADD = \
@Xcursor_libs@ \

View File

@ -118,3 +118,29 @@ ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win)
return pixmap;
}
EAPI Ecore_X_Window
ecore_x_composite_render_window_enable(Ecore_X_Window root)
{
Ecore_X_Window win = 0;
#ifdef ECORE_XCOMPOSITE
XRectangle rect;
win = XCompositeGetOverlayWindow(_ecore_x_disp, root);
rect.x = -1;
rect.y = -1;
rect.width = 1;
rect.height = 1;
XShapeCombineRectangles(_ecore_x_disp, win, ShapeInput, 0, 0, &rect, 1,
ShapeSet, Unsorted);
#endif
return win;
}
EAPI void
ecore_x_composite_render_window_disable(Ecore_X_Window root)
{
#ifdef ECORE_XCOMPOSITE
XCompositeReleaseOverlayWindow(_ecore_x_disp, root);
#endif
}

View File

@ -898,10 +898,16 @@ _ecore_x_event_handle_create_notify(XEvent *xevent)
e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
if (!e) return;
e->win = xevent->xcreatewindow.window;
e->parent = xevent->xcreatewindow.parent;
if (xevent->xcreatewindow.override_redirect)
e->override = 1;
e->override = 1;
else
e->override = 0;
e->override = 0;
e->x = xevent->xcreatewindow.x;
e->y = xevent->xcreatewindow.y;
e->w = xevent->xcreatewindow.width;
e->h = xevent->xcreatewindow.height;
e->border = xevent->xcreatewindow.border_width;
e->time = _ecore_x_event_last_time;
ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
}

View File

@ -0,0 +1,269 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_x_private.h"
#include "Ecore_X.h"
#include <X11/extensions/XShm.h>
#include <X11/Xutil.h>
#include <sys/ipc.h>
#include <sys/shm.h>
static int _composite_available;
static int _ecore_x_image_shm_can = -1;
static int _ecore_x_image_err = 0;
static void
_ecore_x_image_error_handler(Display * d, XErrorEvent * ev)
{
_ecore_x_image_err = 1;
}
static void
_ecore_x_image_shm_check(void)
{
XErrorHandler ph;
XShmSegmentInfo shminfo;
XImage *xim;
if (_ecore_x_image_shm_can != -1) return;
XSync(_ecore_x_disp, False);
_ecore_x_image_err = 0;
xim = XShmCreateImage(_ecore_x_disp,
DefaultVisual(_ecore_x_disp,
DefaultScreen(_ecore_x_disp)),
DefaultDepth(_ecore_x_disp,
DefaultScreen(_ecore_x_disp)),
ZPixmap, NULL,
&shminfo, 1, 1);
if (!xim)
{
_ecore_x_image_shm_can = 0;
return;
}
shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
IPC_CREAT | 0666);
if (shminfo.shmid == -1)
{
XDestroyImage(xim);
_ecore_x_image_shm_can = 0;
return;
}
shminfo.readOnly = False;
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
xim->data = shminfo.shmaddr;
if (xim->data == (char *)-1)
{
XDestroyImage(xim);
_ecore_x_image_shm_can = 0;
return;
}
ph = XSetErrorHandler((XErrorHandler)_ecore_x_image_error_handler);
XShmAttach(_ecore_x_disp, &shminfo);
XShmGetImage(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp),
xim, 0, 0, 0xffffffff);
XSync(_ecore_x_disp, False);
XSetErrorHandler((XErrorHandler)ph);
if (_ecore_x_image_err)
{
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
XDestroyImage(xim);
_ecore_x_image_shm_can = 0;
return;
}
shmdt(shminfo.shmaddr);
shmctl(shminfo.shmid, IPC_RMID, 0);
XDestroyImage(xim);
_ecore_x_image_shm_can = 1;
}
struct _Ecore_X_Image
{
XShmSegmentInfo shminfo;
Ecore_X_Visual vis;
XImage *xim;
int depth;
int w, h;
int bpl, bpp, rows;
unsigned char *data;
Eina_Bool shm : 1;
};
EAPI Ecore_X_Image *
ecore_x_image_new(int w, int h, Ecore_X_Visual vis, int depth)
{
Ecore_X_Image *im;
im = calloc(1, sizeof(Ecore_X_Image));
if (!im) return NULL;
im->w = w;
im->h = h;
im->vis = vis;
im->depth = depth;
_ecore_x_image_shm_check();
im->shm = _ecore_x_image_shm_can;
return im;
}
/*
if (_ecore_x_image_shm_can)
{
}
else
{
im->xim = XCreateImage(_ecore_x_disp, im->vis, im->depth,
ZPixmap, 0, NULL, im->w, im->h, 32, 0);
if (!im->xim)
{
free(im);
return NULL;
}
im->xim->data = malloc(im->xim->bytes_per_line * im->xim->height);
if (im->xim->data == NULL)
{
XDestroyImage(im->xim);
free(im);
return NULL;
}
}
im->data = im->xim->data;
*/
EAPI void
ecore_x_image_free(Ecore_X_Image *im)
{
if (im->shm)
{
shmdt(im->shminfo.shmaddr);
shmctl(im->shminfo.shmid, IPC_RMID, 0);
}
else
{
if (im->xim) free(im->xim->data);
}
if (im->xim)
{
im->xim->data = NULL;
XDestroyImage(im->xim);
}
free(im);
}
static void
_ecore_x_image_shm_create(Ecore_X_Image *im)
{
im->xim = XShmCreateImage(_ecore_x_disp, im->vis, im->depth,
ZPixmap, NULL, &(im->shminfo),
im->w, im->h);
if (!im->xim) return;
im->shminfo.shmid = shmget(IPC_PRIVATE,
im->xim->bytes_per_line * im->xim->height,
IPC_CREAT | 0666);
if (im->shminfo.shmid == -1)
{
XDestroyImage(im->xim);
return;
}
im->shminfo.readOnly = False;
im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0);
im->xim->data = im->shminfo.shmaddr;
if ((im->xim->data == (char *)-1) ||
(im->xim->data == NULL))
{
shmdt(im->shminfo.shmaddr);
shmctl(im->shminfo.shmid, IPC_RMID, 0);
XDestroyImage(im->xim);
return;
}
XShmAttach(_ecore_x_disp, &im->shminfo);
im->data = im->xim->data;
im->bpl = im->xim->bytes_per_line;
im->rows = im->xim->height;
if (im->xim->bits_per_pixel <= 8) im->bpp = 1;
else if (im->xim->bits_per_pixel <= 16) im->bpp = 2;
else im->bpp = 4;
}
EAPI void
ecore_x_image_get(Ecore_X_Image *im, Ecore_X_Drawable draw,
int x, int y, int sx, int sy, int w, int h)
{
if (im->shm)
{
if (!im->xim) _ecore_x_image_shm_create(im);
if (!im->xim) return;
// optimised path
if ((sx == 0) && (w == im->w))
{
im->xim->data =
im->data + (im->xim->bytes_per_line * sy) + (sx * im->bpp);
im->xim->width = w;
im->xim->height = h;
XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff);
ecore_x_sync();
}
// unavoidable thanks to mit-shm get api - tmp shm buf + copy into it
else
{
Ecore_X_Image *tim;
unsigned char *spixels, *sp, *pixels, *p;
int bpp, bpl, rows, sbpp, sbpl, srows;
int r;
tim = ecore_x_image_new(w, h, im->vis, im->depth);
ecore_x_image_get(tim, draw, x, y, 0, 0, w, h);
spixels = ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp);
pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp);
p = pixels + (sy * bpl) + (sx * bpp);
sp = spixels;
for (r = srows; r > 0; r--)
{
memcpy(p, sp, sbpl);
p += bpl;
sp += sbpl;
}
ecore_x_image_free(tim);
}
}
else
{
printf("currently unimplemented ecore_x_image_get without shm\n");
}
}
EAPI void
ecore_x_image_put(Ecore_X_Image *im, Ecore_X_Drawable draw,
int x, int y, int sx, int sy, int w, int h)
{
printf("ecore_x_image_put: unimplemented!\n");
}
EAPI void *
ecore_x_image_data_get(Ecore_X_Image *im, int *bpl, int *rows, int *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;
}