adding some stuff for compositing goop!
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 6 Jan 2010 14:14:23 +0000 (14:14 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 6 Jan 2010 14:14:23 +0000 (14:14 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/ecore@44920 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/xlib/Makefile.am
src/lib/ecore_x/xlib/ecore_x_composite.c
src/lib/ecore_x/xlib/ecore_x_events.c
src/lib/ecore_x/xlib/ecore_x_image.c [new file with mode: 0644]

index 924e68b..13f8557 100644 (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
index da19a96..5f1bb7d 100644 (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@ \
index f9e091c..8f0176f 100644 (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   
+}
index e89ca34..c9eb140 100644 (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);
 }
diff --git a/src/lib/ecore_x/xlib/ecore_x_image.c b/src/lib/ecore_x/xlib/ecore_x_image.c
new file mode 100644 (file)
index 0000000..2efa274
--- /dev/null
@@ -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;
+}