move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / xrender_x11 / evas_engine.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_XRender_X11.h"
5
6 /* function tables - filled in later (func and parent func) */
7 static Evas_Func func, pfunc;
8
9 /* engine struct data */
10 typedef struct _Render_Engine        Render_Engine;
11 typedef struct _Render_Engine_Update Render_Engine_Update;
12
13 struct _Render_Engine_Update
14 {
15    int x, y, w, h;
16    Xrender_Surface *surface;
17 };
18
19 struct _Render_Engine
20 {
21    Display              *disp;
22    Visual               *vis;
23    Drawable              win;
24    Pixmap                mask;
25    unsigned char         destination_alpha : 1;
26    
27    Ximage_Info          *xinf;
28    Xrender_Surface      *output;
29    Xrender_Surface      *mask_output;
30    
31    Tilebuf              *tb;
32    Tilebuf_Rect         *rects;
33    Evas_Object_List     *cur_rect;
34    int                   end : 1;
35    
36    Evas_List            *updates;
37 };
38
39 /* internal engine routines */
40
41 /* engine api this module provides */
42 static void *
43 eng_info(Evas *e)
44 {
45    Evas_Engine_Info_XRender_X11 *info;
46
47    info = calloc(1, sizeof(Evas_Engine_Info_XRender_X11));
48    if (!info) return NULL;
49    info->magic.magic = rand();
50    return info;
51    e = NULL;
52 }
53
54 static void
55 eng_info_free(Evas *e, void *info)
56 {
57    Evas_Engine_Info_XRender_X11 *in;
58
59    in = (Evas_Engine_Info_XRender_X11 *)info;
60    free(in);
61 }
62
63 static void
64 eng_setup(Evas *e, void *in)
65 {
66    Render_Engine *re;
67    Evas_Engine_Info_XRender_X11 *info;
68    int resize = 1;
69
70    info = (Evas_Engine_Info_XRender_X11 *)in;
71    if (!e->engine.data.output)
72      {
73         re = calloc(1, sizeof(Render_Engine));
74         evas_common_cpu_init();
75         evas_common_blend_init();
76         evas_common_image_init();
77         evas_common_convert_init();
78         evas_common_scale_init();
79         evas_common_rectangle_init();
80         evas_common_gradient_init();
81         evas_common_polygon_init();
82         evas_common_line_init();
83         evas_common_font_init();
84         evas_common_draw_init();
85         evas_common_tilebuf_init();
86         re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
87         if (re->tb)
88           evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
89         e->engine.data.output = re;
90         resize = 0;
91      }
92    re = e->engine.data.output;
93    if (!re) return;
94    
95    if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
96    
97    re->disp = info->info.display;
98    re->vis = info->info.visual;
99    re->win = info->info.drawable;
100    re->mask = info->info.mask;
101    re->destination_alpha = info->info.destination_alpha;
102    
103    if (re->xinf) _xr_image_info_free(re->xinf);
104    re->xinf = _xr_image_info_get(re->disp, re->win, re->vis);
105
106    if (re->output) _xr_render_surface_free(re->output);
107    if (re->mask_output) _xr_render_surface_free(re->mask_output);
108    if (!re->mask)
109      re->output = _xr_render_surface_adopt(re->xinf, re->win, e->output.w, e->output.h, re->destination_alpha);
110    else
111      re->output = _xr_render_surface_adopt(re->xinf, re->win, e->output.w, e->output.h, 0);
112    if (re->mask)
113      re->mask_output = _xr_render_surface_format_adopt(re->xinf, re->mask, 
114                                                        e->output.w, e->output.h,
115                                                        re->xinf->fmt1, 1);
116    else
117      re->mask_output = NULL;
118    if (resize)
119      {
120         if (re->tb) evas_common_tilebuf_free(re->tb);
121         if ((e->output.w > 0) && (e->output.h > 0))
122           re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
123         else
124           re->tb = evas_common_tilebuf_new(1, 1);
125         if (re->tb)
126           evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
127      }
128 }
129
130 static void
131 eng_output_free(void *data)
132 {
133    Render_Engine *re;
134
135    re = (Render_Engine *)data;
136    evas_common_font_shutdown();
137    evas_common_image_shutdown();
138    while (re->updates)
139      {
140         Render_Engine_Update *reu;
141         
142         reu = re->updates->data;
143         re->updates = evas_list_remove_list(re->updates, re->updates);
144         _xr_render_surface_free(reu->surface);
145         free(reu);
146      }
147    if (re->tb) evas_common_tilebuf_free(re->tb);
148    if (re->output) _xr_render_surface_free(re->output);
149    if (re->mask_output) _xr_render_surface_free(re->mask_output);
150    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
151    if (re->xinf) _xr_image_info_free(re->xinf);
152    free(re);
153 }
154
155 static void
156 eng_output_resize(void *data, int w, int h)
157 {
158    Render_Engine *re;
159
160    re = (Render_Engine *)data;
161    if (re->output)
162      {
163         if ((re->output->w == w) && (re->output->h ==h)) return;
164         if (re->output) _xr_render_surface_free(re->output);
165      }
166    re->output = _xr_render_surface_adopt(re->xinf, re->win, w, h, 0);
167    if (re->mask_output)
168      {
169         if (re->mask_output) _xr_render_surface_free(re->mask_output);
170         re->mask_output = _xr_render_surface_format_adopt(re->xinf, re->mask, 
171                                                           w, h, 
172                                                           re->xinf->fmt1, 1);
173      }
174    evas_common_tilebuf_free(re->tb);
175    re->tb = evas_common_tilebuf_new(w, h);
176    if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
177 }
178
179 static void
180 eng_output_tile_size_set(void *data, int w, int h)
181 {
182    Render_Engine *re;
183
184    re = (Render_Engine *)data;
185    evas_common_tilebuf_set_tile_size(re->tb, w, h);
186 }
187
188 static void
189 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
190 {
191    Render_Engine *re;
192
193    re = (Render_Engine *)data;
194    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
195 }
196
197 static void
198 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
199 {
200    Render_Engine *re;
201
202    re = (Render_Engine *)data;
203    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
204 }
205
206 static void
207 eng_output_redraws_clear(void *data)
208 {
209    Render_Engine *re;
210
211    re = (Render_Engine *)data;
212    evas_common_tilebuf_clear(re->tb);
213 }
214
215 static void *
216 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
217 {
218    Render_Engine *re;
219    Tilebuf_Rect *rect;
220    int ux, uy, uw, uh;
221
222    re = (Render_Engine *)data;
223    if (re->end)
224      {
225         re->end = 0;
226         return NULL;
227      }
228    if (!re->rects)
229      {
230         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
231         re->cur_rect = (Evas_Object_List *)re->rects;
232      }
233    if (!re->cur_rect) return NULL;
234    rect = (Tilebuf_Rect *)re->cur_rect;
235    ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
236    re->cur_rect = re->cur_rect->next;
237    if (!re->cur_rect)
238      {
239         evas_common_tilebuf_free_render_rects(re->rects);
240         re->rects = NULL;
241         re->end = 1;
242      }
243
244    *x = ux; *y = uy; *w = uw; *h = uh;
245    *cx = 0; *cy = 0; *cw = uw; *ch = uh;
246    if ((re->destination_alpha) || (re->mask))
247      {
248         Xrender_Surface *surface;
249         
250         surface = _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmt32, 1);
251         _xr_render_surface_solid_rectangle_set(surface, 0, 0, 0, 0, 0, 0, uw, uh);
252         return surface;
253      }
254    return _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmtdef, 0);
255 }
256
257 static void
258 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
259 {
260    Render_Engine *re;
261    Render_Engine_Update *reu;
262    
263    re = (Render_Engine *)data;
264    reu = malloc(sizeof(Render_Engine_Update));
265    if (!reu) return;
266    reu->x = x;
267    reu->y = y;
268    reu->w = w;
269    reu->h = h;
270    reu->surface = (Xrender_Surface *)surface;
271    re->updates = evas_list_append(re->updates, reu);
272 }
273
274 static void
275 eng_output_flush(void *data)
276 {
277    Render_Engine *re;
278
279    re = (Render_Engine *)data;
280    while (re->updates)
281      {
282         Render_Engine_Update *reu;
283         
284         reu = re->updates->data;
285         re->updates = evas_list_remove_list(re->updates, re->updates);
286         if (re->mask_output)
287           {
288              Xrender_Surface *tsurf;
289              
290              _xr_render_surface_copy(reu->surface, re->output, 0, 0,
291                                      reu->x, reu->y, reu->w, reu->h);
292              tsurf = _xr_render_surface_new(re->xinf, reu->w, reu->h, re->xinf->fmt1, 1);
293              if (tsurf)
294                {
295                   _xr_render_surface_copy(reu->surface, tsurf, 0, 0,
296                                           0, 0, reu->w, reu->h);
297                   _xr_render_surface_copy(tsurf, re->mask_output, 0, 0,
298                                           reu->x, reu->y, reu->w, reu->h);
299                   _xr_render_surface_free(tsurf);
300                }
301           }
302         else
303           {
304              _xr_render_surface_copy(reu->surface, re->output, 0, 0,
305                                      reu->x, reu->y, reu->w, reu->h);
306           }
307         _xr_render_surface_free(reu->surface);
308         free(reu);
309      }
310    XSync(re->disp, False);
311    _xr_image_info_pool_flush(re->xinf, 0, 0);
312 }
313
314 static void
315 eng_output_idle_flush(void *data)
316 {
317    Render_Engine *re;
318
319    re = (Render_Engine *)data;
320 }
321
322 static void
323 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
324 {
325    _xr_render_surface_rectangle_draw((Xrender_Surface *)surface,
326                                      (RGBA_Draw_Context *)context,
327                                      x, y, w, h);
328 }
329
330 static void
331 eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
332 {
333    _xr_render_surface_line_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, x1, y1, x2, y2);
334 }
335
336 static void
337 eng_polygon_draw(void *data, void *context, void *surface, void *polygon)
338 {
339    _xre_poly_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, (RGBA_Polygon_Point *)polygon);
340 }
341
342 static void *
343 eng_gradient_new(void *data)
344 {
345    Render_Engine *re = (Render_Engine *)data;
346
347    return _xre_gradient_new(re->xinf);
348 }
349
350 static void
351 eng_gradient_free(void *data, void *gradient)
352 {
353    _xre_gradient_free(gradient);
354 }
355
356 static void
357 eng_gradient_color_stop_add(void *data, void *gradient, int r, int g, int b, int a, int delta)
358 {
359    _xre_gradient_color_stop_add(gradient, r, g, b, a, delta);
360 }
361
362 static void
363 eng_gradient_alpha_stop_add(void *data, void *gradient, int a, int delta)
364 {
365    _xre_gradient_alpha_stop_add(gradient, a, delta);
366 }
367
368 static void
369 eng_gradient_color_data_set(void *data, void *gradient, void *map, int len, int has_alpha)
370 {
371    _xre_gradient_color_data_set(gradient, map, len, has_alpha);
372 }
373
374 static void
375 eng_gradient_alpha_data_set(void *data, void *gradient, void *alpha_map, int len)
376 {
377    _xre_gradient_alpha_data_set(gradient, alpha_map, len);
378 }
379
380 static void
381 eng_gradient_clear(void *data, void *gradient)
382 {
383    _xre_gradient_clear(gradient);
384 }
385
386 static void
387 eng_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h)
388 {
389    _xre_gradient_fill_set(gradient, x, y, w, h);
390 }
391
392 static void
393 eng_gradient_fill_angle_set(void *data, void *gradient, double angle)
394 {
395    _xre_gradient_fill_angle_set(gradient, angle);
396 }
397
398 static void
399 eng_gradient_fill_spread_set(void *data, void *gradient, int spread)
400 {
401    _xre_gradient_fill_spread_set(gradient, spread);
402 }
403
404 static void
405 eng_gradient_angle_set(void *data, void *gradient, double angle)
406 {
407    _xre_gradient_angle_set(gradient, angle);
408 }
409
410 static void
411 eng_gradient_offset_set(void *data, void *gradient, float offset)
412 {
413    _xre_gradient_offset_set(gradient, offset);
414 }
415
416 static void
417 eng_gradient_direction_set(void *data, void *gradient, int direction)
418 {
419    _xre_gradient_direction_set(gradient, direction);
420 }
421
422 static void
423 eng_gradient_type_set(void *data, void *gradient, char *name, char *params)
424 {
425    _xre_gradient_type_set(gradient, name, params);
426 }
427
428 static int
429 eng_gradient_is_opaque(void *data, void *context, void *gradient, int x, int y, int w, int h)
430 {
431    RGBA_Gradient  *grad;
432    RGBA_Draw_Context *dc = (RGBA_Draw_Context *)context;
433
434    if (!dc || !gradient) return 0;
435    grad = ((XR_Gradient *)gradient)->grad;
436    if(!grad || !grad->type.geometer)  return 0;
437    return !(grad->type.geometer->has_alpha(grad, dc->render_op) |
438               grad->type.geometer->has_mask(grad, dc->render_op));
439 }
440
441 static int
442 eng_gradient_is_visible(void *data, void *context, void *gradient, int x, int y, int w, int h)
443 {
444    if (!context || !gradient)  return 0;
445    return 1;
446 }
447
448 static void
449 eng_gradient_render_pre(void *data, void *context, void *gradient)
450 {
451    int  len;
452    RGBA_Gradient  *grad;
453
454    if (!context || !gradient) return;
455    grad = ((XR_Gradient *)gradient)->grad;
456    if(!grad || !grad->type.geometer)  return;
457    grad->type.geometer->geom_set(grad);
458    len = grad->type.geometer->get_map_len(grad);
459    evas_common_gradient_map(context, grad, len);
460 }
461
462 static void
463 eng_gradient_render_post(void *data, void *gradient)
464 {
465 }
466
467 static void
468 eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h)
469 {
470    _xre_gradient_draw(surface, context, gradient, x, y, w, h);
471 }
472
473 static int
474 eng_image_alpha_get(void *data, void *image)
475 {
476    if (!image) return 0;
477    return _xre_image_alpha_get((XR_Image *)image);
478 }
479
480 static int
481 eng_image_colorspace_get(void *data, void *image)
482 {
483    if (!image) return EVAS_COLORSPACE_ARGB8888;
484    return ((XR_Image *)image)->cs.space;
485 }
486
487 static void *
488 eng_image_alpha_set(void *data, void *image, int has_alpha)
489 {
490    XR_Image *im;
491    
492    im = (XR_Image *)image;
493    if (!im) return im;
494    if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
495    if (((im->alpha) && (has_alpha)) || ((!im->alpha) && (!has_alpha))) 
496      return im;
497    if (im->references > 1)
498      {
499         XR_Image *old_im;
500         
501         old_im = im;
502         im = _xre_image_copy(old_im);
503         if (im)
504           {
505              im->alpha = old_im->alpha;
506              _xre_image_free(old_im);
507           }
508         else
509           im = old_im;
510      }
511    else
512      _xre_image_dirty(im);
513    _xre_image_alpha_set(im, has_alpha);
514    return im;
515 }
516
517 static void *
518 eng_image_border_set(void *data, void *image, int l, int r, int t, int b)
519 {
520    if (!image) return image;
521    _xre_image_border_set((XR_Image *)image, l, r, t, b);
522    return image;
523 }
524
525 static void
526 eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b)
527 {
528    if (!image) return;
529    _xre_image_border_get((XR_Image *)image, l, r, t, b);
530 }
531
532 static char *
533 eng_image_comment_get(void *data, void *image, char *key)
534 {
535    if (!image) return NULL;
536    return strdup(((XR_Image *)image)->comment);
537 }
538
539 static char *
540 eng_image_format_get(void *data, void *image)
541 {
542    if (!image) return NULL;
543    return ((XR_Image *)image)->format;
544 }
545
546 static void
547 eng_image_colorspace_set(void *data, void *image, int cspace)
548 {
549    XR_Image *im;
550       
551    if (!image) return;
552    im = (XR_Image *)image;
553    if (im->cs.space == cspace) return;
554
555    if (im->im) evas_cache_image_drop(&im->im->cache_entry);
556    im->im = NULL;
557
558    switch (cspace)
559      {
560       case EVAS_COLORSPACE_ARGB8888:
561         if (im->cs.data)
562           {
563              if (!im->cs.no_free) free(im->cs.data);
564              im->cs.data = NULL;
565              im->cs.no_free = 0;
566           }
567         break;
568       case EVAS_COLORSPACE_YCBCR422P601_PL:
569       case EVAS_COLORSPACE_YCBCR422P709_PL:
570         if ((im->free_data) && (im->data)) free(im->data);
571         im->data = NULL;
572         if (im->cs.data)
573           {
574              if (!im->cs.no_free) free(im->cs.data);
575           }
576         if (im->h > 0)
577           im->cs.data = calloc(1, im->h * sizeof(unsigned char *) * 2);
578         im->cs.no_free = 0;
579         break;
580       default:
581         abort();
582         break;
583      }
584    im->cs.space = cspace;
585    _xre_image_dirty(im);
586    _xre_image_region_dirty(im, 0, 0, im->w, im->h);
587 }
588
589 static void
590 eng_image_native_set(void *data, void *image, void *native)
591 {
592 }
593
594 static void *
595 eng_image_native_get(void *data, void *image)
596 {
597    return NULL;
598 }
599
600 static void *
601 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
602 {
603    Render_Engine *re;
604    XR_Image *im;
605    
606    re = (Render_Engine *)data;
607    *error = 0;
608    im = _xre_image_load(re->xinf, file, key, lo);
609    return im;
610 }
611
612 static void *
613 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
614 {
615    Render_Engine *re;
616    XR_Image *im;
617    
618    re = (Render_Engine *)data;
619    im = _xre_image_new_from_data(re->xinf, w, h, image_data, alpha, cspace);
620    return im;
621 }
622
623 static void *
624 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
625 {
626    Render_Engine *re;
627    XR_Image *im;
628    
629    re = (Render_Engine *)data;
630    im = _xre_image_new_from_copied_data(re->xinf, w, h, image_data, alpha, cspace);
631    return im;
632 }
633
634 static void
635 eng_image_free(void *data, void *image)
636 {
637    if (!image) return;
638    _xre_image_free((XR_Image *)image);
639 }
640
641 static void
642 eng_image_size_get(void *data, void *image, int *w, int *h)
643 {
644    if (!image) return;
645    if (w) *w = ((XR_Image *)image)->w;
646    if (h) *h = ((XR_Image *)image)->h;
647 }
648
649 static void *
650 eng_image_size_set(void *data, void *image, int w, int h)
651 {
652    XR_Image *im, *im_old;
653
654    if (!image) return NULL;
655    im_old = image;
656    if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
657        (im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
658      w &= ~0x1;
659    if ((im_old) && (im_old->w == w) && (im_old->h == h))
660      return image;
661    if ((w <= 0) || (h <= 0))
662      {
663         _xre_image_free(im_old);
664         return NULL;
665      }
666    if (im_old)
667      {
668         im = _xre_image_new_from_copied_data(im_old->xinf, w, h, NULL, im_old->alpha, im_old->cs.space);
669         _xre_image_free(im_old);
670         return im;
671      }
672    return image;
673 }
674
675 static void *
676 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
677 {
678    if (!image) return image;
679    _xre_image_dirty((XR_Image *)image);
680    _xre_image_region_dirty((XR_Image *)image, x, y, w, h);
681    return image;
682 }
683
684 static void *
685 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
686 {
687    XR_Image *im;
688    
689    if (!image)
690      {
691         *image_data = NULL;
692         return NULL;
693      }
694    im = (XR_Image *)image;
695    if (im->im)
696      evas_cache_image_load_data(&im->im->cache_entry);
697    switch (im->cs.space)
698      {
699       case EVAS_COLORSPACE_ARGB8888:
700         if (to_write)
701           {
702              if (im->references > 1)
703                {
704                   XR_Image *im_old;
705                   
706                   im_old = im;
707                   im = _xre_image_copy(im_old);
708                   if (im)
709                     _xre_image_free(im_old);
710                   else
711                     im = im_old;
712                }
713              else
714                _xre_image_dirty(im);
715           }
716         break;
717       case EVAS_COLORSPACE_YCBCR422P601_PL:
718       case EVAS_COLORSPACE_YCBCR422P709_PL:
719         break;
720       default:
721         abort();
722         break;
723      }
724    if (image_data) *image_data = _xre_image_data_get(im);
725    return im;
726 }
727
728 static void *
729 eng_image_data_put(void *data, void *image, DATA32 *image_data)
730 {
731    XR_Image *im;
732    
733    if (!image) return image;
734    im = (XR_Image *)image;
735    
736    switch (im->cs.space)
737      {
738       case EVAS_COLORSPACE_ARGB8888:
739         if (_xre_image_data_get(im) != image_data)
740           {
741              XR_Image *im_old;
742              
743              im_old = im;
744              image = _xre_image_data_find(image_data);
745              if (image != im_old)
746                {
747                   if (!image)
748                     {
749                        image = _xre_image_new_from_data(im_old->xinf, im_old->w, im_old->h, image_data, im_old->alpha, EVAS_COLORSPACE_ARGB8888);
750                        if (image)
751                          {
752                             ((XR_Image *)image)->alpha = im_old->alpha;
753                             _xre_image_free(im_old);
754                          }
755                        else
756                          image = im_old;
757                     }
758                   else
759                     {
760                        _xre_image_free(im_old);
761                     }
762                }
763              else
764                {
765                   _xre_image_free(image);
766                   image = im_old;
767                }
768           }
769         break;
770       case EVAS_COLORSPACE_YCBCR422P601_PL:
771       case EVAS_COLORSPACE_YCBCR422P709_PL:
772         if (_xre_image_data_get(im) != image_data)
773           {  
774              if (im->data)
775                {
776                   if (im->free_data) free(im->data);
777                   im->data = NULL;
778                }
779              if (im->cs.data)
780                {
781                   if (!im->cs.no_free) free(im->cs.data);
782                }
783              im->cs.data = image_data;
784              _xre_image_dirty(im);
785           }
786         break;
787       default:
788         abort();
789         break;
790      }
791    return image;
792 }
793
794 static void
795 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
796 {
797    if ((!image) || (!surface)) return;
798    _xre_image_surface_gen((XR_Image *)image);
799    if (((XR_Image *)image)->surface)
800      _xr_render_surface_composite(((XR_Image *)image)->surface,
801                                   (Xrender_Surface *)surface,
802                                   (RGBA_Draw_Context *)context,
803                                   src_x, src_y, src_w, src_h,
804                                   dst_x, dst_y, dst_w, dst_h,
805                                   smooth);
806 }
807
808 static void
809 eng_image_cache_flush(void *data)
810 {
811    int tmp_size;
812
813    tmp_size = _xre_image_cache_get();
814    pfunc.image_cache_flush(data);
815    _xre_image_cache_set(0);
816    _xre_image_cache_set(tmp_size);
817 }
818
819 static void
820 eng_image_cache_set(void *data, int bytes)
821 {
822    pfunc.image_cache_set(data, bytes);
823    _xre_image_cache_set(bytes);
824 }
825
826 static int
827 eng_image_cache_get(void *data)
828 {
829    return pfunc.image_cache_get(data);
830 }
831
832 static void
833 eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
834 {
835    Render_Engine        *re;
836    RGBA_Image           *im;
837
838    re = (Render_Engine *)data;
839
840    _xr_render_surface_clips_set((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, x, y, w, h);
841
842    im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
843                                              ((Xrender_Surface *)surface)->w,
844                                              ((Xrender_Surface *)surface)->h,
845                                              surface,
846                                              0, EVAS_COLORSPACE_ARGB8888);
847    evas_common_draw_context_font_ext_set(context,
848                                          re->xinf,
849                                          _xre_font_surface_new,
850                                          _xre_font_surface_free,
851                                          _xre_font_surface_draw);
852    evas_common_font_draw(im, context, font, x, y, text);
853    evas_common_draw_context_font_ext_set(context,
854                                          NULL,
855                                          NULL,
856                                          NULL,
857                                          NULL);
858    evas_common_cpu_end_opt();
859
860    evas_cache_image_drop(&im->cache_entry);
861 }
862
863 /* module advertising code */
864 EAPI int
865 module_open(Evas_Module *em)
866 {
867    if (!em) return 0;
868    /* get whatever engine module we inherit from */
869    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
870    /* store it for later use */
871    func = pfunc;
872    /* now to override methods */
873 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
874    ORD(info);
875    ORD(info_free);
876    ORD(setup);
877    ORD(output_free);
878    ORD(output_resize);
879    ORD(output_tile_size_set);
880    ORD(output_redraws_rect_add);
881    ORD(output_redraws_rect_del);
882    ORD(output_redraws_clear);
883    ORD(output_redraws_next_update_get);
884    ORD(output_redraws_next_update_push);
885    ORD(output_flush);
886    ORD(output_idle_flush);
887    ORD(rectangle_draw);
888    ORD(line_draw);
889    ORD(polygon_draw);
890    ORD(gradient_new);
891    ORD(gradient_free);
892    ORD(gradient_color_stop_add);
893    ORD(gradient_alpha_stop_add);
894    ORD(gradient_color_data_set);
895    ORD(gradient_alpha_data_set);
896    ORD(gradient_clear);
897    ORD(gradient_fill_set);
898    ORD(gradient_fill_angle_set);
899    ORD(gradient_fill_spread_set);
900    ORD(gradient_angle_set);
901    ORD(gradient_offset_set);
902    ORD(gradient_direction_set);
903    ORD(gradient_type_set);
904    ORD(gradient_is_opaque);
905    ORD(gradient_is_visible);
906    ORD(gradient_render_pre);
907    ORD(gradient_render_post);
908    ORD(gradient_draw);
909    ORD(image_load);
910    ORD(image_new_from_data);
911    ORD(image_new_from_copied_data);
912    ORD(image_free);
913    ORD(image_size_get);
914    ORD(image_size_set);
915    ORD(image_dirty_region);
916    ORD(image_data_get);
917    ORD(image_data_put);
918    ORD(image_alpha_set);
919    ORD(image_alpha_get);
920    ORD(image_border_set);
921    ORD(image_border_get);
922    ORD(image_draw);
923    ORD(image_comment_get);
924    ORD(image_format_get);
925    ORD(image_colorspace_set);
926    ORD(image_colorspace_get);
927    ORD(image_native_set);
928    ORD(image_native_get);
929    ORD(image_cache_flush);
930    ORD(image_cache_set);
931    ORD(image_cache_get);
932    ORD(font_draw);
933    /* now advertise out own api */
934    em->functions = (void *)(&func);
935    return 1;
936 }
937
938 EAPI void
939 module_close(void)
940 {
941 }
942
943 EAPI Evas_Module_Api evas_modapi = 
944 {
945    EVAS_MODULE_API_VERSION, 
946      EVAS_MODULE_TYPE_ENGINE,
947      "xrender_x11",
948      "none"
949 };
950