eolian: rename is_ref API to is_ptr to match syntax
[platform/upstream/efl.git] / src / modules / evas / engines / software_x11 / evas_xcb_outbuf.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <pixman.h>
6
7 #ifdef EVAS_CSERVE2
8 # include "evas_cs2_private.h"
9 #endif
10 #include "evas_common_private.h"
11 #include "evas_macros.h"
12 #include "evas_xcb_outbuf.h"
13 #include "evas_xcb_buffer.h"
14 #include "evas_xcb_color.h"
15
16 /* local structures */
17 typedef struct _Outbuf_Region Outbuf_Region;
18 struct _Outbuf_Region 
19 {
20    Xcb_Output_Buffer *xcbob, *mask;
21    int x, y, w, h;
22 };
23
24 /* local function prototypes */
25 static Xcb_Output_Buffer *_find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data);
26 static void _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync);
27 static void _clear_xcbob(Eina_Bool sync);
28 static void _xcbob_sync(xcb_connection_t *conn);
29
30 /* local variables */
31 static Eina_List *_shmpool = NULL;
32 static int _shmsize = 0;
33 static int _shmlimit = 0;
34 static const unsigned int _shmcountlimit = 32;
35
36 static Eina_Spinlock shmpool_lock;
37 #define SHMPOOL_LOCK() eina_spinlock_take(&shmpool_lock)
38 #define SHMPOOL_UNLOCK() eina_spinlock_release(&shmpool_lock)
39
40 void 
41 evas_software_xcb_outbuf_init(void) 
42 {
43    eina_spinlock_new(&shmpool_lock);
44 }
45
46 void 
47 evas_software_xcb_outbuf_free(Outbuf *buf) 
48 {
49    SHMPOOL_LOCK();
50    _shmlimit -= ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
51    SHMPOOL_UNLOCK();
52    eina_spinlock_take(&(buf->priv.lock));
53    while (buf->priv.pending_writes) 
54      {
55         RGBA_Image *im = NULL;
56         Outbuf_Region *obr = NULL;
57
58         im = buf->priv.pending_writes->data;
59         buf->priv.pending_writes = 
60           eina_list_remove_list(buf->priv.pending_writes, 
61                                 buf->priv.pending_writes);
62         obr = im->extended_info;
63 #ifdef EVAS_CSERVE2
64         if (evas_cserve2_use_get())
65           evas_cache2_image_close(&im->cache_entry);
66         else
67 #endif
68           evas_cache_image_drop(&im->cache_entry);
69
70         if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
71         if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
72         free(obr);
73      }
74    eina_spinlock_release(&(buf->priv.lock));
75
76    evas_software_xcb_outbuf_idle_flush(buf);
77    evas_software_xcb_outbuf_flush(buf, NULL, NULL, MODE_FULL);
78
79    if (buf->priv.x11.xcb.gc)
80      xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc);
81    if (buf->priv.x11.xcb.gcm)
82      xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm);
83    if (buf->priv.pal)
84      evas_software_xcb_color_deallocate(buf->priv.x11.xcb.conn, 
85                                         buf->priv.x11.xcb.cmap, 
86                                         buf->priv.x11.xcb.visual, 
87                                         buf->priv.pal);
88
89    eina_array_flush(&buf->priv.onebuf_regions);
90    eina_spinlock_free(&(buf->priv.lock));
91    free(buf);
92    _clear_xcbob(EINA_TRUE);
93 }
94
95 Outbuf *
96 evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha) 
97 {
98    Outbuf *buf = NULL;
99    Gfx_Func_Convert func_conv = NULL;
100    Xcb_Output_Buffer *xob;
101    const xcb_setup_t *setup;
102
103    if (!(buf = calloc(1, sizeof(Outbuf)))) 
104      return NULL;
105
106    if (xdepth < 15) rot = 0;
107    
108    setup = xcb_get_setup(conn);
109
110    buf->w = w;
111    buf->h = h;
112    buf->depth = depth;
113    buf->rot = rot;
114    buf->priv.x11.xcb.conn = conn;
115    buf->priv.x11.xcb.screen = screen;
116    buf->priv.x11.xcb.visual = vis;
117    buf->priv.x11.xcb.cmap = cmap;
118    buf->priv.x11.xcb.depth = xdepth;
119    buf->priv.mask_dither = shape_dither;
120    buf->priv.destination_alpha = alpha;
121    buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);
122
123    xob = 
124      evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
125                                          buf->priv.x11.xcb.visual, 
126                                          buf->priv.x11.xcb.depth, 
127                                          1, 1, buf->priv.x11.xcb.shm, 
128                                          NULL);
129    if (!xob) buf->priv.x11.xcb.shm = 0;
130    xob = 
131      evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
132                                          buf->priv.x11.xcb.visual, 
133                                          buf->priv.x11.xcb.depth, 
134                                          1, 1, buf->priv.x11.xcb.shm, 
135                                          NULL);
136    if (!xob) 
137      {
138         free(buf);
139         return NULL;
140      }
141    buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
142    evas_software_xcb_output_buffer_unref(xob, EINA_FALSE);
143    
144    eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);
145
146 #ifdef WORDS_BIGENDIAN
147    if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
148      buf->priv.x11.xcb.swap = EINA_TRUE;
149 #else
150    if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
151      buf->priv.x11.xcb.swap = EINA_TRUE;
152 #endif
153    if (setup->bitmap_format_bit_order == XCB_IMAGE_ORDER_MSB_FIRST)
154      buf->priv.x11.xcb.bit_swap = EINA_TRUE;
155
156    if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || 
157         (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && (xdepth > 8)) 
158      {
159         buf->priv.mask.r = (DATA32)vis->red_mask;
160         buf->priv.mask.g = (DATA32)vis->green_mask;
161         buf->priv.mask.b = (DATA32)vis->blue_mask;
162         if (buf->priv.x11.xcb.swap) 
163           {
164              SWAP32(buf->priv.mask.r);
165              SWAP32(buf->priv.mask.g);
166              SWAP32(buf->priv.mask.b);
167           }
168      }
169    else if ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || 
170             (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || 
171             (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || 
172             (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) || 
173             (xdepth <= 8)) 
174      {
175         Convert_Pal_Mode pm = PAL_MODE_RGB332;
176
177         if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || 
178             (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))
179           grayscale = EINA_TRUE;
180         if (grayscale) 
181           {
182              if (max_colors >= 256)
183                pm = PAL_MODE_GRAY256;
184              else if (max_colors >= 64)
185                pm = PAL_MODE_GRAY64;
186              else if (max_colors >= 16)
187                pm = PAL_MODE_GRAY16;
188              else if (max_colors >= 4)
189                pm = PAL_MODE_GRAY4;
190              else
191                pm = PAL_MODE_MONO;
192           }
193         else 
194           {
195              if (max_colors >= 256)
196                pm = PAL_MODE_RGB332;
197              else if (max_colors >= 216)
198                pm = PAL_MODE_RGB666;
199              else if (max_colors >= 128)
200                pm = PAL_MODE_RGB232;
201              else if (max_colors >= 64)
202                pm = PAL_MODE_RGB222;
203              else if (max_colors >= 32)
204                pm = PAL_MODE_RGB221;
205              else if (max_colors >= 16)
206                pm = PAL_MODE_RGB121;
207              else if (max_colors >= 8)
208                pm = PAL_MODE_RGB111;
209              else if (max_colors >= 4)
210                pm = PAL_MODE_GRAY4;
211              else
212                pm = PAL_MODE_MONO;
213           }
214         /* FIXME: Only allocate once per display & colormap */
215         buf->priv.pal = 
216           evas_software_xcb_color_allocate(conn, cmap, vis, pm);
217         if (!buf->priv.pal) 
218           {
219              free(buf);
220              return NULL;
221           }
222      }
223    if ((buf->rot == 0) || (buf->rot == 180))
224      {
225         w = buf->w;
226         h = buf->h;
227      }
228    else if ((buf->rot == 90) || (buf->rot == 270)) 
229      {
230         w = buf->h;
231         h = buf->w;
232      }
233
234    if (buf->priv.pal) 
235      {
236         func_conv = 
237           evas_common_convert_func_get(0, w, h, xdepth, 
238                                        buf->priv.mask.r, 
239                                        buf->priv.mask.g, 
240                                        buf->priv.mask.b, 
241                                        buf->priv.pal->colors, buf->rot);
242      }
243    else 
244      {
245         func_conv = 
246           evas_common_convert_func_get(0, w, h, xdepth, 
247                                        buf->priv.mask.r, 
248                                        buf->priv.mask.g, 
249                                        buf->priv.mask.b, 
250                                        PAL_MODE_NONE, buf->rot);
251      }
252    if (!func_conv) 
253      {
254         ERR("XCB Engine"
255             " {"
256             "  At depth         %i:"
257             "  RGB format mask: %08x, %08x, %08x"
258             "  Palette mode:    %i"
259             "  Not supported by any compiled in converters!"
260             " }", buf->priv.x11.xcb.depth, buf->priv.mask.r,
261             buf->priv.mask.g, buf->priv.mask.b,
262             buf->priv.pal ? (int)buf->priv.pal->colors : -1);
263      }
264
265    evas_software_xcb_outbuf_drawable_set(buf, draw);
266    evas_software_xcb_outbuf_mask_set(buf, mask);
267    eina_spinlock_new(&(buf->priv.lock));
268
269    SHMPOOL_LOCK();
270    _shmlimit += ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
271    SHMPOOL_UNLOCK();
272    return buf;
273 }
274
275 void *
276 evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) 
277 {
278    RGBA_Image *im = NULL;
279    Outbuf_Region *obr = NULL;
280    Eina_Bool use_shm = EINA_TRUE;
281    Eina_Bool alpha = EINA_FALSE;
282    int bpl = 0;
283
284    eina_spinlock_take(&(buf->priv.lock));
285    if ((buf->onebuf) && (buf->priv.x11.xcb.shm)) 
286      {
287         Eina_Rectangle *rect;
288
289         RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
290
291         if (!(obr = calloc(1, sizeof(Outbuf_Region))))
292           {
293              eina_spinlock_release(&(buf->priv.lock));
294              return NULL;
295           }
296
297         if (!(rect = eina_rectangle_new(x, y, w, h))) 
298           {
299              free(obr);
300              eina_spinlock_release(&(buf->priv.lock));
301              return NULL;
302           }
303
304         if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
305             (buf->priv.onebuf))
306           {
307              if (cx) *cx = x;
308              if (cy) *cy = y;
309              if (cw) *cw = w;
310              if (ch) *ch = h;
311              if (!buf->priv.synced) 
312                {
313                   _xcbob_sync(buf->priv.x11.xcb.conn);
314                   buf->priv.synced = EINA_TRUE;
315                }
316              free(obr);
317              eina_spinlock_release(&(buf->priv.lock));
318              return buf->priv.onebuf;
319           }
320         obr->x = 0;
321         obr->y = 0;
322         obr->w = buf->w;
323         obr->h = buf->h;
324         if (cx) *cx = x;
325         if (cy) *cy = y;
326         if (cw) *cw = w;
327         if (ch) *ch = h;
328
329         alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
330         use_shm = buf->priv.x11.xcb.shm;
331
332         if ((buf->rot == 0) &&
333             (buf->priv.x11.xcb.imdepth == 32) &&
334             (buf->priv.mask.r == 0xff0000) &&
335             (buf->priv.mask.g == 0x00ff00) &&
336             (buf->priv.mask.b == 0x0000ff))
337           {
338              obr->xcbob = 
339                evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
340                                                    buf->priv.x11.xcb.visual, 
341                                                    buf->priv.x11.xcb.depth, 
342                                                    buf->w, buf->h, use_shm, 
343                                                    NULL);
344              if (!obr->xcbob) 
345                {
346                   free(obr);
347                   eina_spinlock_release(&(buf->priv.lock));
348                   return NULL;
349                }
350 #ifdef EVAS_CSERVE2
351              if (evas_cserve2_use_get())
352                {
353                   im = 
354                     (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), 
355                                                          buf->w, buf->h, 
356                                                          (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
357                                                          alpha, EVAS_COLORSPACE_ARGB8888);
358                }
359              else
360 #endif
361                {
362                   im = 
363                     (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), 
364                                                         buf->w, buf->h, 
365                                                         (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
366                                                         alpha, EVAS_COLORSPACE_ARGB8888);
367                }
368
369              if (!im) 
370                {
371                   evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE);
372                   free(obr);
373                   eina_spinlock_release(&(buf->priv.lock));
374                   return NULL;
375                }
376              im->extended_info = obr;
377              if (buf->priv.x11.xcb.mask) 
378                {
379                   obr->mask = 
380                     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
381                                                         buf->priv.x11.xcb.visual, 
382                                                         1, buf->w, buf->h, 
383                                                         use_shm, NULL);
384                }
385           }
386         else 
387           {
388              int bw = 0, bh = 0;
389
390 #ifdef EVAS_CSERVE2
391              if (evas_cserve2_use_get())
392                {
393                   im = 
394                     (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
395                }
396              else
397 #endif
398                {
399                   im = 
400                     (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
401                }
402
403              if (!im) 
404                {
405                   free(obr);
406                   eina_spinlock_release(&(buf->priv.lock));
407                   return NULL;
408                }
409              im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
410 #ifdef EVAS_CSERVE2
411              if (evas_cserve2_use_get())
412                evas_cache2_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
413              else
414 #endif
415                evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
416
417              im->extended_info = obr;
418              if ((buf->rot == 0) || (buf->rot == 180)) 
419                {
420                   bw = buf->w;
421                   bh = buf->h;
422                }
423              else if ((buf->rot == 90) || (buf->rot == 270)) 
424                {
425                   bw = buf->h;
426                   bh = buf->w;
427                }
428              obr->xcbob = 
429                evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
430                                                    buf->priv.x11.xcb.visual, 
431                                                    buf->priv.x11.xcb.depth, 
432                                                    bw, bh, use_shm, NULL);
433              if (!obr->xcbob) 
434                {
435 #ifdef EVAS_CSERVE2
436                   if (evas_cserve2_use_get())
437                     evas_cache2_image_close(&im->cache_entry);
438                   else
439 #endif
440                     evas_cache_image_drop(&im->cache_entry);
441
442                   free(obr);
443                   eina_spinlock_release(&(buf->priv.lock));
444                   return NULL;
445                }
446              if (buf->priv.x11.xcb.mask) 
447                {
448                   obr->mask = 
449                     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
450                                                         buf->priv.x11.xcb.visual, 
451                                                         1, bw, bh, use_shm, 
452                                                         NULL);
453                }
454           }
455         /* FIXME: We should be able to remove this memset. */
456         if ((alpha) && (im->image.data)) 
457           {
458              /* FIXME: Faster memset */
459 //             memset(im->image.data, 0, (w * h * sizeof(DATA32)));
460           }
461         buf->priv.onebuf = im;
462         eina_spinlock_release(&(buf->priv.lock));
463         return im;
464      }
465
466    if (!(obr = calloc(1, sizeof(Outbuf_Region))))
467      {
468         eina_spinlock_release(&(buf->priv.lock));
469         return NULL;
470      }
471
472    obr->x = x;
473    obr->y = y;
474    obr->w = w;
475    obr->h = h;
476    if (cx) *cx = 0;
477    if (cy) *cy = 0;
478    if (cw) *cw = w;
479    if (ch) *ch = h;
480
481    use_shm = buf->priv.x11.xcb.shm;
482    alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
483    if ((buf->rot == 0) &&
484        (buf->priv.x11.xcb.imdepth == 32) &&
485        (buf->priv.mask.r == 0xff0000) && 
486        (buf->priv.mask.g == 0x00ff00) &&
487        (buf->priv.mask.b == 0x0000ff)) 
488      {
489         obr->xcbob = 
490           _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
491                       buf->priv.x11.xcb.depth, w, h, use_shm, NULL);
492         if (!obr->xcbob) 
493           {
494              free(obr);
495              eina_spinlock_release(&(buf->priv.lock));
496              return NULL;
497           }
498 #ifdef EVAS_CSERVE2
499         if (evas_cserve2_use_get())
500           {
501              im = 
502                (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(), 
503                                                    w, h, 
504                                                    (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
505                                                    alpha, EVAS_COLORSPACE_ARGB8888);
506           }
507         else
508 #endif
509           {
510              im = 
511                (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), 
512                                                    w, h, 
513                                                    (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), 
514                                                    alpha, EVAS_COLORSPACE_ARGB8888);
515           }
516
517         if (!im) 
518           {
519              _unfind_xcbob(obr->xcbob, EINA_FALSE);
520              free(obr);
521              eina_spinlock_release(&(buf->priv.lock));
522              return NULL;
523           }
524         im->extended_info = obr;
525         if (buf->priv.x11.xcb.mask) 
526           {
527              obr->mask = 
528                _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
529                            1, w, h, use_shm, NULL);
530           }
531      }
532    else 
533      {
534         int bw = 0, bh = 0;
535
536 #ifdef EVAS_CSERVE2
537         if (evas_cserve2_use_get())
538           {
539              im = 
540                (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
541           }
542         else
543 #endif
544           {
545              im = 
546                (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
547           }
548
549         if (!im) 
550           {
551              free(obr);
552              eina_spinlock_release(&(buf->priv.lock));
553              return NULL;
554           }
555         im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
556 #ifdef EVAS_CSERVE2
557         if (evas_cserve2_use_get())
558           evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
559         else
560 #endif
561           evas_cache_image_surface_alloc(&im->cache_entry, w, h);
562
563         im->extended_info = obr;
564         if ((buf->rot == 0) || (buf->rot == 180)) 
565           {
566              bw = w;
567              bh = h;
568           }
569         else if ((buf->rot == 90) || (buf->rot == 270)) 
570           {
571              bw = h;
572              bh = w;
573           }
574         obr->xcbob = 
575           _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
576                       buf->priv.x11.xcb.depth, bw, bh, use_shm, NULL);
577         if (!obr->xcbob) 
578           {
579 #ifdef EVAS_CSERVE2
580              if (evas_cserve2_use_get())
581                evas_cache2_image_close(&im->cache_entry);
582              else
583 #endif
584                evas_cache_image_drop(&im->cache_entry);
585              free(obr);
586              eina_spinlock_release(&(buf->priv.lock));
587              return NULL;
588           }
589         if (buf->priv.x11.xcb.mask) 
590           {
591              obr->mask = 
592                _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 1, 
593                            bw, bh, use_shm, NULL);
594           }
595      }
596    /* FIXME: We should be able to remove this memset. */
597    if (((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)) && 
598        (im->image.data)) 
599      {
600         /* FIXME: Faster memset */
601 //        memset(im->image.data, 0, (w * h * sizeof(DATA32)));
602      }
603
604    buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
605
606    eina_spinlock_release(&(buf->priv.lock));
607    return im;
608 }
609
610 void 
611 evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Image *update EINA_UNUSED) 
612 {
613    /* NOOP: Cleaned up on flush */
614 }
615
616 void 
617 evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf_Rect *buffer_damage EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
618 {
619    Eina_List *l = NULL;
620    RGBA_Image *im = NULL;
621    Outbuf_Region *obr = NULL;
622
623    eina_spinlock_take(&(buf->priv.lock));
624    if ((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions)))
625      {
626         Eina_Array_Iterator it;
627         Eina_Rectangle *rect;
628         unsigned int i = 0;
629         pixman_region16_t tmpr;
630
631         im = buf->priv.onebuf;
632         obr = im->extended_info;
633         pixman_region_init(&tmpr);
634         EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
635           {
636              Eina_Rectangle xr = { 0, 0, 0, 0 };
637
638              /* rect = buf->priv.onebuf_regions->data; */
639              /* buf->priv.onebuf_regions =  */
640              /*   eina_list_remove_list(buf->priv.onebuf_regions,  */
641              /*                         buf->priv.onebuf_regions); */
642              if (buf->rot == 0)
643                {
644                   xr.x = rect->x;
645                   xr.y = rect->y;
646                   xr.w = rect->w;
647                   xr.h = rect->h;
648                }
649              else if (buf->rot == 90)
650                {
651                   xr.x = rect->y;
652                   xr.y = buf->w - rect->x - rect->w;
653                   xr.w = rect->h;
654                   xr.h = rect->w;
655                }
656              else if (buf->rot == 180)
657                {
658                   xr.x = buf->w - rect->x - rect->w;
659                   xr.y = buf->h - rect->y - rect->h;
660                   xr.w = rect->w;
661                   xr.h = rect->h;
662                }
663              else if (buf->rot == 270)
664                {
665                   xr.x = buf->h - rect->y - rect->h;
666                   xr.y = rect->x;
667                   xr.w = rect->h;
668                   xr.h = rect->w;
669                }
670              pixman_region_union_rect(&tmpr, &tmpr, xr.x, xr.y, xr.w, xr.h);
671              if (buf->priv.debug)
672                evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, 
673                                                    xr.x, xr.y, xr.w, xr.h);
674              eina_rectangle_free(rect);
675           }
676         eina_array_clean(&buf->priv.onebuf_regions);
677         xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, 
678                                 XCB_CLIP_ORDERING_YX_BANDED, 
679                                 buf->priv.x11.xcb.gc, 0, 0, 
680                                 pixman_region_n_rects(&tmpr), 
681                                 (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
682         if (obr->xcbob)
683           {
684              evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xcbob,
685                                                      &shmpool_lock);
686              evas_software_xcb_output_buffer_paste(obr->xcbob,
687                                                    buf->priv.x11.xcb.win,
688                                                    buf->priv.x11.xcb.gc, 0, 0, 0);
689           }
690         if (obr->mask) 
691           {
692              xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, 
693                                      XCB_CLIP_ORDERING_YX_BANDED, 
694                                      buf->priv.x11.xcb.gcm, 0, 0, 
695                                      pixman_region_n_rects(&tmpr), 
696                                      (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
697              evas_software_xcb_output_buffer_paste(obr->mask, 
698                                                    buf->priv.x11.xcb.mask, 
699                                                    buf->priv.x11.xcb.gcm, 
700                                                    0, 0, 0);
701           }
702         pixman_region_fini(&tmpr);
703         buf->priv.synced = EINA_FALSE;
704      }
705    else 
706      {
707 #if 1
708         _xcbob_sync(buf->priv.x11.xcb.conn);
709         EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) 
710           {
711              obr = im->extended_info;
712              if (buf->priv.debug)
713                evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, 
714                                                    obr->x, obr->y, obr->w, obr->h);
715              if (obr->xcbob)
716                {
717                   evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
718                                                           obr->xcbob,
719                                                           &shmpool_lock);
720                   evas_software_xcb_output_buffer_paste(obr->xcbob,
721                                                         buf->priv.x11.xcb.win,
722                                                         buf->priv.x11.xcb.gc,
723                                                         obr->x, obr->y, 0);
724                }
725              if (obr->mask)
726                evas_software_xcb_output_buffer_paste(obr->mask, 
727                                                      buf->priv.x11.xcb.mask, 
728                                                      buf->priv.x11.xcb.gcm, 
729                                                      obr->x, obr->y, 0);
730           }
731         while (buf->priv.prev_pending_writes) 
732           {
733              im = buf->priv.prev_pending_writes->data;
734              buf->priv.prev_pending_writes = 
735                eina_list_remove_list(buf->priv.prev_pending_writes, 
736                                      buf->priv.prev_pending_writes);
737              obr = im->extended_info;
738 # ifdef EVAS_CSERVE2
739              if (evas_cserve2_use_get())
740                evas_cache2_image_close(&im->cache_entry);
741              else
742 # endif
743                evas_cache_image_drop(&im->cache_entry);
744
745              if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
746              if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
747              free(obr);
748           }
749         buf->priv.prev_pending_writes = buf->priv.pending_writes;
750         buf->priv.pending_writes = NULL;
751         xcb_flush(buf->priv.x11.xcb.conn);
752 #else
753         /* FIXME: Async Push Disabled */
754
755         _xcbob_sync(buf->priv.x11.xcb.conn);
756         while (buf->priv.pending_writes) 
757           {
758              im = eina_list_data_get(buf->priv.pending_writes);
759              buf->priv.pending_writes = 
760                eina_list_remove_list(buf->priv.pending_writes, 
761                                      buf->priv.pending_writes);
762              obr = im->extended_info;
763 # ifdef EVAS_CSERVE2
764              if (evas_cserve2_use_get())
765                evas_cache2_image_close(&im->cache_entry);
766              else
767 # endif
768                evas_cache_image_drop(&im->cache_entry);
769              if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
770              if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
771              free(obr);
772 # ifdef EVAS_CSERVE2
773              if (evas_cserve2_use_get())
774                evas_cache2_image_close(&im->cache_entry);
775              else
776 # endif
777                evas_cache_image_drop(&im->cache_entry);
778           }
779 #endif
780      }
781    eina_spinlock_release(&(buf->priv.lock));
782    evas_common_cpu_end_opt();
783 }
784
785 void 
786 evas_software_xcb_outbuf_idle_flush(Outbuf *buf) 
787 {
788    eina_spinlock_release(&(buf->priv.lock));
789    if (buf->priv.onebuf) 
790      {
791         RGBA_Image *im;
792         Outbuf_Region *obr;
793
794         im = buf->priv.onebuf;
795         buf->priv.onebuf = NULL;
796         obr = im->extended_info;
797         if (obr->xcbob)
798           {
799              SHMPOOL_LOCK();
800              evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE);
801              SHMPOOL_UNLOCK();
802           }
803         if (obr->mask)
804           {
805              SHMPOOL_LOCK();
806              evas_software_xcb_output_buffer_unref(obr->mask, EINA_FALSE);
807              SHMPOOL_UNLOCK();
808           }
809         free(obr);
810 # ifdef EVAS_CSERVE2
811         if (evas_cserve2_use_get())
812           evas_cache2_image_close(&im->cache_entry);
813         else
814 # endif
815           evas_cache_image_drop(&im->cache_entry);
816      }
817    else 
818      {
819         if (buf->priv.prev_pending_writes)
820           _xcbob_sync(buf->priv.x11.xcb.conn);
821         while (buf->priv.prev_pending_writes) 
822           {
823              RGBA_Image *im;
824              Outbuf_Region *obr;
825
826              im = buf->priv.prev_pending_writes->data;
827              buf->priv.prev_pending_writes = 
828                eina_list_remove_list(buf->priv.prev_pending_writes, 
829                                      buf->priv.prev_pending_writes);
830              obr = im->extended_info;
831 # ifdef EVAS_CSERVE2
832              if (evas_cserve2_use_get())
833                evas_cache2_image_close(&im->cache_entry);
834              else
835 # endif
836                evas_cache_image_drop(&im->cache_entry);
837              if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
838              if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
839              free(obr);
840           }
841         _clear_xcbob(EINA_FALSE);
842      }
843    eina_spinlock_release(&(buf->priv.lock));
844 }
845
846 void 
847 evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h) 
848 {
849    Gfx_Func_Convert func_conv = NULL;
850    Outbuf_Region *obr = NULL;
851    DATA32 *src_data = NULL;
852    unsigned char *data = NULL;
853    int bpl = 0, yy = 0;
854    int bw = 0, bh = 0;
855
856    eina_spinlock_release(&(buf->priv.lock));
857    obr = update->extended_info;
858    if (!obr->xcbob)
859      {
860         eina_spinlock_release(&(buf->priv.lock));
861         return;
862      }
863
864    if ((buf->rot == 0) || (buf->rot == 180)) 
865      {
866         bw = w;
867         bh = h;
868      }
869    else if ((buf->rot == 90) || (buf->rot == 270)) 
870      {
871         bw = h;
872         bh = w;
873      }
874    if (buf->priv.pal) 
875      {
876         func_conv = 
877           evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r, 
878                                        buf->priv.mask.g, buf->priv.mask.b, 
879                                        buf->priv.pal->colors, buf->rot);
880      }
881    else 
882      {
883         func_conv = 
884           evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r, 
885                                        buf->priv.mask.g, buf->priv.mask.b, 
886                                        PAL_MODE_NONE, buf->rot);
887      }
888    if (!func_conv)
889      {
890         eina_spinlock_release(&(buf->priv.lock));
891         return;
892      }
893
894    if (!(data = evas_software_xcb_output_buffer_data(obr->xcbob, &bpl)))
895      {
896         eina_spinlock_release(&(buf->priv.lock));
897         return;
898      }
899    if (!(src_data = update->image.data))
900      {
901         eina_spinlock_release(&(buf->priv.lock));
902         return;
903      }
904    if (buf->rot == 0) 
905      {
906         obr->x = x;
907         obr->y = y;
908         obr->w = w;
909         obr->h = h;
910      }
911    else if (buf->rot == 90) 
912      {
913         obr->x = y;
914         obr->y = (buf->w - x - w);
915         obr->w = h;
916         obr->h = w;
917      }
918    else if (buf->rot == 180) 
919      {
920         obr->x = (buf->w - x - w);
921         obr->y = (buf->h - y - h);
922         obr->w = w;
923         obr->h = h;
924      }
925    else if (buf->rot == 270) 
926      {
927         obr->x = (buf->h - y - h);
928         obr->y = x;
929         obr->w = h;
930         obr->h = w;
931      }
932    if (buf->onebuf)
933      {
934         src_data += x + (y * update->cache_entry.w);
935         data += (bpl * obr->y) + (obr->x * (buf->depth / 8));
936      }
937    if (data != (unsigned char *)src_data) 
938      {
939         if (buf->priv.pal)
940           {
941              func_conv(src_data, data, update->cache_entry.w - w, 
942                        bpl - obr->w, obr->w, obr->h, x, y,
943                        buf->priv.pal->lookup);
944           }
945         else
946           {
947              int pixelb = evas_software_xcb_output_buffer_depth(obr->xcbob) / 8;
948              int run;
949              int dstjump;
950              
951              if (pixelb == 3)
952                {
953                   run = obr->w * pixelb;
954                   dstjump = bpl - run;
955                }
956              else if ((pixelb == 2) || (pixelb == 4))
957                {
958                   run = obr->w;
959                   dstjump = (bpl / pixelb) - run;
960                }
961              else
962                {
963                   run = obr->w;
964                   dstjump = bpl - run;
965                }
966              func_conv(src_data, data, update->cache_entry.w - w, dstjump,
967                        obr->w, obr->h, x, y, NULL);
968           }
969      }
970 #if 1
971 #else
972    /* Async Push */
973    if (!((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions))))
974      {
975         if (buf->priv.debug)
976           evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, 
977                                               obr->x, obr->y, obr->w, obr->h);
978         if (obr->xcbob)
979           {
980              evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
981                                                      obr->xcbob,
982                                                      &shmpool_lock);
983              evas_software_xcb_output_buffer_paste(obr->xcbob,
984                                                    buf->priv.x11.xcb.win,
985                                                    buf->priv.x11.xcb.gc,
986                                                    obr->x, obr->y, 0);
987           }
988      }
989 #endif
990    if (obr->mask) 
991      {
992         if (buf->rot == 0) 
993           {
994              for (yy = 0; yy < obr->h; yy++)
995                evas_software_xcb_write_mask_line(buf, obr->mask, 
996                                                  src_data + (yy * obr->w), 
997                                                  obr->w, yy);
998           }
999         else if (buf->rot == 90) 
1000           {
1001              for (yy = 0; yy < obr->h; yy++)
1002                evas_software_xcb_write_mask_line_vert(buf, obr->mask, 
1003                                                       src_data + yy, 
1004                                                       h, (obr->h - yy - 1), w);
1005           }
1006         else if (buf->rot == 180) 
1007           {
1008              for (yy = 0; yy < obr->h; yy++)
1009                evas_software_xcb_write_mask_line_rev(buf, obr->mask, 
1010                                                      src_data + (yy * obr->w), 
1011                                                      obr->w, (obr->h - yy - 1));
1012           }
1013         else if (buf->rot == 270) 
1014           {
1015              for (yy = 0; yy < obr->h; yy++)
1016                evas_software_xcb_write_mask_line_vert_rev(buf, obr->mask, 
1017                                                           src_data + yy, 
1018                                                           h, yy, w);
1019           }
1020 #if 1
1021 #else
1022         /* Async Push */
1023         if (!((buf->priv.onebuf) && 
1024               (eina_array_count(&buf->priv.onebuf_regions))))
1025           evas_software_xcb_output_buffer_paste(obr->mask, 
1026                                                 buf->priv.x11.xcb.mask, 
1027                                                 buf->priv.x11.xcb.gcm, 
1028                                                 obr->x, obr->y, 0);
1029 #endif
1030      }
1031 #if 1
1032 #else
1033    xcb_flush(buf->priv.x11.xcb.conn);
1034 #endif
1035    eina_spinlock_release(&(buf->priv.lock));
1036 }
1037
1038 void 
1039 evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth) 
1040 {
1041    if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) && 
1042        (depth == buf->depth)) return;
1043    SHMPOOL_LOCK();
1044    _shmlimit -= ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
1045    buf->w = w;
1046    buf->h = h;
1047    buf->rot = rot;
1048    _shmlimit += ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
1049    SHMPOOL_UNLOCK();
1050    evas_software_xcb_outbuf_idle_flush(buf);
1051 }
1052
1053 int 
1054 evas_software_xcb_outbuf_width_get(Outbuf *buf) 
1055 {
1056    return buf->w;
1057 }
1058
1059 int 
1060 evas_software_xcb_outbuf_height_get(Outbuf *buf) 
1061 {
1062    return buf->h;
1063 }
1064
1065 Outbuf_Depth 
1066 evas_software_xcb_outbuf_depth_get(Outbuf *buf) 
1067 {
1068    return buf->depth;
1069 }
1070
1071 void 
1072 evas_software_xcb_outbuf_drawable_set(Outbuf *buf, xcb_drawable_t drawable) 
1073 {
1074    if (buf->priv.x11.xcb.win == drawable) return;
1075    if (buf->priv.x11.xcb.gc) 
1076      {
1077         xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc);
1078         buf->priv.x11.xcb.gc = 0;
1079      }
1080    buf->priv.x11.xcb.win = drawable;
1081    buf->priv.x11.xcb.gc = xcb_generate_id(buf->priv.x11.xcb.conn);
1082    xcb_create_gc(buf->priv.x11.xcb.conn, 
1083                  buf->priv.x11.xcb.gc, buf->priv.x11.xcb.win, 0, NULL);
1084 }
1085
1086 void 
1087 evas_software_xcb_outbuf_mask_set(Outbuf *buf, xcb_drawable_t mask) 
1088 {
1089    if (buf->priv.x11.xcb.mask == mask) return;
1090    if (buf->priv.x11.xcb.gcm) 
1091      {
1092         xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm);
1093         buf->priv.x11.xcb.gcm = 0;
1094      }
1095    buf->priv.x11.xcb.mask = mask;
1096    if (buf->priv.x11.xcb.mask) 
1097      {
1098         buf->priv.x11.xcb.gcm = xcb_generate_id(buf->priv.x11.xcb.conn);
1099         xcb_create_gc(buf->priv.x11.xcb.conn, 
1100                       buf->priv.x11.xcb.gcm, buf->priv.x11.xcb.mask, 0, NULL);
1101      }
1102 }
1103
1104 int 
1105 evas_software_xcb_outbuf_rotation_get(Outbuf *buf) 
1106 {
1107    return buf->rot;
1108 }
1109
1110 void 
1111 evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rotation) 
1112 {
1113    buf->rot = rotation;
1114 }
1115
1116 Eina_Bool 
1117 evas_software_xcb_outbuf_alpha_get(Outbuf *buf) 
1118 {
1119    return buf->priv.x11.xcb.mask;
1120 }
1121
1122 void 
1123 evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug) 
1124 {
1125    buf->priv.debug = debug;
1126 }
1127
1128 void 
1129 evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h) 
1130 {
1131    int i;
1132    xcb_screen_t *screen = NULL;
1133    xcb_get_geometry_reply_t *geom;
1134    xcb_drawable_t root;
1135    xcb_screen_iterator_t si;
1136
1137    geom = 
1138      xcb_get_geometry_reply(buf->priv.x11.xcb.conn, 
1139                             xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, 
1140                                                        drawable), 0);
1141    root = geom->root;
1142    free(geom);
1143    geom = 
1144      xcb_get_geometry_reply(buf->priv.x11.xcb.conn, 
1145                             xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, 
1146                                                        root), 0);
1147
1148    si = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(buf->priv.x11.xcb.conn));
1149    for (; si.rem; xcb_screen_next(&si))
1150      {
1151         if (si.data->root == geom->root)
1152           {
1153              screen = si.data;
1154              break;
1155           }
1156      }
1157    free(geom);
1158
1159    for (i = 0; i < 20; i++)
1160      {
1161         xcb_rectangle_t rect = { x, y, w, h};
1162         uint32_t mask;
1163         uint32_t value[2];
1164
1165         mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
1166         value[0] = screen->black_pixel;
1167         value[1] = XCB_EXPOSURES_NOT_ALLOWED;
1168         xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, 
1169                       mask, value);
1170         xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, 
1171                                 buf->priv.x11.xcb.gc, 1, &rect);
1172         _xcbob_sync(buf->priv.x11.xcb.conn);
1173         _xcbob_sync(buf->priv.x11.xcb.conn);
1174
1175         mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
1176         value[0] = screen->white_pixel;
1177         value[1] = XCB_EXPOSURES_NOT_ALLOWED;
1178         xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, 
1179                       mask, value);
1180         xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, 
1181                                 buf->priv.x11.xcb.gc, 1, &rect);
1182         _xcbob_sync(buf->priv.x11.xcb.conn);
1183         _xcbob_sync(buf->priv.x11.xcb.conn);
1184      }
1185 }
1186
1187
1188 /* local functions */
1189 static Xcb_Output_Buffer *
1190 _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data) 
1191 {
1192    Eina_List *l = NULL, *xl = NULL;
1193    Xcb_Output_Buffer *xcbob = NULL, *xcbob2 = NULL;
1194    int lbytes = 0, bpp = 0, sz = 0;
1195    int fitness = 0x7fffffff;
1196
1197    if (!shm)
1198      return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h, 
1199                                                 shm, data);
1200
1201    if (depth > 1) 
1202      {
1203         bpp = (depth / 8);
1204         if (bpp == 3) bpp = 4;
1205         lbytes = ((((w * bpp) + 3) / 4) * 4);
1206      }
1207    else
1208      lbytes = (((w + 63) / 64) * 8);
1209
1210    sz = (lbytes * h);
1211    SHMPOOL_LOCK();
1212    EINA_LIST_FOREACH(_shmpool, l, xcbob2) 
1213      {
1214         int szdif = 0;
1215
1216         if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) || 
1217             (xcbob2->connection != conn) || (xcbob2->w != w)) continue;
1218         szdif = (xcbob2->psize - sz);
1219         if (szdif < 0) continue;
1220         if (szdif == 0) 
1221           {
1222              xcbob = xcbob2;
1223              xl = l;
1224              goto have_xcbob;
1225           }
1226         if (szdif < fitness) 
1227           {
1228              xcbob = xcbob2;
1229              xl = l;
1230              fitness = szdif;
1231           }
1232      }
1233    if (
1234        (fitness > (400 * 400)) ||
1235        (!xcbob)
1236       )
1237      {
1238         SHMPOOL_UNLOCK();
1239         return evas_software_xcb_output_buffer_new(conn, vis, depth, 
1240                                                    w, h, shm, data);
1241      }
1242
1243 have_xcbob:
1244    _shmpool = eina_list_remove_list(_shmpool, xl);
1245    xcbob->w = w;
1246    xcbob->h = h;
1247 //   xcbob->bpl = lbytes;
1248    xcbob->xim->width = xcbob->w;
1249    xcbob->xim->height = xcbob->h;
1250    xcbob->xim->stride = xcbob->bpl;
1251    _shmsize -= (xcbob->psize * (xcbob->xim->depth / 8));
1252    SHMPOOL_UNLOCK();
1253    return xcbob;
1254 }
1255
1256 static void 
1257 _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync) 
1258 {
1259    if (xcbob->shm_info) 
1260      {
1261         SHMPOOL_LOCK();
1262         _shmpool = eina_list_prepend(_shmpool, xcbob);
1263         _shmsize += xcbob->psize * xcbob->xim->depth / 8;
1264         while ((_shmsize > _shmlimit) || 
1265                (eina_list_count(_shmpool) > _shmcountlimit))
1266           {
1267              Eina_List *xl = NULL;
1268
1269              if (!(xl = eina_list_last(_shmpool))) 
1270                {
1271                   _shmsize = 0;
1272                   break;
1273                }
1274              xcbob = xl->data;
1275              _shmpool = eina_list_remove_list(_shmpool, xl);
1276              _shmsize -= xcbob->psize * xcbob->xim->depth / 8;
1277              evas_software_xcb_output_buffer_unref(xcbob, sync);
1278           }
1279         SHMPOOL_UNLOCK();
1280      }
1281    else
1282      {
1283         SHMPOOL_LOCK();
1284         evas_software_xcb_output_buffer_unref(xcbob, sync);
1285         SHMPOOL_UNLOCK();
1286      }
1287 }
1288
1289 static void 
1290 _clear_xcbob(Eina_Bool sync) 
1291 {
1292    SHMPOOL_LOCK();
1293    while (_shmpool) 
1294      {
1295         Xcb_Output_Buffer *xcbob;
1296  
1297         xcbob = _shmpool->data;
1298         _shmpool = eina_list_remove_list(_shmpool, _shmpool);
1299         evas_software_xcb_output_buffer_unref(xcbob, sync);
1300      }
1301    _shmsize = 0;
1302    SHMPOOL_UNLOCK();
1303 }
1304
1305 static void 
1306 _xcbob_sync(xcb_connection_t *conn) 
1307 {
1308    free(xcb_get_input_focus_reply(conn, 
1309                                   xcb_get_input_focus_unchecked(conn), NULL));
1310 }